You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 05:05:09