android串口通信以及串口协议解析

Android - 串口通讯(SerialPort) 最早的博客里就是用过 Google 提供的 demo,最近想再写个其他的demo发现用起来有点麻烦,还需要导入其他 module,因此在网上找到了也是自Google开源的Android串口通信Demo。话不多说,直接开搞。demo地址放在了最后。 阅读详情

http://blog.youkuaiyun.com/junfeng120125/article/details/9328947

一,android串口通信
串口通信采用一个第三方开源项目,实现串口数据收发。
1. 使用了http://code.google.com/p/android-serialport-api/的项目的serialport api和jni;
2. 支持4串口同时收发,有定时自动发送功能,收发模式可选Txt或Hex模式;
3.  n,8,1,没得选;
4. 为减轻界面卡顿的情况,接收区的刷新采用单独的线程进行定时刷新;
5. 发送区的数据以及一些设置项,在程序关闭时会自动保存,打开时自动载入;
6. jni使用最新的NDKr8b重新编译了一下


简单编写步骤:
1.新建一个项目,自己起个名字
2.直接复制serialport api和jni文件夹到新建的工程,如果不想自己编译jni,就连libs文件夹也一起复制
3.去android官方网站下载NDK,解压,在CMD中转到jni目录,并执行 绝对路径\ndk-build
4.自己再封装一个工具类或直接使用SerialPort类都行,举个直接使用的例:
直接剽窃原项目的SerialPortActivity.java,并稍微改一下,重点改这里
mSerialPort = mApplication.getSerialPort();
这里可以改成
new SerialPort(new File("/dev/s3c2410_serial0"), 9600, 0);//COM0,波特率9600
5. SerialPortFinder的使用就没什么好讲的了,实例化后用.getAllDevicesPath()就能获取到所有设备了。
其它如数据转换等请参考源码


源码可以参考谷歌android-serialport-api例子 
http://code.google.com/p/android-serialport-api/source/checkout 
svn checkout http://android-serialport-api.googlecode.com/svn/trunk


二,串口通信协议解析
1.通信基本格式
字段 描述 长度(字节)
起始符 0F,十六进制码  1
信息类型 一个字节,十六进制码(0F,F0,FF等保留码不用)1
信息长度 是信息内容的长度,ASCII码表示(0~9,A~F,最大长度为256)(例如长为11个,十六进制是0B,则两个字节就写0x30 0x42)。
注:因为最大长度256不能满足有些指令的要求,所以对长度做了扩展,下面是扩展说明:
如果第一个字节的最高位为1,则表示扩展长度。在扩展长度状态下,其他15个字节通过16进制大端模式来保存长度。比如:0x80 0x12表示长度为0x001 2,0x81 0x12表示长度为0x0112。2
信息内容 一组十六进制码  N
校验 一个字节,十六进制码,是自信息类型起至对象号止所有码的异或。1
结束符 F0,一个字节,十六进制码 (为了保证可靠性,车机下发的结束符为F0 FF)1

2.协议解析

