Trying to code a system for hydroponics

I think it’s important that i start out explaining a little about my project, so i am currently designing a cheap, reliable hydroponics system, i’m planning on making it all open source when it’s done.

but i needed a micro-controller for the watering system, and possible future additions, i have a some basic understanding about how code works, but it’s very limited and basic, i had literally no idea what i was doing, but i wrote the code below took me 5 hours to look through the community for my desired functions and get something that worked so bear with me it’s a mess.

i tried commenting the functions that i understand, to help myself in the future and to show you guys what i understand of the code

as you see in the code i uncommented all the DHT sensor stuff, because that’s what’s been annoying me i got all the other code working, but now i can’t get the DHT sensor written in there, any feedback on my code, what am i doing wrong, is it formatting, or simply a question of how i’m placing my code, also i’m experiencing connection issues with the app?

appreciate all help <3


//Defining Pins and Serial
#define BLYNK_PRINT Serial                                    //Defines using the Blynk print serial function, and send commands to the Serial Monitor
//#define DHTPIN 1                                              //Defines what Pin the DHT Sensor is using
//#define DHTTYPE DHT11                                         //Defines which type of DHT Sensor is used


//Including libraries
#include <ESP8266WiFi.h>                                      //Including the ESP8255WiFi Library
#include <BlynkSimpleEsp8266.h>                               //Including the BlynkSimpleEsp8266 Library
//#include <DHT.h>                                              //Including the DHT Library


//Userinformation
char auth[] = "*************************************";             //Authentication code
char ssid[] = "***********";                                     //WiFi SSID 
char pass[] = "**********";                                     //WiFI Password


//my variables
int ONOFF;                                                    //this variable is used to track the On/Off State
int timerID =1;                                                //this is the timer used for the delay counter
BlynkTimer timer;                                          //
//DHT dht(DHTPIN, DHTTYPE);                   //




//My Delay Timer code
BLYNK_WRITE(V1)                                               //Recieve Slider variable from Virtual pin 1
{
   int minutes = param.asInt();                               //Saves Value from Virtual pin 1 to minutes
   Serial.println(minutes);                                   //Prints the Value from minutes
   timer.deleteTimer(timerID);                                //Deletes old timer
   timerID = timer.setInterval(minutes * 60000L, Pumpe);      //Sets new timer to minutes * 60000L (miliseconds) and runs the Pump Void
   Serial.print("V1 Slider Value: ");                         //Prints Text to Serial Monitor
   Serial.print("Countdown timer: ");                         //Prints Text to Serial Monitor
}


    
//My Pump On code
void Pumpe(){                                                 //Creates a Custom void for my Pump On code
  if (timerID < 0);                                           //Triggers if the timer is below zero
  digitalWrite(D0, LOW);                                      //Turns desired Pin On
  digitalWrite(ONOFF, LOW);                                   //Turns the On/Off state tracker On
  Blynk.virtualWrite(V2, 255);                                //Attempting to turn On a virtual LED
  timer.setTimeout(10000L, Off);                              //Sets a timeout for this void (amount of time for pump to be On, and runs the Off Void
}



//My Pump Off code
void Off(){                                                   //Creates a Custom void for my Pump off code
  if (ONOFF = LOW);                                           //Reads the state of the On/Off tracker
  digitalWrite(D0, HIGH);                                     //Turns Desired Pin Off
  digitalWrite(ONOFF, HIGH);                                  //Turns the On/Off state tracker Off
  Blynk.virtualWrite(V2, 0);                                  //Attempting to turn Off a virtual LED
}



//my DHT Sensor code
//void Sensor(){                                                //Creates a Custom void for my DHT Sensor code
//  float h = dht.readHumidity();                               //Tell Blynk that h is a float number used to store latest humidity reading
//  float t = dht.readTemperature();                            //Tell Blynk that t is a float number used to store latest temperature reading
//
//  if (isnan(h) || isnan(t)) {                                 //If h or t isn't a number  
//    Serial.println("Failed to read Sensor!");                 //Print "Failed to read Sensor" to Serial Monitor
//   return;                                                   //Try again
//  }
//  Blynk.virtualWrite(V5, h);                                  //Writes humidity readings to Virtual Pin 5
//  Blynk.virtualWrite(V6, t);                                  //Writes temperature readings to Virtual Pin 5
//}



