Hydroponic Automation Code with Arduino Uno + ESP8266 "need help"

Hey guys. I am currently working on a hydroponic grow tent project. I have completed the automation code for now that is working fine. But for the current state of my program, if something goes wrong with my RTC, AHT10 or ESP8266 in the "void setup()" section, my code enters to while loops until it gets positive response from these modules and it prevents my program to run "void loop()" and operate the pump or growlights which means my plants can die. You can see this setup code below.

void setup()
{
  Serial.begin(115200);

 //****  RTC:  *******
  if (! rtc.begin())
  {
    Serial.println(F("Couldn't find RTC"));
    Serial.flush();
    while (1) delay(10);
  }

  //*****  AHT10:  *******
  while (aht10.begin() != true)
  {
    Serial.println(F("AHT1x not connected or fail to load calibration coefficient"));
    delay(5000);
  }
  Serial.println(F("AHT10 OK"));
  delay(3000);

//******** ESP8266: ******
  esp.begin(115200);    //ESP8266 serial comm start
  esp.println("AT");    //module check with AT command
  Serial.println("AT sent");
  while(!esp.find("OK"))  //Waiting till the module is ready
  {                              
    esp.println("AT");
    Serial.println("ESP8266 couldnt find.");
  }
  Serial.println("OK recieved");
  esp.println("AT+CWMODE=1");    //setting ESP8266 as a client
  while(!esp.find("OK"))  //waiting for the settings to be done
  {                               
    esp.println("AT+CWMODE=1");
    Serial.println("Setting the ESP....");
  }
  Serial.println("Set as client");
  Serial.println("Connecting to Network...");
  esp.println("AT+CWJAP=\""+wifiName+"\",\""+wifiPass+"\"");    //Connecting to wifi
  while(!esp.find("OK"));    //waiting till it connects
  Serial.println("connected.");
  delay(1000);

}

void loop()
{
//in the loop i get data every 15 secs and operate stuff according these.
}

As you can see, there are 3 while loop sections that waits for their modules to respond positive.

I just need an "example code" for one of the modules above, that: doesnt get stuck at setup section while setting the module, checks it periodically in the loop section and give me feedback. Im new to all of this so i dont know if i can just put the same code to loop section. Waitin for your suggestions.

You will have to define exactly what you mean and then set a flag or boolean to be tested later and stop the code from continuing on.

If I undertand right you want to modify your code that in case of

  • RTC does not work
  • or ESP-module does not respond "OK" to run "emergency-code

That will watering your plants at least "somehow" maybe not the best time but watering at all to prevent from dying dry.

Surely this can be done through adding a timeout to each loop that tries to setup RTC / the ESP-module.

In case you are not at home to check the device once per day I would consider having a second device that can take-over if device 1 does not send a "I'm alive and working properly"-signal

best regards Stefan

1 Like

u mean i can give them some response time or some type of timeout, put a boolean in those while loops, set it false or true depending on the response from the module or sensor, than i can check those booleans in the loop and get feedback or try to get a response again ?

yeahh exactly, its NFT system so in some type of emergency like RTC stops working, i can just let the pump open permanently and prevent my plants from drying.

can u give me an example on how to set a timeout ? as i said im new to this so i didnt see such samples.

Anything you want to define as an error or failure. Be aware, error recovery is a slippery slope down which you may not get out of.

oh okay i will try this out tomorrow. i hope it does not consume me xd

Hi,
Welcome to the forum.

 while (1) delay(10);

I think if you enter this while loop, it will never get out.
What do you expect it to do?

Thanks.. Tom... :smiley: :+1: :coffee: :australia:

Hi, i know it should be something like "while (!rtc.begin()) delay(10);" but i expect them to get out of this loop as well at some point... even if the sensor or module doesnt start up. ima try that today with some kind of time out code.

For "starting" the rtc you can simply delete the while loop
The begin-function returns either true and then the RTC is running or false and then the RTC is not working

This means set a flag-variable named with a self-explaining name

boolean RTC_working