[java]  view plain  copy
  1. /** 
  2.      * 读取终端设备数据 
  3.      * @author Administrator 
  4.      */  
  5.     private class ReadThread extends Thread {  
  6.   
  7.         @Override  
  8.         public void run() {  
  9.             super.run();  
  10.   
  11.             // 定义一个包的最大长度  
  12.             int maxLength = 2048;  
  13.             byte[] buffer = new byte[maxLength];  
  14.             // 每次收到实际长度  
  15.             int available = 0;  
  16.             // 当前已经收到包的总长度  
  17.             int currentLength = 0;  
  18.             // 协议头长度4个字节(开始符1,类型1,长度2)  
  19.             int headerLength = 4;  
  20.   
  21.             while (!isInterrupted()) {  
  22.                 try {  
  23.                     available = mInputStream.available();  
  24.                     if (available > 0) {  
  25.                         // 防止超出数组最大长度导致溢出  
  26.                         if (available > maxLength - currentLength) {  
  27.                             available = maxLength - currentLength;  
  28.                         }  
  29.                         mInputStream.read(buffer, currentLength, available);  
  30.                         currentLength += available;  
  31.                     }  
  32.                       
  33.                 }  
  34.                 catch (Exception e) {  
  35.                     e.printStackTrace();  
  36.                 }  
  37.   
  38.                 int cursor = 0;  
  39.                 // 如果当前收到包大于头的长度,则解析当前包  
  40.                 while (currentLength >= headerLength) {  
  41.                     // 取到头部第一个字节  
  42.                     if (buffer[cursor] != 0x0F) {  
  43.                         --currentLength;  
  44.                         ++cursor;  
  45.                         continue;  
  46.                     }  
  47.                       
  48.                     int contentLenght = parseLen(buffer, cursor, headerLength);  
  49.                     // 如果内容包的长度大于最大内容长度或者小于等于0,则说明这个包有问题,丢弃  
  50.                     if (contentLenght <= 0 || contentLenght > maxLength - 5) {  
  51.                         currentLength = 0;  
  52.                         break;  
  53.                     }  
  54.                     // 如果当前获取到长度小于整个包的长度,则跳出循环等待继续接收数据  
  55.                     int factPackLen = contentLenght + 5;  
  56.                     if (currentLength < contentLenght + 5) {  
  57.                         break;  
  58.                     }  
  59.   
  60.                     // 一个完整包即产生  
  61.                     // proceOnePacket(buffer,i,factPackLen);  
  62.                     onDataReceived(buffer, cursor, factPackLen);  
  63.                     currentLength -= factPackLen;  
  64.                     cursor += factPackLen;   
  65.                 }  
  66.                 // 残留字节移到缓冲区首  
  67.                 if (currentLength > 0 && cursor > 0) {  
  68.                     System.arraycopy(buffer, cursor, buffer, 0, currentLength);  
  69.                 }  
  70.             }  
  71.         }  
  72.     }  
  73.   
  74.     /** 
  75.      * 获取协议内容长度 
  76.      * @param header 
  77.      * @return 
  78.      */  
  79.     public int parseLen(byte buffer[], int index, int headerLength) {  
  80.   
  81. //      if (buffer.length - index < headerLength) { return 0; }  
  82.         byte a = buffer[index + 2];  
  83.         byte b = buffer[index + 3];  
  84.         int rlt = 0;  
  85.         if (((a >> 7) & 0x1) == 0x1) {  
  86.             rlt = (((a & 0x7f) << 8) | b);  
  87.         }  
  88.         else {  
  89.             char[] tmp = new char[2];  
  90.             tmp[0] = (char) a;  
  91.             tmp[1] = (char) b;  
  92.             String s = new String(tmp, 0, 2);  
  93.             rlt = Integer.parseInt(s, 16);  
  94.         }  
  95.   
  96.         return rlt;  
  97.     }  
  98.   
  99. protected void onDataReceived(final byte[] buffer, final int index, final int packlen) {  
  100.         System.out.println("收到信息");  
  101.         byte[] buf = new byte[packlen];  
  102.         System.arraycopy(buffer, index, buf, 0, packlen);  
  103.         ProtocolAnalyze.getInstance(myHandler).analyze(buf);   
  104.     }  


快速开发和使用Android串口 串口叫做串行接口,也称串行通信接口,也可以叫做COM口,按电气标准及协议来分包括RS-232-C、RS-422、RS485、USB等。串行接口是指数据一位一位地顺序传送,其特点是通信线路简单,只要一对传输线就可以实现双向通信,从而大大降低了成本,特别适用于远距离通信,但传送速度较慢。 阅读详情

相关推荐

Android串口通信实战:Modbus协议数据帧解析与实现

本文详细介绍了在Android平台上实现Modbus串口通信的完整实战方案。内容涵盖串口环境搭建、权限配置、Modbus RTU协议帧的构造与解析,并提供了健壮的代码封装与调试技巧,帮助开发者快速掌握工业物联网应用中的核心通信技术。

