About RXTX
RXTX is an open source java class library that provides serial and parallel port communication. The files published by this project follow LGPL protocol.
RXTX project provides compatibility under windows, Linux, Mac OS X, and Solaris Operating Systems javax.comm The implementation of the serial communication package API provides quite convenient for other developers to develop serial applications under such systems.
The use of RXTX is similar to that provided by sun comm.jar Basically the same, the most obvious difference in programming is that the package name to be included is javax.comm . changed to gnu.io .
The core of rxtx API is the abstract CommPort class (used to describe an abstract class of ports supported by the underlying system, which contains some high-level IO control methods, which are common to all different communication ports) and its two subclasses: SerialPort class and parallelport class. Among them, the SerialPort class is used for serial port communication, and the parallelport class is used for parallel port communication. The CommPort class also provides regular communication modes and methods, such as getInputStream() method and getOutputStream() method, which are dedicated to communicating with devices on the port.
However, the constructor of these classes is intentionally set to non-public. Therefore, objects cannot be constructed directly, but first through static CommPortIdentifer.getPortIdentifiers() get the port list, select the required port from the port list, and call the Open() method of the CommPortIdentifier object, so you can get a CommPort object. Of course, the type of CommPort object should also be converted to a non Abstract subclass, indicating that it is a specific communication device. This subclass can be one of SerialPort class and parallelport class. Next, we will introduce CommPortIdentifier class and serial port class in detail.
Interface CommDriver part of the loadable device driver interface CommPortOwnershipListener passes ownership events of various communication ports ParallelPortEventListener passing parallel port events SerialPortEventListener passing serial port events class CommPort communication port CommPortIdentifier communication port management ParallelPort parallel communication port ParallelPortEvent Serial port RS-232 serial communication port SerialPortEvent serial port event Abnormal class NoSuchPortException thrown when the driver cannot find the specified port PortInUseException thrown when the specified port is in use Unsupported commoperationexception driver does not allow throw on specified operation CommPortIdentifier class This class is mainly used to manage and set the communication port. It is the core class for access control of the port. It mainly includes the following methods: addPortName(String,int, CommDriver) add port name to port list addPortOwnershipListener(CommPortOwnershipListener) add a listener owned by the port removePortOwnershipListener(CommPortOwnershipListener) remove the listener owned by the port getCurrentOwner() gets the object or application that currently owns the port getName() gets the port name getPortIdentifier(CommPort) gets the CommPortIdentifier type object of the specified open port getPortIdentifier(String) gets the CommPortIdentifier type object of the port named by the parameter getPortIdentifiers() gets the list of ports in the system getPortType() gets the type of port isCurrentlyOwned() determines whether the current port is occupied open(FileDescriptor) open the port with the type described in the file open(String,int) open port, two parameters: program name, delay time (milliseconds) SerialPort class This class is used to describe the bottom interface of an RS-232 serial communication port, which defines the minimum set of functions required for serial communication. Through it, the user can read, write and set the serial port directly. Description of static member variables of serial port parameters in SerialPort class: DATABITS_5 data bit is 5 DATABITS_6 data bit is 6 DATABITS_7 data bit is 7 DATABITS_8 data bit is 8 PARITY_NONE space check PARITY_ODD test of odd PARITY_EVEN even test PARITY_MARK inspection PARITY_SPACE no inspection STOPBITS_1 stop bit is 1 STOPBITS_2 stop bit is 2 STOPBITS_1_5 stop bit is 1.5 Method description of serial port parameters in SerialPort class: getBaudRate() to get the baud rate getParity() gets the inspection type getDataBits() gets the number of data bits getStopBits() gets stop bits setSerialPortParams(int,int, int, int) set the serial port parameters as (baud rate, data bit, stop bit, parity check) Description of static member variables of events in SerialPort class: BI Break interrupt FE Framing error CD Carrier detect carrier sense OE overflow error CTS Clear to send PE Parity error parity error DSR Data set ready RI Ring indicator ring detection DATA_AVAILABLE data in the available serial port OUTPUT_BUFFER_EMPTY output buffer cleared Method description of events in SerialPort class: Is there carrier in isCD() Is isCTS() cleared for transfer Is isDSR() data ready Is isDTR() data side ready Whether isRI() rings Whether isRTS() requires delivery addEventListener(SerialPortEventListener) adds a serial port event listener to the SerialPort object removeEventListener() removes the serial event listener from the SerialPort object notifyOnBreakInterrupt(boolean) set interrupt event true valid, false invalid notifyOnCarrierDetect(boolean) set carrier listening event true valid, false invalid notifyOnCTS(boolean) setting clear send event true valid, false invalid notifyOnDataAvailable(boolean) set the event that the serial port has data true valid, false invalid notifyOnDSR(boolean) setting data ready event true is valid, false is invalid Notifyonframeingerror (Boolean) setting error event true valid, false invalid notifyOnOutputEmpty(boolean) set send buffer to null event true valid, false invalid Notifyonpartityerror (Boolean) setting parity error event true valid, false invalid notifyOnRingIndicator(boolean) setting the ring detection event true is valid, false is invalid getEventType() gets that the return value of the event type occurred is int sendBreak(int) sets the time of the interrupt process. The parameter is the millisecond value setRTS(boolean) sets or clears the RTS bit setDTR(boolean) sets or clears the DTR bit Other common methods in SerialPort: close() close the serial port getOutputStream() gets an output stream of type OutputStream getInputStream() gets the input stream of InputStream type
preparation
- RXTX package: rxtx-2.2pre2-bins.zip
- Serial virtual tool: vspd.exe
- Serial debugging tool: amcktszs_v2.4.0.0.exe
Install RXTX package
Unzip rxtx-2.2pre2-bins.zip , will RXTXcomm.jar Add to the project dependency library, corresponding to the rxtxSerial.dll and rxtxParallel.dll Put the file in the bin directory of jdk
Precondition: maven has been added to the environment variable mvn install:install-file -DgroupId=gnu.io -DartifactId=RXTXcomm -Dversion=1.0 -Dpackaging=jar -Dfile=E:\Work\Yotrio\libs\RXTXcomm.jar
Tool to create a pair of virtual serial ports
Image.png
Open the serial port debugging tool and configure the serial port parameters
Image [2].png
Sample Demo
Package serial port reading and writing tool class
/** * Module name: projects parent com.yotrio.common * Function Description: serial port service class, which provides services such as opening and closing serial port, reading and sending serial port data (single design mode is adopted) * <br> * Developer: Wangyq * Creation time: 10:05, September 20, 2018 * System version: 1.0.0 **/ public class SerialPortUtil { private static SerialPortUtil serialPortUtil = null; static { //Initializes a SerialTool object when the class is loaded by ClassLoader if (serialPortUtil == null) { serialPortUtil = new SerialPortUtil(); } } //Privatize the constructor of the SerialTool class. No other classes are allowed to generate SerialTool objects private SerialPortUtil() { } /** * Get the SerialTool object that provides the service * * @return serialPortUtil */ public static SerialPortUtil getSerialPortUtil() { if (serialPortUtil == null) { serialPortUtil = new SerialPortUtil(); } return serialPortUtil; } /** * Find all available ports * * @return List of available port names */ public static final ArrayList<String> findPort() { //Obtain all currently available serial ports Enumeration<CommPortIdentifier> portList = CommPortIdentifier.getPortIdentifiers(); ArrayList<String> portNameList = new ArrayList<>(); //Add the available serial port name to the List and return the List while (portList.hasMoreElements()) { String portName = portList.nextElement().getName(); portNameList.add(portName); } return portNameList; } /** * Open serial port * * @param portName Port name * @param baudrate Baud rate * @param databits Data bits * @param parity Parity bit * @param stopbits Stop bit * @return Serial port object * @throws SerialPortParameterFailure Failed to set serial port parameters * @throws NotASerialPort Port pointing device is not of serial port type * @throws NoSuchPort There is no serial device corresponding to this port * @throws PortInUse Port occupied */ public static final SerialPort openPort(String portName, int baudrate, int databits, int parity, int stopbits) throws SerialPortParameterFailure, NotASerialPort, NoSuchPort, PortInUse { try { //Identify ports by port name CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName); //Open the port and give the port name and a timeout CommPort commPort = portIdentifier.open(portName, 2000); //Judge whether it is serial port if (commPort instanceof SerialPort) { SerialPort serialPort = (SerialPort) commPort; try { //Set the baud rate and other parameters of the serial port serialPort.setSerialPortParams(baudrate, databits, stopbits, parity); } catch (UnsupportedCommOperationException e) { throw new SerialPortParameterFailure(); } //System.out.println("Open " + portName + " sucessfully !"); return serialPort; } else { //Not serial throw new NotASerialPort(); } } catch (NoSuchPortException e1) { throw new NoSuchPort(); } catch (PortInUseException e2) { throw new PortInUse(); } } /** * Close the serial port * * @param serialPort Serial port object to be closed */ public static void closePort(SerialPort serialPort) { if (serialPort != null) { serialPort.close(); serialPort = null; } } /** * Send data to serial port * * @param serialPort Serial port object * @param order Data to be sent * @throws SendDataToSerialPortFailure Sending data to serial port failed * @throws SerialPortOutputStreamCloseFailure Error closing output stream of serial port object */ public static void sendToPort(SerialPort serialPort, byte[] order) throws SendDataToSerialPortFailure, SerialPortOutputStreamCloseFailure { OutputStream out = null; try { out = serialPort.getOutputStream(); out.write(order); out.flush(); } catch (IOException e) { throw new SendDataToSerialPortFailure(); } finally { try { if (out != null) { out.close(); out = null; } } catch (IOException e) { throw new SerialPortOutputStreamCloseFailure(); } } } /** * Read data from serial port * * @param serialPort SerialPort object for which the connection is currently established * @return Data read * @throws ReadDataFromSerialPortFailure Error reading data from serial port * @throws SerialPortInputStreamCloseFailure Error closing serial object input stream */ public static byte[] readFromPort(SerialPort serialPort) throws ReadDataFromSerialPortFailure, SerialPortInputStreamCloseFailure { InputStream in = null; byte[] bytes = null; try { in = serialPort.getInputStream(); int bufflenth = in.available(); //Get the data length in the buffer while (bufflenth != 0) { bytes = new byte[bufflenth]; //Initialize byte array as the length of data in buffer in.read(bytes); bufflenth = in.available(); } } catch (IOException e) { throw new ReadDataFromSerialPortFailure(); } finally { try { if (in != null) { in.close(); in = null; } } catch (IOException e) { throw new SerialPortInputStreamCloseFailure(); } } return bytes; } /** * Add listener * * @param port Serial port object * @param listener Serial port monitor * @throws TooManyListeners Too many listening class objects */ public static void addListener(SerialPort port, SerialPortEventListener listener) throws TooManyListeners { try { //Add monitor to serial port port.addEventListener(listener); //Set to wake up listening receiving thread when data arrives port.notifyOnDataAvailable(true); //Set to wake up interrupt thread when communication is interrupted port.notifyOnBreakInterrupt(true); } catch (TooManyListenersException e) { throw new TooManyListeners(); } } /** * Delete listener * * @param port Serial port object * @param listener Serial port monitor * @throws TooManyListeners Too many listening class objects */ public static void removeListener(SerialPort port, SerialPortEventListener listener) { //Delete serial listener port.removeEventListener(); } }
Integrate websocket to get and push to the front page for real-time display
@ServerEndpoint(value = "/websocket") //Accept websocket request path @Component public class PoundWebSocket { private Logger logger = LoggerFactory.getLogger(this.getClass()); /** * Save all online socket connections */ private static Map<String, PoundWebSocket> webSocketMap = new LinkedHashMap<>(); /** * Record the current number of Online */ private static int count = 0; /** * Current connection (each websocket connection will create a MyWebSocket instance */ private Session session; /** * Creating a listening serial port */ private static SerialPort serialPort = null; /** * Create listener */ private static SerialPortEventListener serialPortEventListener = null; /** * Monitor serial port */ private static String PORT_NAME; /** * Monitor serial port baud rate */ private static int BAUD_RATE; /** * Data bits */ private static int DATA_BITS; /** * Stop bit */ private static int STOP_BITS; /** * Parity bit */ private static int PARITY; /** * Model of Weighbridge */ private static String MODEL; private static IPoundInfoService poundInfoService; private static ApplicationContext applicationContext; public static void setApplicationContext(ApplicationContext applicationContext) { PoundWebSocket.applicationContext = applicationContext; } private static StringBuffer stringBuffer = new StringBuffer(); /** * Handle connection establishment * * @param session */ @OnOpen public void onOpen(Session session) { if (poundInfoService == null) { poundInfoService = applicationContext.getBean(IPoundInfoService.class); } //Get weighbridge information PoundInfo poundInfo = poundInfoService.findOne(); PORT_NAME = poundInfo.getSerialPort(); BAUD_RATE = poundInfo.getBaudRate(); MODEL = poundInfo.getModel(); DATA_BITS = poundInfo.getDataBits() != null ? poundInfo.getDataBits() : SerialPort.DATABITS_8; STOP_BITS = poundInfo.getStopBits() != null ? poundInfo.getStopBits() : SerialPort.STOPBITS_1; PARITY = poundInfo.getParity() != null ? poundInfo.getParity() : SerialPort.PARITY_NONE; this.session = session; webSocketMap.put(session.getId(), this); addCount(); // logger.info("new connection join: {}", session.getId()); try { //Make sure that the serial port has been closed. If not, it will fail to listen to the serial port again if (serialPort != null) { SerialPortUtil.closePort(serialPort); serialPort = null; } //Create serial port COM5 bit serial port name 9600 baud rate if (serialPort == null && StringUtils.isNotEmpty(PORT_NAME) && StringUtils.isNotEmpty(MODEL)) { serialPort = SerialPortUtil.openPort(PORT_NAME, BAUD_RATE, DATA_BITS, PARITY, STOP_BITS); // logger.info("create serial port: {}", serialPort); //Set serial monitoring SerialPortUtil.addListener(serialPort, new SerialPortEventListener() { @Override public void serialEvent(SerialPortEvent serialPortEvent) { if (serialPortEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) { try { //Read serial data byte[] bytes = SerialPortUtil.readFromPort(serialPort); //Parse string by model switch (MODEL) { case PoundConstant.MODEL_XK_3190: parsingString1(bytes); break; case PoundConstant.MODEL_XK_3190_10: parsingString2(bytes); break; case PoundConstant.MODEL_D_2008: parsingString1(bytes); break; case PoundConstant.MODEL_DK_3230_D_6: parsingString3(bytes); break; case PoundConstant.MODEL_D_2009_F: parsingString4(bytes); break; default: String value = String.valueOf(Integer.valueOf(new String(bytes, "GB2312")) - RandomUtil.randomInt(1000, 10000)); sendMessageToAll(value); } // System.out.println("received data:" + new string (bytes, "GB2312") + "---" + new date()); } catch (ReadDataFromSerialPortFailure readDataFromSerialPortFailure) { logger.error(readDataFromSerialPortFailure.toString()); } catch (SerialPortInputStreamCloseFailure serialPortInputStreamCloseFailure) { logger.error(serialPortInputStreamCloseFailure.toString()); } catch (UnsupportedEncodingException e) { logger.error(e.toString()); } catch (IOException e) { logger.error(e.toString()); } } } }); } } catch (SerialPortParameterFailure serialPortParameterFailure) { logger.error(serialPortParameterFailure.toString()); } catch (NotASerialPort notASerialPort) { logger.error(notASerialPort.toString()); } catch (NoSuchPort noSuchPort) { logger.error(noSuchPort.toString()); } catch (PortInUse portInUse) { logger.error(portInUse.toString()); } catch (TooManyListeners tooManyListeners) { logger.error(tooManyListeners.toString()); } } /** * Parse string method 1 * * @param bytes Bytecode obtained */ private void parsingString1(byte[] bytes) { StringBuffer sb = new StringBuffer(); //Convert ASCII code to string for (int i = 0; i < bytes.length; i++) { sb.append((char) Integer.parseInt(String.valueOf(bytes[i]))); } //Parse string String[] strs = sb.toString().trim().split("\\+"); int weight = 0; for (int j = 0; j < strs.length; j++) { if (strs[j].trim().length() >= 6) { weight = Integer.parseInt(strs[j].trim().substring(0, 6)); //send data sendMessageToAll(String.valueOf(weight)); break; } } } /** * Parse string method 2 * * @param bytes Bytecode obtained */ private void parsingString2(byte[] bytes) { StringBuffer sb = new StringBuffer(); //Convert ASCII to string for (int i = 0; i < bytes.length; i++) { sb.append((char) Integer.parseInt(String.valueOf(bytes[i]))); } //Parse string String[] strs = sb.toString().trim().split("\\+"); double weight = 0; for (int j = 0; j < strs.length; j++) { if (strs[j].trim().length() >= 6) { weight = Double.parseDouble(strs[j].trim().substring(0, 6)) / 10; //send data sendMessageToAll(String.valueOf(weight)); break; } } } /** * Parse string method 3 * * @param bytes Bytecode obtained */ private void parsingString3(byte[] bytes) { StringBuffer sb = new StringBuffer(); //Convert ASCII code to string for (int i = 0; i < bytes.length; i++) { sb.append((char) Integer.parseInt(String.valueOf(bytes[i]))); } // logger.info("sb:" + sb.toString()); sb.reverse(); //Parse string String[] strs = sb.toString().trim().split("\\="); double weight = 0; for (int j = 0; j < strs.length; j++) { if (strs[j].trim().length() >= 6) { weight = Double.parseDouble(strs[j].trim()); //send data sendMessageToAll(String.valueOf(weight)); break; } } } /** * Parse string method 3 * * @param bytes Bytecode obtained */ private void parsingString4(byte[] bytes) { StringBuffer sb = new StringBuffer(); //Convert ASCII code to string for (int i = 0; i < bytes.length; i++) { sb.append((char) Integer.parseInt(String.valueOf(bytes[i]))); } // logger.info("sb:" + sb.reverse()); //String inversion sb.reverse(); //Parse string String[] strs = sb.toString().trim().split("\\="); int weight = 0; for (int j = 0; j < strs.length; j++) { if (strs[j].trim().length() >= 6) { weight = Integer.parseInt(strs[j].trim().substring(0, 6)); //send data sendMessageToAll(String.valueOf(weight)); break; } } } /** * Accept message * * @param message * @param session */ @OnMessage public void onMessage(String message, Session session) { logger.info("Client received{}Message:{}", session.getId(), message); try { this.sendMessage(message); } catch (Exception e) { logger.error(e.toString()); } } /** * Handling errors * * @param error * @param session */ @OnError public void onError(Throwable error, Session session) { logger.info("An error occurred{},{}", session.getId(), error.getMessage()); } /** * Process connection closure */ @OnClose public void onClose() { webSocketMap.remove(this.session.getId()); reduceCount(); logger.info("Connection closed:{}", this.session.getId()); //Close the serial port after the connection is closed, and listen to the serial port again the next time the connection is opened if (serialPort != null) { SerialPortUtil.closePort(serialPort); serialPort = null; } } /** * Mass message * * @param message */ public void sendMessageToAll(String message) { for (int i = 0; i < webSocketMap.size(); i++) { try { // logger.info("session:id=" + session.getId()); this.session.getBasicRemote().sendText(message); } catch (IOException e) { logger.error(e.getMessage()); } } } /** * send message * * @param message * @throws IOException */ public void sendMessage(String message) throws IOException { // logger.info("session:id=" + session.getId()); this.session.getBasicRemote().sendText(message); } //Broadcast message public static void broadcast() { PoundWebSocket.webSocketMap.forEach((k, v) -> { try { v.sendMessage("This is a test broadcast"); } catch (Exception e) { } }); } //Get the number of online connections public static int getCount() { return count; } //Operation count, use synchronized to ensure thread safety public static synchronized void addCount() { PoundWebSocket.count++; } public static synchronized void reduceCount() { PoundWebSocket.count--; } }
Author: brother xiaotudou
Link: