1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > Rxtx串口通信

Rxtx串口通信

时间:2022-01-13 19:54:25

相关推荐

Rxtx串口通信

最近项目中需要调用串口激光扫码枪,这也是我首次在java项目中实现调用硬件的功能,所以特别感兴趣,经过研究后,在这把实现串口激光扫码枪的实现过程和大家说一下:好了,下面我们要开始介绍详细的开发过程。第一、首先我们要安装硬件驱动,这个产品官网上都有,而且产品都有详细的用户手册,自己可以百度下载,这里就不再细讲。官网地址:/view_product.php?id=87&cid=71###第二、安装串口中文输出工具。推荐使用COM_Text V2.0。COM_Text软件可以仿真串行键输入的效果,将由串口(COM)或USB虚拟串口(USB Virtual COM)获得的数据信息(ASCII码)转换成字符(Unicode、简体中文、日文等)格式,在.txt文本文件或.doc微软Word文件上输出。 所连接的设备(如条码阅读器)使用的必须是RS232串口电缆线或USB电缆线(USB类型必须设置为“USB虚拟串口”)。无论PC机处于何种输入法,都可正确输出中英文等字符。第三、工具我们都准备好了,我们现在需要的是连接扫码枪,这里我要说明一下,因为我用的是笔记本电脑,大部分笔记本电脑已经不支持串口,所以我用了一根串口转USB线,大家可以根据自己的实际情况进行选择,当然也可以直接使用台式机,那就不需要考虑这件事了。第四步、扫码枪连到电脑之后,打开COM_Text软件,如果驱动安装正确,此工具会读出几个重要参数。端口名称、波特率、数据位、停止位、无奇偶校验等属性,这些属性后边我们用的到,这是属性也是我们连接扫码枪的必用参数。第五步、RXTX是个提供串口和并口通信的开源java类库,由该项目发布的文档均遵循LGPL协议。针对x86体系结构的Linux操作系统平台,RXTX的部署包括下面几个文档:* RXTXcomm.jar RXTX自己的实*librxtxSerial.so 由调用的底层串口库文档* librxtxParallel.so 由RXTXcomm.jar调用的底层并口库文档驱动的类配置文档,内容是Driver=gnu.io.RXTXCommDriver。我用的是mfz-rxtx-2.2-1207-win-x64这个版本。当你选择的时候,必须下载使用适配你电脑的版本,我的电脑是win10 64位专业版,所以必须得使用x64的项目,里面包含两个重要的dll文件,即rxtxParallel.dll、rxtxSerial.dll,我们需要把这两个文件放到C:\Windows\System32下。第六步、我们靠开始开发了,入口函数代码如下,

