Java serial communication programming example

Serial communication principle

1. Serial communication means that the serial port transmits and receives bytes in bits. Although slower than parallel communication in bytes, the serial port can receive data with one line while using one line.

2. The serial port is a very common device communication protocol on the computer (not to be confused with the Universal Serial Bus Universal Serial Bus or USB)

3. Ground, serial port is used for the transmission of ASCII characters. Communication is done using 3 wires: (1) ground, (2) transmit, and (3) receive. Since serial communication is asynchronous, a port can send data on one line while receiving data on another line. Other lines are used for handshaking, but are not required. The most important parameters for serial communication are bit rate, data bits, stop bits, and parity. For two ports that communicate, these parameters must match

4.-232 (ANSI/EIA-232 standard) is the serial connection standard on IBM-PC and its compatible machines. RS-422 (EIA RS-422-AStandard) is the serial connection standard for Apple's Macintosh computers. RS-485 (EIA-485 standard) is an improvement of RS-422.

When it comes to open source, I am afraid that few people do not pick up the big name. Students have learned the knowledge through open source code. The programmer has gained the success experience of others through the open source library and the project that can be completed on time. The merchants have made money through open source software... In short, they are all happy. However, the primary drawback of open source software or libraries is that most of them lack detailed documentation and examples of use, or that software code is used by you, that is, documents, examples, and post-service collections. It's no wonder, after all, like a famous NBA player said: "I have to raise a family, so don't talk to me for a contract below $10, otherwise I would rather stay." Yes, people who support open source also have to raise a family, and it is not excessive to collect some money. If you want to spend money and learn knowledge, you can only use the network. I just want to throw a brick and jade, make a small contribution to the open source business, and solve even a small problem for your project.

Although the content introduced in this series is not a web framework, nor an open source server, I believe that as a programmer, what kind of problems will be encountered. Sometimes the simpler problem is more difficult; the smaller the place, the less the guy who can't find the hand. As long as you don't only deal with "architecture", "components", and "framework" all day long, I believe that what I said will be used.

1 Introduction to serial communication

1.1 Common Java Serial Port Package

1.2 Serial port package installation (under Windows)

2 Serial Port API Overview

2.1 javax.comm.CommPort

2.2 javax.comm.CommPortIdentifier

2.3 javax.comm.SerialPort

2.4 Serial API Example

2.4.1 List all available serial ports of this machine

2.4.2 Configuration of Serial Port Parameters

2.4.3 Reading and Writing of Serial Port

3 General mode of serial communication and its problems

3.1 event listener model

3.2 Thread model for serial port read data

3.3 The third method

4 Conclusion

1 Introduction to serial communication

Many applications and tests of embedded systems or sensor networks require communication with embedded devices or sensor nodes via a PC. Among them, the most commonly used interface is RS-232 serial port and parallel port (in view of the complexity of the USB interface and the need for a large amount of data transmission, the USB interface is still too expensive here, and currently there is a USB-enabled package in addition to SUN. In addition, I have not seen other Java class libraries that directly support USB.) SUN's CommAPI provides support for common RS232 serial ports and IEEE1284 parallel port communication. RS-232-C (also known as EIA RS-232-C, hereinafter referred to as RS232) was developed in 1970 by the American Electronics Industry Association (EIA) in conjunction with Bell Systems, modem manufacturers and computer terminal manufacturers for serial communication. Standard. RS232 is a full-duplex communication protocol that allows simultaneous data reception and transmission.

1.1 Common Java Serial Port Package

At present, the common Java serial port package has the serial communication API released by SUN in 1998: comm2.0.jar (under Windows), comm3.0.jar (Linux/Solaris); IBM's serial communication API and an open source implementation. In view of the fact that Sun's API is more commonly used under Windows and IBM's implementation is the same as Sun's API level, the open source implementation is not as reassuring as the products of the two major manufacturers. Here, only the serial communication of SUN is introduced. The use of the API on the Windows platform.

1.2 Serial port package installation (under Windows)

Go to the SUN website and download javacomm20-win32.zip. The included items are as follows:

Java serial communication programming example

According to its instructions (Readme.html), in order to use the serial port package for serial communication, in addition to setting the environment variables, also copy win32com.dll to the "JDK" / bin directory; copy comm.jar Go to "JDK"/lib; copy javax.comm.properties to the "JDK"/lib directory as well. However, when you actually use the serial port package, it is not enough to do this. Because usually when running "java MyApp", MyApp is started by the virtual machine under JRE. And we only copy the above files to the corresponding directory of the JDK, so the application will prompt to find the serial port. The solution to this problem is very simple, we just need to put the above mentioned files in the corresponding directory of the JRE.

