A simple Arduino based sensor monitoring platform for Hydroponics

linkedinrssyoutubeinstagram
image_pdfimage_print

Last time I posted about automation I talked about how I use an Arduino to automate the monitoring and management of my home hydroponic system. Today I want to talk about how you can build an Arduino based station to monitor the most important variables of your hydroponic crop without having to solder anything, use complicated bread board setups or learn to how to do any coding. I will walk you through some of the steps to build the system, talk about the parts you need and show you the code you need to run to have this setup work.

A basic sensor monitoring application for hydroponics should be able to get the most critical information needed to grow a crop successfully. The basic variables you would want to monitor to achieve this goal would be: temperature, humidity, carbon dioxide concentration, pH and electrical conductivity. An Arduino micro-controller can help you achieve all these goals at a reduced cost when compared with commercially available monitoring solutions of the same quality.

The list above contains all the pieces you need to get this to work. This includes the Arduino plus an LCD display that we will use to be able to read the information we obtain from the sensors. I have included links to the pieces at the dfrobot site (one of my favorite sources for DIY electronics) but you can definitely get them elsewhere if you prefer. The pH sensor included here is of industrial quality while the EC sensor has a lower quality level. However I have been able to use both for extended periods of time without anything else than a calibration around once every 2 months. If you want you can also purchase an industrial quality EC probe if you find the prove from the included Gravity kit to be insufficient for your needs.

The cool thing about this setup is that the LCD screen already contains all the connections we need for the sensors. The bottom part contains numbered analog inputs while the left part contains numbered digital inputs. In this setup we have two digital sensors – the DHT22 humidity/temperature sensor and the solution temperature sensor that comes with the EC sensor – and three analog sensors, which are pH, EC and CO2. I have put some text on the image to show you exactly where you should connect the sensors according to the code, make sure the orders of the colors on the wires match the colors on the connector in the LCD screen. The Arduino code contains some defines with the pins for each sensor so you can just change those numbers if you want to connect the sensors in different places.

//Libraries
#include <DHT.h>;
#include <U8glib.h>
#include <stdio.h>
#include <OneWire.h>
#include <Wire.h>
#include <Arduino.h>
#include <Adafruit_Sensor.h>

//PINS
#define DHT_PIN        5          // DHT pin
#define DHTTYPE        DHT22      // DHT 22  (AM2302)
#define PH_PIN         2          //pH meter pin
#define CO2_PIN        3          //ORP meter pin
#define EC_PIN         1          //EC meter pin
#define DS18B20_PIN    6          //EC solution temperature pin

// AVERAGING VALUES
#define MEDIAN_SAMPLE 8
#define MEASUREMENTS_TAKEN 100

// EC - solution temperature variables
#define StartConvert 0
#define ReadTemperature 1

// EC values // CHANGE THESE PARAMETERS FOR EC PROBE CALIBRATION
#define EC_PARAM_A 0.00754256

//pH values // CHANGE THESE PARAMETERS FOR PH PROBE CALIBRATION
#define PH_PARAM_A 1.0
#define PH_PARAM_B 0.0

#define XCOL_SET 55
#define XCOL_SET2 65
#define XCOL_SET_UNITS 85

//--------------------------

DHT dht(DHT_PIN, DHTTYPE); 
U8GLIB_NHD_C12864 u8g(13, 11, 10, 9, 8); 
unsigned long int avgValue;  
float b, phValue;
int buf[MEASUREMENTS_TAKEN],tmp;
int chk;
float hum;  
float temp;
unsigned int AnalogAverage = 0,averageVoltage=0; 
float solution_temp,ECcurrent; 
unsigned int levelAverage;
float co2;
OneWire ds(DS18B20_PIN); 

//--------------------------

void draw() {
  u8g.setFont(u8g_font_04b_03); 
  
  u8g.drawStr( 0,11,"Temp:");
  u8g.setPrintPos(XCOL_SET,11);
  u8g.print(temp); 
  u8g.drawStr( XCOL_SET_UNITS, 11,"C" ); 
  
  u8g.drawStr(0,21,"Humidity:");
  u8g.setPrintPos(XCOL_SET,21);
  u8g.print(hum);
  u8g.drawStr( XCOL_SET_UNITS,21,"%" );
  
  u8g.drawStr(0,31,"pH:");
  u8g.setPrintPos(XCOL_SET,31);
  u8g.print(phValue);
  
  u8g.drawStr(0,41,"EC:");
  u8g.setPrintPos(XCOL_SET,41);
  u8g.print(ECcurrent);
  u8g.drawStr( XCOL_SET_UNITS,41,"mS/cm" );
  
  u8g.drawStr(0,51,"Sol.Temp:");
  u8g.setPrintPos(XCOL_SET,51);
  u8g.print(solution_temp);
  u8g.drawStr( XCOL_SET_UNITS,51,"C" );
  
  u8g.drawStr(0,61,"CO2:");
  u8g.setPrintPos(XCOL_SET,61);
  u8g.print(co2);
  u8g.drawStr( XCOL_SET_UNITS,61,"ppm" );
  
}

