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

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

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

时间: 2024-10-13 16:19:04

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

Linux串口接收不到0X11数据

转自:http://www.2cto.com/os/201302/189931.html linux串口接收不到0x11解决 网上许多流行的linux串口编程的版本中都没对c_iflag(termios成员变量)这个变量进行有效的设置,这样传送ASCII码时没什么问题,但传送二进制数据时遇到0x0d,0x11和0x13却会被丢掉.不用说也知道,这几个肯定是特殊字符,被用作特殊控制了.关掉ICRNL和IXON选项即可解决. www.2cto.com c_iflag &= ~(ICRNL | IXO

USART与USB接收不定数据方法,标准库、HAL库都适用

很多时候,我们使用串口或USB接收数据时,往往不知道PC端会发多长的数据下来, 为了解决这个不定数据接收问题,在此各提供一个解决思路. 串口数据不定接收: 由于STM32单片机带IDLE中断,所以利用这个中断,可以接收不定长字节的数据, 由于STM32属于ARM单片机,所以这篇文章的方法也适合其他的ARM单片机. IDLE就是串口收到一帧数据后,发生的中断.什么是一帧数据呢?比如说给单片机一 次发来1个字节,或者一次发来8个字节,这些一次发来的数据,就称为一帧数据,也可以 叫做一包数据. 还有一

基础问题:在一个 Activity 中定义的串口接收程序,如果 Activity 切换到其它 Activity 后还能接收到串口数据吗?

============问题描述============ RT:基础问题:在一个 Activity 中定义的串口接收程序,如果 Activity 切换到其它 Activity 后还能接收到串口数据吗? 我的程序有两个 Activity,在启动后的 Activity 中已经验证了接收与发送数据. 后继做了第二个 Activity,此时从第二个 Activity 返回 第一个 Activity 时串口的接收线程会出错.调试了一下,串口再次被初始化了. 问题: (1)不想串口被反复初始化,应该如何做?

vc mscom控件串口接收不到数据问题

读对边距的时候,刚开始有数,后来不行了,重新拔插后可以了. 在接收到数据的程序中,oncomm()函数 中,加入了 串口打开.关闭图标的程序.使得串口接收大数据,执行这部分程序的时候,串口数据卡死了. 删掉串口打开.关闭图标的程序后,数据接收正常.

2018最新mfc作为上位机接收硬件端USB或串口数据显示成图片 解决串口接收数据丢字节丢包问题

本文用的是VS2013MFC写串口数据接收: 第一步:首先建立一个MFC工程,成功后会跳出一个对话框,直接在对话框上点击右键->点击插入ACTIVAE控件->选择MicrosoftCommunications Control, version 6.0 成功后会显示一个电话的图标在对话框上,运行起来不会显示的 不用担心这个美观问题.如果没有这个插件的话,可能是版本太低  可以自己下载一个补上 第二步:大概的窗体搞好:   那个显示图片的大框是PICTURE控件变量 然后就要项目->类向导中

【转】搞定单片机多字节串口接收(串口多字节接收发送的高阶研究)

搞定单片机多字节串口接收(串口多字节接收发送的高阶研究) 原文地址:http://bbs.ednchina.com/BLOG_ARTICLE_3007162.HTM 工作了一年多,写了不少单片机串口程序.感觉串口多字节接收部分的逻辑相对于配置寄存器跟串口回复来说,是有点难度的——寄存器配置基本上都是死的,串口回复多字节跟回复一字节只是多了一个循环. 串口接收程序是基于串口中断的,单片机的串口每次接收到一字节数据产生一次中断,然后再读取某个寄存器就可以得到串口接收的数据了.然而在实际应用当中,基本

linux串口接收0x03等特殊字符的问题

近日在写一个linux的串口程序,发现大多数情况下数据接收没问题,但是有时却有问题.主要是接收的字符串中包含有0x03这个字符,会造成与它相邻的字符同时也接收不到,搞了好久才发现这个错误.查找资料后发现许多ARM板也存着这个问题,存在问题的字符串还包括0x13.0x0D等特殊含义的字符. 解决方法 方法比较简单,在接收数据前,对串口的文件描述符fd进行如下设置, <pre name="code" class="cpp">struct termios op

C#:蓝牙串口读数据和写数据

原文:C#:蓝牙串口读数据和写数据 首次使用C#编写与COM口有关的程序,期间遇到了很多问题,写下自己的经验总结,如有错漏,欢迎批评指正! 1.新建一个串口类(nbsp;SerialPort类) 1 //Create a serial port for bluetooth 2 SerialPort BluetoothConnection = new SerialPort(); 2.串口端口号搜索: string[] Ports = SerialPort.GetPortNames();or (in

单片机多字节串口接收(转)

工作了一年多,写了不少单片机串口程序.感觉串口多字节接收部分的逻辑相对于配置寄存器跟串口回复来说,是有点难度的——寄存器配置基本上都是死的,串口回复多字节跟回复一字节只是多了一个循环. 串口接收程序是基于串口中断的,单片机的串口每次接收到一字节数据产生一次中断,然后再读取某个寄存器就可以得到串口接收的数据了.然而在实际应用当中,基本上不会有单字节接收的情况.一般都是基于一定串口通信协议的多字节通信.在422或者485通信中,还可能是一个主机(一般是计算机)带多个从机(相应的有单片机的板卡).这就