Arduino⾃定义通讯协议的实现(键值型,不定长数据,传输稳定,提供多机通
讯模块调度demo)
参考仁泉之⼦⽼哥给的思路上实现拓展 :
数据帧⽰例:
{{Data@Name|verify}}
↑值和键都可以为任意长度
数据帧
{{开始标志
Data数据段(值),可以替换为你想要发送的数据
Name数据名称(键),可以替换为你要给哪个(从机/模块)(接收/发送)数据
Verify校验码,对内容 Data@Name|verify 进⾏校验
stimulated}}结束标志
校验⽅法:获取校验码
char GetVertifyValue(char* buf)
{
int sum =0;山市 翻译
for(int i =0; i <strlen(buf); i++)
{
sum +=*(buf + i);
}
return sum %('z'-' ')+' ';
}
通讯协议内容
#include"EleCom.h"
ELeCom::ELeCom()
{
tBufSize(BUFSIZE);
}
ELeCom::~ELeCom()
{
if(buf !=NULL)
{
free(buf);
buf =NULL;
}
}
inline bool ELeCom::tBufSize(unsigned int size)
{
buf =(byte *)malloc(sizeof(byte)* size);
if(NULL== buf)
{
return fal;
}
bufSize = size;
memt(buf,0, size);
memt(buf,0, size);
}
void ELeCom::addData(byte data)
{
//Err: 数据头 {{ 确认
if(data =='{')
{
if(cnt ==1|| cnt ==2)
{
*(buf +1)= data;
cnt =2;
//rDict = NULL;
return;
}
*buf = data;
cnt =1;
return;
}
//Err: 未确认数据头
if(cnt <2)
{
rockandrollcnt =0;
return;
}
//Err: 接收数据⼤于接收缓冲区⼤⼩
if(cnt >= bufSize)
{
cnt =0;
return;
}
//Err: 过滤掉其他⾮字符
if(data <' '|| data >'}')
{
cnt =0;
return;
}
//添加数据
*(buf + cnt)= data;
cnt++;
//判断数据尾
if(data =='}')
{
if(*(buf + cnt -2)=='}')
{
resolveCommand(cnt);
cnt =0;
posSepa =0;
macosx
posSepl =0;
}
}
embrace}新视野大学英语网站
void ELeCom::resolveCommand(int length) {
if(length <7)
{
return;
}
}
posSepa =GetChPos(buf,'@');
posSepl =GetChPos(buf,'|');
if(posSepa ==0)
{
return;
}
//提取键()
int keyLen = posSepl - posSepa -1;
char thisKey[keyLen +1]={0};
memt(thisKey,0, keyLen +1);
strncpy(thisKey, buf + posSepa +1, keyLen);
thisKey[keyLen]='\0';
// 提取校验码
char verify =*(buf + posSepl +1);
if(verify >0)
{
int sum =0;
for(int i =2; i < posSepl; i++)
{
sum +=*(buf + i);
// DEBUG("*(buf + i):");
// DEBUGln(*(buf + i));
}
// DEBUG("sum:");
// DEBUGln(sum);
char thisValueVerify = sum %('z'-' ')+' ';
DEBUG("thisValueVerify:");
DEBUGln(thisValueVerify);
DEBUG("verify:");
DEBUGln(verify);
if(thisValueVerify != verify)
{
return;
}
}
//提取值
int valueLen = posSepa -2;
char thisValue[valueLen +1]={0};
memt(thisValue,0, valueLen +1);
strncpy(thisValue, buf +2, valueLen);
thisValue[valueLen]='\0';
www chsi com cn cet
flushSerDict(&rDict.dicKey, thisKey, keyLen); flushSerDict(&rDict.dicValue, thisValue, valueLen);
revFlag =true;
}
void ELeCom::flushSerDict(char** tmp,char* value,int len) {
flushSerDictMemory(tmp, len +1);
strcpy(*tmp, value);
韩国身份证号}
void ELeCom::flushSerDictMemory(char** tmp,int len){
free(*tmp);
*tmp =(char*)malloc(len);
memt(*tmp,0, len);
}
SerDict* ELeCom::getSerialDict()
{
if(revFlag)
{
revFlag =fal;
return&(rDict);
}
return NULL;
}
//void ELeCom::tResolveCallback(ResolveCallback fun) {
/
/ this->resolveCallback = fun;
//}
专业美容培训/*
@Author:ou
@Date: 2021-08-06 13:24:53
@LastEditTime: 2021-08-09 10:49:15
@LastEditors: Plea t LastEditors
@Description: ⾃定义通信指令解析库, 专门解析固定格式的字符串例: {{Data@Name|verify}} @FilePath: \undefinede:\project\72 UNO导⼊py\EleCommunication\EleCom.h
*/
#ifndef ELECOM_H
#define ELECOM_H
#include<Arduino.h>
//接收数组缓冲区⼤⼩
#define BUFSIZE 250
typedef void(*ResolveCallback)(char* key,char* value);
typedef struct SerDict
{
char* dicKey;
char* dicValue;
};
class ELeCom
{
private:
//接收缓冲区
byte *buf =NULL;root是什么意思
int bufSize =0;
//已接收数据的总长度
int cnt =0;
//@分隔位置
int posSepa =0;
//|分隔位置
int posSepl =0;
ResolveCallback resolveCallback =NULL;
public:
//完整接收标志位
bool revFlag =fal;
SerDict rDict;
ELeCom(/* args */);
~ELeCom();
bool tBufSize(unsigned int size);
void flushSerDictMemory(char** tmp,int len);
void flushSerDict(char** tmp,char* value,int len);
void addData(byte data);
void resolveCommand(int length);
/
/void tResolveCallback(ResolveCallback fun);
SerDict*getSerialDict();
friend void MySub(char** dest,char* src,int len);
};
static ELeCom eleCom;
#define GetChPos(thisBuf,ch) (int)strchr(thisBuf, ch) - (int)thisBuf
#define Debug 1
#if Debug
#define DEBUG(s) Serial.print(s)
#define DEBUGln(s) Serial.println(s)
#el
#define DEBUG(s)
#define DEBUGln(s)
#endif
#endif
main
#include"EleCommunication.h"
void tup(){
Serial.begin(9600);
}
void loop(){
//SendUltValue(Ult_RevPinsValues, GetStructNum(Ult_RevPinsValues)); Task_Process();
}
void Task_DataProcessing()
{
SerDict* EData = SerialDict();
if(EData)
{
char* moudleName =NULL;
moudleName =GetModuleName(moudleName, EData);
DEBUG("moudleName: ");
DEBUGln(moudleName);
ModuleScheduling(moudleName, EData);
free(moudleName);
}
}