Arduino Uno + ESP8266 Project Goes Offline Randomly (I have tried almost everything)

Hello all!

A few weeks back I had come up with the idea to create a hydroponics system, for fun of course. long before short I realized that the device needed to be automated because I won’t be at home all the time to switch on/off lights etc etc.

I then discovered the Arduino Uno + ESP8266 + Blynk combination. I am an engineering student so I have had exposure to writing code as well as the electronics and all that kind of thing.

After dipping my toe into the water I am all of a sudden neck deep and the project has gone from a single growing unit to (what I think is) a very neat little setup :slight_smile:

This is the situation…

  • Arduino Uno
  • ESP8266 WiFi Shield (to connect to my home network obvs)
  • 2 x growing units
  • 2 x 12v DC brushless fans (one for each unit)
  • Breadboard
  • Breadboard power supply with 5V and 3.3V rails
  • 2 x DHT11 sensors to measure temp + humidity (one for each unit)
  • 2 x 5V relays (to control the lights for each unit)
  • L293D motor driver to drive the fans

It’s pretty simple, I have wired it all up and it is working 100% functionally.
I had run into problems from day 1 and searching this forum has helped me make it what it is today, so I would like to thank you all in advance for that.
I also want to note that I have tried everything to fix my problem so this really is my last resort.

Now. The problem.

My device goes offline in the app randomly, but continues to run and do its thing.

It used to disconnect after a few hours like I have seen many people struggle with as well, I just used to power cycle it by switching off the mains and switching everything back on again because the button on the Arduino never made a difference.

I considered writing code for it to reconnect but was hesitant because I didn’t really understand it so I wasn’t just going to guess.

I of course could not control any buttons through the app while it wass in the offline state (just to clarify).

I added the second DHT11 sensor recently and had to rewrite the code for it.
The code I have written is just for the DHT11 sensors because I have just used the app widgets and selected the correct digital pins for the relays and whatnot as I thought it would be less room for error as I don’t really back my coding all that much.

Since I have given it the new code (yesterday) it randomly went offline, but then for some reason had reconnected itself. I was okay with this because it seemed to have found it’s own solution.

This must have happened 4 or 5 times since I uploaded the new code, but as of this morning has been offline and seemed to be stuck in the same offline loop and I now have to power cycle again.

Extra Information that might be useful:

  • I have added snubbers for the relays to absorb kickback voltage
  • I have added a 100 micro farrad capacitor across the ESP8266 in case it had power problems there
  • I am using iOS (the latest version of the app)
  • I am using the Blynk server
  • My internet has not had problems as I am always connected to it
  • My code may have unnecessary libraries as I have changed it so many times I have lost track of what needs to be there although I don’t think this matters I am aware of it

#include <ESP8266_Lib.h>
#include <BlynkSimpleShieldEsp8266.h>
#include <DHT.h>
#include <blynk.h>

SimpleTimer timer;

char auth[] = "xxxxxxxxxxxxxxxxxxx"; //Blynk App auth Token
char server [] = "blynk-cloud.com";
char ssid[] = "xxxxxxxxxx"; //WiFi name
char pass[] = "xxxxxxxxx"; //WiFi password, set password to "" for open networks
unsigned int port = 8442;

#include <SoftwareSerial.h>
SoftwareSerial EspSerial(2, 3); // RX, TX

// Your ESP8266 baud rate:
#define ESP8266_BAUD 9600

ESP8266 wifi(&EspSerial);

#define DHT1PIN 5 // What digital pin we're connected to (sensor 1)
#define DHT2PIN 12 // Sensor 2

#define DHT1TYPE DHT11   // Sensor 1 type DHT 11
#define DHT2TYPE DHT11   // Sensor 2 type DHT 11

DHT dht1(DHT1PIN, DHT1TYPE);
DHT dht2(DHT2PIN, DHT2TYPE);

void sendSensor1()
{
  float h = dht1.readHumidity();
  float t = dht1.readTemperature(); // or dht.readTemperature(true) for Fahrenheit

  if (isnan(h) || isnan(t)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }
 
  Blynk.virtualWrite(V5, h);
  Blynk.virtualWrite(V6, t);
}

