搜索
查看
编辑修改
首页
UNITY
NODEJS
PYTHON
AI
GIT
PHP
GO
CEF3
JAVA
HTML
CSS
搜索
笔触狂放9
这个屌丝很懒,什么也没留下!
关注作者
热门标签
jquery
HTML
CSS
PHP
ASP
PYTHON
GO
AI
C
C++
C#
PHOTOSHOP
UNITY
iOS
android
vue
xml
爬虫
SEO
LINUX
WINDOWS
JAVA
MFC
CEF3
CAD
NODEJS
GIT
Pyppeteer
article
热门文章
1
使用 Fiddler 抓包PC微信小程序_fiddler 可以抓到微信的请求地址嘛
2
实用攻略:云服务器如何选购?要考虑哪些因素?超详细!(上)_业务云服务器怎么选购集群
3
探索Web中的颜色选择:不同取色方法的实现
4
使用docker快速搭建openvpn
5
Local to local copy not supported
6
基于JavaScript在Web端用Cesium加载自己的点云数据_cesium加载点云数据
7
C++ replace() 函数用法_c++ replace函数怎么用
8
前端面试八股文(详细版)— 下_前端八股文pdf
9
Kubernetes 集群疑难杂症排障:服务器 IP 变更后集群故障了,我该如何修复?
10
2024年AI辅助研发:科技变革的引擎
当前位置:
article
> 正文
智能小车六《串口协议》_华清远见智能小车串口通信
作者:笔触狂放9 | 2024-03-22 12:17:03
赞
踩
华清远见智能小车串口通信
在智能小车四《串口通信》中讲解了串口的通信原理,它就是一个直接把信息转为电信号的工具,透明传输。接着这篇文章我们来解决一下没有协议而发生信息错乱的情况。比如在我们的小车里,收到字符u表示要前进。我们用实际手机给小车发一条蓝牙串口命令。
从上面你拼出什么了么?CONNECT ...... 这些是蓝牙协议的内容,他可能会与我们的命令重合,使我们的小车发生错乱。于是我想自己定义一个协议,我参考TCP协议的结构来定义的。关于TCP协议也是大学里网络课程有的,我简单描述一下。
TCP包结构:
TCP协议是基于端口的,所以它有源端口、目的端口,而串口协议不存在这个。其它的字段的含义可以网上查到,我这里面不再赘述了。最后我把协议定义成如下结构:
如何实现这个协议呢?需要分别在小车(arduino c语言)和控制端(android java)各实现一套数据包的解析和生成程序。
首先是小车端:
一、发送数据包:
ZZProtocol zzp;
/**
cmd是要发送的命令
*/
void sendCmd(String cmd){
int len=cmd.length();
char data[len+3];
char cmdArray[len];
for(int i=0;i<len;i++){
cmdArray[i]=cmd.charAt(i);
}
zzp.sendMsg(cmdArray,len,data);
for(int i=0;i<len+3;i++){
Serial.print(data[i]);
}
Serial.println();
}
/*
msg:要发送的内容
len:数据长度
data:最后发送数据包
*/
void ZZProtocol::sendMsg(char msg[], int& len, char data[]) {
if (len <= 0) {
return;
}
data[0] = STARTFLAG;
data[1] = (char) len;
data[3] = msg[0];
char tmpCode = data[3];
for (int i = 1; i < len; i++) {
data[i + 3] = msg[i];
tmpCode = tmpCode^data[i + 3];
}
data[2] = tmpCode;
}
二、接收数据包:
/**
得到命令
*/
int getCmd(){
int receiveData[64];
int rstData[64];
int rstNum=0;
receiveMsg(receiveData,rstData,rstNum);
if(rstNum>0){
if(rstNum==1){
int cmd=(int)rstData[0];
return cmd;
}
}
return 0;
}
/**
接收命令
*/
void receiveMsg(int receiveData[],int rstData[],int &rstNum){
int readNum=Serial.available();
if(readNum>0){
int startIndex=0;
readHead(receiveData,startIndex);
int rstFlag=zzp.checkFullPackage(receiveData,startIndex,rstData,rstNum);
if(rstNum>0){
//正常命令
/*
Serial.println("cmd:");
printMsg(rstData,rstNum);
*/
}else{
//错误信息,调试时用,Serial.print会再次传给蓝牙,造成arduino死机
Serial.print("error:");
Serial.println(rstFlag);
if(rstFlag==-1){
char str[100]="";
sprintf(str, "[(head error) byte0 btye1 char0 char1 length]:%d,%d,%c,%c,%d",receiveData[0],receiveData[1],receiveData[0],receiveData[1],readNum);
Serial.println(str);
}else if(rstFlag==-2){
for(int i=1;i<startIndex;i++){
Serial.print((byte)receiveData[i]);
Serial.print(" ");
}
Serial.println();
}
}
}else{
//读到的数,调试用
/*
if(readNum>0){
Serial.print("readNum:");
Serial.println(readNum);
}
*/
}
}
里面的包头识别函数(readHead)与检查包函数(checkFullPackage)我要用伪代码了。因为代码太多了,再粘下去,文章不能看了。
包头识别函数(readHead):
一个字符一个字符的读取,只到读到首部标识字符。第二位是长度,所以用一个循环while读取,直到读取到长度或超时退出。如果读到长度,则可以计算出还需多少空间来存储包。当然第二位也有可能是首部标识,这种情况,就舍弃第一个字符,重新从头计算。之后就可以开始读取数据了,但数据里还有可能是首部字符,这时又舍弃前面的字符,重新执行本函数。
检查包函数(checkFullPackage)比较简单:
/**
*
* @param receiveData 接收字符串
* @param dataLen 接收字符串长度
* @param rstData 返回字符串
* @param rstLen 返回字符串长度
* @return -1:head或len验证没通过。-2 checkCode验证没通过 。1正常返回
*/
int ZZProtocol::checkFullPackage(int receiveData[],int dataLen,int rstData[],int &rstLen) {
int head= receiveData[0];
int len = receiveData[1];
int checkCode = receiveData[2];
int dataCheck=-1;
if(head==STARTFLAG&&dataLen==len+3){
for (int i=3; i < dataLen ; i++) {
if (dataCheck == -1) {
dataCheck = receiveData[i];
} else {
dataCheck = dataCheck^receiveData[i];
}
}
}else{
return -1;
}
if(checkCode==dataCheck){
int index = 0;
while (index < len ) {
rstData[index]=receiveData[index+3];
index++;
}
rstLen=len;
return 1;
}else{
return -2;
}
}
最后得到这个命令,可以看得出,getCmd的返回值是个int,并不是一个字符串。嗯,这是因为我的小车功能还比较简单,一个int就能表示所有的命令了,这样也方便调试。另外还有一个问题就是int占用空间少,比较适合arduino这样的硬件受限的设备,字符串可能效率非常低。不过只要我一直玩下去,这就能变成一个字符串。
好累,android部分的协议我还是放到讲android的时候再讲吧。
声明:
本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:
https://www.wpsshop.cn/w/笔触狂放9/article/detail/288112?site
推荐阅读
article
《花雕
学
AI
》18:
AI
绘画
尝鲜
Prompt
Hunt
,使用
人工智能
模型
来
创造
、探索和分享
艺术作品
_...
正面
的
影响是,它可以让更多
的
人参与到艺术
创作
中,提高他们
的
创造
力和表达力,也可以让他们欣赏和
学
习不同
的
艺术风格和技巧。S...
赞
踩
article
基于
matlab
的
语音
信号
加窗
,
[转载]基于
Matlab
的
语音
识别技术
的
应用...
语音
识别技术
的
应用是2013年5月份参加Mathorcup数学建模竞赛
的
题目,整体部分代码,如下%
语音
信号
采集n=5*8...
赞
踩
article
中文
C语言
编程
鸿蒙
Hi3861
智能硬件
开发
套件_
鸿蒙
中文
编程
语言
...
华为海思为物联网
开发
的
Hi3861
芯片已发布较长时间,其性能优异,接口丰富,并有
鸿蒙
系统加持,但在现实应用场景普及程度,...
赞
踩
article
微信
小
程序
三级
分销商
城源码
系统
+
区域代理
+完整
的
部署教程...
随着电商行业
的
快速发展,越来越多
的
商家希望能够拥有自己
的
线上销售渠道,而
微信
小
程序
作为一种轻量级
的
应用
程序
,具有易于开发...
赞
踩
article
毫米波
雷达
与
激光
雷达
探秘_
毫米波
雷达
发射点
云
为什么
比
激光
少...
激光
雷达
是以发射
激光
束探测目标的位置、速度等特征量的
雷达
系统,计算时是按照光的特性来计算。而
毫米波
雷达
是指工作在
毫米波
波...
赞
踩
article
(
Appium
_
apk
package
)查询
apk
包名
_查看
apk
包名
...
查看当前正在运行应用的
包名
。_查看
apk
包名
查看
apk
包名
查询...
赞
踩
article
Android
中使用
Adapter
(
适配器
)给
RecycleView
设置
数据源
_将
数据源
添加到
适配器
...
场景RecyclerViewRecyclerView是
Android
一个更强大的控件,其不仅可以实现和ListView同...
赞
踩
article
查看
cordova
-
android
版本
支持信息_
查看
有
cordova
版本
...
有时需要添加Cordova对应得Android支持
版本
,但具体不知道哪些
版本
得时候,可通过如下命令
查看
npm view...
赞
踩
article
suocr
打码
平台
的
原理与用法...
打码
平台
的
原理
打码
平台
的
核心功能是自动识别验证码,其原理可以分为两大类:人工
打码
:工作方式:这种方式主要依赖于人工进行验...
赞
踩
article
慧差...
彗差:轴外物体发出的光线,在经过光学系统后,焦点处于不同的平面,且由于通过OC的光线不被改变光路,在像平面处产生从像点一...
赞
踩
article
Hcaptcha
自动识别/打码
解决方案
...
Hcaptcha
recaptcha funcapthca 打码
解决方案
接口_hcaptchahcaptcha ...
赞
踩
article
Android
项目没有
BuildConfig
解决方案_
android
buildconfig
...
新建了一个项目发现无论怎么编译清理还是清除缓存都没有
BuildConfig
这个 文件。只需要在gradle中加入。然...
赞
踩
article
【SDL实践指南】
安全
风险
评估
规范_
sdl
等
应用
安全
风险
识别
方法论和实操经验:...
信息
安全
风险
管理是信息
安全
保障工作中的一项重要基础性工作,其核心思想是对管理对象面临的信息
安全
风险
进行管控。信息
安全
风险
...
赞
踩
article
8
语义
搜索
_
语义
检索...
不同
搜索
模式之间的技术差异:1、对用户需求的表示(query model)2、对底层数据的表示(data model)3...
赞
踩
article
OpenCV
图像
处理——对比
两张
图像
差异
的
位置并标记_深度学习找出
两张
图片
差异最大
的
区域...
前言1.有一个小游戏,就给出
两张
内容几乎差不多全部相同
的
图像
,让大家在最快
的
时间内找出两个
图像
中有几处不同地方,我这里试...
赞
踩
article
【
K8S
】
docker
和
K8S
(
kubernetes
)理解?
docker
是什么?
K8S
架构、Mast...
docker
爆火的原因——轻!,
K8S
,就是基于容器的集群管理平台,Build、Ship and Run”(构建、运输(...
赞
踩
article
华为
Harmony
——
ArkTs
语言
_鸿蒙
arkts
语言
操作
sqlserver
数据库
...
在ArkUI中,UI显示的内容均为组件,由框架直接提供的称为系统组件,由开发者定义的称为自定义组件。在进行 UI 界面开...
赞
踩
article
Android
超方便 集成
Zxing
实现
扫一扫
,
闪光灯
,生成
二维码
图片,解析
二维码
(条码)等功能_...
之前我写过一篇博客是关于如何将
zxing
集成到
Android
Studio中,以及简单的实现
扫一扫
功能。 详情请看:An...
赞
踩
article
back
propagation
(BP)
算法
拓展——
自动
微分简介:
前向
模式
、反向
模式
及
python
...
back
propagation
(BP)
算法
拓展——
自动
微分简介:
前向
模式
、反向
模式
及
python
代码实现 ...
赞
踩
article
数字
图像处理
---
窗
函数
在
图像处理
中的
应用
_矩阵
窗
函数
...
窗
函数
在
图像处理
中的
应用
上次我初略的讲了一下什么是
窗
函数
,以及
窗
函数
在DSP
应用
中的例子。之所以要引用
窗
函数
,主要是为...
赞
踩
相关标签
人工智能
AI作画
深度学习
基于matlab的语音信号加窗
harmonyos
c语言
智能硬件
微信小程序
小程序
微信小程序分销商城
appium
android
adb
Android
cordova
python
云计算
C++
Camera Tuning
相机
servlet
javascript
前端
算法