上一步我们完成了子节点与PC交互,下面我们使用主节点和从节点进行交互,目前是一个主节点、单个从节点,相当于是一对一传输,主要的思路如下:
------>主节点发送问询帧
------>延时等待子节点回复
------>子节点回复
------>解析数据,判断数据的完整性,如果数据完整则对数据进行转化保存,等待上传
上面就是大概的流程,如果没有在指定时间收到子节点回复的数据则认为子节点收超时,进入到下一个节点的问询过程,这个过程基本都差不多,目前这个过程比较简单,没有太过复杂的东西,下面是我处理单个节点的函数,仅供参考。
//处理单个节点的具体操作
void GetLoraSlaveAData(void)
{
char params[256] = {0};
uint8_t RX_FLAG = 0;
/*1、清除上次状态*/
/*清除串口接收长度*/
LORA_RX_LENGTH = 0;
/*清除标志位*/
LORA_RX_FLAG = 0;
/*清接收缓存*/
memset(usart2RxBuff, 0, sizeof(usart2RxBuff));
/*2、获取节点数据*/
debug_print("\r\n获取A节点数据\r\n");
debug_print("\n <------ Lora A Send: ");
printBuffer(get_slave_A, sizeof(get_slave_A));
loraSendData(get_slave_A, sizeof(get_slave_A));
user_delay_ms(2000);
/*3、等待节点回复*/
//while (elapsed_time < timeout_ms)
{
//user_delay_ms(check_interval_ms); // 等待 500 毫秒
//elapsed_time += check_interval_ms; // 更新已等待时间
// 检查 LORA_RX_FLAG
if (LORA_RX_FLAG == 1)
{
LORA_RX_FLAG = 0;
RX_FLAG = 1; //表示收到数据
/*打印收到的节点A原始数据*/
debug_print("\n ------> Lora A Recv: ");
printBuffer(usart2RxBuff, LORA_RX_LENGTH);
debug_print("\r\n收到应答:\r\n");
/*解析数据*/
if (parseFrame(usart2RxBuff, LORA_RX_LENGTH, &frameData))
{
/*获取当前的RSSI数据*/
GetLoraRSSI();
// 输出解析结果
//这个地方用来打印解析的关键字,debug使用
debug_print("\r\n应答设备地址: 0x%02X, 帧类型: %02X, 帧内容长度: %d\r\n", frameData.deviceAddress, frameData.keyword, frameData.frameLength);
/*这个帧内容是包含校验和的*/
debug_print("\r\n帧内容: ");
printBuffer(frameData.frameContent, frameData.frameLength);
#if 0
debug_print("\r\n");
debug_print("\r\n校验和: %02X\r\n", frameData.checksum);
#endif
/*解析温度*/
/*解析湿度*/
/*解析气压*/
debug_print("\r\n温度: %.2f℃, 湿度: %.2f%%, 气压: %.2fhPa\r\n", rxNodeData.TEMP, rxNodeData.HUMB, rxNodeData.PRESS);
/*组包准备上传*/
snprintf(params, sizeof(params), "\"temp\":%.1f,\"humidity\":%.1f,\"pressure\":%.1f", rxNodeData.TEMP, rxNodeData.HUMB, rxNodeData.PRESS);
//C511_TX_AliYun(1, params);
memset(usart2RxBuff, 0, sizeof(usart2RxBuff));
} else {
debug_print("\r\n解析失败\r\n");
}
/*到这个地方说明已经接收到数据,不管有没有解析成功都要跳出循环*/
//break;
}
}
// 判断是否超时
if (RX_FLAG != 1)
{
debug_print("\r\n节点A回复超时\r\n");
}
}
下面是我实际测试过程中的debug截图: