任务要求:
基于温湿度传感节点和光照度传感节点,要求轮询读取温湿度传感节点,光照度传感节点,将接收数据透传串口。
一、修改设备地址
//定义网络编号和设备地址,网络地址不需要修改同在同一网络内。
#define MY_NET_ID 0xD0C2 //网络ID
#define ADDR_MIN 1 //最小起始地址
#define ADDR_MAX 2 //最大终结地址
二、网关请求函数
void LoRa_SendRead( uint16_t NetId, uint8_t addr )用于发送读取传感器数据命令给指定网络设备参数为网络ID,addr为设备地址。
void LoRa_SendRead( uint16_t NetId, uint8_t addr )
{
uint8_t TxBuffer[BUFFER_SIZE];
TxBuffer[0]=START_HEAD;
TxBuffer[1]=CMD_READ;
TxBuffer[2]=(uint8_t)(NetId>>8);
TxBuffer[3]=(uint8_t)NetId;
TxBuffer[4]=addr;
TxBuffer[5]=CheckSum((uint8_t *)TxBuffer, 5);
Radio.Send( TxBuffer, 6);
}
三、Lora数据解析
数据解析和其他传感一致,只有一下代码发生改变。
//传感数据显示到OLED屏上
char OledBuf[32];
memset(OledBuf, ' ', 32);
memcpy(OledBuf+1, &DATASTAR_DATA, (LEN_DATA-1)>30?30:(LEN_DATA-1));
OLED_ShowString(0,4, (uint8_t *)OledBuf);
#ifndef TRANSPARENCY
//打印接收到的信息到调试助手
char output[BUFFER_SIZE*5]={0};
memset(output, '\0', BUFFER_SIZE*5);
GetHexStr((uint8_t *)LoRaRxBuf, len, (uint8_t *)output);//十六进制显示函数
printf("收到%d个字节的LoRa无线数据:%s\r\n", len, (const char *)output);
//提取响应数据中的传感数据
uint8_t StrBuf[BUFFER_SIZE*5]={0};
memset(StrBuf, '\0', BUFFER_SIZE*5);
memcpy(StrBuf, &DATASTAR_DATA, LEN_DATA-1);
printf("网络ID=0x%04X,源地址=%d\r\n", ((((uint16_t)NETH_DATA)<<8)+NETL_DATA), ADDR_DATA);
printf("传感数据:%s\r\n",StrBuf);
#else
USART1_SendStr((uint8_t *)DestData, 7+(*(DestData+6)));//透传
#endif /*(ENGINEER_DEBUG != false)*/
}
四、网关轮询函数
LoRa_ReadSensorProcess(uint8_t AddrMin, uint8_t AddrMax) // 轮询起始地址:AddrMin;轮询最后地址:AddrMax;在开始定义了两个参数。
例: LoRa_ReadSensorProcess(ADDR_MIN, ADDR_MAX);
void LoRa_ReadSensorProcess(uint8_t AddrMin, uint8_t AddrMax)
{
static uint16_t time = 1000;
static uint8_t addr = 1;
if(User0Timer_MS > time)
{
User0Timer_MS = 0;
time = randr( 1000, 4000 );//给定一个随机间隔时间,减少信道冲突概率
#ifndef TRANSPARENCY
printf("读取网络ID为0x%04X, 地址为%d的传感节点\r\n", MY_NET_ID, addr);
#endif
//显示屏提示轮询地址和网络号
char StrBuf[32];
memset(StrBuf, '\0', 32);
sprintf(StrBuf, " ID:%04X,Addr:%d", MY_NET_ID, addr);
OLED_ShowString(0,2, (uint8_t *)StrBuf);
//清除显示屏第3、4行的内容
memset(StrBuf, ' ', 32);
OLED_ShowString(0,4, (uint8_t *)StrBuf);
LoRa_SendRead( MY_NET_ID, addr++ );//发送读取传感命令,轮询地址+1
if(addr > AddrMax)//轮询地址大于最大值
{
addr = AddrMin;//轮询地址最小值
}
GpioToggle( &Led1 );//发送数据切换亮灯指示
}
}
五、主函数调用
主函数不断轮询传感器数据,Lora无线射频接收数据后,调用Lora数据解析函数将传感器信息取出。
int main( void )
{
PlatformInit();
while( 1 )
{
//IWDG_PrmRefresh( );//喂独立看门狗
MyRadioRxDoneProcess();//LoRa无线射频接收数据处理进程
LoRa_ReadSensorProcess(ADDR_MIN, ADDR_MAX);
}
}