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

ESP32基于CTBot的Telegram Bot接收少量消息后停止显示问题

问题修复方案:ESP32 Telegram Bot消息显示失效问题

问题根源分析

  1. WiFi与Bot初始化冲突:原代码在WiFi连接循环内重复调用myBot.wifiConnect(),导致连接状态混乱,后续Telegram交互稳定性下降。
  2. 无连接维护机制:loop中未定期检查WiFi/Bot连接状态,几次消息交互后可能因连接断开无法接收新消息。
  3. 消息阶段逻辑缺陷:无新消息时直接跳回初始显示阶段,后续消息无法被捕获;消息转存时未做缓冲区边界检查,存在溢出风险。
  4. 冗余资源消耗:每秒多次调用printLocalTime(),占用系统资源影响稳定性。

修复代码与步骤

1. 修正WiFi与CTBot初始化逻辑

移除WiFi连接循环内的Bot初始化操作,仅在WiFi稳定后初始化Bot:

void setup() {
  pinMode(buzzer, OUTPUT);
  Serial.begin(115200);
  Serial.print("Connecting to ");
  Serial.println(ssid);
  
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("\nWiFi connected.");

  // WiFi稳定后再初始化Telegram Bot
  myBot.setTelegramToken(token);
  if (myBot.testConnection())
    Serial.println("CTBot connection OK");
  else
    Serial.println("CTBot connection NOK");

  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
  delay(5000);
  printLocalTime();
  
  P.begin(NUM_ZONES);
  P.setZone(0, 0, 3);
  P.setIntensity(0);
  P.addChar('$', degC);
  P.displayZoneText(0, szMesg, PA_CENTER, SPEED_TIME, 0, PA_PRINT, PA_NO_EFFECT);
}

2. 新增连接维护与消息监听逻辑

在loop中添加WiFi/Bot连接检查,优化消息阶段的等待逻辑:

void loop() {
  // 定期检查WiFi连接,断开时自动重连
  static unsigned long lastReconnectAttempt = 0;
  if (WiFi.status() != WL_CONNECTED && millis() - lastReconnectAttempt > 5000) {
    lastReconnectAttempt = millis();
    Serial.println("WiFi disconnected, reconnecting...");
    WiFi.begin(ssid, password);
    if (WiFi.status() == WL_CONNECTED) {
      Serial.println("WiFi reconnected.");
      myBot.setTelegramToken(token);
      if (myBot.testConnection())
        Serial.println("CTBot reconnected OK");
    }
  }

  // 每秒更新一次时间,减少资源消耗
  static unsigned long lastTimeUpdate = 0;
  if (millis() - lastTimeUpdate >= 1000) {
    lastTimeUpdate = millis();
    printLocalTime();
  }

  getTemperature();
  static uint32_t lastTime = 0;
  static uint8_t display = 0;
  static bool flasher = false;

  if (atoi(second) == 0 && lastMinute != 0) {
    digitalWrite(buzzer, HIGH);
    delay(100);
    digitalWrite(buzzer, LOW);
  }
  lastMinute = atoi(second);
  P.displayAnimate();

  if (P.getZoneStatus(0)) {
    switch (display) {
      case 0:  // 温度显示
        P.setFont(0, nullptr);
        P.setPause(0, 5000);
        P.setTextEffect(0, PA_SCROLL_LEFT, PA_SCROLL_UP);
        display++;
        dtostrf(temp, 3, 1, szMesg);
        strcat(szMesg, "$");
        Serial.print("Temperature: ");
        Serial.println(temp);
        break;

      case 1:  // 时钟显示
        P.setFont(0, numeric7Seg);
        P.setTextEffect(0, PA_PRINT, PA_NO_EFFECT);
        P.setPause(0, 0);
        if ((millis() - lastTime) >= 500) {
          lastTime = millis();
          getTime(szMesg, flasher);
          Serial.println(szMesg);
          flasher = !flasher;
        }
        if (atoi(second) == 5) {
          P.setTextEffect(0, PA_PRINT, PA_WIPE_CURSOR);
          display++;
        }
        break;

      case 2:  // 日历显示
        P.setFont(0, nullptr);
        P.setTextEffect(0, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
        display++;
        getDays(szMesg);
        P.setPause(0, 3000);
        break;

      case 3:  // 消息监听与显示
        static bool msgDisplayed = false;
        TBMessage msg;
        if (myBot.getNewMessage(msg, 0)) {
          msgDisplayed = true;
          // 安全转存消息,避免缓冲区溢出
          msg.text.toCharArray(szMesg, sizeof(szMesg)-1);
          szMesg[sizeof(szMesg)-1] = '\0';
          Serial.print("Received message: ");
          Serial.println(szMesg);
          myBot.sendMessage(msg.sender.id, "Hello, " + msg.sender.firstName + " " + msg.sender.lastName + ", Your Message:\n" + msg.text + "\ndisplayed on system...");
          P.setFont(0, nullptr);
          P.displayZoneText(0, szMesg, PA_CENTER, SPEED_TIME, 2000, PA_PRINT, PA_SCROLL_LEFT);
        }

        // 无新消息时保持监听状态,显示占位提示
        if (!msgDisplayed) {
          P.displayZoneText(0, "WAIT MSG", PA_CENTER, SPEED_TIME, 1000, PA_PRINT, PA_NO_EFFECT);
        } else {
          msgDisplayed = false;
          display = 0; // 消息显示完成后跳转回温度
        }
        break;
    }
    P.displayReset(0);
  }
}

3. 修复blinker函数计数逻辑

将局部计数变量改为静态,确保闪烁次数正确:

void blinker(long interval, int maxBlinks) {
  static unsigned long previousMillis = 0;
  static int blinkCount = 0;
  
  unsigned long currentMillis = millis();
  if (blinkCount < (maxBlinks*2) && currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
    digitalWrite(buzzer, !digitalRead(buzzer));
    blinkCount++;
    
    // 闪烁完成后重置状态
    if (blinkCount >= maxBlinks*2) {
      digitalWrite(buzzer, LOW);
      blinkCount = 0;
    }
  }
}

关键优化说明

  • 分离WiFi与Bot初始化流程,避免连接冲突
  • 添加自动重连机制,保障网络与Bot连接稳定性
  • 消息阶段新增等待逻辑,无新消息时保持监听状态
  • 缓冲区操作添加边界检查,防止内存溢出
  • 降低时间更新频率,减少系统资源消耗

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 08:59:50