基于STM32L0的LoRaWAN终端节点持续发送入网请求需求问询
基于STM32L0的LoRaWAN终端持续入网与重连实现
核心逻辑设计
- 上电/复位后立即启动入网流程,循环发送
Join Request帧,直到收到网关的Join Accept;连续重试失败后加入退避机制,避免网络拥堵 - 入网成功后,通过心跳帧ACK反馈或协议栈事件监测链路状态;一旦检测到链路中断,立即重置协议栈并重新启动入网流程
代码实现示例(基于LMIC协议栈)
以下代码适配STM32L0平台,需结合STM32CubeMX配置的LoRaWAN工程使用:
状态定义与参数配置
#include "lmic.h" #include "hal.h" typedef enum { LORAWAN_UNJOINED, LORAWAN_JOINING, LORAWAN_JOINED } LoRaWAN_State; LoRaWAN_State current_state = LORAWAN_UNJOINED; uint32_t join_retry_cnt = 0; // 重试阈值与退避时间可根据实际网络调整 #define MAX_RETRY_BEFORE_BACKOFF 5 #define JOIN_BACKOFF_MS 30000 #define HEARTBEAT_INTERVAL_MS 60000
主循环状态处理
int main(void) { HAL_Init(); SystemClock_Config(); // 初始化LoRaWAN硬件与协议栈 lmic_init(); // 配置DevEUI、AppEUI、AppKey等参数(需替换为实际值) os_memcpy(LMIC.devEui, devEui, 8); os_memcpy(LMIC.appEui, appEui, 8); os_memcpy(LMIC.appKey, appKey, 16); while (1) { switch(current_state) { case LORAWAN_UNJOINED: join_retry_cnt = 0; current_state = LORAWAN_JOINING; break; case LORAWAN_JOINING: // 发送入网请求 if(LMIC_join() == LMIC_SUCCESS) { join_retry_cnt++; uint32_t start_tick = HAL_GetTick(); // 等待10秒,判断是否收到入网响应 while(HAL_GetTick() - start_tick < 10000) { LMIC_run(); // 处理协议栈事件 if(LMIC.state == LORAMAC_STATE_JOINED) { current_state = LORAWAN_JOINED; join_retry_cnt = 0; break; } } // 超时未响应,判断是否需要退避 if(current_state == LORAWAN_JOINING) { if(join_retry_cnt >= MAX_RETRY_BEFORE_BACKOFF) { HAL_Delay(JOIN_BACKOFF_MS); join_retry_cnt = 0; } } } else { // 发送失败,短延时后重试 HAL_Delay(1000); } break; case LORAWAN_JOINED: static uint32_t last_heartbeat_tick = 0; // 每60秒发送一次心跳帧,监测链路 if(HAL_GetTick() - last_heartbeat_tick > HEARTBEAT_INTERVAL_MS) { LMIC_setTxData2(1, (uint8_t*)"HB", 2, 0); // 端口1发送"HB"心跳数据 last_heartbeat_tick = HAL_GetTick(); uint32_t ack_wait_tick = HAL_GetTick(); // 等待15秒,判断是否收到ACK while(HAL_GetTick() - ack_wait_tick < 15000) { LMIC_run(); if(LMIC.txrxFlags & TXRX_ACK) { LMIC.txrxFlags &= ~TXRX_ACK; // 清除ACK标志 break; } } // 未收到ACK,判定链路中断,触发重连 if(!(LMIC.txrxFlags & TXRX_ACK)) { current_state = LORAWAN_UNJOINED; LMIC_reset(); // 重置协议栈状态 } } LMIC_run(); // 持续处理协议栈事件 break; } } }
关键注意事项
- 退避机制:必须加入退避逻辑,避免终端在网关不可达时持续发送入网请求,造成网络资源浪费
- 协议栈配置:确保DevEUI、AppEUI、AppKey等参数与LoRaWAN网络服务器配置一致
- 功耗优化:电池供电场景下,退避期间可将STM32L0切换到STOP/STANDBY低功耗模式,降低功耗
- 事件回调优化:可利用LMIC的事件回调(如
EV_JOINED、EV_TXCOMPLETE)替代轮询,提升响应效率与代码简洁性
内容的提问来源于stack exchange,提问作者Mr._Nileshkumar_Solanki
相关产品推荐
相关产品推荐

