05 October, 2011

Agricultural Sensors - Part 3: Source Code

Read Agricultural Sensors - Part 2: Digital

Blogging generally isn't the best format for distributing code, but here it is.  I'll try to find a home for the source code in a downloadable file later.  The code comments, as well as the previous two blog posts should explain the concepts here.




/*
 * GardenSensor v0.4a
 * 
 * Reads three 10k Ohm thermistors for ambient, soil, and shade temperature
 * Reads one 1M Ohm CdS photocell for ambient light between 500-700nM
 * Reads one IR LED as a sensor for ~ 950nM infrared radiation levels

 * Reads one UV LED as a sensor for ~ 405nM ultraviolet radiation levels
 *
 * Outputs either human readable or CSV readings via serial
 *
 * TODO: Add humidity sensor, soil moisture sensor, rain detector, wireless
 *       network, and perhaps data logging to micro SD
 *
 * Thermistor code modified from example by Milan Malesevic and Zoran Stupic 2011
 * in Arduino Playground at http://www.arduino.cc/playground/ComponentLib/Thermistor2
 *
 * GuiltyPixel / James Dice - http://www.guiltypixel.com
 *
 * Garden Sensors by GuiltyPixel/James Dice is licensed under a Creative Commons
 * Attribution-NonCommercial-ShareAlike 3.0 Unported License.
 *
 */


#include <math.h>


#define DebugPRINT 0                    // Enter 0 for CSV, any other value for verbose


#define Thermistor0PIN 0                // Analog Pin 0 for Direct Sunlight Temp
#define Thermistor1PIN 1                // Analog Pin 1 for Shade Temp
#define Thermistor2PIN 2                // Analog Pin 2 for Soil Temp


#define Thermistor0COMP 0               // Compensation in deg F for thermistors
#define Thermistor1COMP 7
#define Thermistor2COMP 0


#define IR_N_SIDE 2
#define IR_P_SIDE 3
#define UV_N_SIDE 4
#define UV_P_SIDE 5


#define CdS_PIN 3


float vcc = 4.94;                       // only used for display purposes, if used
                                        // set to the measured Vcc.
float pad = 9910;                       // balance/pad resistor value, set this to
                                        // the measured resistance of your pad resistor
float thermr = 10000;                   // thermistor nominal resistance


float Thermistor(int RawADC) {
  long Resistance;  
  float Temp;  // Dual-Purpose variable to save space.


  Resistance=((1024 * pad / RawADC) - pad); 
  Temp = log(Resistance); // Saving the Log(resistance) so not to calculate  it 4 times later
  Temp = 1 / (0.001129148 + (0.000234125 * Temp) + (0.0000000876741 * Temp * Temp * Temp));
  Temp = Temp - 273.15;  // Convert Kelvin to Celsius                      


//Comment out the following line to return Celcius
  Temp = (Temp * 9.0)/ 5.0 + 32.0;                  // Convert to Fahrenheit
  return Temp;                                      // Return the Temperature
}


void setup() {
  Serial.begin(115200);
}


void loop() {
  float temp0;
  float temp1;
  float temp2;
  temp0=Thermistor(analogRead(Thermistor0PIN)) + Thermistor0COMP;       // read ADC and  convert it to temperature
  temp1=Thermistor(analogRead(Thermistor1PIN)) + Thermistor1COMP;
  temp2=Thermistor(analogRead(Thermistor2PIN)) + Thermistor2COMP;
  
  //temp0 = (temp0 * 9.0)/ 5.0 + 32.0;                  // converts to Fahrenheit if Thermistor() conversion
  //Serial.print(", Fahrenheit: ");                     // lines are not uncommented
  //Serial.print(temp0,1);                              // display Fahrenheit
  Serial.println("");                                   
  
  
  

  //------------------------------------------
  // Begin code for IR / UV capacitive sensors

  unsigned int ir;


  // Apply reverse voltage, charge up the pin and led capacitance
  pinMode(IR_N_SIDE,OUTPUT);
  pinMode(IR_P_SIDE,OUTPUT);
  digitalWrite(IR_N_SIDE,HIGH);
  digitalWrite(IR_P_SIDE,LOW);


  // Isolate the pin 2 end of the diode
  pinMode(IR_N_SIDE,INPUT);
  digitalWrite(IR_N_SIDE,LOW);  // turn off internal pull-up resistor


  // Measure how long it takes for the IR diode to drain to logical zero
  for ( ir = 0; ir < 30000; ir++) {
    if ( digitalRead(IR_N_SIDE)==0) break;
  }






  //UV LED sensor section
  unsigned int uv;


  // Apply reverse voltage, charge up the pin and led capacitance
  pinMode(UV_N_SIDE,OUTPUT);
  pinMode(UV_P_SIDE,OUTPUT);
  digitalWrite(UV_N_SIDE,HIGH);
  digitalWrite(UV_P_SIDE,LOW);


  // Isolate the pin 2 end of the diode
  pinMode(UV_N_SIDE,INPUT);
  digitalWrite(UV_N_SIDE,LOW);  // turn off internal pull-up resistor


  // Measure how long it takes for the UV diode to drain to logical zero
  for ( uv = 0; uv < 30000; uv++) {
    if ( digitalRead(UV_N_SIDE)==0) break;
  }




  
  
  //-----------------------------------------------------------
  // Begin code for Cadmuim Sulfide broad spectrum light sensor
  long light;
  int pulldown;
  pulldown=1000000;
  light=(analogRead(CdS_PIN));
  
  
  
  
  //Convert values for a roughly 0-100 scale output
  //Values derived from field testing during peak
  //summer conditions in Texas
  
    uv = 100 - (uv / 300);
    ir = 100 - (ir / 300);
    light = light / 5;
    
    
  //OUTPUT OVER SERIAL
  //If DebugPRINT value is 1 then output human
  //readable values to simplify things
  //If not, then output simple comma separated
  //values for spreadsheet applications
  if (DebugPRINT != 0)
  {
    //
    Serial.print("Temp0 Fahrenheit: "); 
    Serial.print(temp0,1);
    Serial.println("");
    Serial.print("Temp1 Fahrenheit: ");
    Serial.print(temp1,1);
    Serial.println("");
    Serial.print("Temp2 Fahrenheit: ");
    Serial.print(temp2,1);
    Serial.println("");
    Serial.print("IR = ");
    Serial.print(ir);
    Serial.println("");
    Serial.print("UV = ");
    Serial.print(uv);
    Serial.println("");
    Serial.println("");
    Serial.print("Light Level = ");
    Serial.print(light);
    Serial.println("");
    Serial.println("");
  }
  else
  {
    
    Serial.print(light);
    Serial.print(",");
    Serial.print(uv);
    Serial.print(",");
    Serial.print(ir);
    Serial.print(",");
    Serial.print(temp0);
    Serial.print(",");
    Serial.print(temp1);
    Serial.print(",");
    Serial.print(temp2);
  }
  
  delay(4000);                                      // Delay in ms until next reading 
}

0 comments:

Post a Comment