if (! rtc.begin()) {
    Serial.println(F("Couldn't find RTC"));
    Serial.flush();
    RTC_working = false;
  }

or even shorter

same thing for the the AHT10-sensor

boolean RTC_working
RTC_working = rtc.begin();
if (!RTC_working ) {
    Serial.println(F("Couldn't find RTC"));
    Serial.flush();
  }

and later on in your code you make RTC-operations conditional
or you use a pure software-RTC instead

if(RTC_working) {
  use RTC
}
else {
 use pure SoftwareRTC
}

same thing for the temperature / humidity-sensor AHT10

boolean AHT_working
AHT_working = aht10.begin();
if (!AHT_working ) {
    Serial.println(F("Couldn't find AHT10"));
  }

For the ESP8266 there could be some kind of mechanism that re-tries to connect every 5 minutes
I code a lot for EPS8266 / ESP32 where I use the ESP as the complete replacement for the Arduinos.
The ESP8266 / ESP32 can be programmed exact the same way as arduinos with the Arduino IDE

This is the reason why I have never worked with ESP8266 with AT-firmware like your code does.

of course these supertiny super-cheap ESP8266-01 can do nothing more than communicate serial
but as soon as you use a ESP8266 nodeMCU or even better a ESP32-nodeMCU these boards in most cases can completely REPLACE the Arduino
https://de.aliexpress.com/item/32959541446.html

best regards Stefan

1 Like

You should also consider using the watchdog timer, so that the arduino will reset if something causes the code to lock up.

If the ESP8266 can access the internet, you can get the current time in the event the RTC is non-operational.

Use the Time library by Paul Stoffregen for the time functions, then in setup you can either set the clock to synchronize to the RTC, or get the time from the ESP8266 and set the correct time. The actual clock runs off the millis timer, so no other changes to the code would be needed in the event of an RTC failure. If you current code directly accesses the RTC to get the time, then every reference to the RTC would have to check that the RTC was properly detected in setup, and properly handle the error condition. Directly accessing the RTC for every time reference also greatly increases the possibility of a failure due to an error on the I2C bus.

You have been finding that the RTC is unreliable? Perhaps a better solution would be to get a better and more reliable RTC.

You've been finding that the AHT10 is unreliable? Perhaps a better solution would be to get a better and more reliable AHT10.

You've been finding that the ESP8266 is unreliable? Perhaps a better solution would be to get a better and more reliable MCU.

My ESP32 has been keeping my wife's house plants watered and fertilized and feed nutrients for 2 years now without an issue.

If these devices work reliable or not depends on multiple factors

is there a lot of electromagntic noise? If yes is the mcu in a shielded housing?
RTC, AHT10 how long is the wiring of the I²C-bus?
Does the bus have correct pullup-resistors?
Does the MCU have a really sufficient power-supply?
As the ESP8266 / ESP32 have short current-spikes
does the MCU have a 2000µF-Capacitor connected as close as possible to the GND and 5V pin of the board?

best regards Stefan

uhh okay im gonna do a little research on watchdog timer thingy. And yes u r right im accessing the RTC everytime for reference... should i use millis() instead? or the "Time Library" has a solution to this ? im gonna check that library too if so. Thank you !:slight_smile:

thanks a million! i got the idea and fixed the parts about AHT10 and RTC. Then i tried to do this:

and end up with this code below. what do u think ?


#include <SoftwareSerial.h>

String wifiName = "ozmen apart1@vipnet";
String wifiPass = "ozmen1515";
String ip = "184.106.153.149";   

int rxPin = 10;
int txPin = 11;
SoftwareSerial esp(rxPin, txPin); 

bool espWorking = false;
bool espSetClient = false;
bool espWifiConnected = false;

const long timeOut = 60000;
unsigned long wTime;
unsigned long cTime;
unsigned long fTime;

void setup()
{
  Serial.begin(115200);
  esp.begin(115200);    //ESP8266 serial comm start
  esp8266_check();      //SEE THIS FUNCTION BELOW THE VOID LOOP !!
}      //** end of setup

