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

ESP32使用UniversalTelegramBot仅发送首条消息后停止发送问题

问题分析

你的核心问题是WiFiClientSecure连接未正确重置,叠加一处变量作用域错误,导致Telegram消息发送异常:

  1. Setup函数中重新定义局部变量previousMillis,覆盖全局变量,造成定时器初始值逻辑混乱;
  2. 每次发送消息后,WiFiClientSecure的连接未主动关闭,后续请求无法建立有效新连接。

修复步骤

1. 修复变量作用域错误

在setup()中,你定义了局部的unsigned long previousMillis = millis();,这会覆盖全局的previousMillis变量,导致定时器初始值未正确赋值。修改为:

// 去掉unsigned long,直接给全局变量赋值
previousMillis = millis();

2. 重置WiFiClientSecure连接

每次发送消息前后,强制关闭客户端连接,确保下次发送时能建立全新的有效连接。修改loop()中的消息发送逻辑:

if (WiFi.status() == WL_CONNECTED) {
  // 发送前关闭已有无效连接
  if(secured_client.connected()){
    secured_client.stop();
  }
  // 重新设置SSL根证书,确保连接安全性
  secured_client.setCACert(TELEGRAM_CERTIFICATE_ROOT);
  
  if(bot.sendMessage(CHAT_ID, "Temp: " + TempState, ""))
    DEBUG_PRINTLN("Message sent");
  else 
    DEBUG_PRINTLN("Message NOT sent");
  
  // 发送后主动关闭连接
  secured_client.stop();
}

3. 简化定时器逻辑(可选)

移除冗余的firstTime变量,直接通过全局previousMillis的初始值0触发第一次执行:

// 删除全局变量:bool firstTime = true;
// loop中的触发条件改为:
if(millis() - previousMillis >= TIMER_INTERVAL*60000UL) {
  previousMillis = millis();
  // 后续执行逻辑
}

完整修改代码

/****************************************************************
 * 
 * Sends dummy temperature value string to Telegram account 
 * once ever N minutes
 * 
 * 
 * HARDWARE:
 * Adafruit Huzzah ESP32
 * 
 * SOFTWARE:
 * Arduino v 1.8.19
 * UniversalTelegramBot v 1.3.0
 * ArduinoJson v 6.19.4
 * 
 *****************************************************************/

#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <WiFiMulti.h>
#include <UniversalTelegramBot.h>
#include <ArduinoJson.h>
#include "Credentials.h"

WiFiMulti wifiMulti;

#define VER "TelegramBotDemo_v2"

// Turn on debugging
#define MY_DEBUG

// ************** Print to serial only when MY_DEBUG is defined *****************
#ifdef MY_DEBUG
#define DEBUG_PRINTF(x)     Serial.print (x)
#define DEBUG_PRINTLNF(x)   Serial.println (x)
#define DEBUG_PRINT(x)      Serial.print (x)
#define DEBUG_PRINTDEC(x)   Serial.print (x, DEC)
#define DEBUG_PRINTLN(x)    Serial.println (x)
#define DEBUG_PRINTHEX(x)   Serial.print(x,HEX)
#else
#define DEBUG_PRINTF(x)
#define DEBUG_PRINTLNF(x)
#define DEBUG_PRINT(x)
#define DEBUG_PRINTDEC(x)
#define DEBUG_PRINTLN(x)
#define DEBUG_PRINTHEX(x)
#endif

bool wifiFound = false;

// Set GPIOs for LED and IO_PIN
const int BUILTIN_LED_PIN = 13; //optional
const int IO_PIN = 0;
float temp = 49.9;
bool state;
String TempState = "NONE";
unsigned long previousMillis = 0; 
const long TIMER_INTERVAL = 1; // mins (set to 1 for test otherwise 60)
#define LED_ON HIGH
#define LED_OFF LOW

WiFiClientSecure secured_client;
UniversalTelegramBot bot(BOTtoken, secured_client);


