Arduino Uno and WiFiEsp timeout for ESP8266

What I 'm trying to do
Send temperature read from a DS18B20 (PCB version) sensor and send the value to a REST API.

Problem:
WiFiEsp starts handing me ">>> TIMEOUT >>>" messages after a few hours (it differs) of running flawlessly. I've not seen it run longer than about 14 hours but that was only once. It always stops working at some point and I want this to be 100% stable.

I've been working on this for a few weeks now and I've searched through forums and many have similar problems but I have not found a fix that works permanently.

I'm powering the Arduino via USB and the ESP8266 via a 9 Volt battery via the 3.3v pins of the breadboard Power Supply Adapter.
Update 2022-01-25:
The first illustration I uploaded was completely unrelated so I've updated that now. Also as of writign this I'm a "new" user and can't embedd more than one image so you'll have to look into the history edits to see the first illustration.

The error log
10:34:34.916 -> [WiFiEsp] Initializing ESP module
10:34:38.639 -> [WiFiEsp] Initilization successful - 1.5.4
10:34:45.713 -> [WiFiEsp] Connected to PrettyFlyForAWifi
10:34:45.760 -> SSID: PrettyFlyForAWifi
10:34:46.419 -> [WiFiEsp] Connecting to exampledomain
10:35:18.513 -> [WiFiEsp] Disconnecting 3
10:35:18.654 -> [WiFiEsp] Connecting to exampledomain
10:35:50.786 -> [WiFiEsp] Disconnecting 3
10:35:50.881 -> [WiFiEsp] Connecting to exampledomain
10:36:22.991 -> [WiFiEsp] Disconnecting 3
10:36:23.131 -> [WiFiEsp] Connecting to exampledomain
10:36:55.221 -> [WiFiEsp] Disconnecting 3
10:36:55.360 -> [WiFiEsp] Connecting to exampledomain
...
14:41:56.227 -> [WiFiEsp] Disconnecting 3
14:41:56.367 -> [WiFiEsp] Connecting to exampledomain
14:42:28.475 -> [WiFiEsp] Disconnecting 3
14:42:28.616 -> [WiFiEsp] Connecting to exampledomain
14:42:30.942 -> [WiFiEsp] >>> TIMEOUT >>>
14:42:30.989 -> [WiFiEsp] Data packet send error (2)
14:42:30.989 -> [WiFiEsp] Failed to write to socket 3
14:42:34.977 -> [WiFiEsp] Disconnecting 3
14:42:39.017 -> [WiFiEsp] >>> TIMEOUT >>>
14:43:10.439 -> [WiFiEsp] Connecting to exampledomain
14:43:15.506 -> [WiFiEsp] >>> TIMEOUT >>>
14:43:46.022 -> [WiFiEsp] Disconnecting 3
14:43:46.162 -> [WiFiEsp] Connecting to exampledomain
14:43:51.225 -> [WiFiEsp] >>> TIMEOUT >>>
14:44:21.749 -> [WiFiEsp] Disconnecting 3
14:44:21.887 -> [WiFiEsp] Connecting to exampledomain
14:44:26.934 -> [WiFiEsp] >>> TIMEOUT >>>
14:44:57.458 -> [WiFiEsp] Disconnecting 3
14:44:57.621 -> [WiFiEsp] Connecting to exampledomain
14:45:02.677 -> [WiFiEsp] >>> TIMEOUT >>>
14:45:33.172 -> [WiFiEsp] Disconnecting 3

I'm running ESP8266 on baud rate 9600 (according to the example in the book).
I'm running Arduino board on baud rate 19200 (to not conflict with the ESP).

Here's the sketch

#include <arduino_secrets.h>
#include "WiFiEsp.h"
#include <SoftwareSerial.h>
#include <OneWire.h>
#include <DallasTemperature.h>

// Data wire is plugged into digital pin 2 on the Arduino
// Setup a oneWire instance to communicate with any OneWire device
// Pass oneWire reference to DallasTemperature library
#define ONE_WIRE_BUS 2
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

SoftwareSerial epsWifi(6,7);
char ssid[] = SECRET_SSID;
char pass[] = SECRET_PASS;
int status = WL_IDLE_STATUS;
float temp;
void(* resetFunc) (void) = 0;

WiFiEspClient client; 

void setup() {  
  sensors.begin();
  Serial.begin(19200);
  epsWifi.begin(9600);  
  connectToNetwork();       
}

void loop() {  
  //Serial.println("Ram: " + String(freeRAM()));    
  getTemperature();
  makeHttpRequest();  
  delay(30000);     
}

void connectToNetwork(){
  WiFi.init(&epsWifi);  
  if (WiFi.status() == WL_NO_SHIELD) {    
    while(true);  
  }

  while(status != WL_CONNECTED) {
    status = WiFi.begin(ssid, pass);
  }  

  printWifiStatus();
}