It's worth noting that when using the serial API in a web application, you will encounter other more complicated problems. If you are interested, you can check the post on the "The Applet uses javacomm20 to read the client serial port on the webpage" in the CSDN community.

2 Serial Port API Overview

2.1 javax.comm.CommPort

This is an abstract class for describing a port that is supported by the underlying system. It contains some high-level IO control methods that are common to all different communication ports. Both SerialPort and ParallelPort are subclasses of the former, which are used to control the serial port and the latter to control the parallel port. Both have different control methods for the underlying physical ports. Here we only care about SerialPort.

2.2 javax.comm.CommPortIdentifier

This class is mainly used to manage and set the serial port. It is the core class for access control of the serial port. Mainly includes the following methods

l Determine if there is a communication port available

l Open the communication port for IO operations

l determine the ownership of the port

l handle contention for port ownership

l Manage events caused by port ownership changes (Event)

2.3 javax.comm.SerialPort

This class is used to describe the underlying interface of an RS-232 serial communication port, which defines the minimum set of functions required for serial communication. Through it, users can directly read, write and set up the serial port.

2.4 Serial API Example

The big paragraph of text is not as clear as a small example. Let's take a look at the serial port package's own example - a small piece of code in SerialDemo to deepen the understanding of the use of the serial API core class.

2.4.1 List all available serial ports of this machine

