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

ESP8266 raising Panic at runtime #3666

Closed
KunalAggarwal opened this issue Oct 1, 2017 · 1 comment
Closed

ESP8266 raising Panic at runtime #3666

KunalAggarwal opened this issue Oct 1, 2017 · 1 comment

Comments

@KunalAggarwal
Copy link

Basic Infos

Trying to control 8 channel relay board using NodeMCU v3 and Alexa (base sketch from here: https://github.com/kakopappa/arduino-esp8266-alexa-multiple-wemo-switch)

Hardware

Hardware: ESP-12E
Core Version: 0.9.6-float

Description

Problem description: Program crashing again and again on runtime. Don't know why.

Settings in IDE

Module: NodeMCU v3
Flash Size: 4MB
CPU Frequency: 80Mhz
Flash Mode: DIO
Flash Frequency: 80Mhz
Upload Using: SERIAL
Reset Method: nodemcu

Sketch

#include "FS.h"
#include <ESP8266WebServer.h>
#include <ArduinoJson.h>
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <functional>
#include "switch.h"
#include "UpnpBroadcastResponder.h"
#include "CallbackFunction.h"
#include <Wire.h>

#define WIFI_CONF_FILE "wifi_conf_file"

const char *setup_password = "29472609";

UpnpBroadcastResponder upnpBroadcastResponder;
String chip_ssid = "HOME-AP-";
ESP8266WebServer setupServer;
ESP8266WebServer mainServer;
boolean setupMode = false;
int LED_PIN = D4;

int my_switches_pin[] = {
  D0, D1, D2, D3, D5, D6, D7, D8
};

String my_switches_name[] = {
  "Light One",
  "Light Two",
  "Light Three",
  "Fan One",
  "Fan Two",
  "Fan Three",
  "Switch One",
  "Switch Two"
};

int getNumberOfSwitches() {
  return sizeof(my_switches_pin)/sizeof(my_switches_pin[0]);
}

int len = getNumberOfSwitches();
int* switchStates = new int [len];
Switch** my_switches = new Switch* [len];

int findSwitchByName(String needle)
{
  int len = getNumberOfSwitches();
  for(int i=0; i < len; i++)
  {
    if(my_switches_name[i] == needle)
      return i;
  }
  return -1;
}

void switchAction(String switchName, String action)
{
  int switchIndex = findSwitchByName(switchName);
  if(switchIndex == -1)
  {
    mainServer.send(403, "application/json", "{\"status\":false,\"message\":\"Access Denied.\"}");
  }
  else
  {
    String uSwitchName = my_switches_name[switchIndex];
    int switchPin = my_switches_pin[switchIndex];
    if(action == "0")
    {
      digitalWrite(switchPin, 1);
      switchStates[switchIndex] = 0;
      String message = "{\"status\":true,\"message\":\"";
      message += switchName;
      message += " set to state Off\"}";
      Serial.print(switchName);
      Serial.println(" turned off");
      mainServer.send(200, "application/json", message);
    }
    else if(action == "1")
    {
      digitalWrite(switchPin, 0);
      switchStates[switchIndex] = 1;
      String message = "{\"status\":true,\"message\":\"";
      message += switchName;
      message += " set to state On\"}";
      Serial.print(switchName);
      Serial.println(" turned on");
      mainServer.send(200, "application/json", message);
    }
    else
      mainServer.send(403, "application/json", "{\"status\":false,\"message\":\"Access Denied.\"}");
  }
}

void relayStatus() {
  String statusMsg = "{";
  int len = getNumberOfSwitches();
  for(int i = 0; i < len; i++)
  {
    if(i == 0)
      statusMsg += "\"";
    else
      statusMsg += ",\"";
    statusMsg += my_switches_name[i];
    statusMsg += "\":";
    statusMsg += switchStates[i];
  }
  statusMsg += "}";
  mainServer.send(200, "application/json", statusMsg);
}

void discover() {
  int len = getNumberOfSwitches();
  String message = "{\"switches\":[";
  for(int i = 0; i < len; i++)
  {
    if(i != 0)
      message += ",";
    message += "\"";
    message += my_switches_name[i];
    message += "\"";
  }
  message += "]}";
  mainServer.send(200, "application/json", message);
}

void pinChange() {
  if(mainServer.hasArg("switch") && mainServer.hasArg("state"))
  {
    String uSwitch = mainServer.arg("switch");
    String uState = mainServer.arg("state");
    switchAction(uSwitch, uState);
  }
  else
  {
    mainServer.send(403, "application/json", "{\"status\":403,\"message\":\"Access Denied.\"}");
  }
}

boolean connectWifi(String ssid, String password) {
  boolean state = true;
  int i = 0;

  if(WiFi.status() == WL_CONNECTED) {
    Serial.print("[+] Already connected to ");
    Serial.println(ssid);
    Serial.print("[+] IP address: ");
    Serial.println(WiFi.localIP());
    return true;
  }

  WiFi.begin(ssid.c_str(), password.c_str());
  Serial.println("[+] Connecting to WiFi");
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    if (i > 10) {
      state = false;
      break;
    }
    i++;
  }

  if (state) {
      Serial.print("[+] Connected to ");
      Serial.println(ssid);
      Serial.print("[+] IP address: ");
      Serial.println(WiFi.localIP());
      digitalWrite(LED_PIN, LOW);
  }
  else{
    digitalWrite(LED_PIN, LOW);
    delay(50);
    digitalWrite(LED_PIN, HIGH);
    delay(50);
    digitalWrite(LED_PIN, LOW);
    delay(50);
    digitalWrite(LED_PIN, HIGH);
    delay(50);
  }
  return state;
}

void factoryReset() {
  if(mainServer.hasArg("pin"))
  {
    if(mainServer.arg("pin") == setup_password)
    {
      boolean res = SPIFFS.remove(WIFI_CONF_FILE);
      if(res)
      {
        Serial.println("Done factory reset. Restarting in 1 second.");
        mainServer.send(200, "text/plain", "done");
        WiFi.disconnect(true);
        digitalWrite(LED_PIN, HIGH);
        delay(1000);
        ESP.restart();
      }
      else
        mainServer.send(200, "text/plain", "try_again");
    }
    else
      mainServer.send(200, "text/plain", "try_again");
  }
  else
    mainServer.send(200, "text/plain", "try_again");
}

void pingPong() {
  digitalWrite(LED_PIN, HIGH);
  delay(50);
  digitalWrite(LED_PIN, LOW);
  delay(50);
  mainServer.send(200, "text/plain", "pong");
}

void setupPingPong() {
  digitalWrite(LED_PIN, HIGH);
  delay(50);
  digitalWrite(LED_PIN, LOW);
  delay(50);
  setupServer.send(200, "text/plain", "pong");
}

void joinWifi() {
  if(setupServer.hasArg("ssid") && setupServer.hasArg("password"))
  {
    Serial.println("Configuration recieved, attempting connection to WiFi.");
    String ssid = setupServer.arg("ssid");
    String password = setupServer.arg("password");
    DynamicJsonBuffer jsonBuffer;
    JsonObject& root = jsonBuffer.createObject();
    root["ssid"] = ssid;
    root["password"] = password;
    int counter = 3;
    boolean result = false;
    while(counter > 0)
    {
      digitalWrite(LED_PIN, HIGH);
      delay(50);
      Serial.print("Setup attempting connection to WiFi... Try #");
      Serial.println(counter);
      result = connectWifi(ssid, password);
      if(result)
      {
        digitalWrite(LED_PIN, LOW);
        delay(500);
        String message = "{\"status\":true,\"ip\":\"";
        message += WiFi.localIP().toString();
        message += "\"}";
        setupServer.send(200, "application/json", message);
        break;
      }
      digitalWrite(LED_PIN, LOW);
      delay(50);
      counter -= 1;
    }
    if(result)
    {
      int len = root.measureLength();
      char msgBuffer[len + 1];
      root.printTo(msgBuffer, sizeof(msgBuffer));
      File f = SPIFFS.open(WIFI_CONF_FILE, "w");
      f.print(msgBuffer);
      f.close();
      Serial.println("Configuration saved to file");
    }    
    else
    {
      digitalWrite(LED_PIN, HIGH);
      Serial.println("Failed to connect to WiFi. Please retry.");
      setupServer.send(200, "application/json", "{\"status\":false}");
    }
  }
  else
  {
    setupServer.send(403, "application/json", "{\"status\":403,\"message\":\"Access Denied.\"}");
  }
}

void getIP() {
  if(WiFi.status() == WL_CONNECTED)
  {
    String message = "{\"status\":true,\"ip\":\"";
    message += WiFi.localIP().toString();
    message += "\"}";
    setupServer.send(200, "application/json", message);
  }
  else
    setupServer.send(200, "application/json", "{\"status\":false}");
}

void rebootModule() {
  if(setupServer.hasArg("pin"))
  {
    if(setupServer.arg("pin") == setup_password)
    {
      setupServer.send(200, "text/plain", "ok");
      Serial.println("Recieved shutdown... Rebooting in 1 sec.");
      delay(1000);
      ESP.restart();
    }
    else
      setupServer.send(200, "text/plain", "try_again");
  }
  else
    setupServer.send(200, "text/plain", "try_again");
}

void scanWifi() {
  DynamicJsonBuffer jsonBuffer;
  JsonObject& root = jsonBuffer.createObject();
  JsonArray& data = root.createNestedArray("data");
  int n = WiFi.scanNetworks();
  if (n == 0)
    setupServer.send(200, "application/json", "{\"data\":[]}");
  else
  {
    for (int i = 0; i < n; ++i)
    {
      digitalWrite(LED_PIN, LOW);
      delay(50);
      JsonObject& ap = jsonBuffer.createObject();
      ap["ssid"] = WiFi.SSID(i);
      ap["range"] = WiFi.RSSI(i);
      ap["enc_type"] = WiFi.encryptionType(i);
      data.add(ap);
      digitalWrite(LED_PIN, HIGH);
      delay(50);
    }
    int len = root.measureLength();
    char msgBuffer[len + 1];
    root.printTo(msgBuffer, sizeof(msgBuffer));
    setupServer.send(200, "application/json", msgBuffer);
  }  
}

void setup() {
  Serial.begin(115200);
  SPIFFS.begin();
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, HIGH);

  for(int x = 0; x < len; x++)
  {
    pinMode(my_switches_pin[x], OUTPUT);
    digitalWrite(my_switches_pin[x], HIGH);
  }
  
  WiFi.disconnect(true);

  WiFi.mode(WIFI_AP_STA);
  chip_ssid += String(ESP.getChipId(), HEX);
  chip_ssid.toUpperCase();
  WiFi.softAP(chip_ssid.c_str(), setup_password);
  IPAddress myIP = WiFi.softAPIP();
  setupServer = ESP8266WebServer(myIP, 8888);
  Serial.println("Created AP: " + chip_ssid);
  Serial.print("Password: ");
  Serial.println(setup_password);
  setupServer.on("/ping", setupPingPong);
  setupServer.on("/scan", scanWifi);
  setupServer.on("/join", joinWifi);
  setupServer.on("/getip", getIP);
  setupServer.on("/reboot", rebootModule);
  setupServer.begin();  
  
  boolean fileExists = SPIFFS.exists(WIFI_CONF_FILE);
  if(!fileExists)
  {
    setupMode = true;
    Serial.println("Beginning Setup Mode");
  }
  else
  {
    Serial.println("Configuration File Exists.. Loading");
    File f = SPIFFS.open(WIFI_CONF_FILE, "r");
    String ssidInfo;
    while(f.available()) {
      ssidInfo += char(f.read());
    }
    f.close();
    DynamicJsonBuffer jsonBuffer;
    JsonObject& root = jsonBuffer.parseObject(ssidInfo);
    String ssid = root["ssid"].asString();
    String password = root["password"].asString();
    int counter = 5;
    boolean result = false;
    while(counter > 0)
    {
      Serial.println("Attempting connection to WiFi");
      result = connectWifi(ssid, password);
      if(result)
      {
        Serial.print("Connected to WiFi, switching off AP... ");
        setupServer.stop();
        setupServer.close();
        WiFi.softAPdisconnect(true);
        WiFi.mode(WIFI_STA);
        Serial.println("Done");
        break;
      }
      Serial.println("Failed attempt.. Retrying.");
      counter -= 1;
    }
    if(!result)
    {
      Serial.println("Failed to connect to WiFi. Configuration might be stale. Module in AP Mode, reconfigure again!");
      setupMode = true;
      Serial.println("Beginning Setup Mode");
    }
    else
    {
      upnpBroadcastResponder.beginUdpMulticast();
      for(int x = 0; x < len; x++)
      {
        switchStates[x] = 0;
        my_switches[x] = new Switch(my_switches_name[x], 80 + (x * 2), switchAction);
        upnpBroadcastResponder.addDevice(*my_switches[x]);
      }
      mainServer = ESP8266WebServer(WiFi.localIP(), 8080);
      mainServer.on("/ping", pingPong);
      mainServer.on("/factoryReset", factoryReset);
      mainServer.on("/status", relayStatus);
      mainServer.on("/handle", pinChange);
      mainServer.on("/discover", discover);
      mainServer.begin();
      Serial.println("WiFi Server Active");
    }
  }
}

void loop() {
  if(setupMode)
    setupServer.handleClient();
  else
  {
    mainServer.handleClient();
    upnpBroadcastResponder.serverLoop();
    for(int x = 0; x < len; x++)
    {
      my_switches[x]->serverLoop();
    }
  }
}

Debug Messages

Got UDP Belkin Request..
HTTP/1.1 200 OK
CACHE-CONTROL: max-age=86400
DATE: Sat, 26 Nov 2016 04:56:29 GMT
EXT:
LOCATION: http://192.168.0.143:80/setup.xml
OPT: "http://schemas.upnp.org/upnp/1/0/"; ns=01
01-NLS: b9200ebb-736d-4b93-bf03-835149d13983
SERVER: Unspecified, UPnP/1.0, Unspecified
ST: urn:Belkin:device:**
USN: uuid:Socket-1_0-38323636-4558-4dda-9188-cda0e63ca657-80::urn:Belkin:device:**
X-User-Agent: redsonic


HTTP/1.1 200 OK
CACHE-CONTROL: max-age=86400
DATE: Sat, 26 Nov 2016 04:56:29 GMT
EXT:
LOCATION: http://192.168.0.143:82/setup.xml
OPT: "http://schemas.upnp.org/upnp/1/0/"; ns=01
01-NLS: b9200ebb-736d-4b93-bf03-835149d13983
SERVER: Unspecified, UPnP/1.0, Unspecified
ST: urn:Belkin:device:**
USN: uuid:Socket-1_0-38323636-4558-4dda-9188-cda0e63ca657-82::urn:Belkin:device:**
X-User-Agent: redsonic


HTTP/1.1 200 OK
CACHE-CONTROL: max-age=86400
DATE: Sat, 26 Nov 2016 04:56:29 GMT
EXT:
LOCATION: http://192.168.0.143:84/setup.xml
OPT: "http://schemas.upnp.org/upnp/1/0/"; ns=01
01-NLS: b9200ebb-736d-4b93-bf03-835149d13983
SERVER: Unspecified, UPnP/1.0, Unspecified
ST: urn:Belkin:device:**
USN: uuid:Socket-1_0-38323636-4558-4dda-9188-cda0e63ca657-84::urn:Belkin:device:**
X-User-Agent: redsonic


HTTP/1.1 200 OK
CACHE-CONTROL: max-age=86400
DATE: Sat, 26 Nov 2016 04:56:29 GMT
EXT:
LOCATION: http://192.168.0.143:86/setup.xml
OPT: "http://schemas.upnp.org/upnp/1/0/"; ns=01
01-NLS: b9200ebb-736d-4b93-bf03-835149d13983
SERVER: Unspecified, UPnP/1.0, Unspecified
ST: urn:Belkin:device:**
USN: uuid:Socket-1_0-38323636-4558-4dda-9188-cda0e63ca657-86::urn:Belkin:device:**
X-User-Agent: redsonic



Exception (28):
epc1=0x4020cba2 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000004 depc=0x00000000

ctx: cont 
sp: 3fff2130 end: 3fff23e0 offset: 01a0

>>>stack>>>
3fff22d0:  0000019a 3ffefa10 3fffb34c 4020cba0  
3fff22e0:  0000001a 3ffefa10 3fff12f8 4020d654  
3fff22f0:  3ffe8b9c 3ffefa10 3ffefa0c 3fff2398  
3fff2300:  3fffba54 3ffefa10 3ffefa0c 40206f64  
3fff2310:  2e323931 2e383631 34312e30 40200033  
3fff2320:  3ffe98a0 8600a8c0 00000000 00000000  
3fff2330:  00000000 00000000 00000000 00000000  
3fff2340:  00000000 3fffba54 0000019f 0000019a  
3fff2350:  3ffe98a0 8f00a8c0 3fff12f8 4020d654  
3fff2360:  3ffe8c3c 05dbcb62 3fff12f8 3ffef930  
3fff2370:  0000c350 3ffefa0c 00000003 402071dc  
3fff2380:  00000000 00000000 00000000 3fffaf9c  
3fff2390:  0000013f 0000013e 3ffe98a0 8600a8c0  
3fff23a0:  00000000 00000000 00000008 3fff13b4  
3fff23b0:  3fffdad0 00000000 00000000 40207af8  
3fff23c0:  3fffdad0 00000000 3fff13ac 4020e1f4  
3fff23d0:  feefeffe feefeffe 3fff13c0 40100718  
<<<stack<<<

Decoded the stacktrace to find this:

Decoding 9 results
0x4020cba0: UdpContext::send(ip_addr*, unsigned short) at C:\Users\mmt4066\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\libraries\ESP8266WiFi\src\include/slist.h line 14
:  (inlined by) WiFiUDP::endPacket() at C:\Users\mmt4066\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\libraries\ESP8266WiFi\src/WiFiUdp.cpp line 191
0x4020d654: Print::println() at C:\Users\mmt4066\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/Print.cpp line 76
0x40206f64: Switch::respondToSearch(IPAddress&, unsigned int) at C:\Users\mmt4066\AppData\Local\Temp\arduino_build_79286\sketch/Switch.cpp line 177
0x4020d654: Print::println() at C:\Users\mmt4066\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/Print.cpp line 76
0x402071dc: UpnpBroadcastResponder::serverLoop() at C:\Users\mmt4066\AppData\Local\Temp\arduino_build_79286\sketch/UpnpBroadcastResponder.cpp line 76
0x40207af8: loop at C:\Users\mmt4066\Documents\Arduino\sketch_aug29a\sketch_sep29a/sketch_sep29a.ino line 440
0x4020e1f4: loop_wrapper at C:\Users\mmt4066\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/core_esp8266_main.cpp line 56
0x40100718: cont_norm at C:\Users\mmt4066\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/cont.S line 109

Can someone tell me what's happening?

Thanks!

PS: Apologies if this has been posted in the wrong section. I am a newbie to ESP8266 and found the github section to be quite helpful.

@devyte
Copy link
Collaborator

devyte commented Oct 1, 2017

@KunalAggarwal I'm controlling 8 relays myself, although without upnp or alexa, and it works.
I see in the code that you are making several mistakes, e.g.: your have a lot of const char * strings, which are stored in RAM, or use of C-style dynamic arrays, which should probably be replaced with std::vector. Also, if you are using eh upnpresponder code as-is, you may have name shadowing or something.
Your sketch is huge, and it's unlikely anyone here will take it apart and test it for you. You should do that yourself, and pursue the crash by testing the individual parts individually.
In any case, this is not the right place to ask for help for your particular project.
Closing as off-topic, see #3655 .

@devyte devyte closed this as completed Oct 1, 2017
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