What's new
  • As of today ICMag has his own Discord server. In this Discord server you can chat, talk with eachother, listen to music, share stories and pictures...and much more. Join now and let's grow together! Join ICMag Discord here! More details in this thread here: here.

VPD/Humidity controler build low budget (Arduino)

Awesome!

It looks like your sensor is on a board, which may have the resistor built in.

Did you double check that you have the wires connected right?
 
OH! I bet the program is made for a DHT11 and takes readings too often for the DHT22. If you make the delay "2000" (in milliseconds, so that's 2 seconds) it hopefully will give you readings each time.
 
OH! I bet the program is made for a DHT11 and takes readings too often for the DHT22. If you make the delay "2000" (in milliseconds, so that's 2 seconds) it hopefully will give you readings each time.
figured it out! the DHT22 wasnt happy with my using USB power to power it up. Powered it up via external power supply and now it works perfect. Havent uploaded VPD code yet going to have to chop up some AC power cords for the relays first. Keep you updated!
 
ok just uploaded your code and it seems to be horribly all out of whack.

First of all, the serial monitor keeps saying TOO DRY as my humidity is at 52% while my temps are at 80 degrees F. So the obvious thing to do is humidify, not Dehumidify. Why does your code turn on the humidifier under TOO WET conditions and why does your code turn on the de-humidifier under TOO DRY conditions?? If VPD is lower than the minumum you set (7.5) then its obviously too wet right? So why turn on the humidifier under wet conditions? And turning the exhaust fan or de-humidifer fan would make things drier so why is the code turning these things on when its already dry??
 
switched humidify and dehumidify so that exhaust turns on during wet conditions and the fogger turns on during dry conditions. No matter what though the humidifier keeps clicking back on regardless of wet or dry. Im trying to figure out why...
 
dont understand why sometimes the exhaust will stay on for a long time without clicking off.. but most of the times its clicking on and off.... its like its so random.. now both my exhaust and fogger is on at the same time... i dont get why...

EDIT: figure it out! apparently the relay board had printed NO and NC inversely. No wonder everything was staying powered on.

EDIT 2: got a rough working version running right now. Going to do some minor tweaks to the code and re-share, maybe in a day or two..

For now, I need to figure out how to set this ultrasonic fogger rig up. It uses water so I need some kind of recirculation system where it never runs out of water... hmm... any ideas?
 
Last edited:
Ok i understand why your code is written the way it is in regards to digitalwrite HIGH and LOW. Active Low relays! I have one too apparently :tiphat:

Heres the code that im currently using:

//Libraries
#include <DHT.h>;
#include <Adafruit_Sensor.h>
#include <DHT_U.h>

//Constants
#define DHTPIN 2 // what pin we're connected to
#define DHTTYPE DHT22 // DHT 22 (AM2302)
DHT dht(DHTPIN, DHTTYPE); //// Initialize DHT sensor for normal 16mhz Arduino

//Variables
int chk;
float hum; //Stores humidity value
float temp; //Stores temperature value
float vpdSetHigh = 12.5;
float vpdSetLow = 7.5;
int vpdHighLed = 12; //pin for low humidity light on
int vpdLowLed = 11; //pin for high humidity light on
int dehumidify = 10; //pin for dehumidify relay
int humidify = 9; //pin for humidify relay
int dehumidifyTimeOn = 20000;//set time on for your system in millisecondes
int humidifyTimeOn = 20000;//et time on for your system in millisecondes
int readDelay = 5000; //DHT 22 (AM2302) can only take a reading every 2 sec

void setup()
{
Serial.begin(9600);
dht.begin();
Serial.println("Initializing VPD Controller...");
pinMode (vpdHighLed, OUTPUT);
pinMode (vpdLowLed, OUTPUT);
pinMode (dehumidify, OUTPUT);
pinMode (humidify, OUTPUT);
}

void loop()
{
delay(2000);
//Read data and store it to variables hum and temp
hum = dht.readHumidity();
temp = dht.readTemperature();
float temp_f = (temp * 9.0+2)/5.0 + 32.0;
float vpd = ((1-hum/100)*0.611*exp(17.27*temp/(temp+237.3))*10*10)/10.0;

//Print temp and humidity values to serial monitor
Serial.print("CALCULATING... ");
Serial.print("Humidity: ");
Serial.print(hum);
Serial.print(" %, Temp: ");
Serial.print(temp);
Serial.println(" Celsius");
Serial.print(temp_f);
Serial.println(" Farenheit");
delay(500); //Delay 2 sec.

if (isnan(hum) || isnan(temp)) {
Serial.println("Failed to read from DHT sensor!");// Check if any reads failed && exit early (to try again).
return;

}

if (vpd <= vpdSetLow){
Serial.print ("Environment is WET. Turning On De-Humidifier/Exhaust Fan...");Serial.print (" VPD=");Serial.print (vpd);Serial.print (" Temperature=");Serial.print (temp_f);Serial.print (" Humidity=");Serial.print (hum);
digitalWrite (vpdLowLed, LOW);
digitalWrite (dehumidify, LOW);
digitalWrite (vpdHighLed, HIGH);
digitalWrite (humidify, HIGH);
delay (dehumidifyTimeOn);
}

if (vpd >= vpdSetHigh){
Serial.print ("Environment is DRY. Turning On Humidifier/Fogger...");Serial.print (" VPD=");Serial.print (vpd);Serial.print (" Temperature=");Serial.print (temp_f);Serial.print (" Humidity=");Serial.print (hum);
digitalWrite (vpdLowLed, HIGH);
digitalWrite (dehumidify, HIGH);
digitalWrite (vpdHighLed, LOW);
digitalWrite (humidify, LOW);
delay (humidifyTimeOn);
}

else {
Serial.print ("Environment is within acceptable VPD range! Turning Off ALL Environmental Devices...");Serial.print (" VPD=");Serial.print (vpd);Serial.print (" Temperature=");Serial.print (temp_f);Serial.print (" Humidity=");Serial.print (hum);
digitalWrite (vpdHighLed, HIGH);
digitalWrite (vpdLowLed, HIGH);
digitalWrite (dehumidify, HIGH);
digitalWrite (humidify, HIGH);
delay(readDelay);


}}
I plan to add more things to the code :)
 
Agreed.

I've been using these for the past 3 years and they've served me well.

That's great! I never got this integrated into my grow, then stopped growing (moved, divorce, life) and lost track of this project.
I'm playing around with this again and looked up this thread to find the old code. I'm so happy to see that it is being used! Now I'm working on a vegetable farm and thinking about greenhouse management applications.
 

ButterflyEffect

Well-known member
That's great! I never got this integrated into my grow, then stopped growing (moved, divorce, life) and lost track of this project.
I'm playing around with this again and looked up this thread to find the old code. I'm so happy to see that it is being used! Now I'm working on a vegetable farm and thinking about greenhouse management applications.

Funny update.

I'm currently looking for a more robust option, as one of the Megas locked up for some unknown reason and the temp got to 130. Cooked a nice run at day 58. Very depressing. 3 years and nary a glitch.

Life goes on, I guess. I'm currently looking at my options and I'm not sure there's a great OTS solution. I already run a home-brew flip board(4 CDM 315 ballasts + 8 lights) for my 2 primary flower rooms and my 3rd room is only oine donut with 2 lamps.

In reality, I only need 2 controllers. One for AC/Heat and one for Dehuey/Mister. I just want logging and remote adjustability without uploading new code each time.

I'm switching sensors to SHT31s soon, as the DHT22s are very primitive and have a high failure rate(3 month life). Also considering using a pair of UNOs for the controllers that report to a MEGA.

We'll see what the new year brings!
 

icganja

New member
Funny update.

I'm currently looking for a more robust option, as one of the Megas locked up for some unknown reason and the temp got to 130. Cooked a nice run at day 58. Very depressing. 3 years and nary a glitch.


Did the arduino itself actually fry? I've never seen that happen before, it's usually just a software issue.

I think this code just needs a watchdog timer! It's a piece of code that will prevent the arduino from locking up.



The piece of code is gonna look something like this:


#include <avr/wdt.h> //adds library for watchdog timer


void setup(){
//watchdog timer with 2 Seconds time out
wdt_enable(WDTO_2S); //can be changed for 4 or 8 seconds

}

void loop(){
//do stuff here

wdt_reset();
}


So if your arduino fails to execute any code for 2 seconds, the watchdog will bite and reset your arduino. If your code executes well it will reach the watchdog timer reset at the end and the cycle starts over again.



For good measure you can also add a reset at the very end of your code:


void(* resetFunc) (void) = 0;//declare reset function at address 0
...
resetFunc(); //call reset
 

breily

New member
Hello. I don't know much English, sorry. I encourage me to play with arduiin0o and esp32 thanks to your project.I have made some modd to be able to use it in wemos d1 r32 and it goes from fabula. Soon I would like to add the wifi function to monitor easier. I'm noob so be patient


#if (defined(__AVR__))
#include <avr\pgmspace.h>
#else
#include <pgmspace.h>
#endif
//Libraries
#include <DHT.h>;
#include <Adafruit_Sensor.h>
#include <DHT_Async.h>
//Constants
#define DHTPIN 14 // what pin we're connected to
#define DHTTYPE DHT22 // DHT 22 (AM2302)
DHT dht(DHTPIN, DHTTYPE); //// Initialize DHT sensor for normal 16mhz Arduino
//Variables
int chk;
float hum; //Stores humidity value
float temp; //Stores temperature value
float vpdSetHigh = 22.5;
float vpdSetLow = 18.5;
int vpdHighLed = 23; //pin for low humidity light on
int vpdmiddLed = 19; //pin for ok humidity light on
int vpdLowLed = 18; //pin for high humidity light on
int dehumidify = 33; //pin for dehumidify relay
int humidify = 32; //pin for humidify relay
int dehumidifyTimeOn = 2000;//set time on for your system in millisecondes
int humidifyTimeOn = 2000;//et time on for your system in millisecondes
int readDelay = 2200; //DHT 22 (AM2302) can only take a reading every 2 sec
void setup()
{
Serial.begin(19200);
dht.begin();
Serial.println("Iniciando vpd controlador...");
pinMode (vpdHighLed, OUTPUT);
pinMode (vpdmiddLed, OUTPUT);
pinMode (vpdLowLed, OUTPUT);
pinMode (dehumidify, OUTPUT);
pinMode (humidify, OUTPUT);
}
void loop()
{
//Read data and store it to variables hum and temp
hum = dht.readHumidity();
temp = dht.readTemperature();
float temp_f = (temp * 9.0+2)/5.0 + 32.0;
float vpd = ((1-hum/100)*0.611*exp(17.27*temp/(temp+237.3))*10*10)/10.0;
//Print temp and humidity values to serial monitor
Serial.print("CALCULANDO... ");
Serial.print("Humedad: ");
Serial.print(hum);
Serial.print(" %, Temp: ");
Serial.print(temp);
Serial.println(" Celsius");
Serial.print(temp_f);
Serial.println(" Farenheit");
delay(2200); //Delay 2 sec.
if (isnan(hum) || isnan(temp)) {
Serial.println("Fallo al leer sensor dht22 !");// Check if any reads failed && exit early (to try again).
return;
}
if (vpd > vpdSetHigh){
Serial.print ("Demasiado seco. Encendiendo Humidificador...");Serial.print (" VPD=");Serial.print (vpd);Serial.print (" Temperature=");Serial.print (temp_f);Serial.print (" Humidity=");Serial.print (hum);
digitalWrite (vpdLowLed, HIGH);
digitalWrite (dehumidify, HIGH);
digitalWrite (vpdHighLed, LOW);
digitalWrite (humidify, LOW);
digitalWrite (vpdmiddLed, LOW);
delay (humidifyTimeOn);
}
else if (vpd < vpdSetLow){
Serial.print ("Demasiado humedo. Encendiendo Des-Humidificador...");Serial.print (" VPD=");Serial.print (vpd);Serial.print (" Temperature=");Serial.print (temp_f);Serial.print (" Humidity=");Serial.print (hum);
digitalWrite (vpdLowLed, LOW);
digitalWrite (dehumidify, LOW);
digitalWrite (vpdHighLed, HIGH);
digitalWrite (humidify, HIGH);
digitalWrite (vpdmiddLed, LOW);
delay (dehumidifyTimeOn);
}
else {
Serial.print ("Acceptable rango VPD! Apagados los dispositivos...");Serial.print (" VPD=");Serial.print (vpd);Serial.print (" Temperature=");Serial.print (temp_f);Serial.print (" Humidity=");Serial.print (hum);
digitalWrite (vpdHighLed, LOW);
digitalWrite (vpdmiddLed, HIGH);
digitalWrite (vpdLowLed, LOW);
digitalWrite (dehumidify, LOW);
digitalWrite (humidify, LOW);
delay (readDelay);
}
}
 

breily

New member
Hello. I don't know much English, sorry. I encourage me to play with arduiin0o and esp32 thanks to your project.I have made some modd to be able to use it in wemos d1 r32 and it goes from fabula. Soon I would like to add the wifi function to monitor easier. I'm noob so be patient


#if (defined(__AVR__))
#include <avr\pgmspace.h>
#else
#include <pgmspace.h>
#endif
//Libraries
#include <DHT.h>;
#include <Adafruit_Sensor.h>
#include <DHT_Async.h>
//Constants
#define DHTPIN 14 // what pin we're connected to
#define DHTTYPE DHT22 // DHT 22 (AM2302)
DHT dht(DHTPIN, DHTTYPE); //// Initialize DHT sensor for normal 16mhz Arduino
//Variables
int chk;
float hum; //Stores humidity value
float temp; //Stores temperature value
float vpdSetHigh = 22.5;
float vpdSetLow = 18.5;
int vpdHighLed = 23; //pin for low humidity light on
int vpdmiddLed = 19; //pin for ok humidity light on
int vpdLowLed = 18; //pin for high humidity light on
int dehumidify = 33; //pin for dehumidify relay
int humidify = 32; //pin for humidify relay
int dehumidifyTimeOn = 2000;//set time on for your system in millisecondes
int humidifyTimeOn = 2000;//et time on for your system in millisecondes
int readDelay = 2200; //DHT 22 (AM2302) can only take a reading every 2 sec
void setup()
{
Serial.begin(19200);
dht.begin();
Serial.println("Iniciando vpd controlador...");
pinMode (vpdHighLed, OUTPUT);
pinMode (vpdmiddLed, OUTPUT);
pinMode (vpdLowLed, OUTPUT);
pinMode (dehumidify, OUTPUT);
pinMode (humidify, OUTPUT);
}
void loop()
{
//Read data and store it to variables hum and temp
hum = dht.readHumidity();
temp = dht.readTemperature();
float temp_f = (temp * 9.0+2)/5.0 + 32.0;
float vpd = ((1-hum/100)*0.611*exp(17.27*temp/(temp+237.3))*10*10)/10.0;
//Print temp and humidity values to serial monitor
Serial.print("CALCULANDO... ");
Serial.print("Humedad: ");
Serial.print(hum);
Serial.print(" %, Temp: ");
Serial.print(temp);
Serial.println(" Celsius");
Serial.print(temp_f);
Serial.println(" Farenheit");
delay(2200); //Delay 2 sec.
if (isnan(hum) || isnan(temp)) {
Serial.println("Fallo al leer sensor dht22 !");// Check if any reads failed && exit early (to try again).
return;
}
if (vpd > vpdSetHigh){
Serial.print ("Demasiado seco. Encendiendo Humidificador...");Serial.print (" VPD=");Serial.print (vpd);Serial.print (" Temperature=");Serial.print (temp_f);Serial.print (" Humidity=");Serial.print (hum);
digitalWrite (vpdLowLed, HIGH);
digitalWrite (dehumidify, HIGH);
digitalWrite (vpdHighLed, LOW);
digitalWrite (humidify, LOW);
digitalWrite (vpdmiddLed, LOW);
delay (humidifyTimeOn);
}
else if (vpd < vpdSetLow){
Serial.print ("Demasiado humedo. Encendiendo Des-Humidificador...");Serial.print (" VPD=");Serial.print (vpd);Serial.print (" Temperature=");Serial.print (temp_f);Serial.print (" Humidity=");Serial.print (hum);
digitalWrite (vpdLowLed, LOW);
digitalWrite (dehumidify, LOW);
digitalWrite (vpdHighLed, HIGH);
digitalWrite (humidify, HIGH);
digitalWrite (vpdmiddLed, LOW);
delay (dehumidifyTimeOn);
}
else {
Serial.print ("Acceptable rango VPD! Apagados los dispositivos...");Serial.print (" VPD=");Serial.print (vpd);Serial.print (" Temperature=");Serial.print (temp_f);Serial.print (" Humidity=");Serial.print (hum);
digitalWrite (vpdHighLed, LOW);
digitalWrite (vpdmiddLed, HIGH);
digitalWrite (vpdLowLed, LOW);
digitalWrite (dehumidify, LOW);
digitalWrite (humidify, LOW);
delay (readDelay);
}
}
I would also like to know how to add a new function to calculate the VPD with the temperature data in the sheets in real time
 

breily

New member
HI, new funcion print html , 100% found

#if (defined(__AVR__))
#include <avr\pgmspace.h>
#else
#include <pgmspace.h>
#endif
//Libraries
#include <DHT.h>;
#include <Adafruit_Sensor.h>
#include <DHT_Async.h>
#include <WiFi.h>
#include <WebServer.h>
//Constants
#define DHTPIN 14 // what pin we're connected to
#define DHTTYPE DHT22 // DHT 22 (AM2302)
DHT dht(DHTPIN, DHTTYPE); //// Initialize DHT sensor for normal 16mhz Arduino
//Variables
int chk;
float hum; //Stores humidity value
float temp; //Stores temperature value
float vpd;
float vpdSetHigh = 22.5;
float vpdSetLow = 18.5;
int vpdHighLed = 23; //pin for low humidity light on
int vpdmiddLed = 19; //pin for ok humidity light on
int vpdLowLed = 18; //pin for high humidity light on
int dehumidify = 33; //pin for dehumidify relay
int humidify = 32; //pin for humidify relay
int dehumidifyTimeOn = 2000;//set time on for your system in millisecondes
int humidifyTimeOn = 2000;//et time on for your system in millisecondes
int readDelay = 2200; //DHT 22 (AM2302) can only take a reading every 2 sec

const char* ssid = "ssid";
const char* password = "pass";
WebServer server(80);
void loop()
{
//Read data and store it to variables hum and temp
hum = dht.readHumidity();
temp = dht.readTemperature();
vpd = ((1-hum/100)*0.611*exp(17.27*temp/(temp+237.3))*10*10)/10.0;
float temp_f = (temp * 9.0+2)/5.0 + 32.0;
float vpd = ((1-hum/100)*0.611*exp(17.27*temp/(temp+237.3))*10*10)/10.0;

// Manejar solicitudes HTTP
server.handleClient();

//Print temp and humidity values to serial monitor
// Imprimir la dirección IP local
Serial.print("Dirección IP local: ");
Serial.println(WiFi.localIP());
Serial.print("CALCULANDO... ");
Serial.print("Humedad: ");
Serial.print(hum);
Serial.print(" %, Temp: ");
Serial.print(temp);
Serial.println(" Celsius");
Serial.print(temp_f);
Serial.println(" Farenheit");
delay(2200); //Delay 2 sec.
if (isnan(hum) || isnan(temp)) {
Serial.println("Fallo al leer sensor dht22 !");// Check if any reads failed && exit early (to try again).
return;
}

if (vpd > vpdSetHigh){
Serial.print ("Demasiado seco. Encendiendo Humidificador...");Serial.print (" VPD=");Serial.print (vpd);Serial.print (" Temperature=");Serial.print (temp_f);Serial.print (" Humidity=");Serial.print (hum);
digitalWrite (vpdLowLed, HIGH);
digitalWrite (dehumidify, HIGH);
digitalWrite (vpdHighLed, LOW);
digitalWrite (humidify, LOW);
digitalWrite (vpdmiddLed, LOW);
delay (humidifyTimeOn);
}

else if (vpd < vpdSetLow){
Serial.print ("Demasiado humedo. Encendiendo Des-Humidificador...");Serial.print (" VPD=");Serial.print (vpd);Serial.print (" Temperature=");Serial.print (temp_f);Serial.print (" Humidity=");Serial.print (hum);
digitalWrite (vpdLowLed, LOW);
digitalWrite (dehumidify, LOW);
digitalWrite (vpdHighLed, HIGH);
digitalWrite (humidify, HIGH);
digitalWrite (vpdmiddLed, LOW);
delay (dehumidifyTimeOn);
}
else {
Serial.print ("Acceptable rango VPD! Apagados los dispositivos...");Serial.print (" VPD=");Serial.print (vpd);Serial.print (" Temperature=");Serial.print (temp_f);Serial.print (" Humidity=");Serial.print (hum);
digitalWrite (vpdHighLed, LOW);
digitalWrite (vpdmiddLed, HIGH);
digitalWrite (vpdLowLed, LOW);
digitalWrite (dehumidify, LOW);
digitalWrite (humidify, LOW);
delay (readDelay);
}
}

void handleRoot() {
String html = "<html><body>";
html += "<h1>Datos del sensor BreilyClima VPD</h1>";
html += "<p>Temperatura: " + String(temp) + " C</p>";
html += "<p>Humedad: " + String(hum) + " %</p>";
html += "<p>VPD: " + String(vpd) + " Kpa</p>";
html += "</body></html>";
server.send(200, "text/html", html);
}

void setup()
{
Serial.begin(19200);
dht.begin();
Serial.println("Iniciando vpd controlador...");
pinMode (vpdHighLed, OUTPUT);
pinMode (vpdmiddLed, OUTPUT);
pinMode (vpdLowLed, OUTPUT);
pinMode (dehumidify, OUTPUT);
pinMode (humidify, OUTPUT);
// Conectar a la red WiFi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Conectando a la red WiFi...");
}
Serial.println("Conectado a la red WiFi");
Serial.print("CALCULANDO... ");
Serial.print("Humedad: ");
Serial.print(hum);
Serial.print(" %, Temp: ");
Serial.print(temp);
Serial.println(" Celsius");
delay(2200); //Delay 2 sec.
// Imprimir la dirección IP local
Serial.print("Dirección IP local: ");
Serial.println(WiFi.localIP());
// Configurar el servidor web
server.on("/", handleRoot);
server.begin();
}
 

Piecho

Well-known member
I recommend checking bme240 sensor. They are more accurate and relatively cheap. I used chatgpt to generate code for mine. I recommend to work with it as your assistance, even if you would like to use this code

 
Top