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)

Thanks for bumping this up, this project has slipped to the back of my desk mess.

I put this together just now. I used linear equations for the upper and lower limit to keep things simple. I believe they hold quite accurate for normal temp range, and probably won't get super wonky in the extreme ranges of a grow room (Please double check that before using). I'm not at all worried about what happens at, say 32F or 130F, just in between.
t is temp in Celsius and h is percentage relative humidity.
if h < 2.079589*t + 11.64955; //trun humidifier on
pin ?? high;
delay 2000;
pin ?? low;

if h > 1.54172*t + 34.90501; //trun dehumidifier on
pin ?? high;
delay 2000;
pin ?? low;

I'll try to make a real program tomorrow night. But please, feedback would be great, there are many people out there who are much better at programming than I.
 
I have yet to see a VPD controller on the market under like $1k - they are usually for greenhouses. I have a Pi and watching closely.

It's the coding part that is going to take the most skill. So hopefully some smart coder comes along here.

EDIT: I have just put up a bounty on a freelancer website - willing to throw some decent money on just the software. If anyone knows a good coder please PM me.

With a Raspberry pi you can probably run a more complex formula that will give greater accuracy. But the more I ponder this project, the more I think a simple solution is fitting. There is a limited range that a room will ever be and the temperature and humidity readings will not be exactly that of the surface of the leaf. So if we can put together the simplest thing that works within a few % in normal range, good enough to use...

...Then comes the time for finding small improvements.
 
Got the code written, I'll be testing it over the next few days. If you see/find any problems or improvements, please share.

This doesn't work over about 100F.
It also has a serial print of temp and humidity to test your sensor.

