通过串口接收带有标识符的数据方法

原创
2014/12/12 22:00
阅读数 2.5K

在做串口通信过程中,下位机向上位机发送的串口数据有时候需要带有指定的标识符,便于上位机根据标识符判断后续几位数据是做什么用的。也就是下位机和上位机约定数据帧的传输格式,便于在上位机将数据分离,当然这种数据帧格式可以自定义。

今天用arduino作为下位机,模拟数据通过自定义格式发送数据帧,利用串口将数据帧发送到android上位机,上位机用java代码实现数据提取,并在界面实时显示接收数据,虽然是模拟数据通过串口发送,但在实际项目开发中,原理相通。

以下是arduino代码,通过设定定时器,当接收到android上位机发送的开始发送控制指令字符‘S’后,每10ms发送一组数据帧;当接收到停止发送控制指令字符‘T’后,即关闭定时器,停止发送数据帧。

#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阻塞问题,需要开启一个子线程循环读取串口数据帧,关键代码如下。

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数据格式提取程序片段,认真分析了几遍,感觉这种数据提取方式很不错,以后就为己所用啦。


展开阅读全文
打赏
0
8 收藏
分享
加载中
更多评论
打赏
0 评论
8 收藏
0
分享
返回顶部
顶部