物联网的媒介——java usb串口通信
背景:
15年暑假期间参加ICAN全国物联网大赛,主题是应用于各种气体危险场合的四轴飞行器的大气参数测试。由于需要地面服务器作为单片机数据与上位机的传输,并且要存储进数据库,开始写java usb串口的小程序。因各种事情的搁浅,并没有在大赛之前完成这个项目,最近几天将其简单的修改,实现了基本功能。
准备工作:
java主要发展方向为上位机软件方向,所以底层的开源包较少,且需要C语言写的脚本做铺垫,所以实现java的USB串口通讯过程比较复杂,下面是具体步骤:
1、需要一个RXTX.jar的开源包,切将内置文件按说明放置到指定位置。
说明如下:
1)、把rxtxParallel.dll、rxtxSerial.dll放置在:C:\WINDOWS\system32下。
2)、如果是在开发的时候(JDK),需要把RXTXcomm.jar、rxtxParallel.dll、rxtxSerial.dll拷贝到..\jre...\lib\ext下;
如:D:\Program Files\Java\jre1.6.0_02\lib\ext。
2、DButils包、数据库驱动包。
(两个驱动包。)
3、通信单片机。
4、数据库环境。
大体组成:
主要由面向对象、通信、JDBC、JDBCTools、Swing等几个累组成。通过Swing图形化界面将几个累贯穿起来,就形成了大体框架。主界面如下所示:
图1(主界面)
(由于是事后制作,并没有具体数据类型,只能将名称暂时定义为数据n,单位亦是如此。)
具体实现:
串口通信类:
需要对串口、频率、数据位、校验位、停止位等做相应的匹配,比较复杂。
public class SimpleRead implements Runnable, SerialPortEventListener {static CommPortIdentifier portId;//枚举类static Enumeration portList;
//String Xian = "";static boolean isOpen = false;InputStream inputStream;SerialPort serialPort;Thread readThread;public void Srun() {isOpen = false;portList = CommPortIdentifier.getPortIdentifiers();/*不带参数的getPortIdentifiers方法获得一个枚举对象,该对象又包含了系统中管理每个端口的CommPortIdentifier对象。注意这里的端口不仅仅是指串口,也包括并口。这个方法还可以带参数。getPortIdentifiers(CommPort)获得与已经被应 用程序打开的端口相对应的CommPortIdentifier对象。getPortIdentifier(String portName)获取指定端口名(比如“COM1”)的CommPortIdentifier对象。*/ System.out.println(Parity);while (portList.hasMoreElements()) { portId = (CommPortIdentifier) portList.nextElement();/*getPortType方法返回端口类型*/ if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {/* 找Windows下的第一个串口*/if (portId.getName().equals(com)) {/*找Unix-like系统下的第一个串口*///if (portId.getName().equals("/dev/term/a")) { SimpleRead reader = new SimpleRead();}}}}public SimpleRead() {try {/* open方法打开通讯端口,获得一个CommPort对象。它使程序独占端口。如果端口正被其他应用程序占用,将使用
CommPortOwnershipListener事件机制,传递一个PORT_OWNERSHIP_REQUESTED事件。每个端口都关联一个
InputStream和一个OutputStream。如果端口是用open方法打开的,那么任何的getInputStream都将返回 相同的数据流对象,除非有close被调用。有两个参数,第一个为应用程序名;第二个参数是在端口打开 时阻塞等待的毫秒数。 */ serialPort = (SerialPort) portId.open("SimpleReadApp", 2000);} catch (PortInUseException e) {}try {/*获取端口的输入流对象*/ inputStream = serialPort.getInputStream();} catch (IOException e) {}try {/*注册一个SerialPortEventListener事件来监听串口事件*/ serialPort.addEventListener(this);} catch (TooManyListenersException e) {}/*数据可用*/ serialPort.notifyOnDataAvailable(true);try {/*设置串口初始化参数,依次是波特率,数据位,停止位和校验*/ /*serialPort.setSerialPortParams(115200,SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);*/serialPort.setSerialPortParams(PinLv,DataBits,StopBits,Parity);} catch (UnsupportedCommOperationException e) {}readThread = new Thread(this);readThread.start();}public void run() {try {Thread.sleep(20000);} catch (InterruptedException e) {}}//串口事件 public void serialEvent(SerialPortEvent event) {switch(event.getEventType()) {case SerialPortEvent.BI:/*Break interrupt,通讯中断*/ case SerialPortEvent.OE:/*Overrun error,溢位错误*/ case SerialPortEvent.FE:/*Framing error,传帧错误*/case SerialPortEvent.PE:/*Parity error,校验错误*/case SerialPortEvent.CD:/*Carrier detect,载波检测*/case SerialPortEvent.CTS:/*Clear to send,清除发送*/ case SerialPortEvent.DSR:/*Data set ready,数据设备就绪*/ case SerialPortEvent.RI:/*Ring indicator,响铃指示*/case SerialPortEvent.OUTPUT_BUFFER_EMPTY:/*Output buffer is empty,输出缓冲区清空*/break;case SerialPortEvent.DATA_AVAILABLE:/*Data available at the serial port,端口有可用数据。读到缓冲数组,输出到终端*/byte[] readBuffer = new byte[20];char[] readChar = new char[20];String readStr=""; String reg = ","; int numBytes=0;try {while (inputStream.available() > 0) {numBytes= inputStream.read(readBuffer);}for(int iii=0;iii<numBytes;iii++){ readStr= readStr+(readBuffer[iii]);//Byte.toString(readBuffer[iii]); } String txt = new String(readBuffer,"gbk")+"\r\n";String [] arr = txt.split(reg);//正则表达式切割 //System.out.printf(s+" ");OneJFrame.jTextField1.setText(arr[0]); //切割后的字符串在主界面上显示OneJFrame.jTextField2.setText(arr[1]);OneJFrame.jTextField3.setText(arr[2]);OneJFrame.jTextField4.setText(arr[3]);} catch (IOException e) {} isOpen = true;break; }}public void close() { if (isOpen) { try { serialPort.notifyOnDataAvailable(false); serialPort.removeEventListener(); inputStream.close(); serialPort.close(); isOpen = false; } catch (IOException ex) { //"关闭串口失败"; } } }
(PS:串口通信的方法部分借鉴于他人,由于时间太长无法找到出处,得罪之处还望海涵。在此表示感谢。)
JDBC及JDBCTools类:
将串口调试通过,以后的工作变变得简单起来,无非就是一个图形化界面加JDBC数据库的操作。下面进行说明。
JDBCTools:
public static Connection getConnection() throws Exception {Properties properties = new Properties();InputStream inStream = JDBCTools.class.getClassLoader().getResourceAsStream("jdbc.properties");properties.load(inStream);// 1. 准备获取连接的 4 个字符串: user, password, jdbcUrl, driverClassString user = properties.getProperty("user");String password = properties.getProperty("password");String jdbcUrl = properties.getProperty("jdbcUrl");String driverClass = properties.getProperty("driverClass");// 2. 加载驱动: Class.forName(driverClass)Class.forName(driverClass);// 3. 调用// DriverManager.getConnection(jdbcUrl, user, password)// 获取数据库连接Connection connection = DriverManager.getConnection(jdbcUrl, user,password);return connection;}public static void releaseDB(ResultSet resultSet, Statement statement,Connection connection) {if (resultSet != null) {try {resultSet.close();} catch (SQLException e) {e.printStackTrace();}}if (statement != null) {try {statement.close();} catch (SQLException e) {e.printStackTrace();}}if (connection != null) {try {connection.close();} catch (SQLException e) {e.printStackTrace();}}}//提交事务public static void commit(Connection connection){if(connection != null){try {connection.commit();} catch (SQLException e) {e.printStackTrace();}}}
<pre name="code" class="java"> JDBC数据库操作类:
<pre name="code" class="java">public void Query(){
<span style="white-space:pre"> </span>//数据库查询。Connection connection = null;try {connection = JDBCTools.getConnection();String sql = "SELECT * " +"FROM customers";Object obj = queryRunner.query(connection, sql, new MyResultSetHandler());//System.out.println(obj); new Select().setVisible(true);String s = "a\tb\tc\td\t\r\n\r\n";Select.jTextArea1.setText(s+obj.toString());} catch (Exception e) {{JOptionPane.showMessageDialog( null , "查询失败了" ,"很遗憾" , JOptionPane.ERROR_MESSAGE) ;}} finally{JDBCTools.releaseDB(null, null, connection);}}
public void InsertBlob(){
<span style="white-space:pre"> </span>//存储数据库Connection connection = null;PreparedStatement preparedStatement = null;// System.out.print(connection);try {connection = JDBCTools.getConnection();//System.out.print(connection);String sql = "INSERT INTO customers(A, B, C, D)" + "VALUES("+"\'"+jTextField1.getText()+"\'"+","+"\'"+jTextField2.getText()+"\'"+","+"\'"+jTextField3.getText()+"\'"+","+"\'"+jTextField4.getText()+"\'"+")";// System.out.print(sql); preparedStatement = connection.prepareStatement(sql); preparedStatement.executeUpdate();//JOptionPane.showMessageDialog( null , "存入成功" ,"恭喜!" , JOptionPane.ERROR_MESSAGE) ;JOptionPane.showMessageDialog(null, "存入成功");} catch (Exception e) {//e.printStackTrace();{JOptionPane.showMessageDialog( null , "失败了" ,"很遗憾" , JOptionPane.ERROR_MESSAGE) ;}} finally{//JDBCTools.commit(connection);JDBCTools.releaseDB(null, preparedStatement, connection);}}
(PS:感谢尚硅谷的教学视频,让我能够自学成长)
这里重点总结一下在调试中出现的小问题:
1、jdbc.properties文件的存放位置
读取jdbc.properties(进入数据库的信息配置文件)时,要注意文件的构造位置,不同的软件有不同的存放方式,那自己做项目用的netbeans来说。当文件在下图位置时
图2(文件信息1)
jdbc.properties文件是不会被加载的,所以系统会一直报告空指针错误,即数据库没有连接上。我们需要将其放在独属的一个包中并进行选择,如下图:
图3(文件信息2)
这样,文件就会被加载了。
2、数据库数据类型问题
自己将四个数据类型全部都设置为varchar2类型(相当于java中的String),当用到insert语句往数据库里面存储数字类型时,是不需要加修饰的,而存储字符串类型时,需要用到‘’单引号括起来,否则会存入失败。如:
<pre name="code" class="sql">insert into customers values(你,你,你,你);
是不可行的,而需要
insert into customers values('你','你','你','你');
所以编写java代码时要格外注意不要忘掉单引号,自己写的代码如下:
String sql = "INSERT INTO customers(A, B, C, D)" + "VALUES("+"\'"+jTextField1.getText()+"\'"+","+"\'"+jTextField2.getText()+"\'"+","+"\'"+jTextField3.getText()+"\'"+","+"\'"+jTextField4.getText()+"\'"+")";
之前遇到只能将数字存入数据库而汉字与字符不可以的情况,所以这里做一下细节的总结。
面向对象类:
简单的一个类,不做过多赘述。
import java.sql.Date;public class Customer {private String a;private String b;private String c;private String d;public Customer(String a,String b,String c,String d){this.a=a;this.b=b;this.c=c;this.d=d;}public String getA() {return a;}public void setA(String a) {this.a = a;}public String getB() {return b;}public void setB(String b) {this.b = b;}public String getC() {return c;}public void setC(String c) {this.c = c;}public String getD() {return d;}public void setD(String d) {this.d = d;}@Overridepublic String toString() {return a + "\t" + b + "\t" + c + "\t" + d+"\r\n";}}
Swing类:
代码过长,这里不做展示,有兴趣的同学可以对netbeans的图形化界面的制作做一下了解。
这里给大家分享一个关于图形化界面异常处理弹出小框的博客供大家学习。
JOptionPane类提示框的一些常用的方法 - - ITeye技术网站 http://url.cn/9u9uNd
总结:
这个小项目的完成虽然比较简单,但涉及知识面较广,且数据库部分做的并不是很完善,有待改进。作为物联网专业的学生,串口通讯是一个非常关键的媒介,打通了上位机与下位机的通道,数据库、网站展示、大数据分析都将可以实现,这也将我的认知程度提高了一个境界,甚至将大学所学的知识完全贯穿了起来,我相信,在惠普实训结束以后,一个通过惠普EPM实训提高以后的我,下学期的课程设计,将会交给老师一个完美的答卷。
感谢:
从小老师对我来说是高一个档次的职业。对老师尊敬,感恩就好像长在脑子里一样,短短的不到一年,我进步了很多,促使我成长的老师我都一一记得。
建大的汪明、王玉玲、潘春伟老师,我对学习的认识、表达能力薄弱的认知、编程的思想,和他们的直接或间接的教导是分不开的。
惠普的王岩、郭吉楠、张亚冲、代森荣、贾蕊鲜老师,解决了自己之前好多好多不懂的问题,还有对教导专门的教导老师的渴望,java基础有了提升,学到了新的编程语言,我在这里过得很充实,也很满足。
毕竟第一篇博客,感慨有点多,希望大家不要起一身土豆o(^▽^)o。
------------
物联网的媒介——java usb串口通信相关推荐
- Java实现串口通信的小样例
用Java实现串口通信(windows系统下),须要用到sun提供的串口包 javacomm20-win32.zip.当中要用到三个文件,配置例如以下: 1.comm.jar放置到 JAVA_HOME ...
- java串口发送十六进制数,本文实例为大家分享了Java实现串口通信的具体代码,供大家参考,具体内容如下1.介绍使用Java实现的串口通信程序,支持十六进制数据的发送与接收。 源码:...
本文实例为大家分享了Java实现串口通信的具体代码,供大家参考,具体内容如下 1.介绍 使用Java实现的串口通信程序,支持十六进制数据的发送与接收. 源码:SerialPortDemo 效果图如下: ...
- Android USB 串口通信
公司要求安卓PAD对接一台Windows的设备,实现双向数据传输. 是通过Windows设备的一根数据线进行数据传输的,涉及到的技术就是USB转串口通信,网上讲原理的一大堆,我就不讲了,直接上demo ...
- java 采用串口通信实现LED屏发送数据中文乱码问题
java 采用串口通信实现LED屏发送数据中文乱码问题 1.定义:Pointer p = new Pointer(MemoryBlockFactory.createMemoryBlock(1024)) ...
- python做上位机读usb数据_使用python实现win10系统和arduino usb串口通信
前言 arduino有很多可以直接使用的传感器,可以很方便的获取大量的环境数据. 常见的有:温度(室温,冰箱,水箱等场景) 湿度(房间空气湿度,花盆土壤湿度等场景) 声(声控灯,噪音检测,深海测量,医 ...
- Java实现串口通信的小例子
用Java实现串口通信(windows系统下),需要用到sun提供的串口包 javacomm20-win32.zip.其中要用到三个文件,配置如下: 1.comm.jar放置到 JAVA_HOME/j ...
- 基于java的串口通信
文章目录 前言 一.RXTX是什么? 二.环境搭建 引入库 三.代码实现 SerialPortManager类 Tools类 重要代码解析 读取数据 写数据 写EPC号 询查单张标签 CRC校验 测试 ...
- 树莓派串口通信 USB串口通信 常用串口命令
树莓派串口通信 USB串口通信 文章目录 树莓派串口通信 USB串口通信 准备 发送数据 接收数据 如果不知道树莓派怎么使用USB串口通信的,欢迎浏览我的另一篇博客文章: 树莓派使用USB串口通信 C ...
- 使用Java实现串口通信(二)
1.写在前面 距离上一篇文章<使用Java实现串口通信>已经过去快两年的时间了,在此期间收到了很多读者的反馈,很高兴可以帮助到这么多人,根据收到的反馈,我对代码逻辑进行了优化整理,并增加了 ...
- Java 如何串口通信以及常见报错解决
文章目录 一.Java 串口通信部署 准备 部署 1. 配置 Java 环境 2. 新建项目,引入依赖. 3. 代码(网上荡的) 运行 二.Java 串口通信报错 1. JDK 有关错误 2. dll ...
最新文章
- 启动tomcat时jmx port被占用
- linux下防火墙iptables原理及使用
- 【微信网页版】给所有微信群发消息
- java httprequesthandler_Spring-webmvc源码解析之ResourceHttpRequestHandler
- 下载Google Play中的APK
- java api 英文_教你查阅Java API 英文文档(JDK 11)
- 实验5: IOS的升级与恢复
- c语言查单词小程序,【附源码】小程序初窥之简单查单词
- 阿里帝国到底有多庞大
- fopen php 乱码,如何解决php fgets读取文件乱码的问题
- oracle dba_waiters中的lockid是什么,查杀oracle lock session and table
- java 23种设计模式(转载)
- 云计算:大数据时代的系统工程
- 一种FlashBuilder不能启动的解决方法
- 【MySQL】011-多表查询
- 教育培训机构如何利用小程序招生?
- form表单reset重置按钮
- 为什么MASKRCNN中使用ROIAlign替代ROIPool
- windows家庭中文版升级至专业版
- javascript中 String对象方法(大小写转换、连接与拆分)