package .checknull.rxtx.main;import mPortIdentifier;import gnu.io.SerialPort;import java.util.ArrayList;import java.util.Arrays;import java.util.Enumeration;import java.util.HashMap;import java.util.List;import java.util.Observable;import java.util.Observer;import .checknull.rxtx.bean.SerialPortParms;import .checknull.rxtx.listener.SerialReader;public class SerialPortMain implements Observer {private List<String> mListComName; // 集合:串口名字private SerialReader sr = new SerialReader();public static void main(String[] args) {new SerialPortMain(); }public SerialPortMain() {searchSerialPort(); //搜索串口connectSerialPort(); //连接串口sendOrder(); //传数据// sr.close();//关闭串口}private void searchSerialPort() {mListComName = new ArrayList<String>();CommPortIdentifier portId;Enumeration enumeration = CommPortIdentifier.getPortIdentifiers();while (enumeration.hasMoreElements()) {portId = (CommPortIdentifier) enumeration.nextElement();if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {mListComName.add(portId.getName());}}}private void connectSerialPort() {String comName;if (mListComName.size() > 0) {comName = mListComName.get(0);String PortName = comName;String rate_value = SerialPortParms.RATE[0];String databit_value = SerialPortParms.DATABIT[0];String stopbit_value = SerialPortParms.STOPBIT[0];HashMap<String, Comparable> params = new HashMap<String, Comparable>();int parityInt = SerialPort.PARITY_NONE;params.put(SerialReader.PARAMS_PORT, PortName);// 端口名称params.put(SerialReader.PARAMS_RATE, rate_value); // 波特率params.put(SerialReader.PARAMS_DATABITS, databit_value); // 数据位params.put(SerialReader.PARAMS_STOPBITS, stopbit_value); // 停止位params.put(SerialReader.PARAMS_PARITY, parityInt); // 无奇偶校验params.put(SerialReader.PARAMS_TIMEOUT, 100); // 设备超时时间 1秒params.put(SerialReader.PARAMS_DELAY, 100); // 端口数据准备时间 1秒try {sr.open(params);sr.addObserver(SerialPortMain.this);System.out.println(PortName + ":已经打开");} catch (Exception e1) {System.out.println("端口被占用");}}}private void sendOrder() {byte []all = new byte[]{0x00,0x01,0x02};if ( all!= null) {sr.start();sr.run(all);}}@Overridepublic void update(Observable o, Object arg) {byte []date = (byte[])arg;System.out.println(Arrays.toString(date));}}

package .checknull.rxtx.listener;import mPort;import mPortIdentifier;import gnu.io.NoSuchPortException;import gnu.io.PortInUseException;import gnu.io.SerialPort;import gnu.io.SerialPortEvent;import gnu.io.SerialPortEventListener;import gnu.io.UnsupportedCommOperationException;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.util.ArrayList;import java.util.Enumeration;import java.util.HashMap;import java.util.HashSet;import java.util.List;import java.util.Observable;import java.util.TooManyListenersException;public class SerialReader extends Observable implements Runnable,SerialPortEventListener {static CommPortIdentifier portId;int delayRead = 100;int numBytes; //private static byte[] readBuffer = new byte[1024]; //static Enumeration portList;InputStream inputStream;OutputStream outputStream;static SerialPort serialPort;HashMap serialParams;Thread readThread;boolean isOpen = false;public static final String PARAMS_DELAY = "delay read"; //public static final String PARAMS_TIMEOUT = "timeout"; // 超时时间public static final String PARAMS_PORT = "port name"; // 端口名称public static final String PARAMS_DATABITS = "data bits"; //public static final String PARAMS_STOPBITS = "stop bits"; //public static final String PARAMS_PARITY = "parity"; // 奇偶校验public static final String PARAMS_RATE = "rate"; //private HashMap<Byte, byte[]> map;public boolean isOpen() {return isOpen;}/*** 初始化端口操作的参数.* * @throws SerialPortException* * @see*/public SerialReader() {isOpen = false;}public void open(HashMap params) throws NoSuchPortException,PortInUseException, IOException, UnsupportedCommOperationException,TooManyListenersException {serialParams = params;if (isOpen) {close();}/* try { */// 参数初始int timeout = Integer.parseInt(serialParams.get(PARAMS_TIMEOUT).toString());int rate = Integer.parseInt(serialParams.get(PARAMS_RATE).toString());int dataBits = Integer.parseInt(serialParams.get(PARAMS_DATABITS).toString());int stopBits = Integer.parseInt(serialParams.get(PARAMS_STOPBITS).toString());int parity = Integer.parseInt(serialParams.get(PARAMS_PARITY).toString());delayRead = Integer.parseInt(serialParams.get(PARAMS_DELAY).toString());String port = serialParams.get(PARAMS_PORT).toString();// 打开端口portId = CommPortIdentifier.getPortIdentifier(port);serialPort = (SerialPort) portId.open("SerialReader", timeout);inputStream = serialPort.getInputStream();serialPort.addEventListener(this);serialPort.notifyOnDataAvailable(true);serialPort.setSerialPortParams(rate, dataBits, stopBits, parity);isOpen = true;serialParams.clear();}public void run() {try {Thread.sleep(50);} catch (InterruptedException e) {e.printStackTrace();}}public void start() {try {outputStream = serialPort.getOutputStream();} catch (IOException e) {}try {readThread = new Thread(this);readThread.start();} catch (Exception e) {e.printStackTrace();}}public void run(byte[] message) {try {Thread.sleep(4);} catch (InterruptedException e) {}try {if (message != null) {System.out.println("run message:" + message);outputStream.write(message);}} catch (IOException e) {e.printStackTrace();}}public void close() {if (isOpen) {try {serialPort.notifyOnDataAvailable(false);serialPort.removeEventListener();inputStream.close();serialPort.close();isOpen = false;} catch (IOException ex) {// "关闭串口失败";ex.printStackTrace();}}}@Overridepublic void serialEvent(SerialPortEvent event) {String strs[] = null;try {Thread.sleep(delayRead);} catch (InterruptedException e) {e.printStackTrace();}switch (event.getEventType()) {case SerialPortEvent.BI: // 10 Break interrupt,通讯中断case SerialPortEvent.OE: // 7 Overrun error,溢位错误case SerialPortEvent.FE: // 9 Framing error,传帧错误case SerialPortEvent.PE: // 8 Parity error,校验错误case SerialPortEvent.CD: // 6 Carrier detect,载波检测case SerialPortEvent.CTS: // 3 Clear to send,清除发送case SerialPortEvent.DSR: // 4 Data set ready,数据设备就绪case SerialPortEvent.RI: // 5 Ring indicator,响铃指示case SerialPortEvent.OUTPUT_BUFFER_EMPTY: // 2 Output buffer is empty,输出缓冲区清空break;case SerialPortEvent.DATA_AVAILABLE: // 1 Data available at the serial port,端口有可用数据。读到缓冲数组,输出到终端try {// 多次读取,将所有数据读while (inputStream.available() > 0) {readBuffer = new byte[inputStream.available()];numBytes = inputStream.read(readBuffer);}// 打印接收到的字节数据//for (int i = 0; i < numBytes; i++) {strs = changeMessage(readBuffer, numBytes);//}System.out.print("条形码为:");for (int i = 0 ;i < strs.length; i++) {System.out.print(strs[i]);}} catch (IOException e) {e.printStackTrace();}break;}}// 通过observer pattern将收到的数据给observer// 将buffer中的空字节删除后再发送更新消息通知观察者public String[] changeMessage(byte[] message, int length) {boolean flag = false;byte type = message[3];setChanged();notifyObservers(message);List<String> list = new ArrayList<String>();for (int i = 0; i < message.length; i++) {String result = toAsciiImage(message[i]);list.add(result);}String strs[] = new String[list.size()];for (int i = 0; i < list.size(); i++) {strs[i] = list.get(i);}return strs;}public String toAsciiImage(byte b){String result = "";switch (b) {case 48:result = "0";break;case 49:result = "1";break;case 50:result = "2";break;case 51:result = "3";break;case 52:result = "4";break;case 53:result = "5";break;case 54:result = "6";break;case 55:result = "7";break;case 56:result = "8";break;case 57:result = "9";break;default:break;}return result;}static void listPorts() {Enumeration portEnum = CommPortIdentifier.getPortIdentifiers();while (portEnum.hasMoreElements()) {CommPortIdentifier portIdentifier = (CommPortIdentifier) portEnum.nextElement();}}static String getPortTypeName(int portType) {switch (portType) {case CommPortIdentifier.PORT_I2C:return "I2C";case CommPortIdentifier.PORT_PARALLEL:return "Parallel";case CommPortIdentifier.PORT_RAW:return "Raw";case CommPortIdentifier.PORT_RS485:return "RS485";case CommPortIdentifier.PORT_SERIAL:return "Serial";default:return "unknown type";}}public HashSet<CommPortIdentifier> getAvailableSerialPorts()// 本来static{HashSet<CommPortIdentifier> h = new HashSet<CommPortIdentifier>();Enumeration thePorts = CommPortIdentifier.getPortIdentifiers();while (thePorts.hasMoreElements()) {CommPortIdentifier com = (CommPortIdentifier) thePorts.nextElement();switch (com.getPortType()) {case CommPortIdentifier.PORT_SERIAL:try {CommPort thePort = com.open("CommUtil", 50);thePort.close();h.add(com);} catch (PortInUseException e) {System.out.println("Port, " + com.getName()+ ", is in use.");} catch (Exception e) {System.out.println("Failed to open port " + com.getName()+ e);}}}return h;}}

package .checknull.rxtx.bean;public class SerialPortParms {/** 串口号、波特率、校验位、数据位、停止位这些常量需要查看具体厂家提供的文档 */public static final String[] RATE = { "9600", "9600", "4800", "2400" };public static final String[] DATABIT = { "8", "7", "6", "5" };public static final String[] STOPBIT = { "1", "1.5", "2" };}

第七步、运行主程序之后,串口扫码枪就可以开始工作了。这里我要特别说一下,我扫描的一般都是条形码,大部分条形码都是采用的ASCII图形格式,因为扫描枪扫描出来的一般是十进制数字,所以在程序中转换了一下,转成ASCII值。结尾:我只给大家普及一个小知识,大部分药品盒上的条形码采用的ASCII图形格式,所以,童鞋们,为了知道其数字代表的十进制是多少,赶紧去背ASCII数值对照表吧。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。