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

ESP32基于C/C++向Azure IoT发送消息时出现超时问题求助

解决ESP32 Azure IoT Hub消息发送超时问题

我帮你分析了日志和代码,核心问题是ESP32成功建立了WiFi和IoT Hub连接,但发送事件时始终超时,错误提示Waiting for send confirmation, time is up还伴随TLS销毁的状态异常。下面是几个针对性的排查和修复方案:

1. 延长发送超时时间

Azure IoT Hub Arduino SDK默认的发送超时在某些网络环境下可能不够用,你可以手动调整这个阈值:

  • 找到日志里提到的Esp32MQTTClient.cpp文件(路径:/Users/stephanedeluca/Library/Arduino15/packages/esp32/hardware/esp32/1.0.6/libraries/AzureIoT/src/Esp32MQTTClient.cpp)
  • 定位到SendEventOnce函数的第316行,把超时时间从10000ms左右调整到20000ms甚至更长,比如:
    // 原超时判断
    if (millis() - start_time > 10000) {
    // 修改为
    if (millis() - start_time > 20000) {
    }
    

2. 优化MQTT心跳配置

ESP32和IoT Hub的MQTT连接可能因为心跳间隔设置不合理导致隐性断开,建议在初始化后添加心跳配置:
在Esp32MQTTClient_Init成功后,加入这行代码:

// 设置MQTT心跳间隔为30秒(IoT Hub建议范围是2-300秒)
Esp32MQTTClient_SetOption(MQTT_OPT_KEEPALIVE_INTERVAL, 30);

3. 升级ESP32核心和Azure IoT SDK

你当前用的ESP32核心版本是1.0.6,Azure IoT SDK是1.1.23,这两个版本都比较旧,存在不少已知的网络兼容性bug:

  • 把ESP32 Arduino核心升级到最新稳定版(比如2.x系列)
  • 同步升级Azure IoT Hub Arduino库到最新版本,新版本修复了很多TLS和MQTT发送相关的问题

4. 调整消息发送逻辑

你的代码现在每5秒就发送一次消息,可能造成消息堆积或连接压力过大,建议优化:

  • 增加发送失败后的重试延迟,不要立刻再次发送
  • 发送前先检查IoT Hub连接状态,确保连接正常再发送:
    调整后的loop函数示例:
    void loop() {
      if (hasIoTHub) {
        IOTHUB_CLIENT_CONNECTION_STATUS status;
        // 先确认连接已认证
        if (Esp32MQTTClient_GetConnectionStatus(&status) == IOTHUB_CLIENT_CONNECTION_AUTHENTICATED) {
          Serial.println("============ start sending events.");
          char buff[128];
          snprintf(buff, 128, "{\"batteries\":{\"0\":{\"current\": 1234.5}}}");
          if (Esp32MQTTClient_SendEvent(buff)) {
            Serial.println("============ Sending data succeeded");
          } else {
            Serial.printf ("xxxxxxxxxxxx Failure sending data: %s...", buff);
            Serial.println();
            delay(10000); // 失败后延迟10秒再重试
          }
        } else {
          Serial.println("============ IoT Hub connection not authenticated, waiting...");
        }
        delay(5000);
      }
    }
    

5. 排查网络环境

  • 确认ESP32所在网络没有防火墙或代理拦截MQTT端口(Azure IoT Hub使用8883端口,必须确保该端口开放)
  • 尝试切换到2.4GHz WiFi网络,旧版本ESP32核心对5GHz WiFi的兼容性较差

完整修改后的代码示例

#include <WiFi.h>
#include "Esp32MQTTClient.h"
// Please input the SSID and password of WiFi
const char* ssid = "XXX";
const char* password = "XXX";
/*String containing Hostname, Device Id & Device Key in the format: */
/* "HostName=<host_name>;DeviceId=<device_id>;SharedAccessKey=<device_key>" */
/* "HostName=<host_name>;DeviceId=<device_id>;SharedAccessSignature=<device_sas_token>" */
static const char* connectionString = "XXX";
static bool hasIoTHub = false;

void setup() {
  Serial.begin(115200);
  Serial.println("============ Starting connecting WiFi.");
  delay(10);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("\n============ WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  
  if (!Esp32MQTTClient_Init((const uint8_t*)connectionString)) {
    hasIoTHub = false;
    Serial.println("============ Initializing IoT hub failed.");
    return;
  }
  // 设置MQTT心跳间隔
  Esp32MQTTClient_SetOption(MQTT_OPT_KEEPALIVE_INTERVAL, 30);
  hasIoTHub = true;
}

void loop() {
  if (hasIoTHub) {
    IOTHUB_CLIENT_CONNECTION_STATUS status;
    if (Esp32MQTTClient_GetConnectionStatus(&status) == IOTHUB_CLIENT_CONNECTION_AUTHENTICATED) {
      Serial.println("============ start sending events.");
      char buff[128];
      snprintf(buff, 128, "{\"batteries\":{\"0\":{\"current\": 1234.5}}}");
      if (Esp32MQTTClient_SendEvent(buff)) {
        Serial.println("============ Sending data succeeded");
      } else {
        Serial.printf ("xxxxxxxxxxxx Failure sending data: %s...", buff);
        Serial.println();
        delay(10000); // 失败后延迟10秒再重试
      }
    } else {
      Serial.println("============ IoT Hub connection lost, waiting for reconnection...");
    }
    delay(5000);
  }
}

内容的提问来源于stack exchange,提问作者Stéphane de Luca

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.01 03:02:30