Whats wrong with this Code ?

Hello, I’m new in Arduino & IoT, I’m building simple project that can control electronic device using ESP12E AI Thinker, MQTT and HomeAssistant. The system & UI worked fine until I add/edit some GPIO as an input.
The “if function” that use “status3” as a trigger and publish into topic (“ins/room6/status”, “1”) or (“ins/room6/status”, “0”) make Serial monitor display “Attempting Connection … MQTT COnnected” after Callback updated into topic (“ins/room6”).

If I delete that “if function” that use “status3” the system works fine, but I need to use “status3” to send a topic payload.

Is there anything wrong with my code?
Big thanks for help.

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <WiFiClientSecure.h>
#include <WiFiServer.h>
#include <WiFiUdp.h>
#include <PubSubClient.h>

#define MQTT_SERVER "xx.xx.xx.xx"
const char* ssid = "xxxxxxxx";
const char* password = "xxxxxxx";

const int lightPin1 = 15;
const int lightPin2 = 12;
const int lightPin3 = 14;
const int push1 = 5; 
const int push2 = 4;
const int push3 = 9;

char* lightTopic1 = "ins/room1";
char* lightTopic2 = "ins/room2";
char* lightTopic3 = "ins/room3";
char* lightTopic4 = "ins/room4";
char* lightTopic5 = "ins/room5";
char* lightTopic6 = "ins/room6";

WiFiClient wifiClient;
PubSubClient client(MQTT_SERVER, 1883, callback, wifiClient);

void setup() {
  pinMode(lightPin1, OUTPUT);
  pinMode(lightPin2, OUTPUT);
  pinMode(lightPin3, OUTPUT);
  pinMode(push1, INPUT_PULLUP);
  pinMode(push2, INPUT_PULLUP);
  pinMode(push3, INPUT_PULLUP);

  Serial.begin(115200);
  WiFi.begin(ssid, password);
  reconnect();
  delay(2000);
}



void loop(){

  if (!client.connected() && WiFi.status() == 3) {reconnect();}
  client.loop();

  int status1 = digitalRead(push1);
  int status2 = digitalRead(push2);
  int status3 = digitalRead(push3);

  if(status1==0){
  client.publish("ins/room4/status", "1");
  Serial.print("sensor1 : ");
  Serial.println(status1);
  }else if (status1==1){
  client.publish("ins/room4/status", "0");
  Serial.print("sensor1 : ");
  Serial.println(status1);
  }

  if(status2==0){
  client.publish("ins/room5/status", "1");
  Serial.print("sensor2 : ");
  Serial.println(status2);
  }else if (status2==1){
  client.publish("ins/room5/status", "0");
  Serial.print("sensor2 : ");
  Serial.println(status2);
  }
  
  if(status3==0){
  client.publish("ins/room6/status", "1");
  Serial.print("sensor3 : ");
  Serial.println(status3);
  }else if (status3==1){
  client.publish("ins/room6/status", "0");
  Serial.print("sensor3 : ");
  Serial.println(status3);
  }

  delay(100);
}


void callback(char* topic, byte* payload, unsigned int length) {

  String topicStr = topic; 
  Serial.println("Callback update.");
  Serial.print("Topic: ");
  Serial.println(topicStr);

  if(topicStr.equals(lightTopic1)){
    if(payload[0] == '1'){
       digitalWrite(lightPin1, HIGH);
      client.publish("ins/room1/status", "1");
    }
    else if (payload[0] == '0'){
      digitalWrite(lightPin1, LOW);
      client.publish("ins/room1/status", "0");
    }

  }

  if(topicStr.equals(lightTopic2)){
    if(payload[0] == '1'){
       digitalWrite(lightPin2, HIGH);
      client.publish("ins/room2/status", "1");
    }
    else if (payload[0] == '0'){
      digitalWrite(lightPin2, LOW);
      client.publish("ins/room2/status", "0");
    }

  }

  if(topicStr.equals(lightTopic3)){
    if(payload[0] == '1'){
       digitalWrite(lightPin3, HIGH);
      client.publish("ins/room3/status", "1");
    }
    else if (payload[0] == '0'){
      digitalWrite(lightPin3, LOW);
      client.publish("ins/room3/status", "0");
    }

  }

  if(topicStr.equals(lightTopic4)){
    if(payload[0] == '1'){
      client.publish("ins/room4/status", "1");
    }
    else if (payload[0] == '0'){
      client.publish("ins/room4/status", "0");
    }

  }

  if(topicStr.equals(lightTopic5)){
    if(payload[0] == '1'){
      client.publish("ins/room5/status", "1");
    }
    else if (payload[0] == '0'){
      client.publish("ins/room5/status", "0");
    }

  }

  if(topicStr.equals(lightTopic6)){
    if(payload[0] == '1'){
      client.publish("ins/room6/status", "1");
    }
    else if (payload[0] == '0'){
      client.publish("ins/room6/status", "0");
    }

  }

}