void sendSensor2()
{
  float h2 = dht2.readHumidity();
  float t2 = dht2.readTemperature(); // or dht.readTemperature(true) for Fahrenheit

  if (isnan(h2) || isnan(t2)) {
    Serial.println("Failed to read from DHT sensor 2!");
    return;
  }
 
  Blynk.virtualWrite(V7, h2);
  Blynk.virtualWrite(V8, t2);
}

void setup()
{

  Serial.begin(9600); // Debug console


  EspSerial.begin(ESP8266_BAUD); // Set ESP8266 baud rate
  delay(10);

  Blynk.begin(auth, wifi, ssid, pass);

  dht1.begin();
  dht2.begin();

  timer.setInterval(1000L, sendSensor1); // Call sensors every second
  timer.setInterval(1000L, sendSensor2);
}

void loop()
{
  Blynk.run();
  timer.run(); // Initiates SimpleTimer
}

I really hope someone can help with why it keeps going offline. Eventually I would like to pre-set light cycles that run off timers but I would like the device to be stable first.

I also apologize for the lack of serial monitor output, I have thought about keeping my PC connected until it goes offline to try and see why but I haven’t gotten around to it.

Please don’t hesitate to ask if more information is needed.

Thanks in advance

Having both of your timers being called at the same time isn’t a good idea, and once every second is a bit too frequent for the DHT11.

I’d stagger the timers and cha he the frequency.

If you look at @Gunner’s C++ coding examples then you’ll find quite a bit about reconnection routines.

Pete.

Thanks so much, Pete, I will change the frequency and stagger the timers like this

timer.setInterval(30000L, sendSensor1); // Setup a function to be called every 30 seconds
timer.setInterval(30010L, sendSensor2);

I will report back my findings

That’s still only giving the first DHT rad 10 milliseconds to complete before the second one is attempting to initiate. Better to leave a longer gap.

Pete.

I thought the timer couldn’t interrupt - thus they will run in sequence as it is?

Do you have a recommendation for how long a gap I should leave for the one to complete?

They’re non-blocking, so in theory, one set of timed will start running then regardless of whether it’s finished or not the next timed code will try to run 10ms later.
In reality, a single core processor can only process one instruction at a time, but you’re still asking it to do two things at once.
Far better to call one timed event then allow enough time for it to complete, then call the next one.

Pete.

1 Like

Are you suggesting I insert “delay(x)” of a certain amount of time before calling the next timer?

I am unsure of how to apply your solution.

That’s one way to do it, or just go for 30,000 and 31,000

Pete.

Putting a delay before the second timer is the better solution. The other solution with different timer intervals will eventually synchronize and may cause intermittent problems. Using a delay of 1 to 2 seconds between the initial timer set interval calls will keep them separated indefinitely.

1 Like

I looked at your code. It is clean and nice. I can see that you have put some thought into this project and that you have good coding habits. Nicely done.

Hey all!

Just to report back, the device went online at 4:23pm and then went offline again the following morning at around 9am.

Method: set timer intervals to 30000L and 31500L (for safe measures)
Safe to say that didn’t work!

As with any change it’s always good to eliminate some options.

Later this morning I will be changing the code back to 30000L for both timer intervals with a “delay(2000L);” and will wait and see what the outcome is!

Thank you for the comments, I hope this can help others too!

The formal update of my coding - with a little extra.

To the problem, I changed the timers to be called at 30s intervals with a 2 second delay between each as suggested by Pete. This is my last hope.

In addition to everything, I had decided to (for my own entertainment) add some code to display uptime of my device on Virtual Pin V2.

I have adapted the code from another user for the conversion of units to days/hrs/mins etc.
The original code can be found at Converting millis to Sec or Hours for Uptime Display

Here is my code that seems to be working after 13 minutes and counting.

#include <ESP8266_Lib.h>
#include <BlynkSimpleShieldEsp8266.h>
#include <DHT.h>
#include <blynk.h>

SimpleTimer timer;
char auth[] = "xxxxxxxxxxxxxxxxxxxxxxxx"; //Blynk App auth Token
char server [] = "blynk-cloud.com";
char ssid[] = "xxxxxxxxxxxxxx"; //WiFi name
char pass[] = "xxxxxxxxxxxxx"; //WiFi password, set password to "" for open networks
unsigned int port = 8442;