void getTemperature(){
   sensors.requestTemperatures();   
   temp = sensors.getTempCByIndex(0);
}

void makeHttpRequest() {  
  String queryString = String("?value=") + String(temp) + "&unit=celsius&device=indoor&location=home";
  client.stop();     
  client.flush();
  delay(100);   
  if(client.connect("exampledomain", 80)) {              
    delay(100);  
    client.println("GET /api/measurements" + queryString + " HTTP/1.1");
    delay(100);  
    client.println("Host: exampledomain");    
    delay(100);  
    client.println("Connection: close");    
    delay(100);  
    client.println(); // end HTTP request header        
    delay(500);  
    if(!client.connected())
    {      
      client.stop();
    }        
  } 
}

void printWifiStatus() {
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());  
}


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

Things I have tried:

  • Adding the client.stop() on the WifiEspClient actually made things a lot more stable per loop (the result is the [WiFiEsp] Disconnecting 3 in each loop). Before I added this about 25% of the http-requests failed sporadically. The client.flush() is probably useless, yes, but it's not the problem either.
  • I've checked available RAM in the loop (via the function as written in the sketch) , it's 100% constant if I would print that on the 19200 serial monitor. It's around 1.1k free so that It's not the issue.
  • I tried running both Arduino Board and ESP8266 on every baud rate there is in different combos. The most stable thing seems to be 9600 for the ESP8266 so I'm sticking with that.
  • Adding delay(100) here and there in the actual HTTP-request seems to also make things a bit more stable. I have no idea why but read somewhere that baud 9600 is very slow and can be overflowing the WiFiEsp lib easy so... yeah.
  • Tried changing client.println("Connection: close"); to client.println("Connection: keep-alive"); - Did nothing but add more errors.
  • Added a reset of the whole Arduino board at an interval, sure, it works but it doesn't solve the issue, it's just a really crappy work around.

My question
What would be the next thing to investigate to try and solve this?

I know the API is a .net build and maybe sometimes that is recycling the application pool on the server. I'm thinking maybe the recyling could cause some longer response times but if that so, there must be a way of handling that in the sketch, right?

Don't overload the ESP8266 with 5V. If you connect the UNO directly to the ESP8266 the TX pin provides 5V to the ESP's RX pin. The protection diode may catch that for some time but I would expect it never work reliably.

Insert level converters between the two boards, at least a voltage divider.

1 Like

As it looks that you do not need the client outside of makeHttpRequest() and it is used only once in 30 seconds. You could make it a local object of makeHttpRequest() and probably avoid any unexpected "data leaks" or whatever creates the problems.

What do you think?

void makeHttpRequest() {  
  String queryString = String("?value=") + String(temp) + "&unit=celsius&device=indoor&location=home";
  WiFiEspClient client; 
  if(client.connect("exampledomain", 80)) {              
    delay(100);  
    client.println("GET /api/measurements" + queryString + " HTTP/1.1");
    delay(100);  
    client.println("Host: exampledomain");    
    delay(100);  
    client.println("Connection: close");    
    delay(100);  
    client.println(); // end HTTP request header        
    delay(500);  
    client.stop();
  } 
}

It is just some guesswork with trial-n-error ... :innocent:

Aha, I must admit, I'm a better programmer than electrician and have misunderstood a few things I see. So there is power coming from some Arduino pins I only thought of as "data" that we must protect the ESp8266 from as well. alright.
I followed a "starter book" for arduino with my wirering but now I see that there is an updated "web version" of the same chapter with a different illustration than in my book. In the updated one there are in fact resistors present as well.


I will give this a try!

Had to try and measure Free RAM for this. In turns out that if I follow your suggestion I save two bytes of RAM :slight_smile: It doesn't solve the main issue but thank you for the optimization.

I guess there was a misunderstanding: It was not about saving RAM rather than making sure you get a clean new client every time the function is called. If we assume - just as an example - that the client stores and never frees data every time the function client.connect() is called, it would create problems after some time. Deleting and creating the object new would not remove the flaw but avoid to run into trouble ... :wink:

If the problem still occurs after some hours, there must be a different problem. At least we can sort out that a data leak in client was the cause.

@pylon Actually in my current connection arduino pin 6 goes to TX on the ESP and Pin 7 goes to the RX on ESP. I've added resistors between pin 6 and TX and that didn't help either. Should there be resistors on Pin 7 - RX as well? I read around 4.8v on that connection with my multimeter now.

Actually the RX is the problem here because there the ESP gets the voltage from the Arduino.
The resistors limit the current the protection diodes get but don't actually solve the problem. You should get a two channel level converter.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.