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

Arduino MKR1500莫名停止工作:代码问题还是GSM信号差所致?

问题分析与代码优化建议

一、核心诱因:极差的GPRS信号是主要问题

钢制箱体属于强电磁屏蔽环境,会大幅衰减GSM/LTE信号,直接导致:

  • 模块频繁断连、注册网络超时,甚至进入无响应状态
  • 通信功耗飙升,可能引发电源波动,干扰主控或传感器稳定性
  • MQTT在弱网下本身就易丢包、连接超时,进一步放大设备异常概率

但你的代码中也存在几个会加重问题的逻辑缺陷,导致设备在信号差时更容易僵死。

二、代码中的潜在问题

  1. GSM重连的无限死循环
    connectGSM()里的while (nbAccess.begin(SECRET_PINNUMBER) != NB_READY)是无限循环,一旦信号差到模块无法注册网络,设备会彻底卡死在这里,无法执行后续的传感器读取、看门狗喂狗等操作。看门狗虽设了2分钟超时,但喂狗代码根本没机会运行,最终触发复位后又会再次进入死循环,陷入重启循环。

  2. MQTT重连的阻塞逻辑
    reconnect()中的while (!mqttClient.connected())同样是无限循环,每次失败还加了delay(5000)。如果信号差导致MQTT一直连不上,设备会僵死在此,同样无法执行核心逻辑,最终要么看门狗复位,要么彻底无响应。

  3. 缺失MQTT心跳处理
    代码里把mqttClient.loop()注释掉了,这会导致MQTT客户端无法向代理发送心跳包,即使连接成功,代理也会因心跳超时主动断开连接,加重断连频率。

  4. 看门狗喂狗时机单一
    仅在15秒一次的数据发送流程中喂狗,若设备卡在重连循环里,超过2分钟没喂狗就会触发复位,但无法解决根本问题。

三、修复建议

  • 给重连逻辑加超时限制:把无限while循环改成带次数/时间限制的重试,失败后退出重连函数,保证loop能继续执行、看门狗能被喂到。示例:
    void connectGSM() {
      Serial.println("Connecting NB IoT / LTE Cat M1 network...");
      int retryCount = 0;
      while (nbAccess.begin(SECRET_PINNUMBER) != NB_READY && retryCount < 5) {
        Serial.println(errortext);
        retryCount++;
        delay(1000);
      }
      if (retryCount >=5) {
        Serial.println("GSM retry failed, skip for now");
        return;
      }
      Serial.println(oktext);
    
      Serial.println("Attaching to GPRS...");
      retryCount = 0;
      while (gprsAccess.attachGPRS() != GPRS_READY && retryCount < 5) {
        Serial.println(errortext);
        retryCount++;
        delay(1000);
      }
      if (retryCount <5) Serial.println(oktext);
    }
    
  • 恢复mqttClient.loop()调用:在loop()的开头加入该函数,保证MQTT心跳正常。
  • 分散看门狗喂狗时机:在loop()开头或每次完成核心操作后都调用MyWatchDoggy.clear(),避免因某段逻辑阻塞导致喂狗超时。
  • 降低GSM状态检查频率:不要每次loop都检查GSM状态,改成和MQTT一样的时间间隔(比如30秒),减少不必要的模块交互。

内容的提问来源于stack exchange,提问作者MathCoMath

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 07:29:57