Your new topic does not fit any of the above??? Check first. Then post here. Thanks.

Moderator: igrr

User avatar
By crossy
#87372 Originally posted in the wrong form - Re-posted here.

Hi All. Noob here so please be gentle.

My first foray in to programming the ESP8266 directly from the Arduino IDE.

A simple relay controller (it's actually an ESP-01 board with a couple of LEDs with 1k resistors on the IO pins at present whilst I wait for the actual relay board). I filched the code from one of the multitude of online tutorials and away we go. Works like a dream.

But, after an indeterminate period the web server stops responding, I can still ping the device so it's evidently alive and after a power-cycle everything works as normal.

It doesn't seem to matter how often the web server is accessed by a page.

A flurry of Googling revealed others with similar issues but no really solid answers. I've reverted to V2.5.2 of the ESP8266 IDE add-on thingy as advised in one of the "solutions" and things do seem to have improved but it's just locked up again after 12 hours.

Power is solid, 12V 2A power block regulated down to 5V for the ESP-01 which has the 3.3V regulator on board.

I added some code to store the relay state in eeprom so it survives a restart and stuck in a timed hard reset, but it's not really a viable solution for the long term.

Thoughts, ideas?

Code below:-

Code: Select all 
/*
V1.0a added fixed IP address.
V1.0b / c added flash to retain the relay state over a reset.
*/

#include <ESP8266WiFi.h>
#include <ESP_EEPROM.h>

// Set up for the WiFi server
IPAddress ip(192, 168, 1, 50);
IPAddress gateway(192, 168, 1, 254);
IPAddress subnet(255, 255, 255, 0);
IPAddress DNS(192, 168, 1, 254);
const char* ssid = "<edited out>"; // fill in here your router or wifi SSID
const char* password = "<edited out>"; // fill in here your router or wifi password
 #define RELAY 0 // relay connected to  GPIO0
WiFiServer server(80);

// Set up for FLASH storage
byte eepromVar1 = 0;

unsigned long oldmillis = 0;
 
void setup()
{
  Serial.begin(9600); // must be same baudrate with the Serial Monitor

  EEPROM.begin(16); // 16 Bytes (minimum is 16)
  EEPROM.get(0, eepromVar1); // Read the relay state from eeprom
  Serial.print ("Getting relay value from eeprom ");
  Serial.println (eepromVar1);

  pinMode(RELAY,OUTPUT);
  if (bitRead(eepromVar1,0) == 0) {    digitalWrite(RELAY,LOW);} // and write it to the relay pins
  else {    digitalWrite(RELAY,HIGH);}
 
  oldmillis = millis(); // Reset timer for brute force reset
 

 
  // Connect to WiFi network
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.config(ip, gateway, subnet, DNS);
  delay (100);
  WiFi.begin(ssid, password);
 
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
 
  // Start the server
  server.begin();
  Serial.println("Server started");
 
  // Print the IP address
  Serial.print("Use this URL to connect: ");
  Serial.print("http://");
  Serial.print(WiFi.localIP());
  Serial.println("/");
 
}


// ********** Main Loop Below *******************

void loop()
{

/*   
    if (millis() - oldmillis >= 180000UL)
    {
    Serial.println("Resetting ESP");
    ESP.restart();   
    }
*/
 
  // Check if a client has connected
  WiFiClient client = server.available();
  if (!client)
  {
    return;
  }
 
  // Wait until the client sends some data
  Serial.println("new client");
  while(!client.available())
  {
    delay(1);
  }

  // Read the first line of the request
  String request = client.readStringUntil('\r');
  Serial.println(request);
  client.flush();
 
  // Match the request
  int value = LOW;
  if (request.indexOf("/RELAY=ON") != -1) 
  {
    Serial.println("RELAY=ON");
    bitSet(eepromVar1 , 0);
    digitalWrite(RELAY,HIGH);
    value = LOW;
  }
  if (request.indexOf("/RELAY=OFF") != -1) 
  {
    Serial.println("RELAY=OFF");
    bitClear(eepromVar1 , 0);
    digitalWrite(RELAY,LOW);
    value = HIGH;
  }

  // Write the eeprom
  EEPROM.put(0, eepromVar1);
  EEPROM.commit();

 
  // Return the response
  client.println("HTTP/1.1 200 OK");
  client.println("Content-Type: text/html");
  client.println(""); //  this is a must
  client.println("<!DOCTYPE HTML>");
  client.println("<html>");
  client.println("<head><title>ESP8266 RELAY Control</title></head>");
  client.print("Relay is now: ");
 
  if(value == HIGH)
  {
    client.print("OFF");
  }
  else
  {
    client.print("ON");
  }
  client.println("<br><br>");
  client.println("Turn <a href=\"/RELAY=OFF\">OFF</a> RELAY<br>");
  client.println("Turn <a href=\"/RELAY=ON\">ON</a> RELAY<br>");
    client.println("</html>");
 
  delay(1);
  Serial.println("Client disonnected");
  Serial.println("");
}

User avatar
By DIRR70
#87717 Hi crossy,

Does your problem depend on how frequently you toggle your relay?
Would it work 'longer' when you switch your relay on/off only once a minute?

In that case you are experiencing a common problem with your heap of the ESP. It is called 'heap fragmentation' and makes your ESP stop responding, because it doesn't have enough free heap (RAM) to send your HTTP response. You will be able to better that if you use PROGMEM strings, like
client.println (F ("HTTP/1.1 200 OK"));

The problem with the memory management is, that all your 'text' (strings) will be allocated in memory (heap) and whatever you send back to the browser will be pushed to the IP stack (also dynamically allocated on the heap). Most of the memory will be released, but because the IP stack will be kept in memory a while you will end up in a lot of small free memory blocks and none of them is big enough to hold the data (string or IP stack).

That is normal on TCP connections, because once a client connects to a server the connection will use resources (RAM) even after the client has disconnected for a while (about 1.5 minutes).

So the best you can do is to use as less heap as you can. And therefore you should use PROGMEM strings for fixed strings (all your strings in your code), because they don't use RAM.

Also you should send a 'CONNECTION: CLOSE' header back to your client. That will force the browser to disconnect faster once it got the response and so free resources of your ESP faster...
User avatar
By mylinux909
#95549 ESP8266 hangs freezes stops responding when sent commands from different devices - comments

I'm checking ESP.getFreeHeap() and have over 30000 free.
I'm checking ESP.getHeapFragmentation() and goes between 1 to 4.
So heap and fragmentation is not the problem in my situation.

Also, I've noticed that HTTP GET requests from Safari and cURL work okay, while the ones from Chrome & Firefox cause the device to freeze.

It is still pingable in that frozen state.

I also installed, EspSaveCrash , GitHub - krzychb/EspSaveCrash: Save exception details and stack trace anytime and anywhere the ESP8266 crashes, https://github.com/krzychb/EspSaveCrash

But no crashes are being recorded.

To get my ESP8266 working after it freezes, I have to unplug the power cord and plug it back in again.