/**********************************************
  Round float to places places, return as string
***********************************************/
String rndS(float value, byte places)
{
  //Storage for displaying float converted to char array
  char valueChar[10];
  dtostrf(value, 5, places, valueChar); //convert float to char array
  String s = (String)valueChar;
  s.trim();  //remove whitespace
  return s ;
}

/************************************
 * Connect to wifi and display stats
 ************************************/
boolean wifiConnect()
{
  DEBUG_PRINTLN();
  WiFi.mode(WIFI_STA);

  uint32_t looptime = millis();
  uint8_t loopCount = 0;
  
  while (wifiMulti.run() != WL_CONNECTED)
  {
    while (millis() - looptime < 500L) yield(); // use this and not delay()
    looptime = millis();
    DEBUG_PRINT(".");
    if(++loopCount >= 20){
      DEBUG_PRINTLN("Timed out waiting for wiFi");
      return false;
    }
  }

  DEBUG_PRINTLN("");
  DEBUG_PRINT(F("IP address:"));
  DEBUG_PRINTLN(WiFi.localIP());
  DEBUG_PRINT(F("RSSI:"));
  DEBUG_PRINTLN(WiFi.RSSI());
  DEBUG_PRINTLN("WiFi Connected");
  DEBUG_PRINTLN("");
  
  return true;
}



/****************** SETUP ***************************/
void setup() {
  // Serial port for debugging purposes
  Serial.begin(115200);  
  Serial.println(VER);
  
  // Set RED LED off (LOW)
  pinMode(BUILTIN_LED_PIN, OUTPUT);
  digitalWrite(BUILTIN_LED_PIN, LED_OFF);
  
  secured_client.setCACert(TELEGRAM_CERTIFICATE_ROOT); // Add root certificate for api.telegram.org

  // Connect to Wi-Fi
  WiFi.mode(WIFI_STA);
  // add multiple WAPs; it will pick the strongest
  wifiMulti.addAP(ssid1, pass1);
  wifiMulti.addAP(ssid2, pass2);
  wifiMulti.addAP(ssid3, pass3);

  if(wifiConnect()){
    delay(500);
    wifiFound = true;  // not used
  }
  else
    exit(0);
    
  WiFi.setSleep(false);

  // Send startup message (this always works)
  if(bot.sendMessage(CHAT_ID, "Bot started up", ""))
    DEBUG_PRINTLN("Startup Message sent");
  else 
    DEBUG_PRINTLN("Startup Message NOT sent");
  
  // 修复:给全局变量赋值,而非定义局部变量
  previousMillis = millis();
}  // END OF SETUP


/****************** LOOP ***************************/
void loop() {    
  if(millis() - previousMillis >= TIMER_INTERVAL*60000UL) {
    previousMillis = millis();
     
    digitalWrite(BUILTIN_LED_PIN, LED_ON); // Flash RED LED
    delay(200);
    digitalWrite(BUILTIN_LED_PIN,LED_OFF);

    TempState = String(rndS(temp,1));
    DEBUG_PRINTLN(TempState);
 
    if (WiFi.status() == WL_CONNECTED) {
      // 发送前关闭已有连接,确保建立新连接
      if(secured_client.connected()){
        secured_client.stop();
      }
      // 重新设置根证书
      secured_client.setCACert(TELEGRAM_CERTIFICATE_ROOT);
      
      // Send dummy string value
      if(bot.sendMessage(CHAT_ID, "Temp: " + TempState, ""))
        DEBUG_PRINTLN("Message sent");
      else 
        DEBUG_PRINTLN("Message NOT sent");
      
      // 发送后关闭连接
      secured_client.stop();
    }
    else
      DEBUG_PRINTLN("WiFi NOT connected");
  
  } // END interval timer

} // END LOOP

修复原理

  • 变量作用域修正:确保定时器初始值正确绑定全局变量,避免触发逻辑混乱;
  • 连接重置:ESP32的WiFiClientSecure在发送请求后易处于半开状态,主动关闭后重新建立连接,可避免复用无效连接导致的请求失败;
  • 证书重设:每次建立连接时重新配置SSL根证书,确保连接的安全性与有效性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 20:01:02