Arduino MKR1500莫名停止工作:代码问题还是GSM信号差所致?
问题分析与代码优化建议
一、核心诱因:极差的GPRS信号是主要问题
钢制箱体属于强电磁屏蔽环境,会大幅衰减GSM/LTE信号,直接导致:
- 模块频繁断连、注册网络超时,甚至进入无响应状态
- 通信功耗飙升,可能引发电源波动,干扰主控或传感器稳定性
- MQTT在弱网下本身就易丢包、连接超时,进一步放大设备异常概率
但你的代码中也存在几个会加重问题的逻辑缺陷,导致设备在信号差时更容易僵死。
二、代码中的潜在问题
GSM重连的无限死循环
connectGSM()里的while (nbAccess.begin(SECRET_PINNUMBER) != NB_READY)是无限循环,一旦信号差到模块无法注册网络,设备会彻底卡死在这里,无法执行后续的传感器读取、看门狗喂狗等操作。看门狗虽设了2分钟超时,但喂狗代码根本没机会运行,最终触发复位后又会再次进入死循环,陷入重启循环。MQTT重连的阻塞逻辑
reconnect()中的while (!mqttClient.connected())同样是无限循环,每次失败还加了delay(5000)。如果信号差导致MQTT一直连不上,设备会僵死在此,同样无法执行核心逻辑,最终要么看门狗复位,要么彻底无响应。缺失MQTT心跳处理
代码里把mqttClient.loop()注释掉了,这会导致MQTT客户端无法向代理发送心跳包,即使连接成功,代理也会因心跳超时主动断开连接,加重断连频率。看门狗喂狗时机单一
仅在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
相关产品推荐
相关产品推荐

