上一步我们完成了子节点与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_FLAGif (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 0debug_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截图: