系列文章:
【从0到1搭建LoRa物联网】1、LoRa物联网的架构
【从0到1搭建LoRa物联网】2、终端设备开发方式
【从0到1搭建LoRa物联网】3、国产LoRa终端ASR6505软硬件
【从0到1搭建LoRa物联网】4、国产LoRa终端ASR6505普通GPIO
【从0到1搭建LoRa物联网】5、国产LoRa终端ASR6505驱动DHT11
【从0到1搭建LoRa物联网】6、国产LoRa终端ASR6505 I2C接口
【从0到1搭建LoRa物联网】7、国产LoRa终端ASR6505驱动段式LCD例程
【从0到1搭建LoRa物联网】8、国产LoRa终端ASR6505 PingPong通信
1、前言
在上一节的基础上,对PingPong通信进行改造,加入OLED显示,显示接收、发送数据包的个数和显示接收数据包的RSSI和SNR。
2、RSSI和SNR
RSSI:是Received Signal Strength Indication的缩写,中文含义是接收的信号强度指示,RSSI越大,表明信号越好。
SNR:是Signal Noise Ratio的缩写,中文含义是信噪比,是信号电平与噪声电平之比,SNR越大,表明信号越好。
3、实验设计
标定一个主机(M)一个从机(S),上电后主机主动发起通讯(发送“ping”),从机处于接收状态,从机接收到主机的信号后,回复信号(pong),完成一次正常通讯。在下一个发送点到来之前,主机都会一直等待从机的回复。下一个发送点到达之后发起下一次通讯。在整个通讯过程中从机不会主动发起通讯,只会在收到主机的信号后,回复主机信号。主从机的OLED会相应显示各自发送和接收到的包的个数和接收信号的RSSI和SNR。
4、代码实现
void MasterCycleSendTimerEvent()
{
TimerStop(&MasterCycleSendTimer);
Buffer[0] = 'P';
Buffer[1] = 'I';
Buffer[2] = 'N';
Buffer[3] = 'G';
for( i = 4; i < BufferSize; i++ )
{
Buffer[i] = i - 4;
}
DelayMs( 1 );
printf("Send: PING\r\n");
Radio.Send( Buffer, BufferSize );
TimerStart(&MasterCycleSendTimer);
}
//回调函数
void OnTxDone( void )
{
Radio.Sleep( );
TxCnt++;
printf("Tx=%d\r\n",TxCnt);
memset(OLED_BUF,0,sizeof(OLED_BUF));
if(isMaster)
{
sprintf(OLED_BUF,"M TX:%d ",TxCnt);
}
else
{
sprintf(OLED_BUF,"S TX:%d ",TxCnt);
}
OLED_ShowString(8,0,OLED_BUF,16);
Radio.Rx( 0 );
}
void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr )
{
Radio.Sleep( );
BufferSize = size;
memcpy( Buffer, payload, BufferSize );
RssiValue = rssi;
SnrValue = snr;
if( isMaster == true )
{
if( BufferSize > 0 )
{
if( strncmp( ( const char* )Buffer, ( const char* )PongMsg, 4 ) == 0 )
{
RxCnt++;
memset(OLED_BUF,0,sizeof(OLED_BUF));
sprintf(OLED_BUF,"RX:%d",RxCnt);
OLED_ShowString(24,2,OLED_BUF,16);
memset(OLED_BUF,0,sizeof(OLED_BUF));
sprintf(OLED_BUF,"Rssi:%d ",RssiValue);
OLED_ShowString(24,4,OLED_BUF,16);
memset(OLED_BUF,0,sizeof(OLED_BUF));
sprintf(OLED_BUF,"Snr:%d ",SnrValue);
OLED_ShowString(24,6,OLED_BUF,16);
printf("Received: PONG,rssi=%d,snr=%d\r\n",RssiValue,SnrValue);
}
else
{
Radio.Rx( 0 );
}
}
}
else
{
if( BufferSize > 0 )
{
if( strncmp( ( const char* )Buffer, ( const char* )PingMsg, 4 ) == 0 )
{
RxCnt++;
memset(OLED_BUF,0,sizeof(OLED_BUF));
sprintf(OLED_BUF,"RX:%d",RxCnt);
OLED_ShowString(24,2,OLED_BUF,16);
memset(OLED_BUF,0,sizeof(OLED_BUF));
sprintf(OLED_BUF,"Rssi:%d ",RssiValue);
OLED_ShowString(24,4,OLED_BUF,16);
memset(OLED_BUF,0,sizeof(OLED_BUF));
sprintf(OLED_BUF,"Snr:%d ",SnrValue);
OLED_ShowString(24,6,OLED_BUF,16);
printf("Received: PING,rssi=%d,snr=%d\r\n",RssiValue,SnrValue);
Buffer[0] = 'P';
Buffer[1] = 'O';
Buffer[2] = 'N';
Buffer[3] = 'G';
for( i = 4; i < BufferSize; i++ )
{
Buffer[i] = i - 4;
}
DelayMs( 1 );
Radio.Send( Buffer, BufferSize );
printf("Send: PONG\r\n");
}
else
{
Radio.Rx( 0 );
}
}
}
}
void OnTxTimeout( void )
{
Radio.Sleep( );
Radio.Rx( 0 );
}
void OnRxTimeout( void )
{
printf("OnRxTimeout\r\n");
Radio.Sleep( );
memset(OLED_BUF,0,sizeof(OLED_BUF));
sprintf(OLED_BUF,"RX:%d",RxCnt);
OLED_ShowString(24,2,OLED_BUF,16);
Radio.Rx( 0 );
}
void OnRxError( void )
{
Radio.Sleep( );
Radio.Rx( 0 );
}
int main( void )
{
BoardInitMcu( );
printf("ASR6505 PingPong test !\r\n");
I2C_PeriphInit();
BoardInitPeriph( );
OLED_Init();
OLED_Clear();
OLED_ShowString(16,1,(char *)("LoRa"),16);
OLED_ShowCN(48,1,0);
OLED_ShowCN(64,1,1);
OLED_ShowCN(80,1,2);
OLED_ShowString(24,4,(char *)("ASR6505"),16);
OLED_ShowString(8,6,(char *)("PingPong test"),16);
Delay(3);
OLED_Clear();
memset(OLED_BUF,0,sizeof(OLED_BUF));
// Radio initialization
RadioEvents.TxDone = OnTxDone;
RadioEvents.RxDone = OnRxDone;
RadioEvents.TxTimeout = OnTxTimeout;
RadioEvents.RxTimeout = OnRxTimeout;
RadioEvents.RxError = OnRxError;
Radio.Init( &RadioEvents );
Radio.SetChannel( RF_FREQUENCY );
Radio.SetTxConfig( MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH,
LORA_SPREADING_FACTOR, LORA_CODINGRATE,
LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON,
true, 0, 0, LORA_IQ_INVERSION_ON, 3000 );
Radio.SetRxConfig( MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR,
LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH,
LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON,
0, true, 0, 0, LORA_IQ_INVERSION_ON, true );
if(isMaster)
{
TimerInit(&MasterCycleSendTimer,MasterCycleSendTimerEvent);
TimerSetValue( &MasterCycleSendTimer, 5000 );
TimerStart(&MasterCycleSendTimer);
Buffer[0] = 'P';
Buffer[1] = 'I';
Buffer[2] = 'N';
Buffer[3] = 'G';
for( i = 4; i < BufferSize; i++ )
{
Buffer[i] = i - 4;
}
DelayMs( 1 );
printf("Send: PING\r\n");
Radio.Send( Buffer, BufferSize );
OLED_ShowString(8,0,"M",16);
}
else
{
Radio.Rx( 0 );
OLED_ShowString(8,0,"S",16);
}
while( 1 )
{
Radio.IrqProcess( );
}
}
5、实验现象
从图片中也可以清楚的看出,发送、接收、RSSI、SNR等重要参数。
欢迎关注微信公众号【物联网思考】,回复关键字“ ASR6505”获取资料,《从0到1搭建LoRa物联网》系列的所有软硬件资料将会分享在公众号。