weixin_29185167的博客 113

Android硬件通信之 串口通信

串口通信

qq_29848853的博客 1万+

Unity安卓串口通信开发实战:解决黑屏无响应与多串口线程安全

串口通信作为一种经典的异步字节流通信方式,在物联网、工业控制和智能硬件等领域仍是连接上位机与下位机设备的核心技术。其原理基于UART协议,通过USB转串口驱动(如CH340、FTDI)在安卓系统上以文件设备形式呈现。在Unity引擎中实现安卓串口通信的技术价值在于打通游戏逻辑与物理世界的硬件数据交互,但面临安卓主线程阻塞导致应用无响应、多串口数据流管理复杂等独特挑战。应用场景广泛覆盖智能农业监控、传感器数据采集、工业PLC控制等。本文针对Unity安卓串口开发中常见的黑屏无响应问题,深入解析了线程安全的生产

weixin_32479897的博客 329

【Android】串口通信的理论与使用教程

串口是显控设备与信号处理板之间通信的主要接口,也是显控设备与其他设备、设备与设备之间的协议数据帧通信传输的重要接口。本文将从Android开发者的视角带你去了解串口通信。

宾有为的博客 6979

如何在Android平台上使用串口通信

本章回中介绍了在Aroidn平台下进行串口通信的概念和通信方法,并且通过文字结合代码的方式进行了介绍,最好分享了自己总结的项目经验。

talk_8的专栏 2993

项目回顾一:《高速多端口共享缓存模块》

本帖子仅为了回顾一下一年前自己动手完成的第一个数字ic设计项目的历程,为复试做一下准备,完成的这个sramc模块花了整整四个月的时间,从0到12个模块的代码产出以及模块的验证,虽然没有拿奖,也没有进入复赛,设计过程中使用的技术手段和算法也不太成熟,但这这是一个值得记录的过程!

weixin_60261760的博客 1254

Android之使用串口通信及协议解析

特别声明:尊重原创,原文链接:http://blog.youkuaiyun.com/junfeng120125/article/details/9328947一,android串口通信 串口通信采用一个第三方开源项目,实现串口数据收发。 1. 使用了http://code.google.com/p/android-serialport-api/的项目的serialport api和jni; 2. 支持4串

nadeal在写博客 3506

STM32H743必要外围电路分析

写在前面:这篇博客是我第一次绘制STM32最小系统板的过程记录。 2020-1-11 BOOT STM32采用ARM内核,和ARM处理器一样,都有专门的boot脚决定单片机从何处启动。 在官方数据手册的第105页,我们可以看到 系统复位后,在SYSTICK的第四个上升沿锁存BOOT引脚的值,复位后,BOOT引脚可以由用户自由配置而不会影响系统正常运行。 BOOT引脚决定了自举存储器地址,当BO...

Cui_Hongwei的博客 1万+

Android 串口通信实战指南:从协议解析到工业应用

本文详细解析Android串口通信在工业应用中的核心挑战与实战解决方案,涵盖Modbus协议解析、CRC校验机制、稳定性优化策略及多设备协同管理。重点介绍工业级数据完整性保障和长时间稳定运行的关键技术,帮助开发者构建高可靠性的Android工业控制系统。

whisky的博客 716

Flutter UI代码生成实战:Cursor与MCP的企业级规范适配

本文探讨了在企业级Flutter项目中,如何通过配置Cursor Rules与定制Figma MCP工具,为AI代码生成设定严格的开发规范。该方法解决了AI生成代码与现有项目架构、命名约定及资源引用规范脱节的核心痛点,实现了从Figma设计稿到高质量、可维护Flutter UI代码的自动化流程,显著提升团队协作效率与代码一致性。

http9protocoller的博客 280

Windows11下QGIS 3.34.4安装Geo-SAM插件全流程(附RTX3060 CUDA12.0配置技巧)

