Doing math in IDE: Vapor Pressure Deficit Logger

Hey all,
I've been using my DHT22 Data Logger to keep track of the Temperature and Relative Humidity in my grow tent. I set it to take a reading every 30 seconds, and it writes the data to an SD Card. This has made life easier and given me some insight to how much certain variables effect the environment.

I had been using a MIN/MAX thermo/hygrometer for years, and I'd been keeping a few months worth of data I had collected when doing things that way, but it only gives the min and max of the Temp and RH%, along with the current measurements. No time, no date, no idea when the memory was last cleared, etc. My Data Logger (along with some help from Google Spreadsheets) has taken care of those issues though.

What I'd like to be able to do is use the values gathered by the DHT22, and have the arduino convert those two values to a single value, Vapor Pressure Deficit. To do this I would need to get the Saturated Vapor Pressure (VPsat) and actual vapor pressure (VPactual). I put the equations for VPD below
T=Temperature in Celcius and RH=Relative Humidity
VPsat (Pascals) = 610.7107.5T/(237.3+T)
VPactual = (RH
VPsat)/100
VPD = ((100 - RH)/100)*VPsat

My main questions:
Would I be able to adjust the code and have the arduino spit out the VPD along with Temp and RH? Or would that be something that would need to be done in spreadsheets? I'd like to have it done via the arduino so people can just plug in the SD card and view their VPD along with the rest of the info.

Coding is by far the most confusing part for me so far, so any help is appreciated!

#include <SD.h>
#include <SPI.h>
#include "DHT.h"

#define DHTPIN 8
#define DHTTYPE DHT22

long seconds = 00;
long minutes = 00;
long hours = 00;

int CS_pin = 10;

DHT dht(DHTPIN, DHTTYPE);
File sd_file;

void setup()  {
  Serial.begin(9600);
  pinMode(CS_pin, OUTPUT);
  dht.begin();
  // SD Card Initialization
  if (SD.begin())  {
    Serial.println("SD card is initialized. Ready to go");
  }
  else  {
    Serial.println("Failed");
    return;
  }

  sd_file = SD.open("EnvironmentData.txt", FILE_WRITE);

  if (sd_file)  {
    Serial.print("Time");
    Serial.print(",");
    Serial.print("Humidity");
    Serial.print(",");
    Serial.print("Temperature_C");
    Serial.print(",");
    Serial.print("Temperature_F");
    Serial.print(",");
    Serial.println("Heat_index");

    sd_file.print("Time");
    sd_file.print(",");
    sd_file.print("Humidity");
    sd_file.print(",");
    sd_file.print("Temperature_C");
    sd_file.print(",");
    sd_file.print("Temperature_F");
    sd_file.print(",");
    sd_file.println("Heat_index");
  }
  sd_file.close(); //closing the file
}

void loop()  {
  sd_file = SD.open("Environment.txt", FILE_WRITE);
  if (sd_file)  {
    senddata();
  }
  // if the file didn't open, print an error:
  else  {
    Serial.println("error opening file");
  }
  delay(1000);
}

void senddata()  {
  for (long seconds = 00; seconds < 60; seconds = seconds + 30)  {
    float temp = dht.readTemperature(); //Reading the temperature as Celsius and storing in temp
    float hum = dht.readHumidity();     //Reading the humidity and storing in hum
    float fah = dht.readTemperature(true);
    float heat_index = dht.computeHeatIndex(fah, hum);

    sd_file.print(hours);
    sd_file.print(":");
    sd_file.print(minutes);
    sd_file.print(":");
    sd_file.print(seconds);
    sd_file.print(",  ");
    sd_file.print(hum);
    sd_file.print(",    ");
    sd_file.print(temp);
    sd_file.print(",      ");
    sd_file.print(fah);
    sd_file.print(",      ");
    sd_file.println(heat_index);

    Serial.print(hours);
    Serial.print(":");
    Serial.print(minutes);
    Serial.print(":");
    Serial.print(seconds);
    Serial.print(",  ");
    Serial.print(hum);
    Serial.print(",    ");
    Serial.print(temp);
    Serial.print(",       ");
    Serial.print(fah);
    Serial.print(",      ");
    Serial.println(heat_index);

    if (seconds >= 30)  {
      minutes = minutes + 1;
    }

    if (minutes > 59)  {
      hours = hours + 1;
      minutes = 0;
    }

    sd_file.flush(); //saving the file

    delay(30000);
  }
  sd_file.close();   //closing the file
}

Would I be able to adjust the code and have the arduino spit out the VPD along with Temp and RH?

Yes. The Arduino can do multiplication, division, addition, and subtraction.

    float temp = dht.readTemperature(); // Reading the temperature as Celsius
    float hum = dht.readHumidity();     // Reading the relative humidity percent

    float VPsat = 610.7 * 107.5 * temp / (237.3 + temp); // Saturation vapor pressure in Pascals
    float VPactual = (hum * VPsat) / 100.0;  // Actual vapor pressure in Pascals
    float VPD = ((100.0 - hum) /100.0) * VPsat;  // Vapor Pressure Deficit in Pascals
