专栏首页物联网思考LoRa节点开发——加入打印调试LoRaWAN

LoRa节点开发——加入打印调试LoRaWAN

一般调试我们用两种方法,断点和打印,考虑到射频和RTC,我们主要用打印调试的方法。

1、实现串口打印

#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)PUTCHAR_PROTOTYPE{ HAL_UART_Transmit(&UartHandle, (uint8_t *)&ch, 1, 0xFFFF); return ch;}

2、分等级打印调试信息

typedef enum  
{ 
    LOG_LEVEL_OFF=0,
    LOG_LEVEL_INFO, 
    LOG_LEVEL_DEVELOP, 
    LOG_LEVEL_ALL, 
}LOG_LEVEL; 
 
#define log_develop(level,...) \
do { \
     if(level>=LOG_LEVEL_DEVELOP) \
     { \
  printf("\nFILE:%s LINE:%d,FUNC:%s  ", __FILE__, __LINE__ ,__func__); \
  printf(##__VA_ARGS__); \
     } \
} while (0) 
#define log_info(level, ...) \
 do { \
  if(level>=LOG_LEVEL_INFO) \
  printf(##__VA_ARGS__ ); \
 } while (0) 
 
#define log_debug(level, ...) \
do {  \
  if(level>=LOG_LEVEL_ALL) \
  printf(##__VA_ARGS__ ); \
} while (0)

3、定义调试等级

LOG_LEVEL loglevel;
//定义打印等级,可以根据自己的实际设定,一般在调试阶段我们设定为LOG_LEVEL_ALL,即所有信息可见。

4、源码关键部分加入打印

以US915频段说明,其余频段类似。

4.1、在RegionUS915TxConfig函数打印发送的参数

bool RegionUS915TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime_t* txTimeOnAir )
{
    RadioModems_t modem;
    int8_t phyDr = DataratesUS915[txConfig->Datarate];
    int8_t txPowerLimited = LimitTxPower( txConfig->TxPower, NvmCtx.Bands[NvmCtx.Channels[txConfig->Channel].Band].TxMaxPower, txConfig->Datarate, NvmCtx.ChannelsMask );
    uint32_t bandwidth = GetBandwidth( txConfig->Datarate );
    int8_t phyTxPower = 0;
 
    // Calculate physical TX power
    phyTxPower = RegionCommonComputeTxPower( txPowerLimited, txConfig->MaxEirp, txConfig->AntennaGain );
    // Setup the radio frequency
    Radio.SetChannel( NvmCtx.Channels[txConfig->Channel].Frequency );
    if( txConfig->Datarate == DR_7 )
    { // High Speed FSK channel
        modem = MODEM_FSK;
        Radio.SetTxConfig( modem, phyTxPower, 25000, bandwidth, phyDr * 1000, 0, 5, false, true, 0, 0, false, 4000 );
    }
    else
    {
        modem = MODEM_LORA;
        Radio.SetTxConfig( modem, phyTxPower, 0, bandwidth, phyDr, 1, 8, false, true, 0, 0, false, 4000 );
    }
    // Setup maximum payload lenght of the radio driver
    Radio.SetMaxPayloadLength( modem, txConfig->PktLen );
    // Get the time-on-air of the next tx frame
    *txTimeOnAir = Radio.TimeOnAir( modem, txConfig->PktLen );
    *txPower = txPowerLimited;
    log_info (loglevel, "[%.3fMHz, SF%d ,%ddBm ,%dbyte]",  
                       Channels[txConfig->Channel].Frequency/1e6, 
                       phyDr, 
                       phyTxPower, 
                       txConfig->PktLen );
    return true;
}

4.2、在SendFrameOnChannel函数里面打印发送的数据(加密之后的)

LoRaMacStatus_t SendFrameOnChannel( uint8_t channel )
{
    TxConfigParams_t txConfig;
    int8_t txPower = 0;
 
    txConfig.Channel = channel;
    txConfig.Datarate = MacCtx.NvmCtx->MacParams.ChannelsDatarate;
    txConfig.TxPower = MacCtx.NvmCtx->MacParams.ChannelsTxPower;
    txConfig.MaxEirp = MacCtx.NvmCtx->MacParams.MaxEirp;
    txConfig.AntennaGain = MacCtx.NvmCtx->MacParams.AntennaGain;
    txConfig.PktLen = MacCtx.PktBufferLen;
 
    RegionTxConfig( MacCtx.NvmCtx->Region, &txConfig, &txPower, &MacCtx.TxTimeOnAir );
  
    MacCtx.McpsConfirm.Status = LORAMAC_EVENT_INFO_STATUS_ERROR;
    MacCtx.McpsConfirm.Datarate = MacCtx.NvmCtx->MacParams.ChannelsDatarate;
    MacCtx.McpsConfirm.TxPower = txPower;
    MacCtx.McpsConfirm.Channel = channel;
    // Store the time on air
    MacCtx.McpsConfirm.TxTimeOnAir = MacCtx.TxTimeOnAir;
    MacCtx.MlmeConfirm.TxTimeOnAir = MacCtx.TxTimeOnAir;
    if( LoRaMacClassBIsBeaconModeActive( ) == true )
    {
        // Currently, the Time-On-Air can only be computed when the radio is configured with
        // the TX configuration
        TimerTime_t collisionTime = LoRaMacClassBIsUplinkCollision( MacCtx.TxTimeOnAir );
        if( collisionTime > 0 )
        {
            return LORAMAC_STATUS_BUSY_UPLINK_COLLISION;
        }
    }
    if( MacCtx.NvmCtx->DeviceClass == CLASS_B )
    {
        // Stop slots for class b
        LoRaMacClassBStopRxSlots( );
    }
    LoRaMacClassBHaltBeaconing( );
    MacCtx.MacState |= LORAMAC_TX_RUNNING;
    if( MacCtx.NodeAckRequested == false )
    {
        MacCtx.ChannelsNbTransCounter++;
    }
    // Send now
    Radio.Send( MacCtx.PktBuffer, MacCtx.PktBufferLen );
    for( uint16_t i = 0; i < MacCtx.PktBufferLen; i++ )
    {
      log_info(loglevel," %02X",MacCtx.PktBuffer[i]);
    }
    log_info(loglevel,"\r\n");
    return LORAMAC_STATUS_OK;
}

4.3、在RegionUS915RxConfig函数里面打印接收参数

bool RegionUS915RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate )
{
    RadioModems_t modem;
    int8_t dr = rxConfig->Datarate;
    uint8_t maxPayload = 0;
    int8_t phyDr = 0;
    uint32_t frequency = rxConfig->Frequency;
 
    if( Radio.GetStatus( ) != RF_IDLE )
    {
        return false;
    }
 
    if( rxConfig->RxSlot == RX_SLOT_WIN_1 )
    {
        // Apply window 1 frequency
        frequency = NvmCtx.Channels[rxConfig->Channel].Frequency;
        // Apply the alternative RX 1 window frequency, if it is available
        if( NvmCtx.Channels[rxConfig->Channel].Rx1Frequency != 0 )
        {
            frequency = NvmCtx.Channels[rxConfig->Channel].Rx1Frequency;
        }
    }
    // Read the physical datarate from the datarates table
    phyDr = DataratesUS915[dr];
    Radio.SetChannel( frequency );
    // Radio configuration
    if( dr == DR_7 )
    {
        modem = MODEM_FSK;
        Radio.SetRxConfig( modem, 50000, phyDr * 1000, 0, 83333, 5, rxConfig->WindowTimeout, false, 0, true, 0, 0, false, rxConfig->RxContinuous );
    }
    else
    {
        modem = MODEM_LORA;
        Radio.SetRxConfig( modem, rxConfig->Bandwidth, phyDr, 1, 0, 8, rxConfig->WindowTimeout, false, 0, false, 0, 0, true, rxConfig->RxContinuous );
    }
    if( rxConfig->RepeaterSupport == true )
    {
        maxPayload = MaxPayloadOfDatarateRepeaterEU868[dr];
    }
    else
    {
        maxPayload = MaxPayloadOfDatarateEU868[dr];
    }
 
    Radio.SetMaxPayloadLength( modem, maxPayload + LORA_MAC_FRMPAYLOAD_OVERHEAD );
    *datarate = (uint8_t) dr;
    log_info( loglevel,"Recv[%.3fMHz, SF%d %dK, st:%d]... \r\n",
    frequency/1e6, 
    phyDr, 
    ( rxConfig->Bandwidth == 0 ) ? 125 : ( rxConfig->Bandwidth == 1 ) ? 250 : 500, 
    rxConfig->WindowTimeout );
    return true;
}

4.4、在OnRadioRxDone函数里面打印接收到的数据(未解密的数据)

static void OnRadioRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr )
{
    RxDoneParams.LastRxDone = TimerGetCurrentTime( );
    RxDoneParams.Payload = payload;
    RxDoneParams.Size = size;
    RxDoneParams.Rssi = rssi;
    RxDoneParams.Snr = snr;
    log_info(loglevel,"\r\nRecv data:%d byte,rssi:%d,snr:%d,data[",size,rssi,snr);
    for(uint8_t i=0;i<size;i++)
    {
      log_info(loglevel," %02x",payload[i]);
    }
    log_info(loglevel,"]\r\n");
  
    LoRaMacRadioEvents.Events.RxDone = 1;
 
    if( ( MacCtx.MacCallbacks != NULL ) && ( MacCtx.MacCallbacks->MacProcessNotify != NULL ) )
    {
        MacCtx.MacCallbacks->MacProcessNotify( );
    }
}