#include <SoftwareSerial.h>
SoftwareSerial EspSerial(2, 3); // RX, TX

// Your ESP8266 baud rate:
#define ESP8266_BAUD 9600

ESP8266 wifi(&EspSerial);

#define DHT1PIN 5 // What digital pin we're connected to
#define DHT2PIN 12

#define DHT1TYPE DHT11   // DHT 11
#define DHT2TYPE DHT11   // DHT 11

DHT dht1(DHT1PIN, DHT1TYPE);
DHT dht2(DHT2PIN, DHT2TYPE);

void sendSensor1()
{
  float h = dht1.readHumidity();
  float t = dht1.readTemperature(); // or dht.readTemperature(true) for Fahrenheit

  if (isnan(h) || isnan(t)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }
  // You can send any value at any time.
  // Please don't send more that 10 values per second.
  Blynk.virtualWrite(V5, h);
  Blynk.virtualWrite(V6, t);
}

void sendSensor2()
{
  float h2 = dht2.readHumidity();
  float t2 = dht2.readTemperature(); // or dht.readTemperature(true) for Fahrenheit

  if (isnan(h2) || isnan(t2)) {
    Serial.println("Failed to read from DHT sensor 2!");
    return;
  }
  // You can send any value at any time.
  // Please don't send more that 10 values per second.
  Blynk.virtualWrite(V7, h2);
  Blynk.virtualWrite(V8, t2);
}


void setup()
{

  Serial.begin(9600); // Debug console

  EspSerial.begin(ESP8266_BAUD); // Set ESP8266 baud rate
  delay(10);

  Blynk.begin(auth, wifi, ssid, pass);

  dht1.begin();
  dht2.begin();

  timer.setInterval(30000L, sendSensor1); // Setup a function to be called every 10 seconds
  delay(2000L);
  timer.setInterval(30000L, sendSensor2);
  delay(2000L);
  timer.setInterval(1000L, uptime);

}

void uptime()
{
  long ms = millis();
  long days = 0;
  long hours = 0;
  long mins = 0;
  long secs = 0;
  String secs_o = ":";
  String mins_o = ":";
  String hours_o = ":";
  secs = ms / 1000; // set the seconds remaining
  mins = secs / 60; //convert seconds to minutes
  hours = mins / 60; //convert minutes to hours
  days = hours / 24; //convert hours to days
  secs = secs - (mins * 60); //subtract the coverted seconds to minutes in order to display 59 secs max
  mins = mins - (hours * 60); //subtract the coverted minutes to hours in order to display 59 minutes max
  hours = hours - (days * 24); //subtract the coverted hours to days in order to display 23 hours max
  if (secs < 10) {
    secs_o = ":0";
  }
  if (mins < 10) {
    mins_o = ":0";
  }
  if (hours < 10) {
    hours_o = ":0";
  }
  String disptime = days + hours_o + hours + mins_o + mins + secs_o + secs;

  Blynk.virtualWrite(V2, disptime);
}


void loop()
{
  Blynk.run();
  timer.run(); // Initiates SimpleTimer
}

I will update this thread with new information as it comes along.

Sadly, after a mere 1hr 56min and 44s the device went offline again.

I did notice that this happened when I opened the app on my phone where it showed that it was connected, but after a few seconds disconnected. Does anyone have a solution to this problem maybe?

I will do research and then report back here.

The learning continues

Could be a power supply issue, or a dodgy connection on a breadboard.

Pete.

Would maybe having a look into setting static IPs be worth it?

How exactly are you providing power to the ESP8266 and Arduino? Is everything running off the Arduino power rails or do you have external power?

Would you like to try this to see if the issue gone.

  1. Use HardwareSerial instead of SoftwareSerial
  2. You can update ESP-01 AT firmware to make it working at 115200 bauds
  3. If problem persists, you can upgrade to ESP8266 (NodeMCU) as this is more reliable than UNO+ESP-01
  4. Power supply for ESP-01 might be also a problem. Some topics in this forum have talked about this issue.
#include <ESP8266_Lib.h>
#include <BlynkSimpleShieldEsp8266.h>
#include <DHT.h>

//#include <blynk.h>

//SimpleTimer timer;
BlynkTimer timer;

