在作串口通讯过程当中,下位机向上位机发送的串口数据有时候须要带有指定的标识符,便于上位机根据标识符判断后续几位数据是作什么用的。也就是下位机和上位机约定数据帧的传输格式,便于在上位机将数据分离,固然这种数据帧格式能够自定义。java
今天用arduino做为下位机,模拟数据经过自定义格式发送数据帧,利用串口将数据帧发送到android上位机,上位机用java代码实现数据提取,并在界面实时显示接收数据,虽然是模拟数据经过串口发送,但在实际项目开发中,原理相通。python
如下是arduino代码,经过设定定时器,当接收到android上位机发送的开始发送控制指令字符‘S’后,每10ms发送一组数据帧;当接收到中止发送控制指令字符‘T’后,即关闭定时器,中止发送数据帧。android
#include "MsTimer2.h" char ch; void timer_interrupt()//定时中断函数,数据帧为FF F9 XX XX,其中FF F9为标识符,XX XX为数据 { Serial1.write(0xff); Serial1.write(0xf9); Serial1.write(0x11+random(0,10)); Serial1.write(0x22+random(0,10)); } void setup()//初始化函数 { Serial1.begin(9600);//设定串口1波特率为9600 MsTimer2::set(10,timer_interrupt);//设置定时器,每10ms中断一次 } void loop() { if(Serial1.available()) { ch=Serial1.read(); if(ch=='S')//当接收到字符'S'后,打开定时器 { MsTimer2::start(); } if(ch=='T')//当接收到子都'T'后,中止定时器 { MsTimer2::stop(); } } }
对于android上位机,须要作的是读取串口数据,从数据帧中提出来有用数据,为了解决主UI阻塞问题,须要开启一个子线程循环读取串口数据帧,关键代码以下。dom
class ReadThread extends Thread{ Handler mHandler; ReadThread(Handler h) { mHandler=h; this.setPriority(MAX_PRIORITY);//设置成最高优先级 } @Override public void run() { // TODO Auto-generated method stub super.run(); byte[] start_PRESSURE={(byte)0xff,(byte)0xf9};//提取数据标识符 byte[] tmp1=new byte[2]; int readCount=0; int state=0; int index=0; Message msg; bReadTheadEnable=true;//准备开启线程读数据 while(true==bReadTheadEnable){ try{ Thread.sleep(10);//休眠10ms } catch(Exception e){ e.printStackTrace(); } readCount=ftDev.getQueueStatus();//读取缓冲区数据个数 if(state==0) { if(readCount>2)//保证读取缓冲区内至少有三个字节,方便内部读取 { ftDev.read(tmp1,1);//读取一个字节数据 if(tmp1[0]==start_PRESSURE[index]) { index++; if(index==start_PRESSURE.length) { ftDev.read(global_tmp2,2);//读取两个字节 index=0; msg=mHandler.obtainMessage(GIVETHERESULT);//通知主UI更新 mHandler.sendMessage(msg); } } else { index=0; } } } } } }
在这里循环读取判断串口数据的方法,不管是C,C++仍是python等语言,都很是适用,早先本身用python的pyserial模块作串口数据提取是将数据转化成字符串,好比12.34,而后前面加一个标识符D,再一位一位的判断读取和整合,这样效率比较低,而且写出来的代码功能虽然实现了,但感受不爽。后来偶然在网上看到MJPEG数据格式提取程序片断,认真分析了几遍,感受这种数据提取方式很不错,之后就为己所用啦。ide