void setup()
{
  // Debug console
  Serial.begin(9600);

  Blynk.begin(auth, ssid, pass);
  // You can also specify server:
  //Blynk.begin(auth, ssid, pass, "blynk-cloud.com", 80);
  //Blynk.begin(auth, ssid, pass, IPAddress(192,168,1,100), 8080);

//my delay timer setup
timerID = timer.setInterval(60000L, Pumpe);
pinMode(D0, OUTPUT);

//my DHT timer setup
//dht.begin();
//timer.setInterval(1000L, Sensor);
}


void loop()
{
  Blynk.run();
  timer.run();
}

You’ve declared a variable called ONOFF to use as a flag to track the state of your pump, but instead of simply saying:
ONOFF =0;
you’re using a digitalWrite (and later a digitalRead) to alter/read the state of your GPIO pins.
HIGH = 1 and LOW = 0, so you’re changing the state of pins 1 and 0.

As GPIO pin 1 is where you’ve connected your DHT sensor, this is probably why it’s not working.

You’re also making a simple mistake with your equals signs. Here for example:

One equals sign sets the value, two equals signs check the value. The statement above is setting ONOFF to LOW (0). What it should say is:
if (ONOFF == LOW)

or, better still:
If (ONOFF == 0)

Also, 1 second is a little bit too frequent to be interrogating the DHT11 sensor, as it’s a little slow. Better to change to every 5 seconds.

Pete.

thank your very much for your reply, i really have so little understanding of code, that i barely understand what you are getting at here :slight_smile:

i’m very aware of my bad code, i have zero experience in coding and all this is stitched together from what i could somehow understand, i just fixed the sensor, (i think it was because i didn’t define the pinmode for the pin the sensor is on?) so now the whole program actually runs fairly decent, despite my obvious errors.

but how do i know if i write to a pin or not, cause as u notice ive used the D1 and so on as designators for my pins, and i was under the impression that since i didn’t tell the “flag” as u called it that it was bound to a pin then it would just be a stored value?

took your tip on the increasing the intervals between reading the DHT, i get much better readings now thanks alot.

digitalWrite writes the value to the specific GPIO pin. You do NOT want to be doing this for a straightforward value that you’re trying to store as a simple variable.
You simply want to be assigning a value to the variable with:
ONOFF = 1;

And retrieving it for a comparison with:

if (ONOFF == 1)
 }
    do some stuff in here...
 {

Your existing code will not work correctly unless you fix this issue, and the single equals sign in the if comparisons.

Pete.

what i’m finding weird is you telling me the code isn’t going to work, even tho it actually works pretty well, it’s taking temp and moisture measurements, and its activating the pump whenever the delay is over, and turns off the pump after the delay, and repeats.

i really don’t see what isn’t working here.

with that being said, what your telling me that is basically that i can’t write to the value and instead u wan’t me to make to different static values, one for on and one for off?.

what command would i use to write to the On/Off state to my ONOFF (flag)

It may do, but all this line is actually doing is updating GPIO 0 to be HIGH or LOW, not your variable.

digitalWrite(ONOFF, HIGH);

You’re actually writing a 0 (LOW) value to ONOFF here:

void Off(){                                                   //Creates a Custom void for my Pump off code
  if (ONOFF = LOW);   // <<<<<<<<<<
  digitalWrite(D0, HIGH);                                     //Turns Desired Pin Off
  digitalWrite(ONOFF, HIGH);                                  //Turns the On/Off state tracker Off
  Blynk.virtualWrite(V2, 0);                                  //Attempting to turn Off a virtual LED
}
void Off(){
  if (ONOFF == LOW); // Notice the double ==
  digitalWrite(D0, HIGH);
  ONOFF = 1; // Sets ONOFF to '1'
  Blynk.virtualWrite(V2, 0);
}

If you think that the code is working correctly then leave it as it is, I’m simply pointing-out some programming errors and syntax issues with your original code.

I’d suggest that you find some ”Arduino programming 101” type of course in your preferred learning format and get some tuition on the use of variables and if/else tests.

Then, come back and read what I wrote initially and see if it makes more sense to you.

Pete.

2 Likes

Thank you so much to both of you!

the extra context and clarification, that JustBertC gave helped me much better understand what you guys meant, i rewrote the code and it still seems to work perfectly, at least im happier knowing that the code is more “right”

i’ll definately try and read some programming 101 on variables and statements, i do however have a hard time understanding alot of it without the proper context, but with how active and friendly this community is i definately feel more optimistic about it all.

to clarifiy what i understanded, so when you use a single = you set a value, which was one of the things i did wrong, instead i should use == when trying to read a value.

and digitalwrite is only for writing to pins, and not simple values.

here is the new code hope it looks much better to you guys now, if i wanted to track my timer in the blynk interface, would it just be as simple as doing a small void, and a virtualwrite with a interval?


//Defining Pins and Serial
#define BLYNK_PRINT Serial                                    //Defines using the Blynk print serial function, and send commands to the Serial Monitor
#define DHTPIN D1                                             //Defines what Pin the DHT Sensor is using
#define DHTTYPE DHT11                                         //Defines which type of DHT Sensor is used


//Including libraries
#include <ESP8266WiFi.h>                                      //Including the ESP8255WiFi Library
#include <BlynkSimpleEsp8266.h>                               //Including the BlynkSimpleEsp8266 Library
#include <DHT.h>                                              //Including the DHT Library


//Userinformation
char auth[] = "****************************";             //Authentication code
char ssid[] = "*******";                                           //WiFi SSID 
char pass[] = "********";                                        //WiFI Password


//my variables
int ONOFF = 0;                                                //this variable is used to track the On/Off State
int timerID = 1;                                              //this is the timer used for the delay counter
BlynkTimer timer;                                             //Blynks simpletimer used for my timer
DHT dht(DHTPIN, DHTTYPE);                                     //Tell the DHT library what pin and what DHT sensor we are using




//My Delay Timer code
BLYNK_WRITE(V1)                                               //Recieve Slider variable from Virtual pin 1
{
   int minutes = param.asInt();                               //Saves Value from Virtual pin 1 to minutes
   Serial.println(minutes);                                   //Prints the Value from minutes
   timer.deleteTimer(timerID);                                //Deletes old timer
   timerID = timer.setInterval(minutes * 60000L, Pumpe);      //Sets new timer to minutes * 60000L (miliseconds) and runs the Pump Void
   Serial.print("V1 Slider Value: ");                         //Prints Text to Serial Monitor
   Serial.print("Countdown timer: ");                         //Prints Text to Serial Monitor
}


    
//My Pump On code
void Pumpe(){                                                 //Creates a Custom void for my Pump On code
  if (timerID < 0);                                           //Triggers if the timer is below zero
  digitalWrite(D0, LOW);                                      //Turns desired Pin On
  ONOFF = 1;                                                  //Turns the On/Off state tracker On
  Blynk.virtualWrite(V2, 255);                                //Turns on Virtual LED to signal pump activity
  timer.setTimeout(45000L, Off);                              //Sets a timeout for this void (amount of time for pump to be On, and runs the Off Void
}



//My Pump Off code
void Off(){                                                   //Creates a Custom void for my Pump off code
  if (ONOFF == 1);                                            //Reads the state of the On/Off tracker
  digitalWrite(D0, HIGH);                                     //Turns Desired Pin Off
  ONOFF = 0;                                                  //Turns the On/Off state tracker Off
  Blynk.virtualWrite(V2, 0);                                  //Turns Off Virtual LED to signal pump inactivity
}



//my DHT Sensor code
void Sensor(){                                                //Creates a Custom void for my DHT Sensor code
  float h = dht.readHumidity();                               //Tell Blynk that h is a float number used to store latest humidity reading
  float t = dht.readTemperature();                            //Tell Blynk that t is a float number used to store latest temperature reading

  if (isnan(h) || isnan(t)) {                                 //If h or t isn't a number  
    Serial.println("Failed to read Sensor!");                 //Print "Failed to read Sensor" to Serial Monitor
   return;                                                    //Try again
  }
  Blynk.virtualWrite(V5, h);                                  //Writes humidity readings to Virtual Pin 5
  Blynk.virtualWrite(V6, t);                                  //Writes temperature readings to Virtual Pin 5
}



void setup()
{
  // Debug console
  Serial.begin(9600);

  Blynk.begin(auth, ssid, pass);
  // You can also specify server:
  //Blynk.begin(auth, ssid, pass, "blynk-cloud.com", 80);
  //Blynk.begin(auth, ssid, pass, IPAddress(192,168,1,100), 8080);

//my delay timer setup
timerID = timer.setInterval(60000L, Pumpe);
pinMode(D0, OUTPUT);

//my DHT timer setup
dht.begin();
timer.setInterval(5000L, Sensor);
pinMode(D1, INPUT);
}


void loop()
{
  Blynk.run();
  timer.run();
}

1 Like

I don’t understand what you’re trying to achieve with this line of code. Can you explain what you think it does?

Pete.

1 Like

well i was trying to make the timerID a countdown timer that got it’s value from the slider i have on V1, so that everytime it reaches 0 i was hoping it would run the functions below the statement.

D0 is the onboard LED, i’m using it to illustrate a Relay that’s supposed to control my irrigation pump, which is supposed to run the 45 second states in pump void, with the interval i input from V1, don’t know if this helps a bit? :slight_smile:

im currently testing the code to see if it actually runs as intended.

When a timer instance is created, an identifier is assigned to it. In most cases this timer ID isn’t needed, but if you want to delete the timer at some point then you need to reference it by its ID.

You can’t specify the ID of the timer, that’s done automatically when the timer instance is created, and I can’t remember if the first one allocated is 0 or 1, but that’s irrelevant in this case.

I don’t really understand you’re description of what you’re trying to achieve.

Pete.

it’s hard for me to explain in context with code, so i’ll try without maybe that makes it easier for me to explain.

so i’m designing a hydroponics system, this system has a pump for watering that i want to run for 45 seconds and then shut off, wait for a specific amount of time (delay), and then do the same thing again.

for this purpose i choose a nodemcu, a 12v pump, and a relay, and then i wanted to be able to change the delay between waterings using a slider (V1) in the blynk interface.

so i’m wanting the timer to be the delay between waterings, does this help?

You’re handling what you’ve described correctly in the BLYNK_WRITE (V1) callback function, but the if statement that I highlighted earlier makes no sense to me.

Pete.

ohh i’m sorry i mustve misunderstood.

well i was hoping that “if (timerID < 0)” would mean that if the the number on my timer reached 0 or below that it would run it’s function, is this wrong of me?

Yes, as I explained earlier, the timer ID is a number assigned automatically by the system to identify the timer in case it needs to be stopped, stated, deleted etc. It will be a number between 1 and 16 (or 0 and 15 if it’s a zero-based ide tinier) and will remain static for the life of the timer instance.

The way that the timeout timer should work is that once it expires (after the time that you’ve set has elapsed) it should run the named function.

Pete.

I think he has just named his int variable timerID…

He’s setting the variable to be equal to the ID of the timer here:

Pete.

okay so if i’m understanding you correctly, what you are saying is that i would only need the timer ID, in case i for example needed to delete or in some other way use that specific timer later on in my program?

would this mistake in, have any effect on the program, i ask because right now it seems to work and accept the delay i set.

so if i were to remove the ID part of all my timer instances, the code would be right? :slight_smile:

There’s no problem capturing the ID for each of the timers and storing them in variables.
The problem arises when you try to use those timer ID’s in the way that you are within your code.
As I explained before, each timer object (in this case the object is defined as ‘timer’) can have up to 16 separate timers assigned to it. The system will allocate numerical IDs for each one, starting at either 0 or 1 (I can’t remember which).
This means that the timer ID will NEVER be less than 0, so this line of code will never evaluate to true:

But, looking at this section of code more closely, your if statement t syntax is all wrong, which is why it’s being skipped.

Pete.