5、运行调试

入网调试打印:

发送数据打印调试:

加入打印之后,可以方便的调试,还可以打印入网之后、发送超时、接收超时等,可以根据自己的需要添加。

————END————

本文分享自微信公众号 - 物联网思考(everythinglink),作者:everythinglink

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-03-18

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 聊一聊,如何解密、分析LoRaWAN数据包?

    LoRaWAN中规定了7种不同的数据包,每种数据包又有不同的字段,除过“入网请求”和“入网回复”,其他的数据包都是AES-128加密的,如何明显的看出每个字段对...

    ManInRoad
  • LoRa终端设备之国产ASR6505软硬件

    ASR6505是基于stm8l152和sx1262 SIP封装的,因此开发ASR6505实际上就是开发STM8。STM8的开发环境一般常用的有IAR for S...

    ManInRoad
  • LoRa终端设备ASR6505之ADC采样

    前言:对低功耗设备来说,采集上报电池电压非常重要,通过电池电压可以辅助判断设备的使用寿命。ASR6505提供了丰富的外设接口,本篇文章主要聊一聊ADC接口的使用...

    ManInRoad
  • 搭建NFS Server

    执行命令 vim /etc/exports,创建 exports 文件,文件内容如下:

    gang_luo
  • Kubernetes 集群使用 NFS 网络文件存储

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.n...

    哎_小羊
  • CentOS7搭建NFS服务端和客户端

    院长技术
  • Kubernetes 集群部署 NFS 网络存储

    Kubernetes 对 Pod 进行调度时,以当时集群中各节点的可用资源作为主要依据,自动选择某一个可用的节点,并将 Pod 分配到该节点上。在这种情况下,P...

    高楼Zee
  • 腾讯云文件存储CFS中国香港地区上线,打造企业出海高速直通车

    2017年11月22日,腾讯云率先在香港地区推出了文件存储CFS,以中国香港为中心辐射国外市场,满足公有云客户日益增长的业务出海需求。这也是国内首家在香港地区提...

    云加社区
  • NFS存储服务部署

    什么是NFS 中文意思是网络文件系统,主要功能是通过网络(一般是局域网)让不同主机之间可以共享文件或目录 NFS属于本地文件存储服务  缺点1: windows...

    863987322
  • Redhat设置NFS挂载的简单步骤

    初识 nfs 还是在测试 lvs 负载均衡的时候,为了保证代码的一致性,将一台 Realserver 作为 nfs 服务器,而其他 Realserver 均以 ...

    张戈

扫码关注云+社区

领取腾讯云代金券