本文详细介绍了在Windows 11系统中为QGIS 3.34.4安装和配置Geo-SAM插件的完整流程,特别针对RTX 3060显卡用户提供了CUDA 12.0与PyTorch环境的精准搭建方案。通过预编码与交互式分割两大核心步骤,该插件能显著提升遥感图像半自动标注的效率,降低硬件门槛,是地理信息处理领域融合AI技术的实用指南。

weixin_29089057的博客 295

android串口通信协议文档,android串口通信以及串口协议解析

/***读取终端设备数据*@authorAdministrator*/privateclassReadThreadextendsThread{@Overridepublicvoidrun(){super.run();//定义一个包的最大长度intmaxLength=2048;byte[]buffer=newbyte[maxLength];//每次收到实际长度...

weixin_36252618的博客 476

YOLOv13改进策略【注意力机制篇】| ICASSP 2023 EMA 高效多尺度注意力,跨空间学习提高远距离建模依赖

ICASSP 2023 EMA 高效多尺度注意力在 YOLOv13 的接入实战:跨空间学习提升远距离依赖建模,含原理图解、完整代码、yaml 配置与实测参数量对比(ultralytics 8.3.63)。

qq_53329130的博客 932

串口通信命令解析

android串口通信以及串口协议解析                      分类:             java             android              2013-07-15 10:10     694人阅读     评论(3)     收藏     举报     一,android串口通信 串口通信采用一个第三方开源项目,实现

gaoqilai008的专栏 2642

【2005】人工智能⭐

问题的解答来自于过去的经验而不是规则,这些经验是以案例方式存储的。但是当人们遇到一个新的问题的时候,一般先是回忆,从记忆中找到一个与新的问题相似的案例,然后把该案例的有关信息和知识复用到新问题的求解之中。1、若案例(case)不够充足,而有足够的规则(知识),试问如何构建一个包含有基于案例推理和基于规则推理的推理系统,以使推理效率提高而且总能求得问题的解。一般认为,CBR适合缺乏完备和健全的理论,但又可获取丰富经验的领域,而RBR则适合于对领域有充分的认识,能以完备和健全的形式表示领域理论的场合。

super_mochi1 279

Android16 动态隐藏systemUI右侧音量条

本文介绍了如何屏蔽SystemUI系统音量条并显示自定义音量控制条的实现方法。主要通过两个步骤:1)在编译脚本中定义控制属性persist.rp.show.volume.dialog=off来隐藏系统音量条;2)修改SystemUI源码中的VolumeDialogImpl.java文件,在showH方法中根据属性值判断是否显示系统音量条。当属性值为off时直接return,从而屏蔽系统音量条的显示,实现自定义音量控制条的替代显示。该方法通过系统属性控制显示状态,具有灵活可控的特点。

tzj1058756809的博客 779

android串口通信接受自定义协议数据并解析问题

1.一般自定义的串口协议  串口传输接口底层是按位(bit)发送的,上层是按byte发送和接收的,但协议为了方便描述,每个byte用十六进制数(0x00~0xFF)表示,范相当于十进制的0~255,而byte为八位且是有符号类型,相当于十进制的-128~127,明显0x8F~0xFF(128~255)是不能准确转换为byte的,咋办? byte b = 0xFF; 编译器会提示出错,因为0...

qq_17441227的博客 4925

【webrtc】openh264编码:动态配置码控参数触发IDR编码

SetRates 下发RateControlParameters 给到openh264 编码器 void SetRates(const RateControlParameters& parameters) override; LayerConfig 编码器这边的配置是layerconfig,具体到层的: std::vector<LayerConfig> configurations_; void H264EncoderImpl::SetRates(const RateCo.

突围 723
上一篇: EditText 的输入类型inputType
下一篇: Centos 6.6上安装Git Lab服务及问题总结
千雅爸爸
博客等级 码龄18年 292粉丝 639原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值