Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem with ESP.reset() #120

Open
bosoft-ESP opened this issue Apr 28, 2024 · 4 comments
Open

Problem with ESP.reset() #120

bosoft-ESP opened this issue Apr 28, 2024 · 4 comments

Comments

@bosoft-ESP
Copy link

Hello
I have tried to implement a reset to an ESP01S via a telegram text message.
The function is:
`

if (msg.text.indexOf(F("RESET_ESP")) != -1){
myBot.sendMessage(msg.sender.id,"RESET of the ESP received");
msg.text = "";
delay(1000);
ESP.reset();
}

On receiving 'RESET_ESP', it sends the message “RESET of the ESP received” and executes ESP.reset(). The problem is at startup. The ESP receives 'RESET_ESP' again and resets indefinitely, and there is no way to stop it. I have implemented this before resetting:
while (myBot.getNewMessage(msg)){
delay(1000);
msg.text = "";
}`
But it keeps receiving from telegram 'RESET_ESP'.
This last function I have also put it in the setup(), but it does not detect pending text. . The ESP is still receiving 'RESET_ESP'.
Any idea?

Regards

@shurillu
Copy link
Owner

Hello bosoft-ESP,
the issue you pointed out is due to the message confirmation protocol. Every time you call a getNewMessage() method, you mark as read the previous message.
This mean that when the bot receive a message for resetting himself, the bot execute the reset procedure without marking as read the reset message, going in a reset loop.
So:

  • if you are using the v2.x version of the library, you can solve the issue executing another getNewMessage() method ONLY when you receive a reset message. In this way you mark as read the reset message. You don't need to manage the second getNewMessage() because you does not mark as read the message so after the reset you'll receive it.
  • if you are using the v3.x version of the library, there is a getNewMessage() parameter that mark as read the message read (by default it should mark as read once the message is retreived):
	// get the first unread message from the queue (text and query from inline keyboard). 
	// This is a destructive operation: once read, the message will be marked as read
	// so a new getMessage will read the next message (if any).
	// params
	//   message : the data structure that will contains the data retrieved
	//   mode    : change the behavior of the getNewMessage
	//             CTBotGetMessageNoOption            - no blocking, no destructive
	//             CTBotGetMessageDestructuve         - once read, the message is no more retrieved
	//             CTBotGetMessageBlocking            - wait until a Telegram Server response
	//             CTBotGetMEssageBlockingDestructive - the sum of the two effects
	// returns
	//   CTBotMessageNoData  : an error has occurred
	//   CTBotMessageText    : the received message is a text
	//   CTBotMessageQuery   : the received message is a query (from inline keyboards)
	//   CTBotMessageLocation: the received message is a location
	//   CTBotMessageContact : the received message is a contact
	CTBotMessageType getNewMessage(TBMessage& message, CTBotGetMessageMode mode = CTBotGetMessageDestructive);

Hoping this can help, regards.

Stefano

@bosoft-ESP
Copy link
Author

bosoft-ESP commented Apr 29, 2024

Hello
Sorry for the late reply.
Based on your echoBot.ino:
`/*
Name: echoBot.ino
Created: 12/21/2017
Author: Stefano Ledda [email protected]
Description: a simple example that check for incoming messages
and reply the sender with the received message
*/
#include "CTBot.h"
CTBot myBot;
TBMessage msg;

String ssid = ""; // REPLACE mySSID WITH YOUR WIFI SSID
String pass = ""; // REPLACE myPassword YOUR WIFI PASSWORD, IF ANY
String token = ""; //REPLACE myToken WITH YOUR TELEGRAM BOT TOKEN

void setup() {
// initialize the Serial
Serial.begin(115200);
Serial.println("Starting TelegramBot...");
myBot.wifiConnect(ssid, pass);
myBot.setTelegramToken(token);
if (myBot.testConnection())
Serial.println("\ntestConnection OK");
else
Serial.println("\ntestConnection NOK");

if(myBot.getNewMessage(msg)) Serial.println("setup: "+msg.text);

}

void loop() {
if (CTBotMessageText == myBot.getNewMessage(msg)){

  Serial.println("loop: "+msg.text);
	if(msg.text.indexOf("RESET_ESP")!=-1){
      myBot.sendMessage(msg.sender.id, msg.text);
      if(myBot.getNewMessage(msg)) Serial.println("in RESET: "+msg.text);
      delay(1000);
      ESP.reset();
      }
  }`

Answers in serial:
`
17:34:44.353 -> testConnection OK
17:34:57.360 -> loop: /start
17:35:19.664 -> loop: RESET_ESP
17:35:22.732 -> ets Jan 8 2013,rst cause:2, boot mode:(3,6)
17:35:22.732 -> load 0x4010f000, len 3424, room 16
17:35:22.732 -> tail 0

17:35:22.732 -> chksum 0x2e
17:35:22.732 -> load 0x3fff20b8, len 40, room 8
17:35:22.732 -> tail 0
17:35:22.732 -> chksum 0x2b
17:35:22.732 -> csum 0x2b
17:35:22.732 -> v000652c0
17:35:22.732 -> ~ld
17:35:29.513 ->
17:35:29.513 -> testConnection OK
17:35:30.825 -> setup: RESET_ESP
`
As you can see, upon receiving a 'RESET_ESP', I again ask for a new getNewMessage, but it does not write anything to serial.
However, in setup, after the reset, it reads 'RESET_ESP' again.
I will try again this solution which seems to work.
I will also try version 3 to see if it is simpler to solve.

Thanks for your great work and for the answer

Regards

Edit: tested with version 3. Same result

Translated with DeepL.com (free version)

@shurillu
Copy link
Owner

shurillu commented Apr 29, 2024

I'm sorry bosoft-ESP I forgot to say that the getNewMessage() must be blocking because you must wait a valid Telegram server response.

Here a working sketch:

#include "CTBot.h"
CTBot myBot;
TBMessage msg;

String ssid = ""; // REPLACE mySSID WITH YOUR WIFI SSID
String pass = ""; // REPLACE myPassword YOUR WIFI PASSWORD, IF ANY
String token = ""; //REPLACE myToken WITH YOUR TELEGRAM BOT TOKEN

void setup() {
    // initialize the Serial
    Serial.begin(115200);
    delay(300);
    Serial.println("\nStarting TelegramBot...");
    myBot.wifiConnect(ssid, pass);
    myBot.setTelegramToken(token);
    if (myBot.testConnection())
        Serial.println("\ntestConnection OK");
    else
        Serial.println("\ntestConnection NOK");
}

void loop() {
    if (CTBotMessageText == myBot.getNewMessage(msg)) {
        if (msg.text.equals("RESET")) {
            Serial.println("Resetting...");
            myBot.getNewMessage(msg, true);  // <- blocking must be true!
            ESP.reset();
        }
        else
            Serial.println(msg.text.c_str());
    }
}

Let me know if this solve the issue.
Regards,

Stefano

EDIT: I tried it with a ESP8266 board, but the rule is still valid for the ESP32.

@bosoft-ESP
Copy link
Author

That's it. Thank you very much for your help.
I didn't know about the blocking.

Regards

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants