-->
Page 1 of 1

Unstable code crashing unexpectedly

PostPosted: Sat Mar 23, 2019 11:49 am
by JABFreak
I have been strugeling with this for a week now and I cannot figure out where the problem is. I am not a full time programmer, I picked up code from the web and put it together.
I am using ESP8266-07 with Arduino 1.8.5 IDE

The goal of my project:
I receive a web request from another ESP device (or my PC web browser for now)
I process the information (the temperature of a fridge or the voltage of 3 battery banks)
I display the information on a Waveshare 1.54 e-paper.

After uploading the code to the ESP I get:
Code: Select allSketch uses 306508 bytes (29%) of program storage space. Maximum is 1023984 bytes.
Global variables use 38148 bytes (46%) of dynamic memory, leaving 43772 bytes for local variables. Maximum is 81920 bytes.


When I boot the ESP the display updates itself
When I send a web request to the ESP, sometimes it works and sometimes it crashes showing:
Code: Select allSoft WDT reset
>>>stack>>>
ctx: cont
sp: 3ffffcd0 end: 3fffffc0 offset: 01b0


I am not sure if I am doing the right thing by sending a web request as I don't need any feedback from the webpage, but I couln't think of another way.
Another mystery is if I add Serial.println("test") at the top of the loop, it behaves as expected but if I do the same at the bottom of the loop, it only shows up at the serial monitor when I send a web request.

Here is my code (only missing the image.h but that part works fine)

Code: Select all#include <NTPClient.h>
#include <WiFiUdp.h>
#include <ESP8266WiFi.h>
#include <ESP8266NetBIOS.h>

#include <GxEPD.h> //  ----  https://github.com/ZinggJM/GxEPD
#include <GxGDEW0154Z04/GxGDEW0154Z04.cpp>
#include "images.h"
#include <Fonts/FreeMonoBold9pt7b.h>
#include <Fonts/FreeMonoBold12pt7b.h>
#include <Fonts/FreeMonoBold18pt7b.h>
#include <GxIO/GxIO_SPI/GxIO_SPI.cpp>
#include <GxIO/GxIO.cpp>
GxIO_Class io(SPI, /*CS=D16*/ 16, /*DC=D4*/ 4, /*RST=D5*/ 5);
GxEPD_Class ePaper(io, 5, 12 /*RST=D5*/ /*BUSY=D12*/);

const char* ssid = "myssid";
const char* password = "mypw";
String req,val1,val2,val3, valf;

WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP);
String formattedDate;
String dayStamp;
String timeStamp;
String dtStampf = "0000-00-00 00:00";
String dtStampb = "0000-00-00 00:00";


// Create an instance of the server
// specify the port to listen on as an argument
WiFiServer server(80);

void updateDisplay();
void epaperUpdate();

void setup() {
  Serial.begin(115200);
  delay(10);
  updateDisplay();
  NBNS.begin("FLOSTATION");
  timeClient.begin();
  timeClient.setTimeOffset(-14400);
  // Connect to WiFi network
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
 
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
  }
  Serial.println("");
  Serial.println("WiFi connected");
 
  // Start the server
  server.begin();
  Serial.println("Server started");
  // Print the IP address
  Serial.println(WiFi.localIP());
}

void updateDisplay() {
  //Serial.println("Updating Display");
  ePaper.init(115200); // enable diagnostic output on Serial
  //Serial.println("Init Display");
  ePaper.drawPaged(epaperUpdate);
}

void epaperUpdate() {
  ePaper.eraseDisplay();
  ePaper.setRotation(1);
  ePaper.drawBitmap(gImage_boatdisp, 0, 0, 200, 200, GxEPD_RED);
  ePaper.setTextColor(GxEPD_BLACK);

  const GFXfont* f9 = &FreeMonoBold9pt7b;
  const GFXfont* f12 = &FreeMonoBold12pt7b;
  const GFXfont* f18 = &FreeMonoBold18pt7b;
  ePaper.setFont(f18);
  ePaper.setCursor(90, 50);
  ePaper.print(valf);
  ePaper.print("C");
  ePaper.setFont(f9);
  ePaper.setCursor(10, 80);
  ePaper.println(dtStampf);
  ePaper.setFont(f12);
  ePaper.setCursor(80, 118);
  ePaper.print("C ");
  ePaper.print(val1);
  ePaper.print("V");
  ePaper.setCursor(80, 138);
  ePaper.print("H ");
  ePaper.print(val2);
  ePaper.print("V");
  ePaper.setCursor(80, 158);
  ePaper.print("G ");
  ePaper.print(val3);
  ePaper.print("V");
  ePaper.setFont(f9);
  ePaper.setCursor(10, 182);
  ePaper.println(dtStampb);
}

void loop() {
   //----top of loop
  WiFiClient client = server.available();
  if (!client) {
    return;
  }
  while(!client.available()){
    delay(1);
  }

  //generate request for battery with: http://FLOSTATION/batteryb100.00b200.00b300.00
  //generate request for fridge with:  http://FLOSTATION/fridge00
  req = client.readStringUntil('\r');
  //---------I don't need any response from that web page but if I don't include the folowing 6 lines,
  //         my code loops a bunch times.
  client.println("HTTP/1.1 200 OK");
  client.println("Content-type:text/html");
  client.println("Connection: close");
  client.println();
  client.flush();
  client.stop();

  //----expected input: 'GET /batteryb1xx.xxb2xx.xxb3xx.xx HTTP/1.1'
  if(req.indexOf("battery") != -1){
    val1 = req.substring(14, 19);
    val2 = req.substring(21, 26);
    val3 = req.substring(28, 33);
     
    while(!timeClient.update()) {
      timeClient.forceUpdate();
    }
    formattedDate = timeClient.getFormattedDate();
    int splitT = formattedDate.indexOf("T");
    dayStamp = formattedDate.substring(0, splitT);
    timeStamp = formattedDate.substring(splitT+1, formattedDate.length()-4);
    dtStampb = dayStamp + " " + timeStamp;
    updateDisplay();
  }
 
  //----expected input: 'GET /fridgexx HTTP/1.1' 
  if(req.indexOf("fridge") != -1){
    valf = req.substring(11, 13);
    while(!timeClient.update()) {
      timeClient.forceUpdate();
    }
    formattedDate = timeClient.getFormattedDate();
    int splitT = formattedDate.indexOf("T");
    dayStamp = formattedDate.substring(0, splitT);
    timeStamp = formattedDate.substring(splitT+1, formattedDate.length()-4);
    dtStampf = dayStamp + " " + timeStamp;
    updateDisplay();
  }
//----bottom of loop
}

Re: Unstable code crashing unexpectedly

PostPosted: Tue Mar 26, 2019 2:23 am
by DIRR70
Hello JABFreak,

please check the simple "HelloServer" WebServer example delivered with the ESP library. I would strongly recommend to use
Code: Select all  server.on("/", handleRoot);

in your setup and as the only code line in your loop:
Code: Select all  server.handleClient();


Also while handling the incoming request it seems to me that you are doing an outgoing one:
Code: Select allwhile(!timeClient.update()) {
  timeClient.forceUpdate();
}

Maybe you should think about setting up a ticker (see "ticker.h") and within the ticker event update the time like this (you shouldn't use a while loop for that at all, because that may turn into an endless loop!!):
Code: Select all#include <Ticker.h>

Ticker myTicker;

void onTick()
{
  if(!timeClient.update()) {
    timeClient.forceUpdate();
  }
}

void setup() {
  myTicker.attach(30.0, onTick); // Timer every 30 seconds
}