Char array crashes ESP32

When i invoke this function the esp32 crashes and reboots. from what i can tell it crashes at “Message[6]=’\0’;” Serial.println(“msg recv local2”); never prints. did i null terminate incorrectly?

void LocalMessage( char Message[7]) {
  Serial.println("msg recv local");
  Message[6] = '\0'; //null terminate
Serial.println("msg recv local2");
 if (strcmp( Message, "NODDI1") == 0) {
    Serial.println("en1");
    _EEPROM.timerEnabled[0] = true;
    timerStates[0] = 0;
    _writeEEPROM();
  }

this is how i invoke the functon,

server.on("/disabletm1t1", [] {LocalMessage("NODDI1"  );});

EDIT: the lambda function and the LocalMessage strcmp function string did not match. i revised my original post. problem is still the same and remains. Why does this crash esp32 and not esp8266?

I removed **Message[6] = '\0'; //null terminate** and all is working. is this okay?

void LocalMessage( const char*  Message) {

would make more sense . but the whole lambda sequence adds no value that i can see.

this would be simpler

server.on("/disabletm1t1", LocalMessage);
void LocalMessage( void) {
  Serial.println("msg recv local");
Serial.println("msg recv local2");
    Serial.println("en1");
    _EEPROM.timerEnabled[0] = true;
    timerStates[0] = 0;
    _writeEEPROM();
  }

can you explain a little how i can invoke that function without explicitly passing arguments to localMessage?

i would say what message ?
as you had it you were trying to pass a const char “message” array to a function by value , c++ does not support that method. secondly the message is a constant unchanging thing that is never used
at all even if it was “transferred” other than to verify it is == to itself, how could it not be ?

This is my packet handler and i had to modify it to receive commands locally. This chunk is a real eyesore. Could you provide me with some tips maybe to get this shortened a little bit.

void LocalMessage(const char* Message) {
  if (strcmp( Message, "NODEN1") == 0) {
    _EEPROM.timerEnabled[0] = true;
    timerStates[0] = 0;
    _writeEEPROM();
  }
   if (strcmp( Message, "NODDI1") == 0) {
    _EEPROM.timerEnabled[0] = false;
    //   Relays[0].readyToTurnOn = false;
    timerStates[0] = 0;
    digitalWrite(relay[0], HIGH);
    _writeEEPROM();
  }
  if (strcmp( Message, "NODDI2") == 0) {
    _EEPROM.timerEnabled[1] = false;
    // Relays[1].readyToTurnOn = false;
    timerStates[1] = 0;
    digitalWrite(relay[1], HIGH);
    _writeEEPROM();
  }
  if (strcmp( Message, "NODEN2") == 0) {
    _EEPROM.timerEnabled[1] = true;
    timerStates[1] = 0;
    _writeEEPROM();
  }
  if (strcmp( Message, "NODDI3") == 0) {
    _EEPROM.timerEnabled[2] = false;
    //Relays[2].readyToTurnOn = false;
    timerStates[2] = 0;
    digitalWrite(relay[2], HIGH);
    _writeEEPROM();
  }
  if (strcmp( Message, "NODEN3") == 0) {
    _EEPROM.timerEnabled[2] = true;
    timerStates[2] = 0;
    _writeEEPROM();
  }
  if (strcmp( Message, "NODDI4") == 0) {
    //  Relays[3].readyToTurnOn = false;
    _EEPROM.timerEnabled[3] = false;
    timerStates[3] = 0;
    digitalWrite(relay[3], HIGH);
    _writeEEPROM();
  }
  if (strcmp( Message, "NODEN4") == 0) {
    _EEPROM.timerEnabled[3] = true;
    timerStates[3] = 0;
    _writeEEPROM();
  }
  if (strcmp( Message, "NODENA") == 0) {
    _EEPROM.enabled = true;
    handleTimerStates(0, 0, 0, 0);
    timerState = 1;
    _writeEEPROM();
  }
  if (strcmp( Message, "NODDIA") == 0) {
    _EEPROM.enabled = false;
    handleTimers(1, 1, 1, 1);
    handleTimerStates(0, 0, 0, 0);
    timerState = 1;
    _writeEEPROM();
  }
  if (_EEPROM.enabled && _EEPROM.timerMode == 1) {
    if (strcmp( Message, "T1STAR") == 0) {
      if (digitalRead(relay[0])) { //if time 1 off turn it on
        timerState = 1;
        handleTimers(0, 1, 1, 1);
        handleTimerStates(0, 0, 0, 0);
      }
    }
    if (strcmp( Message, "T2STAR") == 0) {
      if (digitalRead(relay[1])) { //if time 2 off turn it on
        timerState = 2;
        handleTimers(1, 0, 1, 1);
        handleTimerStates(0, 0, 0, 0);
      }
    }
    if (strcmp( Message, "T3STAR") == 0) {
      if (digitalRead(relay[2])) { //if time 3 off turn it on
        timerState = 3;
        handleTimers(1, 1, 0, 1);
        handleTimerStates(0, 0, 0, 0);
      }
    }
    if (strcmp( Message, "T4STAR") == 0) {
      if (digitalRead(relay[3])) { //if time 4 off turn it on
        timerState = 4;
        handleTimers(1, 1, 1, 0);
        handleTimerStates(0, 0, 0, 0);
      }
    }
  }

  if (_EEPROM.enabled && _EEPROM.timerMode == 2) {
    if (strcmp( Message, "T1STAR") == 0) {
      for (int r = 0; r < RelayCount; r++) {
        Relays[r].readyToTurnOn = false;
        Relays[r].isOn = false;
        Relays[r].StartTime = millis();
      }
      handleTimers(0, 1, 1, 1);
      delay(150);
      ARelayIsOn = false;
      Relays[0].readyToTurnOn = true;
    }
    if (strcmp( Message, "T2STAR") == 0) {
      for (int r = 0; r < RelayCount; r++) {
        Relays[r].readyToTurnOn = false;
        Relays[r].isOn = false;
        Relays[r].StartTime = millis();
      }
      handleTimers(1, 1, 1, 1);
      delay(150);
      ARelayIsOn = false;
      Relays[1].readyToTurnOn = true;
    }
    if (strcmp( Message, "T3STAR") == 0) {
      for (int r = 0; r < RelayCount; r++) {
        Relays[r].readyToTurnOn = false;
        Relays[r].isOn = false;
        Relays[r].StartTime = millis();
      }
      handleTimers(1, 1, 1, 1);
      delay(150);
      ARelayIsOn = false;
      Relays[2].readyToTurnOn = true;
    }
    if (strcmp( Message, "T4STAR") == 0) {
      for (int r = 0; r < RelayCount; r++) {
        Relays[r].readyToTurnOn = false;
        Relays[r].isOn = false;
        Relays[r].StartTime = millis();
      }
      handleTimers(1, 1, 1, 1);
      delay(150);
      ARelayIsOn = false;
      Relays[3].readyToTurnOn = true;
    }
  }
  if (strcmp( Message, "T1STOP") == 0) {
    if (digitalRead(relay[0]) == LOW) { //if time 1 on turn it off
      handleTimers(1, 1, 1, 1);
      handleTimerStates(0, 0, 0, 0);
      timer1offMillis = millis();
    }
  }

  if (strcmp( Message, "T2STOP") == 0) {
    if (digitalRead(relay[1]) == LOW) { //if time 2 on turn it off
      handleTimers(1, 1, 1, 1);
      handleTimerStates(0, 2, 0, 0);
      timer2offMillis = millis();
    }
  }

  if (strcmp( Message, "T3STOP") == 0) {
    if (digitalRead(relay[3]) == LOW) { //if time 3 on turn it off
      handleTimers(1, 1, 1, 1);
      handleTimerStates(0, 0, 2, 0);
      Serial.println("stopping t3");
      timer3offMillis = millis();
    }
  }

  if (strcmp( Message, "T4STOP") == 0) {
    Serial.println("t4=stop");
    if (digitalRead(relay[2]) == LOW) { //if time 1 on turn it off
      handleTimers(1, 1, 1, 1);
      handleTimerStates(0, 0, 0, 2);
      Serial.println("stopping t4");
      timer4offMillis = millis();
    }
  }
}

void recPacket() {
  int packetSize = Udp.parsePacket();
  if (packetSize) {
    int len = Udp.read(incomingPacket, 355);
    char verify[13]; //NODEC1 plus null
    unsigned long _data;
    strncpy (verify, (char*)incomingPacket, 6);//6 bytes
    strncat (verify, (char*)incomingPacket + len - 6 , 6 );//6 bytes
    memcpy(&_data, incomingPacket + 6 , 4); //copy 4 bytes to _data
    if (strcmp(verify, "PAIRMEEMRIAP") == 0) {
      String str = Udp.remoteIP().toString();
      char new_ip[15];
      str.toCharArray(new_ip, 15);
      masterIP = Udp.remoteIP().toString();
      if (strcmp(_EEPROM.masterIP, new_ip) != 0) {
        masterIP.toCharArray(_EEPROM.masterIP, 15);
        _writeEEPROM();
      }
      Serial.println("updated gateway ip");
      Udp.beginPacket(_EEPROM.masterIP, 4210);
      Udp.print(nodePairID0);
      Udp.print(nodePairID1);
      Udp.endPacket();
    }
    if (strcmp(verify, "T1ONDEUDT1ON") == 0) {
      _EEPROM.timerTimes[0][0] = _data;
      _writeEEPROM();
      now4 = millis();
    }
    if (strcmp(verify, "T1OFFEUT1OFF") == 0) {
      _EEPROM.timerTimes[0][1] = _data;
      _writeEEPROM();
      now4 = millis();
    }
    if (strcmp(verify, "T2ONDEUDT2ON") == 0) {
      _EEPROM.timerTimes[1][0] = _data;
      _writeEEPROM();
      now4 = millis();
    }
    if (strcmp(verify, "T2OFFEUT2OFF") == 0) {
      _EEPROM.timerTimes[1][1] = _data;
      _writeEEPROM();
      now4 = millis();
    }
    if (strcmp(verify, "T3ONDEUDT3ON") == 0) {
      _EEPROM.timerTimes[2][0] = _data;
      _writeEEPROM();
      now4 = millis();
    }
    if (strcmp(verify, "T3OFFEUT3OFF") == 0) {
      _EEPROM.timerTimes[2][1] = _data;
      _writeEEPROM();
      now4 = millis();
    }
    if (strcmp(verify, "T4ONDEUDT4ON") == 0) {
      _EEPROM.timerTimes[3][0] = _data;
      _writeEEPROM();
      now4 = millis();
    }
    if (strcmp(verify, "T4OFFEUT4OFF") == 0) {
      _EEPROM.timerTimes[3][1] = _data;
      _writeEEPROM();
      now4 = millis();
    }
    if (strcmp(verify, "T1NNDEUDT1NN") == 0) {
      _EEPROM.timerTimes[0][2] = _data;
      _writeEEPROM();
      now4 = millis();
    }
    if (strcmp(verify, "T1NFFEUT1NFF") == 0) {
      _EEPROM.timerTimes[0][3] = _data;
      _writeEEPROM();
      now4 = millis();
    }
    if (strcmp(verify, "T2NNDEUDT2NN") == 0) {
      _EEPROM.timerTimes[1][2] = _data;
      _writeEEPROM();
      now4 = millis();
    }
    if (strcmp(verify, "T2NFFEUT2NFF") == 0) {
      _EEPROM.timerTimes[1][3] = _data;
      _writeEEPROM();
      now4 = millis();
    }
    if (strcmp(verify, "T3NNDEUDT3NN") == 0) {
      _EEPROM.timerTimes[2][2] = _data;
      _writeEEPROM();
      now4 = millis();
    }
    if (strcmp(verify, "T3NFFEUT3NFF") == 0) {
      _EEPROM.timerTimes[2][3] = _data;
      _writeEEPROM();
      now4 = millis();
    }
    if (strcmp(verify, "T4NNDEUDT4NN") == 0) {
      _EEPROM.timerTimes[3][2] = _data;
      _writeEEPROM();
      now4 = millis();
    }
    if (strcmp(verify, "T4NFFEUT4NFF") == 0) {
      _EEPROM.timerTimes[3][3] = _data;
      _writeEEPROM();
      now4 = millis();
    }
    if (strcmp(verify, "NODDI1ID1ODE") == 0) {
      _EEPROM.timerEnabled[0] = false;
      timerStates[0] = 0;
      digitalWrite(relay[0], HIGH);
      _writeEEPROM();
    }
    if (strcmp(verify, "NODEN11NEODE") == 0) {
      _EEPROM.timerEnabled[0] = true;
      timerStates[0] = 0;
      _writeEEPROM();
    }
    if (strcmp(verify, "NODDI2ID2ODE") == 0) {
      _EEPROM.timerEnabled[1] = false;
      timerStates[1] = 0;
      digitalWrite(relay[1], HIGH);
      _writeEEPROM();
    }
    if (strcmp(verify, "NODEN22NEODE") == 0) {
      _EEPROM.timerEnabled[1] = true;
      timerStates[1] = 0;
      _writeEEPROM();
    }
    if (strcmp(verify, "NODDI3ID3ODE") == 0) {
      _EEPROM.timerEnabled[2] = false;
      timerStates[2] = 0;
      digitalWrite(relay[2], HIGH);
      _writeEEPROM();
    }
    if (strcmp(verify, "NODEN33NEODE") == 0) {
      _EEPROM.timerEnabled[2] = true;
      timerStates[2] = 0;
      _writeEEPROM();
    }
    if (strcmp(verify, "NODDI4ID4ODE") == 0) {
      _EEPROM.timerEnabled[3] = false;
      timerStates[3] = 0;
      digitalWrite(relay[3], HIGH);
      _writeEEPROM();
    }
    if (strcmp(verify, "NODEN44NEODE") == 0) {
      _EEPROM.timerEnabled[3] = true;
      timerStates[3] = 0;
      _writeEEPROM();
    }
    if (strcmp(verify, "NODENAANEODE") == 0) {
      _EEPROM.enabled = true;
      handleTimerStates(0, 0, 0, 0);
      timerState = 1;
      _writeEEPROM();
    }
    if (strcmp(verify, "NODDIAIDEODE") == 0) {
      _EEPROM.enabled = false;
      handleTimers(1, 1, 1, 1);
      handleTimerStates(0, 0, 0, 0);
      timerState = 1;
      _writeEEPROM();
    }
    if (_EEPROM.enabled && _EEPROM.timerMode == 1) {
      if (strcmp(verify, "T1STARRATS1T") == 0) {
        if (digitalRead(relay[0])) { //if time 1 off turn it on
          timerState = 1;
          handleTimers(0, 1, 1, 1);
          handleTimerStates(0, 0, 0, 0);
        }
      }
      if (strcmp(verify, "T2STARRATS2T") == 0) {
        if (digitalRead(relay[1])) { //if time 2 off turn it on
          timerState = 2;
          handleTimers(1, 0, 1, 1);
          handleTimerStates(0, 0, 0, 0);
        }
      }
      if (strcmp(verify, "T3STARRATS3T") == 0) {
        if (digitalRead(relay[2])) { //if time 3 off turn it on
          timerState = 3;
          handleTimers(1, 1, 0, 1);
          handleTimerStates(0, 0, 0, 0);
        }
      }
      if (strcmp(verify, "T4STARRATS4T") == 0) {
        if (digitalRead(relay[3])) { //if time 4 off turn it on
          timerState = 4;
          handleTimers(1, 1, 1, 0);
          handleTimerStates(0, 0, 0, 0);
        }
      }
    }

    if (strcmp(verify, "T1STOPPOTS1T") == 0) {
      if (digitalRead(relay[0]) == LOW) { //if time 1 on turn it off
        handleTimers(1, 1, 1, 1);
        handleTimerStates(2, 0, 0, 0);
        timer1offMillis = millis();
      }
    }

    if (strcmp(verify, "T2STOPPOTS2T") == 0) {
      if (digitalRead(relay[1]) == LOW) { //if time 2 on turn it off
        handleTimers(1, 1, 1, 1);
        handleTimerStates(0, 2, 0, 0);
        timer2offMillis = millis();
      }
    }

    if (strcmp(verify, "T3STOPPOTS3T") == 0) {
      if (digitalRead(relay[2]) == LOW) { //if time 3 on turn it off
        handleTimers(1, 1, 1, 1);
        handleTimerStates(0, 0, 2, 0);
        timer3offMillis = millis();
      }
    }

    if (strcmp(verify, "T4STOPPOTS4T") == 0) {
      if (digitalRead(relay[3]) == LOW) { //if time 1 on turn it off
        handleTimers(1, 1, 1, 1);
        handleTimerStates(0, 0, 0, 2);
        timer4offMillis = millis();
      }
    }
    if (_EEPROM.enabled && _EEPROM.timerMode == 2) {
      if (strcmp(verify, "T1STARRATS1T") == 0) {
        Serial.println("t1start");
        for (int r = 0; r < RelayCount; r++) {
          Relays[r].readyToTurnOn = false;
          Relays[r].isOn = false;
          Relays[r].StartTime = millis();
        }
        handleTimers(0, 1, 1, 1);
        delay(150);
        ARelayIsOn = false;
        Relays[0].readyToTurnOn = true;
      }
      if (strcmp(verify, "T2STARRATS2T") == 0) {
        Serial.println("t2start");
        for (int r = 0; r < RelayCount; r++) {
          Relays[r].readyToTurnOn = false;
          Relays[r].isOn = false;
          Relays[r].StartTime = millis();
        }
        handleTimers(1, 1, 1, 1);
        delay(150);
        ARelayIsOn = false;
        Relays[1].readyToTurnOn = true;
      }
      if (strcmp(verify, "T3STARRATS3T") == 0) {
        Serial.println("t3start");
        for (int r = 0; r < RelayCount; r++) {
          Relays[r].readyToTurnOn = false;
          Relays[r].isOn = false;
          Relays[r].StartTime = millis();
        }
        handleTimers(1, 1, 1, 1);
        delay(150);
        ARelayIsOn = false;
        Relays[2].readyToTurnOn = true;
      }
      if (strcmp(verify, "T4STARRATS4T") == 0) {
        
        Serial.println("t4start");
        for (int r = 0; r < RelayCount; r++) {
          Relays[r].readyToTurnOn = false;
          Relays[r].isOn = false;
          Relays[r].StartTime = millis();
        }
        handleTimers(1, 1, 1, 1);
        delay(150);
        ARelayIsOn = false;
        Relays[3].readyToTurnOn = true;
      }
    }
  }
}

would be nice to lose about 400 lines of code there. as it is, it works but theres got to be a better way

There are 2 fucntions,

void LocalMessage(const char* Message) {}

and,

void recPacket() {

recPacket handles commands from network nodes. while local handles commands from local web server through server handles.

my answer is what message ? where does it come from ?
can’t work with those snippets

Yes i see what you mean now. when i enter a url into the web server it triggers" LocalFunction" in the lambda function, localMessage’s string depends on what url is requested from web server.

if url /disabletm1is requested then “LocalMessage(“NODDIA” )”

here are my server handles,

server.on("/", [] {if (server.hasArg("ssid") && server.hasArg("Password")) {
server.arg("ssid").toCharArray(_EEPROM.sta_ssid, 15);
  server.arg("Password").toCharArray(_EEPROM.sta_password, 15) ;
  _EEPROM.sta_ssid[14] = '\0';
  _EEPROM.sta_password[14] = '\0';
  _writeEEPROM ();
  server.send(200, "text/html", "wifi set");
  delay(1000);
  ESP.restart();
} else {server.sendHeader("Location", "/index.html", true); server.send(302, "text/plane", "");}
                  });

server.on("/timercontrol", [] {server.sendHeader("Location", "/timercontrol.html", true); server.send(302, "text/plane", "");});
server.on("/timerModuel1Settings", handletm1Settings);
server.on("/disabletm1", [] {LocalMessage("NODDIA"   );});
server.on("/enabletm1", [] {LocalMessage("NODENA"   );});
server.on("/disabletm1t1", [] {LocalMessage("NODDI1"  );});
server.on("/enabletm1t1", [] {LocalMessage("NODEN1"  );});
server.on("/disabletm1t2", [] {LocalMessage("NODDI2"   );});
server.on("/enabletm1t2", [] {LocalMessage("NODEN2"   );});
server.on("/disabletm1t3", [] {LocalMessage("NODDI3"   );});
server.on("/enabletm1t3", [] {LocalMessage("NODEN3"  );});
server.on("/disabletm1t4", [] {LocalMessage("NODDI4"   );});
server.on("/enabletm1t4", [] {LocalMessage("NODEN4"   );});
server.on("/gettmjson", handlegettmjson);
server.on("/starttm1t1", [] {LocalMessage("T1STAR"  );}); //lambda functions
server.on("/starttm1t2", [] {LocalMessage("T2STAR"   );});
server.on("/starttm1t3", [] {LocalMessage("T3STAR"   );});
server.on("/starttm1t4", [] {LocalMessage("T4STAR"   );});
server.on("/stoptm1t1",  [] {LocalMessage("T1STOP"   );});
server.on("/stoptm1t2",  [] {LocalMessage("T2STOP"   );});
server.on("/stoptm1t3",  [] {LocalMessage("T3STOP"   );});
server.on("/stoptm1t4",  [] {LocalMessage("T4STOP"  );});
server.on("/mode1",  [] {_EEPROM.timerMode = 1; _writeEEPROM();});
server.on("/mode2",  [] {_EEPROM.timerMode = 2; _writeEEPROM();});
server.on("/mode3",  [] {_EEPROM.timerMode = 3; _writeEEPROM();});
server.on("/resetcycle",  [] {_EEPROM.timerMode3LastCycletime = 0; _writeEEPROM();});
server.on("/lightstatus",  [] {lightstatus( );});
server.on("/rebootsystem",  [] { ESP.restart(); });
server.on("/systemsettings", handleSysAdmin);

server.onNotFound([] {if (loadFromSpiffs(server.uri())) return;}); //Set setver all paths are not found so we can handle as per URI
update_server.onNotFound([] {if (loadFromSpiffs2(update_server.uri())) return;}); //Set setver all paths are not found so we can handle as per URI

you do realise the server can receive arguments , a get or post method exists also

 server.on ("/sr", ssw);
....
void ssw() {//read any reg
  int sw;
  char cmd[4];

  // Serial.print(server.arg());
  if (server.arg("cmd") != "") {
    server.arg("cmd").toCharArray(cmd, 4);
    //    Serial.print("cmd = ");
    //    Serial.print(cmd);
  }
  if (server.arg("sw") != "") {
    sw = constrain(server.arg("sw").toInt(), 0, (sonoCnt - 1)); // register
    //    Serial.print(", sw = ");
    //    Serial.print(sw);
    //    Serial.println();
  }
  set_sw(&sono[sw], cmd);
...
}

This is a good point but then there is a udp server running in addition of the web server that handles communication directly between nodes.

Is there any way i could combine both functions into a single function. What would be i ideal way to handle the commands because regarding the udp server

not a problem
if you design a decent command structure and use a json coded transport layer the transmission medium is irrelevant

 server.on ("/zeroconf/switch", vsw);
.................
void vsw() {//read any reg
  StaticJsonDocument<200> doc;
  String payload = server.arg("plain");
  int err = -1;
  DeserializationError error = deserializeJson(doc, payload );
  if (error == 0) {
    err = 0;
    //serializeJsonPretty(doc, Serial);
    if (doc.containsKey("data")) {
      if ( doc["data"]["switch"] == "on") {
        countdown = millis();
        ttg = ontime ;
        digitalWrite(led, 0);//led active low
        digitalWrite(relay, 1); //relay active high
      } else {
        digitalWrite(led, 1);//led active low
        digitalWrite(relay, 0); //relay active high
        ttg = 0;
      }
    }
  }
  String gd = "{\"error\":" + String(err) + ",\"data\": {\"switch\":";
  if (ttg)
    gd += "\"on\"}}";
  else
    gd += "\"off\"}}";
  server.sendHeader("Content-Type", " application/json");
  server.send(200, "application/json", gd);
}
1 Like

i Will need to think about this a little longer. i been awake for awhile now. i think get what your saying. i use ArduinoJson for sending json object to http client.

If i understand you correctly, you mean i could use a json object to contain a handful of arguments?

the world is your oyster