void loop()
{ 
  //pretend there are some other stuff here that i check periodically:
  //   {
  //    bla bla
  //    bla bla
  //   }

  // (every 30 mins or so, i'm gonna run "esp8266_check()" in the loop to check the esp8266 !)

  if("30 mins passed")  // pretend i'm checking if 30mins passed with some code here...
  {
    esp8266_check();
  }
}


void esp8266_check()
{
  if(espWorking == false)
  {
    wTime = millis();
    while(millis() < wTime+timeOut)
    {
      esp.println("AT");
      Serial.println(F("AT sent... Trying to get a response..."));
      delay(50);
      if(!esp.find("OK"))
      {
        espWorking = false;
        Serial.println(F("Error... esp8266 is not responding..."));
      }
      else
      {
        espWorking = true;
        Serial.println(F("**OK recieved, esp8266 working..."));
        Serial.println();      
        break;
      }
    }
  }
  
  if((espWorking == true)&&(espSetClient == false))
  {
    cTime = millis();
    while(millis() < cTime+timeOut)
    {
      esp.println("AT+CWMODE=1");    //setting ESP8266 as a client
      Serial.println(F("Client mode requested..."));
      delay(20000);
      if(!esp.find("OK"))
      {
        espSetClient = false;
        Serial.println(F("Error... esp8266 couldn't set as client..."));
      }
      else
      {
        espSetClient = true;
        Serial.println(F("OK recieved, esp8266 set as client..."));
        Serial.println();
        break;
      }
    }
  }
  else
  {
    Serial.println(F("esp8266 didnt respond to AT before so we are not trying to set it as client here..."));
    Serial.println();
  }
  
  if((espWorking == true)&&(espSetClient == true)&&(espWifiConnected == false))
  {
    fTime = millis();
    while(millis() < fTime+timeOut)
    {
      esp.println("AT+CWJAP=\""+wifiName+"\",\""+wifiPass+"\"");    //Connecting to wifi
      Serial.println(F("Trying to connect to WiFi..."));
      delay(20000);
      if(!esp.find("OK"))
      {
        espWifiConnected = false;
        Serial.println(F("Error... esp8266 couldn't connect to WiFi..."));
      }
      else
      {
        espWifiConnected = true;
        Serial.println(F("OK recieved, esp8266 connected to WiFi..."));
        Serial.println();
        break;       
      }    
    }
  }
    else
  {
    Serial.println(F("esp8266 couldnt set as client before so we are not trying to connect it to WiFi here..."));
    Serial.println();
  }
}


to give esp some time to process i used delay in this function from time to time, cuz i dont mind getting 1-3 mins late readings from sensors every 30mins in the main loop.

this function works fine for now and i am totally okay to calling it in the setup but i have worries about using it in the loop... i think before checking the "if(espWorking==true)"or"if(espWifiConnected==true)" statements, i have to check esp connection again by sending commands to it and set these booleans again. Right ?

the wiring of RTC and AHT10 is with 2 jumpers so they r not long at all
i did a little research for the pullup resistors before using these modules. they have their own pullup resistors and depending on their values i claimed that it was okay to use them together. so far i didnt get any issues using them. i am just trying to prevent my program to fail IF i get issues from them any time for some reason.
i heard that i could use a capacitor with esp8266 so im gonna get it as soon as possible but im not sure of its value...how many volts should it be ?

To be secure if you are using it at 5V it should be at least 10V any gigher value is OK too.
This is just a maximum specification how much volts the capacitor can handle staying undamanged so if it is 25V, 63V, 400V this doesn't matter. They get just bigger in size with teh same capacity and more volts

The crucial thing is to have enough capacity. Everying below 1000µC does not help so much.
Hence I recommend using a capacitor with 2200µF

Using delay inside loop is a very bad idea.
A too long delay could even make your ESP resetting
You have to use non-blocking timing which I explain here

best regards Stefan

ohh okay cool

wooww i didnt know that...ima get rid of those delays asap. i cant thank you enough, really appreciate your help :slight_smile:

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