Copy paste the rest of this post to try it (you'll have to download a library for the DHT22 sensor)

//VPD Hhumidity Control writen March 3rd, 2017 by Can of Bliss icmag.com , open source, please improve and share
//DO NOT USE AT HIGH TEMPS!!! AROUND 100F things go wrong!!!!
//For use with a DHT 22
// Much of this sketch is from:" Example testing sketch for various DHT humidity/temperature sensors Written by ladyada, public domain"

#include "DHT.h" //you'll need the "library" on your computer for this to work
#define DHTPIN 2 // what digital pin we're connected to
#define DHTTYPE DHT22 // DHT 22

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 = 5000;//set time on for your system in millisecondes
int humidifyTimeOn = 5000;//et time on for your system in millisecondes
int readDelay = 2000; //DHT 22 (AM2302) can only take a reading every 2 sec

// Connect pin 1 (on the left) of the sensor to +5V
// NOTE: If using a board with 3.3V logic like an Arduino Due connect pin 1
// to 3.3V instead of 5V
// Connect pin 2 of the sensor to whatever your DHTPIN is
// Connect pin 4 (on the right) of the sensor to GROUND
// Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor

DHT dht(DHTPIN, DHTTYPE);

void setup() {
Serial.begin(9600);
Serial.println("DHTxx VPD test");

dht.begin();

pinMode (vpdHighLed, OUTPUT);
pinMode (vpdLowLed, OUTPUT);
pinMode (dehumidify, OUTPUT);
pinMode (humidify, OUTPUT);
}
void loop() {

float h = dht.readHumidity();
int t = dht.readTemperature();

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

Serial.print("Humidity: ");
Serial.print(h);
Serial.print(" %\t");
Serial.print("Temperature: ");
Serial.print(t);
Serial.print(" *C ");


if ((h) < (2.079589 * t + 11.64955)){
digitalWrite (vpdHighLed, HIGH);
digitalWrite (humidify, HIGH);
delay (humidifyTimeOn);
}
if ((h) > (1.54172 * t + 34.90501)){
digitalWrite (vpdLowLed, HIGH);
digitalWrite (dehumidify, HIGH);
delay (dehumidifyTimeOn);
}

digitalWrite (vpdHighLed, LOW);
digitalWrite (vpdLowLed, LOW);
digitalWrite (dehumidify, LOW);
digitalWrite (humidify, LOW);
delay(readDelay);
}
 
Last edited:
how hard is it to set up a rasberry pi to use your code Can Of Bliss? I don't have programming skills but am pretty good with computers. I have experience with installing openElec and Rasbpian and RetroPie on Rasberry Pi's. I know how to build PCs. Would setting up my own automated controller be really difficult?
 
how hard is it to set up a rasberry pi to use your code Can Of Bliss? I don't have programming skills but am pretty good with computers. I have experience with installing openElec and Rasbpian and RetroPie on Rasberry Pi's. I know how to build PCs. Would setting up my own automated controller be really difficult?

I use a Pi as my primary computer right now, but I don't know much about how to use it.
I believe there is a way to run a C program on a Pi, but most people use python. I know next to nothing about python, but it is probably possible to convert a simple program like this. It's on my list of things to do, but no promises.
A "library" needs to be loaded so that it knows what to do with the sensor. I'm not sure how that works on the pi, so that's another step that needs to be figured out.

As to the possibility of setting up an automated controller. I would suggest you learn to write some code, you don't need to get good at it. Being able to understand a program is more important than being able to write from scratch.
Something to consider is the reliability of the controller and its failure mode. It's always wise to add backups.
 
I use a Pi as my primary computer right now, but I don't know much about how to use it.
I believe there is a way to run a C program on a Pi, but most people use python. I know next to nothing about python, but it is probably possible to convert a simple program like this. It's on my list of things to do, but no promises.
A "library" needs to be loaded so that it knows what to do with the sensor. I'm not sure how that works on the pi, so that's another step that needs to be figured out.

As to the possibility of setting up an automated controller. I would suggest you learn to write some code, you don't need to get good at it. Being able to understand a program is more important than being able to write from scratch.
Something to consider is the reliability of the controller and its failure mode. It's always wise to add backups.
what is the code you wrote intended for? Arduino? I was hoping that setting up a computerized automated controller woulld be as simple as maybe copying and pasting someone elses code and flashing/installing it to a specific device like the arduino or rasberry pi where it would just run the code upon startup. Is that not how these arduinos work?
 
I found this VPD (in millibars) equation a bit easier and was pretty spot on. A couple values were a 1/10 a decimal off from the reference chart here, possibly due to rounding.

VPD=ROUND((1-RELHUM/100)*0.611*EXP(17.27*AIRTEMP/(AIRTEMP+237.3))*10,1)

This formula could be plugged into Excel, replace RELHUM with the current RH, and AIRTEMP with the current temp (in celsius). I'm rounding the answer to 1 decimal. With this formula, I can create this chart in excel which is almost identical to the chart in the link above:

attachment.php


Once you have that number, you can pick your own range. Some sites says between 8 and 10, others have 5 to 12.

I think you may have to use POW instead of EXP for arduino though. Not sure yet as I haven't got a chance to plug this into the compiler.
 

Attachments

  • vpd1.jpg
    vpd1.jpg
    92.7 KB · Views: 67
float vpd = round((1-hum/100)*0.611*exp(17.27*cel/(cel+237.3))*10*10)/10.0;

passing in floats of "cel" = temp C and "hum" = humidity, this will return the vpd. This works as expected with an arduino or photon and returns numbers as shown in the chart given a specific temp/humidity.
 
float vpd = round((1-hum/100)*0.611*exp(17.27*cel/(cel+237.3))*10*10)/10.0;

passing in floats of "cel" = temp C and "hum" = humidity, this will return the vpd. This works as expected with an arduino or photon and returns numbers as shown in the chart given a specific temp/humidity.

Brilliant!!!!! Thank you!:tiphat:

A quick test shows this is working. I'll have to play around a little, but I'll soon post a new program based on this
 
Seems to work!

//VPD Hhumidity Control writen March 3rd, 2017 by Can of Bliss icmag.com, open source, please improve and share
//updated 3/8/'17 with formula from VintageGreen
//This has not been tested!!!!
//For use with a DHT 22

#include <Adafruit_Sensor.h>

#include <DHT_U.h>
#include <DHT.h>
#include "DHT.h" //you'll need the "library" on your computer for this to work
#define DHTPIN 2 // what digital pin we're connected to
#define DHTTYPE DHT22 // DHT 22
float vpd;
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 = 5000;//set time on for your system in millisecondes
int humidifyTimeOn = 5000;//et time on for your system in millisecondes
int readDelay = 2000; //DHT 22 (AM2302) can only take a reading every 2 sec

// Connect pin 1 (on the left) of the sensor to +5V
// NOTE: If using a board with 3.3V logic like an Arduino Due connect pin 1
// to 3.3V instead of 5V
// Connect pin 2 of the sensor to whatever your DHTPIN is
// Connect pin 4 (on the right) of the sensor to GROUND
// Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor

DHT dht(DHTPIN, DHTTYPE);

void setup() {
Serial.begin(9600);
Serial.println("DHTxx VPD test");

dht.begin();

pinMode (vpdHighLed, OUTPUT);
pinMode (vpdLowLed, OUTPUT);
pinMode (dehumidify, OUTPUT);
pinMode (humidify, OUTPUT);
}
void loop() {

float h = dht.readHumidity();
int t = dht.readTemperature();

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

vpd = ((1-h/100)*0.611*exp(17.27*t/(t+237.3))*10*10)/10.0;

if (vpd <= vpdSetLow){
digitalWrite (vpdLowLed, HIGH);
digitalWrite (humidify, HIGH);
delay (humidifyTimeOn);
Serial.print ("too wet");
}
if (vpd >= vpdSetHigh){
digitalWrite (vpdHighLed, HIGH);
digitalWrite (dehumidify, HIGH);
delay (dehumidifyTimeOn);
Serial.print ("too dry");
}

digitalWrite (vpdHighLed, LOW);
digitalWrite (vpdLowLed, LOW);
digitalWrite (dehumidify, LOW);
digitalWrite (humidify, LOW);
delay(readDelay);
}
 
Awesome! Good stuff.

One note, I noticed you're not using the round() function on the formula which is fine BTW. But if not using round, you can simplify the formula using it like this:
=(1-hum/100)*0.611*exp(17.27*cel/(cel+237.3))*10;

this will give an exact number like 13.78

to round the number to 13.8, I used some math gymnastics to force the decimal rounding which adds the extra parts to the formula.

round((1-h/100)*0.611*exp(17.27*t/(t+237.3))*10*10)/10.0;

The bold parts are not necessary if not using rounding.

Maybe for clarity, it should be:
vpd = (1-h/100)*0.611*exp(17.27*t/(t+237.3))*10; //actual formula
vpd = (vpd*10)/10.0; //math gymnastics to round vpd value to 1 decimal,if needed

I'm also going to change my auto-humidification code to use VPD as well. Right now I just pop it on if < 40% and turn off at 50% regardless of temp. Great thread!
 
Awesome! Good stuff.

One note, I noticed you're not using the round() function on the formula which is fine BTW. But if not using round, you can simplify the formula using it like this:
=(1-hum/100)*0.611*exp(17.27*cel/(cel+237.3))*10;

this will give an exact number like 13.78

to round the number to 13.8, I used some math gymnastics to force the decimal rounding which adds the extra parts to the formula.

round((1-h/100)*0.611*exp(17.27*t/(t+237.3))*10*10)/10.0;

The bold parts are not necessary if not using rounding.

Maybe for clarity, it should be:
vpd = (1-h/100)*0.611*exp(17.27*t/(t+237.3))*10; //actual formula
vpd = (vpd*10)/10.0; //math gymnastics to round vpd value to 1 decimal,if needed

I'm also going to change my auto-humidification code to use VPD as well. Right now I just pop it on if < 40% and turn off at 50% regardless of temp. Great thread!

Ahhh, i was wondering why that *10 was split out like that. I suppose I didn't think about it much. I guess I'll stick the round back in now that I understand how it was meant to work.
 
can you guys tell me what i need to google and learn in order for me to apply the code?

If you buy a Arduino Uno (or clone of one) you can run this program on it. To do that you'll just need to download "Arduino IDE" software on your computer and upload the program to the board.

I haven't yet figured out how to use a Pi for arduino programs, or how to convert a C program (programing language arduino runs) to python (language that most people seem to use on the Pi).

I am actually using a Pi as my primary computer right now and upload to the arduino with it.
 

Attachments

  • 1489009267960-1714458434.jpg
    1489009267960-1714458434.jpg
    66 KB · Views: 54

ReikoX

Knight of the BlackSvn
Nicely done. Love it when you have an idea and somebody else does all the hard work for you. :good:
 
can you guys tell me what i need to google and learn in order for me to apply the code?

Assuming you have a RaspberryPi, there are good tutorials and blogs about how to use a RPi like an Arduino with similar commands. One I found is here.

If you have all the stuff Can of Bliss posted in the beginning of thread (sensors, relays, etc) you could work on getting all of that hooked to your RPi. You should be able to find commands the are the same across Arduino and python.

Example:
Arduino: pinMode (vpdHighLed, OUTPUT);
Python:
import RPi.GPIO as GPIO
GPIO.setup(vpdHighLed, GPIO.OUT)

Google is your friend here.

Easiest way though is you can buy a cheap Arduino,sensor,relay and have Bliss send you a picture/diagram of how he wired the Arduino with the sensor and relay board. Once its all wired, copy his code to the Arduino IDE and flash your Arduino. Voilà, it should work.
 
Top