void reconnect() {

  if(WiFi.status() != WL_CONNECTED){
    Serial.print("Connecting to ");
    Serial.println(ssid);

    while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print(".");
    }
    Serial.println("");
    Serial.println("WiFi connected");  
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());
  }

  if(WiFi.status() == WL_CONNECTED){
    while (!client.connected()) {
      Serial.print("Attempting MQTT connection...");
      String clientName;
      clientName += "esp8266-";
      uint8_t mac[6];
      WiFi.macAddress(mac);
      clientName += macToStr(mac);

      if (client.connect((char*) clientName.c_str())) {
        Serial.print("\tMTQQ Connected");
        client.subscribe(lightTopic1);
        client.subscribe(lightTopic2);
        client.subscribe(lightTopic3);
        client.subscribe(lightTopic4);
        client.subscribe(lightTopic5);
        client.subscribe(lightTopic6);
      }
      else{Serial.println("\tFailed."); abort();}
    }
  }
}


String macToStr(const uint8_t* mac){

  String result;

  for (int i = 0; i < 6; ++i) {
    result += String(mac[i], 16);

    if (i < 5){
      result += ':';
    }
  }

  return result;
}

Maybe you are running out of memory.

How to make sure that my device running out memory?

beware of using a publish() inside a callback() function, you should reserve separate memory for messages to be sent. See the pubsubclient example sketch, that explains how to user a publish inside a callback.

I print this in all my debugs;

int freeRam()
{
        extern int __heap_start, *__brkval;
        int v;
        return (int)&v - (__brkval == 0 ? (int)&__heap_start : (int)__brkval);
}

jremington:
Maybe you are running out of memory.

gmichieletto:
beware of using a publish() inside a callback() function, you should reserve separate memory for messages to be sent. See the pubsubclient example sketch, that explains how to user a publish inside a callback.

bitflogger:
I print this in all my debugs;

int freeRam()

{
        extern int __heap_start, *__brkval;
        int v;
        return (int)&v - (__brkval == 0 ? (int)&__heap_start : (int)__brkval);
}

So, the problem is just about memory?
I'll learn some example sketch. Can somebody give example about memory reserve?

I've add getFreeHeap() in every callback() and loop() function, the serial output tells I got free heaps for about 43.000 - 46.000 bytes of 81.000 bytes.
So, it is not about memory problem.

Can somebody help ? Is that my code going wrong or the esp8266 have some hardware failure?

The problem is, if I delete just one client.publish in void loop(), my system running well but If I add it back, the system must be "disconnected" from MQTT server after checking callback to the last sensor (sensor3) just like bootloop.