1 Like

johnwasser:

    float temp = dht.readTemperature(); // Reading the temperature as Celsius

float hum = dht.readHumidity();     // Reading the relative humidity percent

float VPsat = 610.7 * 107.5 * temp / (237.3 + temp); // Saturation vapor pressure in Pascals
   float VPactual = (hum * VPsat) / 100.0;  // Actual vapor pressure in Pascals
   float VPD = ((100.0 - hum) /100.0) * VPsat;  // Vapor Pressure Deficit in Pascals

Awesome!!! So I'm assuming that would go into here?

void senddata()  {
  for (long seconds = 00; seconds < 60; seconds = seconds + 30)  {
    float temp = dht.readTemperature(); //Reading the temperature as Celsius and storing in temp
    float hum = dht.readHumidity();     //Reading the humidity and storing in hum
    float fah = dht.readTemperature(true);
    float heat_index = dht.computeHeatIndex(fah, hum);

    sd_file.print(hours);
    sd_file.print(":");
    sd_file.print(minutes);
    sd_file.print(":");
    sd_file.print(seconds);
    sd_file.print(",  ");
    sd_file.print(hum);
    sd_file.print(",    ");
    sd_file.print(temp);
    sd_file.print(",      ");
    sd_file.print(fah);
    sd_file.print(",      ");
    sd_file.println(heat_index);

    Serial.print(hours);
    Serial.print(":");
    Serial.print(minutes);
    Serial.print(":");
    Serial.print(seconds);
    Serial.print(",  ");
    Serial.print(hum);
    Serial.print(",    ");
    Serial.print(temp);
    Serial.print(",       ");
    Serial.print(fah);
    Serial.print(",      ");
    Serial.println(heat_index);

let's say I wanted to do away with the heat index, and replace it with VPD. Does this look right?

void senddata()  {
  for (long seconds = 00; seconds < 60; seconds = seconds + 30)  {
    float temp = dht.readTemperature(); //Reading the temperature as Celsius and storing in temp
    float hum = dht.readHumidity();     //Reading the humidity and storing in hum
    float fah = dht.readTemperature(true);
    float VPsat = 610.7 * 107.5 * temp / (237.3 + temp); // Saturation vapor pressure in Pascals
    float VPactual = (hum * VPsat) / 100.0;  // Actual vapor pressure in Pascals
    float VPD = ((100.0 - hum) /100.0) * VPsat;  // Vapor Pressure Deficit in Pascals

    sd_file.print(hours);
    sd_file.print(":");
    sd_file.print(minutes);
    sd_file.print(":");
    sd_file.print(seconds);
    sd_file.print(",  ");
    sd_file.print(hum);
    sd_file.print(",    ");
    sd_file.print(temp);
    sd_file.print(",      ");
    sd_file.print(fah);
    sd_file.print(",      ");
    sd_file.print(VPD);

    Serial.print(hours);
    Serial.print(":");
    Serial.print(minutes);
    Serial.print(":");
    Serial.print(seconds);
    Serial.print(",  ");
    Serial.print(hum);
    Serial.print(",    ");
    Serial.print(temp);
    Serial.print(",       ");
    Serial.print(fah);
    Serial.print(",      ");
    Serial.print(VPD);

Sorry if this is a basic question. Coding has been the biggest challenge for me when it comes to arduino. I'll be spending some time checking out the reference section here on the arduino site trying to learn the language so I don't have to bother you guys with my simple questions lol I appreciate you helping me out though

  for (long seconds = 00; seconds < 60; seconds = seconds + 30)  {

Seconds is a dumb name for the index variable, since the value has nothing to do with seconds, minutes, hours, or rotten tomatoes.

How many times will that loop iterate? How long will it take to iterate that number of times?

PaulS:

  for (long seconds = 00; seconds < 60; seconds = seconds + 30)  {

Seconds is a dumb name for the index variable, since the value has nothing to do with seconds, minutes, hours, or rotten tomatoes.

How many times will that loop iterate? How long will it take to iterate that number of times?

It's the duration the logger has been running. The coding was originally with a 2 second delay, but now I've got it set for a 30 second delay. I have no clue why it was done the way it was, this was a 'copy and past' project as far as coding at first, I've been slowly figuring my way around things and learning what I can. I'll post the full code, I'm open to try doing things another way if you've got some suggestions.

#include <SD.h>
#include <SPI.h>
#include "DHT.h"

#define DHTPIN 8
#define DHTTYPE DHT22

long seconds = 00;
long minutes = 00;
long hours = 00;

int CS_pin = 10;

DHT dht(DHTPIN, DHTTYPE);
File sd_file;

void setup()  {
  Serial.begin(9600);
  pinMode(CS_pin, OUTPUT);
  dht.begin();
  // SD Card Initialization
  if (SD.begin())  {
    Serial.println("SD card is initialized. Ready to go");
  }
  else  {
    Serial.println("Failed");
    return;
  }

  sd_file = SD.open("EnvironmentData.txt", FILE_WRITE);

  if (sd_file)  {
    Serial.print("Time");
    Serial.print(",");
    Serial.print("Humidity");
    Serial.print(",");
    Serial.print("Temperature_C");
    Serial.print(",");
    Serial.print("Temperature_F");
    Serial.print(",");
    Serial.println("Heat_index");

    sd_file.print("Time");
    sd_file.print(",");
    sd_file.print("Humidity");
    sd_file.print(",");
    sd_file.print("Temperature_C");
    sd_file.print(",");
    sd_file.print("Temperature_F");
    sd_file.print(",");
    sd_file.println("Heat_index");
  }
  sd_file.close(); //closing the file
}

void loop()  {
  sd_file = SD.open("data.txt", FILE_WRITE);
  if (sd_file)  {
    senddata();
  }
  // if the file didn't open, print an error:
  else  {
    Serial.println("error opening file");
  }
  delay(1000);
}

void senddata()  {
  for (long seconds = 00; seconds < 60; seconds = seconds + 30)  {
    float temp = dht.readTemperature(); //Reading the temperature as Celsius and storing in temp
    float hum = dht.readHumidity();     //Reading the humidity and storing in hum
    float fah = dht.readTemperature(true);
    float heat_index = dht.computeHeatIndex(fah, hum);

    sd_file.print(hours);
    sd_file.print(":");
    sd_file.print(minutes);
    sd_file.print(":");
    sd_file.print(seconds);
    sd_file.print(",  ");
    sd_file.print(hum);
    sd_file.print(",    ");
    sd_file.print(temp);
    sd_file.print(",      ");
    sd_file.print(fah);
    sd_file.print(",      ");
    sd_file.println(heat_index);

    Serial.print(hours);
    Serial.print(":");
    Serial.print(minutes);
    Serial.print(":");
    Serial.print(seconds);
    Serial.print(",  ");
    Serial.print(hum);
    Serial.print(",    ");
    Serial.print(temp);
    Serial.print(",       ");
    Serial.print(fah);
    Serial.print(",      ");
    Serial.println(heat_index);

    if (seconds >= 30)  {
      minutes = minutes + 1;
    }

    if (minutes > 59)  {
      hours = hours + 1;
      minutes = 0;
    }

    sd_file.flush(); //saving the file

    delay(30000);
  }
  sd_file.close();   //closing the file
}

HERE is the page I got the instructions from

SaintSkinny:
let's say I wanted to do away with the heat index, and replace it with VPD. Does this look right?

void senddata()  {

for (long seconds = 00; seconds < 60; seconds = seconds + 30)  {
   float temp = dht.readTemperature(); //Reading the temperature as Celsius and storing in temp
   float hum = dht.readHumidity();     //Reading the humidity and storing in hum
   float fah = dht.readTemperature(true);
   float VPsat = 610.7 * 107.5 * temp / (237.3 + temp); // Saturation vapor pressure in Pascals
   float VPactual = (hum * VPsat) / 100.0;  // Actual vapor pressure in Pascals
   float VPD = ((100.0 - hum) /100.0) * VPsat;  // Vapor Pressure Deficit in Pascals

sd_file.print(hours);
   sd_file.print(":");
   sd_file.print(minutes);
   sd_file.print(":");
   sd_file.print(seconds);
   sd_file.print(",  ");
   sd_file.print(hum);
   sd_file.print(",    ");
   sd_file.print(temp);
   sd_file.print(",      ");
   sd_file.print(fah);
   sd_file.print(",      ");
   sd_file.print(VPD);

Serial.print(hours);
   Serial.print(":");
   Serial.print(minutes);
   Serial.print(":");
   Serial.print(seconds);
   Serial.print(",  ");
   Serial.print(hum);
   Serial.print(",    ");
   Serial.print(temp);
   Serial.print(",       ");
   Serial.print(fah);
   Serial.print(",      ");
   Serial.print(VPD);

It looks correct to me. Does it compile? Does it produce output that looks correct? If so, it's probably working.

johnwasser:
It looks correct to me. Does it compile? Does it produce output that looks correct? If so, it's probably working.

It took a little finnagling to get it to compile and give data, but I got it spitting out numbers now... The equation from the site I used earlier isn't matching up to the VPD charts I'm seeing so I'm gonna get that figured out, but as far as the coding it seems to be working! Thanks!

1 Like

SaintSkinny:
It took a little finnagling to get it to compile and give data, but I got it spitting out numbers now... The equation from the site I used earlier isn't matching up to the VPD charts I'm seeing so I'm gonna get that figured out, but as far as the coding it seems to be working! Thanks!

I think you have the wrong equation.

Look here: https://www.weather.gov/media/epz/wxcalc/vaporPressure.pdf

Notice that in the equation at the link, something is raised to a power, but I don't see anything raised to a power in the equation you are using.

I am guessing that, somehow, 10 7.5T/(237.3+T) became 107.5T/(237.3+T) by mistake.

I think you want to be using:

float VPsat = 610.7 * pow(10, (7.5 * temp / (237.3 + temp)));