Void listPortChoices() {

CommPortIdentifier portId;

Enumeration en = CommPortIdentifier.getPortIdentifiers();

// iterate through the ports.

While (en.hasMoreElements()) {

portId = (CommPortIdentifier) ​​en.nextElement();

If (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {

System.out.println(portId.getName());

}

}

portChoice.select(parameters.getPortName());

}

The above code can list all the available serial port names of the current system. The output on my machine is COM1 and COM3.

2.4.2 Configuration of Serial Port Parameters

The serial port generally has the following parameters to be configured before the serial port is opened:

Java serial communication programming example

Includes baud rate, input/output flow control, data bits, stop bits, and parity.

SerialPort sPort;

Try {

sPort.setSerialPortParams(BaudRate, Databits, Stopbits, Parity);

/ / Set the input / output control flow

sPort.setFlowControlMode(FlowControlIn | FlowControlOut);

} catch (UnsupportedCommOperationException e) {}

2.4.3 Reading and Writing of Serial Port

You need to open a serial port before reading and writing to the serial port:

CommPortIdentifier portId = CommPortIdentifier.getPortIdentifier(PortName);

Try {

SerialPort sPort = (SerialPort) portId.open ("serial port owner name", timeout wait time);

} catch (PortInUseException e) {/ / throw this exception if the port is occupied

Throw new SerialConnectionException(e.getMessage());

}

/ / used to write data to the serial port

OutputStream os = new BufferedOutputStream(sPort.getOutputStream());

Os.write(int data);

/ / used to read data from the serial port

InputStream is = new BufferedInputStream(sPort.getInputStream());

Int receivedData = is.read();

Read out is int, you can convert it to other types you need.

It should be noted here that since the Java language has no unsigned type, that is, all types are signed, especially when it comes from byte to int. Because if the highest bit of byte is 1, then it will be occupied by 1 when converted to int type. In this way, the number of the byte type originally 10,000,000 becomes int type becomes 1111111110000000, which is a very serious problem and should be avoided.

3 General mode of serial communication and its problems

Finally, I finished the basic knowledge that I hate the most. Let's start our research focus on serial application. Since writing data to the serial port is very simple, here we only focus on reading data from the serial port. Generally, the serial communication application has two modes, one is to implement the SerialPortEventListener interface, listen to various serial port events and handle them accordingly; the other is to establish an independent receiving thread to be responsible for data reception. Since these two methods have serious problems in some cases (as for the problem, I will sell them first), so my implementation uses a third method to solve this problem.

3.1 event listener model

Now let's see how the event listener model works.

:

First you need to add "implements SerialPortEventListener" to your port control class (such as SManager).

l Add the following code during initialization:

Try {

SerialPort sPort.addEventListener(SManager);

} catch (TooManyListenersException e) {

sPort.close();

Throw new SerialConnectionException("too many listeners added");

}

sPort.notifyOnDataAvailable(true);

l Override the public void serialEvent(SerialPortEvent e) method, in which the following events are evaluated:

BI - Communication is interrupted.

CD - carrier detection.

CTS - Clear Send.

DATA_AVAILABLE - There is data arriving.

DSR - The data device is ready.

FE - frame error.

OE - Overflow error.

OUTPUT_BUFFER_EMPTY - The output buffer has been cleared.

PE - Parity error.

RI - Ringing indication.

The most common one is DATA_AVAILABLE--the serial port has a data arrival event. That is to say, when the serial port has data arriving, you can receive and process the received data in the serialEvent. However, in my practice, I encountered a very serious problem.

First, let me describe my experiment: my application needs to receive the query data sent back from the serial port by the sensor node, and display the result as an icon. The baud rate set by the serial port is 115200. Kawaguchi returns a set of data (about 30 bytes) every 128 milliseconds, and the period (that is, the duration) is 31 seconds. When measured, it should return more than 4,900 bytes in a single cycle. With the event listener model, I can only receive less than 1500 bytes. I don't know where these bytes are going. It is not clear what is missing. That part of the data. It's worth noting that this is the result of all the processing code in serialEvent(), leaving only the result of the print code. The data loss is so serious that I can't stand it, so I decided to use other methods.

3.2 Thread model for serial port read data

As the name suggests, this model writes the operation of receiving data as a thread:

Public void startReadingDataThread() {

Thread readDataProcess = new Thread(new Runnable() {

Public void run() {

While (newData != -1) {

Try {

newData = is.read();

System.out.println(newData);

//Other processing

.........

} catch (IOException ex) {

System.err.println(ex);

Return;

}

}

readDataProcess.start();

}

In my application, I packaged the received data into a cache and then started another thread to fetch and process the data from the cache. The two threads work together in a producer-consumer model, and the flow of data is shown in the following figure:

Java serial communication programming example

In this way, I have successfully solved the problem of losing data. However, I didn't feel happy for a long time and I found another equally serious problem: although this time I no longer lost data, but after the original cycle (31 seconds), the sensor power saving has stopped transmitting data, but my serial thread still In the hard work of reading the serial port operation, the console can also see that the received data is still being printed. It turns out that because the data sent by the sensor node is too fast, and my receiving thread can't handle it, InputStream first caches the bytes that have arrived but have not been processed yet, which leads to the fact that the sensor node no longer sends data. The console can still see the strange phenomenon of data being printed continuously. The only thing that is fortunate is that the last received data is really about 4900 bytes, and there is no loss. However, when the last data is processed, it is almost a minute and a half. This time is much longer than the node operation cycle. This delay is a disaster for a real-time display system!

Later I thought, is it because the synchronization and communication between the two threads caused the data to be received slowly? So I removed all the processing code in the code that received the thread, and only kept the statement that printed the received data, the result is still the same. It seems that the communication between threads does not hinder the data reception speed, but the thread model causes the data reception delay in the case where the data transmission rate of the sender is too fast. The point here is that the two models of the former should be easy to use when the data transmission rate is not so fast, but special cases should be handled specially.

3.3 The third method

After suffering for a long time (Boss reminds me every day), chance, I heard that TinyOS (also open source) is part of the serial communication part similar to my application, so I downloaded it 1.x The Java code part of the version refers to its processing method. The way to solve the problem is actually very simple, that is, starting from the root. The root cause is not caused by the receiving thread, then, I simply cancel the receiving thread and the shared cache as an intermediary, and directly call the serial port read data method in the processing thread to solve the problem (what, why not treat the thread also And cancel?----all cancel the application interface is not locked? So must be retained) then the program becomes like this:

Public byte[] getPack(){

While (true) {

// PacketLength is the packet length

Byte[] msgPack = new byte[PacketLength];

For(int i = 0; i " PacketLength; i++){

If( (newData = is.read()) != -1){

msgPack[i] = (byte) newData;

System.out.println(msgPack[i]);

}

}

Return msgPack;

}

}

Calling this method in the processing thread returns the required data sequence and processing it, so that there is no loss of data and no data reception delay. The only thing to note here is that is.read() always returns -1 when the serial port stops sending data or no data. If you find -1 at the beginning of receiving data, don't care about it and continue to receive it until you receive it. The data so far.

4 Conclusion

This article introduces the basics of serial communication, as well as several commonly used modes. Through practice, some questions were raised and resolved at the end. It is worth noting that for the first method, I have increased the time the sensor is sent from 128 milliseconds to 512 milliseconds. There is still a serious data loss, so if your application requires very precise results, the data is transmitted. If the rate is fast, it is best not to use the first method. For the second method, because it is a thread-causing problem, it should be different for different machines. It should be better for machines that handle multi-threading. But my machine is Inter Ben four 3.0 dual-core CPU + 512DDR memory, so the delay is so powerful, but also a strong CPU? So for the transmission with a large amount of data, still use the third method. However, there are many world problems, and the unknown problems are much more than the known ones. Maybe there are other problems. I welcome you to study with me through the following contact methods.

TEMPER GLASS

Mietubl Tempered Glass Screen Protector,High Transparent Tempered Glass,Tempered Glass,Anti-Spy Hot-Selling Tempered Glass

Mietubl Global Supply Chain (Guangzhou) Co., Ltd. , https://www.mietublmachine.com