float TempProcess(bool ch)
{
  static byte data[12];
  static byte addr[8];
  static float TemperatureSum;
  if(!ch){
          if ( !ds.search(addr)) {
              ds.reset_search();
              return 0;
          }      
          if ( OneWire::crc8( addr, 7) != addr[7]) {
              return 0;
          }        
          if ( addr[0] != 0x10 && addr[0] != 0x28) {
              return 0;
          }      
          ds.reset();
          ds.select(addr);
          ds.write(0x44,1); 
  }
  else{  
          byte present = ds.reset();
          ds.select(addr);    
          ds.write(0xBE);           
          for (int i = 0; i < 9; i++) { 
            data[i] = ds.read();
          }         
          ds.reset_search();           
          byte MSB = data[1];
          byte LSB = data[0];        
          float tempRead = ((MSB << 8) | LSB); 
          TemperatureSum = tempRead / 16;
    }
          return TemperatureSum;  
}

void calculateAnalogAverage(int pin){
 AnalogAverage = 0;
  
  for(int i=0;i<MEASUREMENTS_TAKEN;i++)       
  { 
    buf[i]=analogRead(pin);
    delay(10);
  }
  for(int i=0;i<MEASUREMENTS_TAKEN-1;i++)        
  {
    for(int j=i+1;j<MEASUREMENTS_TAKEN;j++)
    {
      if(buf[i]>buf[j])
      {
        tmp=buf[i];
        buf[i]=buf[j];
        buf[j]=tmp;
      }
    }
  }
  
  avgValue=0;
  for(int i=(MEASUREMENTS_TAKEN/2)-(MEDIAN_SAMPLE/2);i<(MEASUREMENTS_TAKEN/2)+(MEDIAN_SAMPLE/2);i++){                     
    avgValue+=buf[i];
  }
    
  AnalogAverage = avgValue/MEDIAN_SAMPLE ; 
}

void read_pH(){
  
  calculateAnalogAverage(PH_PIN);
  phValue=(float)AnalogAverage*5.0/1024; 
  phValue=PH_PARAM_A*phValue+PH_PARAM_B;    
}

void read_EC(){
  
  calculateAnalogAverage(EC_PIN);
  
  solution_temp = TempProcess(ReadTemperature);  
  TempProcess(StartConvert);                   
  
  averageVoltage=AnalogAverage*(float)5000/1024;
  float TempCoefficient=1.0+0.0185*(solution_temp-25.0);   
  float CoefficientVolatge=(float)averageVoltage*TempCoefficient;   
  
  ECcurrent=EC_PARAM_A*CoefficientVolatge;     
}

void read_CO2(){
  float voltage;
  float voltage_difference;
  calculateAnalogAverage(CO2_PIN); 
  voltage = AnalogAverage*(5000/1024.0); 
  
  if(voltage == 0)
  {
    co2=-100.0;
  }
  else if(voltage < 400)
  {
    co2=0.0;
  }
  else
  {
    voltage_difference=voltage-400;
    co2=voltage_difference*50.0/16.0;
  }
}

void setup()
{
    pinMode(13,OUTPUT);  
    Serial.begin(9600);
    
    dht.begin();
    u8g.setContrast(0);
    u8g.setRot180();
    TempProcess(StartConvert);   
}

void loop()
{
 
  digitalWrite(13, HIGH);       
  delay(800);
  digitalWrite(13, LOW);   
    
  hum = dht.readHumidity();
  temp= dht.readTemperature(); 
  read_pH();
  read_EC();
  read_CO2();

  u8g.firstPage();
    do  {
      draw();
    } 
      while( u8g.nextPage() );          
      
}

After you connect the sensors you can then upload the code above using the Arduino IDE to your Arduino via USB. You will need to install the following Arduino libraries to get it to compile and upload:

After you upload this to your Arduino it should start and show you a screen with the temperature, humidity, pH, EC and carbon dioxide readings. The carbon dioxide concentration might show as -100 in the beginning, which simply means that the sensor is heating up (it requires a few minutes before it can start giving readings).

It is also worth noting that you should calibrate your pH sensor. To do this you should read the pH of a 7.0 buffer (M7) – record the value you get – and then repeat the process with a pH 4.0 buffer (M4). You can then change the PH_PARAM_A and PH_PARAM_B values in the code (right at the beginning) to make the sensor match your measurements. The PH_PARAM_A parameter should be equal to 3/(M7-M4) while PH_PARAM_B should be 7-M7*PH_PARAM_A. If you ever need to recalibrate set PH_PARAM_A to 1 and PH_PARAM_B to 0 and repeat the process. For the EC sensor you should perform a calibration using the 1.412 mS/cm solution that comes with the sensor and then change EC_PARAM_A so that your sensor matches this reading (1.412/(MEC/0.00754256)).

With this new monitoring station you should now have a powerful tool to monitor your hydroponic system and make sure everything is where you want it. Of course making the arduino intereact with a computer to record these values and then implementing control mechanisms using fans, peristaltic pumps, water pumps, humidifiers/dehumidifiers and other appliances is the next step in complexity.

 

Facebooktwitterredditpinterestlinkedin

11 Comments

  • May 5, 2017 @ 8:08 am

    Hi Dr. Fernandez, with regards to the attached PH and EC sensors, what is the size of the nutrient tank in your set-up? thanks

    • admin
      May 5, 2017 @ 10:40 am

      Hi Remo,

      Thanks for writing. The tank in my home setup is around 5 gallons. However this will work with a tank of any size provided the sensor tips can be adequately submerged. I hope this answers your question,

      Best regards,

      Daniel

      • May 6, 2017 @ 2:46 am

        Hello Dr. Fernandez, yes thanks for the reply. Definitely, a helpful topic for automation lovers.

  • June 21, 2017 @ 10:04 am

    Hi!
    Will this EC sensor be able to be submerged 24/7?
    It seems on the DFRobit site that many people recommended against that.
    Thanks for a great article!

    Kind regards,
    Lukas

    • admin
      June 22, 2017 @ 1:27 pm

      Hi Lukas,

      I have used this EC sensor for 24/7 readings, although the sensor is NOT fully submerged (just the measuring tip). This sensor will not work for 24/7 total submersion. If you need that you should use this atlas probe instead: https://www.atlas-scientific.com/product_pages/probes/ec_k10.html. Thanks for writing,

      Best Regards,

      Daniel

  • November 20, 2017 @ 10:24 am

    how can i calibrate my EC sensor can you give me an example for how to change the EC_PARAM_A according to the measurement of sensor

  • November 24, 2017 @ 8:29 pm

    Will this work with using something like a bluelab PH probe?

  • December 9, 2017 @ 4:29 pm

    Very cool! Thanks for writing this up. The Uno R3 is out of stock at your URL, would I just Google for “Arduino Uno R3”?…
    A couple of questions:
    1) Can VPD be calculated and printed on the screen?;
    2) Can a quantum sensor, like a Li-COR, be connected?;
    3) Can a humidifier & dehumidifier be controlled based on preset low/high vales for RH (or better, VPD)?
    4) If yes is the answer to any of those questions, would it be for-hire work, or maybe a new blog post?

    • admin
      December 10, 2017 @ 5:06 am

      1) Yes
      2) Probably yes, but not very easily. Since these sensors follow a proprietary standard it would take a lot of hacking to get it to work.
      3) Yes.
      4) It would definitely be for-hire work.

  • February 18, 2018 @ 8:41 pm

    Is it possible to turn the EC and PH sensors on and off, when both are in the water the EC sensor seems to be altering the results of the pH sensor?

  • March 28, 2019 @ 11:14 am

    Do you know of an enclosure to protect and mount the platform? Great project btw. Any updates?

Leave a Reply

Your email address will not be published. Required fields are marked *

Subscribe Today!
Receive our FREE blog post updates and monthly newsletter
Thanks for signing up. You must confirm your email address before we can send you. Please check your email and follow the instructions.
We respect your privacy. Your information is safe and will never be shared.
Don't miss out. Subscribe today.
×
×
WordPress Popup Plugin