I have a bug in a Code i can not debug.
The (almost same) code was running on a Wemos D1 mini.
But the S2 crashes in the last lines of the setup:
void setup() {
...
Serial.println("before reconnect");
reconnect();
Serial.println("setup end");
}
The setup() launches the reconnect().
reconnect() executes fully until the end (Serial.println("reconnect end") - I see the "reconnect end" in the Serial.
The last command in the setup() is not executed.
The S2 resets before printing "setup end".
I can not explain this. Any advice on how to debug this?
Full code:
#include <RCSwitch.h>
#include <WiFi.h>
#include <PubSubClient.h>
#include <IRremoteESP8266.h>
#include <IRsend.h>
#include "config.h"
#include "tv_remote_database.h"
#define BUILTIN_LED 15 // Change this to the pin number of your board's
RCSwitch mySwitch = RCSwitch(); // Create an instance of the RCSwitch library
WiFiClient espClient;
PubSubClient client(espClient);
IRsend irsend(IR_PIN);
unsigned long lastPublish = 0;
void flashLed(int repetitions, int on_duration, int off_duration = 0) {
for (int i = 0; i < repetitions; i++) {
digitalWrite(BUILTIN_LED, LOW); // Turn on the LED
delay(on_duration);
digitalWrite(BUILTIN_LED, HIGH); // Turn off the LED
delay(off_duration);
}
}
void flashforever() {
while (true) {
flashLed(1, 100, 100);
}
}
void setup_wifi() {
delay(10);
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
flashLed(1, 100, 500); // Blink once every 500ms while trying to connect to WiFi
}
flashLed(3, 100, 100); // Blink 3 times if connected to WiFi
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void reconnect() {
while (!client.connected()) {
Serial.print("Attempting MQTT connection... ");
if (client.connect("S2_MQTT_Sender", mqtt_username, mqtt_password)) {
Serial.println("connected");
// Flash the built-in LED 3 times after connecting to the MQTT broker
flashLed(3, 300, 300);
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
flashLed(2, 100, 400); // Blink twice if failed to connect to MQTT broker
if (client.state() == -2) {
Serial.println("Network unreachable, redoing WiFi setup...");
WiFi.disconnect(); // Disconnect from the WiFi network
delay(1000); // Wait for a while
setup_wifi(); // Redo the WiFi setup
}
delay(2000);
}
}
// Subscribe to all device topics
for (int i = 0; i < numDevices; i++) {
char topic[10];
snprintf(topic, 30, "Sender/RC/%s", devices[i][0].c_str());
client.subscribe(topic);
Serial.print("Subscribed to ");
Serial.println(topic);
}
// Subscribe to the IR topic
client.subscribe("Sender/IR");
Serial.println("Subscribed to Sender/IR");
Serial.println("reconnect end");
}
void setup() {
Serial.begin(115200);
pinMode(BUILTIN_LED, OUTPUT);
digitalWrite(BUILTIN_LED, HIGH);
mySwitch.enableTransmit(TRANSMITTER_PIN);
setup_wifi();
client.setServer(mqtt_server, mqtt_port);
client.setCallback(callback);
Serial.println("before reconnect");
reconnect();
Serial.println("setup end");
}
void loop() {
Serial.println("Loop start");
if (!client.connected()) {
reconnect();
}
client.loop();
if (millis() - lastPublish > 5000) {
client.publish("Sender/state", "online");
lastPublish = millis();
}
}
void callback(char* topic, byte* payload, unsigned int length) {
// Find the device based on the topic for RC commands
flashLed(2, 50, 100);
int deviceIndex = -1;
for (int i = 0; i < numDevices; i++) {
std::string deviceTopic = std::string("Sender/RC/") + devices[i][0].c_str();
if (String(topic) == deviceTopic.c_str()) {
deviceIndex = i;
break;
}
}
if (deviceIndex != -1) {
handleRCCommand(devices[deviceIndex], payload, length);
} else if (String(topic) == "Sender/IR") {
handleAndSendIRCommand(payload, length);
} else {
Serial.println("Received message for unknown device or topic");
}
}
void handleAndSendIRCommand(byte* payload, unsigned int length) {
// Parse the message
String message = "";
for (int i = 0; i < length; i++) {
message += (char)payload[i];
}
// Check if the message exists in the IR_CODES_MAP
if (IR_CODES_MAP.find(message.c_str()) != IR_CODES_MAP.end()) {
unsigned long irCode = IR_CODES_MAP.at(message.c_str());
// Send the IR code
IRsend irsend(IR_PIN);
irsend.begin();
irsend.sendSAMSUNG(irCode, 32, 1);
Serial.print("Sent IR code: ");
Serial.println(message); // Print the name of the IR code instead of the hex value
} else {
Serial.print("Received unknown IR command: ");
Serial.println(message);
}
}
void handleRCCommand(const String device[], byte* payload, unsigned int length) {
// Parse the message
String message = "";
for (int i = 0; i < length; i++) {
message += (char)payload[i];
}
// Send the command
if (message == "on" || message == "ON") {
sendRCCode(device, true);
} else if (message == "off" || message == "OFF") {
sendRCCode(device, false);
} else {
Serial.println("Received unknown message for RC command");
}
}
void sendRCCode(const String device[], bool on) {
int protocol = device[4].toInt();
int pulseLength = device[3].toInt();
mySwitch.setProtocol(protocol);
mySwitch.setPulseLength(pulseLength);
int commandCode = on ? device[1].toInt() : device[2].toInt();
mySwitch.send(commandCode, 24);
Serial.print("Sent ");
Serial.print(on ? "on" : "off");
Serial.print(" command for ");
Serial.println(device[0]);
}