char auth[] = "xxxxxxxxxxxxxxxxxxxxxxxx"; //Blynk App auth Token
char server [] = "blynk-cloud.com";
char ssid[] = "xxxxxxxxxxxxxx"; //WiFi name
char pass[] = "xxxxxxxxxxxxx"; //WiFi password, set password to "" for open networks

// Don't need this
//unsigned int port = 8442;
//#define port        8080

//#include <SoftwareSerial.h>
//SoftwareSerial EspSerial(2, 3); // RX, TX

// Use Hardware Serial on UNO better than SoftwareSerial, use pin 0 and 1 instead of 2 and 3
// Remove all Serial.print(ln) to avoid conflict
#define EspSerial Serial

// Your ESP8266 baud rate:
// You can update ESP01 to increase baud rate to 115200
#define ESP8266_BAUD 9600

ESP8266 wifi(&EspSerial);

#define DHT1PIN 5 // What digital pin we're connected to
#define DHT2PIN 12

#define DHT1TYPE DHT11   // DHT 11
#define DHT2TYPE DHT11   // DHT 11

DHT dht1(DHT1PIN, DHT1TYPE);
DHT dht2(DHT2PIN, DHT2TYPE);

void sendSensor1()
{
  float h = dht1.readHumidity();
  float t = dht1.readTemperature(); // or dht.readTemperature(true) for Fahrenheit

  if (isnan(h) || isnan(t)) {
    //Serial.println("Failed to read from DHT sensor!");
    return;
  }
  // You can send any value at any time.
  // Please don't send more that 10 values per second.
  Blynk.virtualWrite(V5, h);
  Blynk.virtualWrite(V6, t);
}

void sendSensor2()
{
  float h2 = dht2.readHumidity();
  float t2 = dht2.readTemperature(); // or dht.readTemperature(true) for Fahrenheit

  if (isnan(h2) || isnan(t2)) {
    //Serial.println("Failed to read from DHT sensor 2!");
    return;
  }
  // You can send any value at any time.
  // Please don't send more that 10 values per second.
  Blynk.virtualWrite(V7, h2);
  Blynk.virtualWrite(V8, t2);
}

void sendSensor()
{
  sendSensor1();
  sendSensor2();
}

void setup()
{

  //Serial.begin(9600); // Debug console

  EspSerial.begin(ESP8266_BAUD); // Set ESP8266 baud rate
  delay(10);

  // This is blocking call, use Blynk.config() instead
  //Blynk.begin(auth, wifi,ssid, pass); 

  Blynk.config(wifi, auth);
  Blynk.connectWiFi(ssid, pass);

  int i = 0;
  while ((i++ < 20) && !Blynk.connect()) 
  {
      delay(500);
  }  

  dht1.begin();
  dht2.begin();

  //timer.setInterval(30000L, sendSensor1); // Setup a function to be called every 10 seconds
  //delay(2000L);
  //timer.setInterval(30000L, sendSensor2);
  //delay(2000L);
  timer.setInterval(30000L, sendSensor);

  // Don't need this for every sec. Make it 25s
  timer.setInterval(25000L /*1000L*/, uptime);

}

void uptime()
{
  long ms = millis();
  long days = 0;
  long hours = 0;
  long mins = 0;
  long secs = 0;
  String secs_o = ":";
  String mins_o = ":";
  String hours_o = ":";
  secs = ms / 1000; // set the seconds remaining
  mins = secs / 60; //convert seconds to minutes
  hours = mins / 60; //convert minutes to hours
  days = hours / 24; //convert hours to days
  secs = secs - (mins * 60); //subtract the coverted seconds to minutes in order to display 59 secs max
  mins = mins - (hours * 60); //subtract the coverted minutes to hours in order to display 59 minutes max
  hours = hours - (days * 24); //subtract the coverted hours to days in order to display 23 hours max
  if (secs < 10) {
    secs_o = ":0";
  }
  if (mins < 10) {
    mins_o = ":0";
  }
  if (hours < 10) {
    hours_o = ":0";
  }
  String disptime = days + hours_o + hours + mins_o + mins + secs_o + secs;

  Blynk.virtualWrite(V2, disptime);
}


void loop()
{
  Blynk.run();
  timer.run(); // Initiates BlynkTimer
}