增加 radio 通讯库
This commit is contained in:
parent
d88f02273e
commit
a5c25cbc80
217
TaiChi/radioTaiChi.cpp
Normal file
217
TaiChi/radioTaiChi.cpp
Normal file
@ -0,0 +1,217 @@
|
||||
#include <NeoHWSerial.h>
|
||||
|
||||
#include "radioTaiChi.h"
|
||||
|
||||
|
||||
//静态变量
|
||||
HandleMessageFunction Radio::hm_func;
|
||||
NeoHWSerial* Radio::NeoSerialX;
|
||||
|
||||
|
||||
Radio::Radio()
|
||||
{
|
||||
NeoSerialX = &RADIO_SERIAL_NUM;
|
||||
|
||||
EnableReceiveInterrupt();
|
||||
}
|
||||
|
||||
|
||||
//打开串口
|
||||
void Radio::BeginTransmit(unsigned long baud_rate)
|
||||
{
|
||||
NeoSerialX->begin(RADIO_BAUD_RATE);
|
||||
}
|
||||
|
||||
|
||||
//发送
|
||||
void Radio::Send(char* message, uint8_t send_type, uint8_t send_times)
|
||||
{
|
||||
//强制发送,禁用接收中断,防止发送被打断
|
||||
if (send_type == FORCE_SEND)
|
||||
DisableReceiveInterrupt();
|
||||
|
||||
//生成完整通信包
|
||||
char full_message[FULL_MESSAGE_SIZE];
|
||||
uint8_t message_length = strlen(message);
|
||||
char check_str[CHECK_STR_LENGTH + 1];
|
||||
|
||||
message_length = message_length < MAX_REAL_MESSAGE_SIZE ? message_length : MAX_REAL_MESSAGE_SIZE;
|
||||
|
||||
itoa(message_length, check_str, 10);
|
||||
|
||||
for (uint8_t i = 0, j = 0, k = 0; i < FULL_MESSAGE_SIZE; i++)
|
||||
{
|
||||
if (i < BLANK_CHAR_LENGTH)
|
||||
{
|
||||
full_message[i] = BLANK_CHAR;
|
||||
}
|
||||
else if (i == BLANK_CHAR_LENGTH)
|
||||
{
|
||||
full_message[i] = START_CHAR;
|
||||
}
|
||||
else if (j < message_length && j < MAX_REAL_MESSAGE_SIZE)
|
||||
{
|
||||
full_message[i] = message[j];
|
||||
j++;
|
||||
}
|
||||
else if (j == message_length || j == MAX_REAL_MESSAGE_SIZE)
|
||||
{
|
||||
full_message[i] = CHECK_CHAR;
|
||||
j++;
|
||||
}
|
||||
else if (k < CHECK_STR_LENGTH)
|
||||
{
|
||||
full_message[i] = check_str[k];
|
||||
k++;
|
||||
|
||||
if (check_str[k] == '\0')
|
||||
k = CHECK_STR_LENGTH;
|
||||
}
|
||||
else
|
||||
{
|
||||
full_message[i] = END_CHAR;
|
||||
}
|
||||
}
|
||||
|
||||
//发送完整通信包
|
||||
for (uint8_t times = 0; times < send_times; times++)
|
||||
{
|
||||
NeoSerialX->print(full_message);
|
||||
}
|
||||
|
||||
#ifdef RADIO_DEBUG
|
||||
NeoSerial.print("#RADIO: SEND: ");
|
||||
full_message[FULL_MESSAGE_SIZE - 1] = '\0';
|
||||
NeoSerial.print(full_message);
|
||||
NeoSerial.print(" TIMES: ");
|
||||
NeoSerial.println(send_times);
|
||||
#endif
|
||||
|
||||
if (send_type == FORCE_SEND)
|
||||
EnableReceiveInterrupt();
|
||||
}
|
||||
|
||||
|
||||
//设置接收回调函数
|
||||
void Radio::SetHandleMessageFunction(HandleMessageFunction hm_func)
|
||||
{
|
||||
Radio::hm_func = hm_func;
|
||||
}
|
||||
|
||||
|
||||
//禁用接收中断
|
||||
void Radio::DisableReceiveInterrupt() //禁用接收中断
|
||||
{
|
||||
NeoSerialX->detachInterrupt();
|
||||
}
|
||||
|
||||
|
||||
//恢复接收中断
|
||||
void Radio::EnableReceiveInterrupt() //恢复接收中断
|
||||
{
|
||||
NeoSerialX->attachInterrupt(Receive);
|
||||
}
|
||||
|
||||
|
||||
//接收,使用中断触发
|
||||
bool Radio::Receive(uint8_t ch, uint8_t status)
|
||||
{
|
||||
static long begin_time = millis();
|
||||
static bool is_start_record = false;
|
||||
static bool is_check_record = false;
|
||||
static bool is_end_record = false;
|
||||
static char message[FULL_MESSAGE_SIZE];
|
||||
static char check_str[CHECK_STR_LENGTH + 1];
|
||||
static uint8_t i = 0, j = 0;
|
||||
|
||||
//若上一次中断已在 100 ms前,可以认为当前是一次新的传输
|
||||
if (millis() - begin_time > 100)
|
||||
{
|
||||
begin_time = millis(); //更新时间
|
||||
|
||||
is_start_record = false;
|
||||
is_check_record = false;
|
||||
is_end_record = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
begin_time = millis(); //更新时间
|
||||
|
||||
switch (ch)
|
||||
{
|
||||
case START_CHAR:
|
||||
{
|
||||
if (is_end_record == false)
|
||||
{
|
||||
is_start_record = true;
|
||||
is_check_record = false;
|
||||
|
||||
//重置字符串
|
||||
for (uint8_t k = 0; k < i; k++)
|
||||
message[k] = '\0';
|
||||
for (uint8_t k = 0; k < j; k++)
|
||||
check_str[k] = '\0';
|
||||
|
||||
i = 0;
|
||||
j = 0;
|
||||
}
|
||||
} break;
|
||||
|
||||
case CHECK_CHAR:
|
||||
{
|
||||
if (is_end_record == false && is_start_record == true)
|
||||
{
|
||||
is_start_record = false;
|
||||
is_check_record = true;
|
||||
}
|
||||
} break;
|
||||
|
||||
case END_CHAR:
|
||||
{
|
||||
if (is_end_record == false && is_check_record == true)
|
||||
{
|
||||
is_check_record = false;
|
||||
|
||||
if (j <= CHECK_STR_LENGTH)
|
||||
check_str[j] = '\0';
|
||||
|
||||
if (atoi(check_str) == strlen(message)) //位数校验成功
|
||||
{
|
||||
is_end_record = true;
|
||||
|
||||
#ifdef RADIO_DEBUG
|
||||
NeoSerial.print("#RADIO: RECEIVE: ");
|
||||
NeoSerial.println(message);
|
||||
#endif
|
||||
|
||||
hm_func(message);
|
||||
}
|
||||
else //位数校验失败
|
||||
{
|
||||
#ifdef RADIO_DEBUG
|
||||
NeoSerial.println("#RADIO: RECEIVE FAIL!");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
default:
|
||||
{
|
||||
if (is_start_record == true)
|
||||
{
|
||||
if (i < FULL_MESSAGE_SIZE)
|
||||
message[i] = ch;
|
||||
i++;
|
||||
}
|
||||
else if (is_check_record == true)
|
||||
{
|
||||
if (j <= CHECK_STR_LENGTH)
|
||||
check_str[j] = ch;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
64
TaiChi/radioTaiChi.h
Normal file
64
TaiChi/radioTaiChi.h
Normal file
@ -0,0 +1,64 @@
|
||||
#ifndef RADIOTAICHI_H
|
||||
#define RADIOTAICHI_H
|
||||
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <NeoHWSerial.h>
|
||||
|
||||
//注释以关闭调试功能
|
||||
#define RADIO_DEBUG
|
||||
|
||||
//默认与 HC-12 连接串口
|
||||
#define RADIO_SERIAL_NUM NeoSerial2
|
||||
//与 HC-12 串口通信波特率
|
||||
#define RADIO_BAUD_RATE 9600
|
||||
|
||||
//通信包大小
|
||||
#define FULL_MESSAGE_SIZE 50
|
||||
//通信包最大有效信息大小
|
||||
#define MAX_REAL_MESSAGE_SIZE 41
|
||||
//通信包前段空字符填充长度
|
||||
#define BLANK_CHAR_LENGTH 4
|
||||
//通信包校验段字符串长度
|
||||
#define CHECK_STR_LENGTH 2
|
||||
//通信包标志字符
|
||||
#define BLANK_CHAR '~'
|
||||
#define START_CHAR '!'
|
||||
#define CHECK_CHAR '@'
|
||||
#define END_CHAR '#'
|
||||
#define SUCCUESS_CHAR '$'
|
||||
#define FAIL_CHAR '%'
|
||||
|
||||
//发送相关宏
|
||||
#define FORCE_SEND 0 //强制发送
|
||||
#define NO_FORCE_SEND 1 //非强制发送
|
||||
|
||||
#define DEFAULT_SEND_TIMES 1 //默认重复发送次数
|
||||
|
||||
|
||||
//回调函数指针
|
||||
typedef void (*HandleMessageFunction)(char*);
|
||||
|
||||
|
||||
class Radio
|
||||
{
|
||||
public:
|
||||
Radio();
|
||||
|
||||
static void BeginTransmit(unsigned long baud_rate = RADIO_BAUD_RATE); //打开串口
|
||||
|
||||
static void Send(char* message, uint8_t send_type = NO_FORCE_SEND, uint8_t send_times = DEFAULT_SEND_TIMES); //发送
|
||||
|
||||
static void SetHandleMessageFunction(HandleMessageFunction hm_func); //设置接收回调函数
|
||||
static void DisableReceiveInterrupt(); //禁用接收中断
|
||||
static void EnableReceiveInterrupt(); //恢复接收中断
|
||||
private:
|
||||
static bool Receive(uint8_t ch, uint8_t status); //接收,使用中断触发
|
||||
|
||||
static HandleMessageFunction hm_func; //接收回调函数
|
||||
|
||||
static NeoHWSerial* NeoSerialX;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
Loading…
x
Reference in New Issue
Block a user