I’m working on a MQTT controlled system with a NodeMCU ESP-12E myself. Below is a working model (still in work tho, so many things havent been completed or added. I suggest seperating your publish into a function and passing the topic and message to that function. Slims your code down for one.

#include <EEPROM.h>
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <stdlib.h>

// Connect to the WiFi
const char* ssid = "WIN_e858";
const char* password = "x4afteae";
const char* mqtt_server = "Raspberry-MQTT";

// For DeepSleep State

#define SLEEP_DELAY_IN_SECONDS  30

// For Temperature
 #define ONE_WIRE_BUS     D1
char temperatureString[6];
 
 WiFiClient espClient;
 PubSubClient client(espClient);
 OneWire oneWire(ONE_WIRE_BUS);
 DallasTemperature DS18B20 (&oneWire);


// EasyIoT server definitions
#define EIOT_USERNAME    "admin"
#define EIOT_PASSWORD    "test"
#define EIOT_IP_ADDRESS  "192.168.254.200"
#define EIOT_PORT        80
#define EIOT_NODE        "N2S0"

// The following function handles all incoming messages from the MQTT server.
void callback(char* topic, byte* payload, unsigned int length) {

  int topicSwitch;
  String strTopic = String((char*)topic);

  if (strTopic == "chickenCoop/Temperature"){
    topicSwitch = 1;
    
  }else if (strTopic == "chickenCoop/Door") {
    topicSwitch = 2;
    
  }else if (strTopic == "chickenCoop/Lights") {
    topicSwitch = 3;
    
  }else {
    topicSwitch = 4;
  }


  switch (topicSwitch) {
    case 1:
    {
            // Bullshit parameter in place of actual OneWire temp for testing
            float temp = getTemperatureF();
            String tempString = "Coop Temperature Currently ";
            tempString += String(temp) + " F ";
            Serial.print("Temperature Requested");
            Serial.println("Current Temperature");
            Serial.println(temp);
            sendMsg("test/sendmsg", tempString);
            break;
    }
    case 2:
           break;
    case 3:
           break;
    case 4:
    {
           Serial.print("Message arrived [");
           Serial.print(topic);
           Serial.print("] ");
           char receivedChar;
           String receivedString;
           for (int i=0;i<length;i++) {
            receivedChar = (char)payload[i];
            receivedString += receivedChar;
            Serial.print(receivedChar);
            }
            Serial.println();
            
          
            Serial.println(receivedString);
          
           
            sendMsg("test/sendmsg", receivedString);
  
            break;
    }
  }
 
 
 

}

// The following function handles all outgoing messages to the MQTT server.

void sendMsg(String loTopic, String loMsg){

  String topicToSend = loTopic;
  String msgToSend = loMsg;

  if (client.publish((char*) topicToSend.c_str(), (char*) msgToSend.c_str()) )
  {
    Serial.println("Publish Succeeded!");
  }
    else
  {
    Serial.println("Publish Failed!");
  }

return;
  
}

// The following function handles comnnecting and re-connecting to the MQTT server. 
void reconnect() {
 // Loop until we're reconnected
 while (!client.connected()) {
 Serial.print("Attempting MQTT connection...");
 // Attempt to connect
 if (client.connect("ESP8266 Client")) {
  Serial.println("connected");
  // ... and subscribe to topic
  client.subscribe("ledStatus");
  client.subscribe("chickenCoop/Temperature");
  sendMsg("test/sendmsg", "Temp Connected");
 } else {
  Serial.print("failed, rc=");
  Serial.print(client.state());
  Serial.println(" try again in 5 seconds");
  // Wait 5 seconds before retrying
  delay(5000);
  }
 }
}

.
void setup_wifi() {
  delay(20);
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

// Once WiFi has connected once, it will autoconnect using stored information.
//  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi Connected");
//  Serial.println("IP Address is: ");
//  Serial.println(WiFi.localIP());
  Serial.println("");
  
}

//  Calls for Temperature passing it back to the callback function to send to the mqtt server

float getTemperatureF(){

    float tempC;
    float tempF;
    do {
      DS18B20.requestTemperatures();
      tempC = DS18B20.getTempCByIndex(0);
      delay(300);
    }
    while (tempC == 85.0 || tempC == (-127.0));

    // Convert to Farhenheit 

    tempF = ((tempC * 1.8)+32);

    return tempF;
  
}

 
void setup()
{
 Serial.begin(115200);
 setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
  DS18B20.begin();
}
 
void loop()
{

// Check if client is connected to the MQTT server - if not call reconnect function.
if (!client.connected()) {
  reconnect();
 }

 
 client.loop();
}