Skip to content

Instantly share code, notes, and snippets.

@rdmtinez
Created January 24, 2018 14:47

Revisions

  1. rdmtinez created this gist Jan 24, 2018.
    170 changes: 170 additions & 0 deletions Arduino
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,170 @@
    // Ricardo Martinez
    // Vinduino Sketch Re-write for WaterMark Sensor
    #include <math.h>
    #include <Time.h>
    #include <Time.h>
    #include <TimeLib.h>


    const int analogInPin1 = A0; // rename Analog Pins
    const int analogInPin2 = A1;

    int NUM_READS = 10; // number of reads by which to average

    int sensorValue1 = 0; // stores analog value read from gypsum sensor (analog)
    int sensorValue2 = 0; // stores analog value read from sensor supply

    float sensorVoltage = 0; // stores converted analog sensor value (V)
    float supplyVoltage = 0; // stores converted analog supply value

    float aveSensorValue1 = 0; // stores the averaged sensor values (analog)
    float aveSensorValue2 = 0; // stores the averaged supply values

    float r = 0; // stores the resistance (Ohms)
    int B = 0; // counter for 'for' loop

    // for testing various calibration equations
    float WPA1 = 0; // stores the Water Potential values (kPa)
    float WPA2 = 0;
    float WPA3 = 0;
    float WPA4 = 0;
    float WPA5 = 0;
    float WPA6 = 0;

    void setup() {
    // initialize serial comm at 9600 bps
    Serial.begin(9600);

    // initialize the digital pin as an output
    // Pin 6 is sensor resistance voltage supply 1
    pinMode(6, OUTPUT);

    // initialize the digital pin as an output.
    // Pin 7 is sensor resistor voltage supply 2
    pinMode(7, OUTPUT);

    // initialize the digital pin as an output.
    // Pin 8 is sensor resistor voltage supply 2
    pinMode(8, OUTPUT);

    // initialize the digital pin as an output.
    // Pin 9 is sense resistor voltage supply 2
    pinMode(9, OUTPUT);

    delay(500);

    // first line of a CSV file
    // copy and paste values to txt file and save as CSV
    // to import into data analysis software
    Serial.println("TimeStamp,avAnalogSig1,avAnalgoSig2,sensorVolt1,supplyVolt2,R,WPA1,WPA2,WPA3,WPA4,WPA5,WPA6");

    //set time
    setTime(15,06,00,23,1,2018);

    }


    void loop() {
    // main loop
    aveSensorValue1 = 0;
    aveSensorValue2 = 0;

    for(B=0; B < NUM_READS; B++){

    // set voltage supply (Pin 7) 'On' and read/store value
    digitalWrite(7, HIGH);
    delay(10);
    sensorValue1 = analogRead(analogInPin1);

    // set voltage supply 'Off'
    digitalWrite(7, LOW);
    delay(10);


    // set voltage supply (Pin 6) 'On' and read/store value
    digitalWrite(6, HIGH);
    delay(10);
    sensorValue2 = analogRead(analogInPin1);

    // set voltage supply 'Off'
    digitalWrite(6, LOW);
    delay(10);

    // add up the for-loop values to take their average
    aveSensorValue1 = aveSensorValue1 + sensorValue1;
    aveSensorValue2 = aveSensorValue2 + sensorValue2;
    }

    aveSensorValue1 = aveSensorValue1 / NUM_READS;
    aveSensorValue2 = aveSensorValue2 / NUM_READS;

    // convert the average sensor analog values into voltages
    // conversion factor 4.88 V / 1023
    sensorVoltage = aveSensorValue1 * 4.88/1023.0;
    supplyVoltage = aveSensorValue2 * 4.88/1023.0;

    //calculate resitance from the obtained values
    // the resistors in the circuit (4300 ohm)
    // Note: in the calibration equations r must be converted into kOhm (i.e. r/1000)
    r = (4300 / sensorVoltage) * (supplyVoltage - sensorVoltage);

    // These calibration equations are also dependant on temperature
    // it would be best if an measurement could be read from a sensor
    // T is measured in Celcius

    float T = 25;

    ////////////////////////////////-WPA Calibration Equations -///////////////////////////

    // WPA1 calibration equation obtained from:
    // https://www.researchgate.net/publication/237805713_WATERMARK_SOIL_MOISTURE_SENSORS_Characteristics_and_Operating_Instructions
    WPA1 = (4.093+(3.2113*(r/1000)))/(1-(0.009733*(r/1000))-(.01205*25));

    // WPA2 has 3 equations conditional on risistance and according to
    // https://www.kimberly.uidaho.edu/water/swm/Calibration_Watermark2.htm#_ftnref2

    if (r >= 0 && r < 1000){
    WPA2 = -20*((r/1000)*(1+.018*(25-T))-.55);
    }
    else if(r >=1000 && r < 8000){
    WPA2 = (-3.213*(r/1000) - 4.093) / (1-.009733*(r/1000)-.01205*T);
    }
    else if(r >= 8000){
    WPA2 = -2.246 - (5.239*(r/1000)*(1+.018*(T-24))) - .06756*pow((r/1000),2)*pow((1+.018*(T-24)),2);
    }


    // WPA3, WPA4, WPA5, WPA6 calibration equations obtained from:
    // https://www.researchgate.net/profile/Clinton_Shock/publication/228762944_Calibration_of_W_ermark_Soil_Moisture_Sensors_for_Irrigation_Management/links/55ed971408ae3e12184819e7/Calibration-of-W-ermark-Soil-Moisture-Sensors-for-Irrigation-Management.pdf

    // (5)
    WPA3 = -6.44 - ((4.196*(r/1000)-2.098) / (1-.013*T));

    // (7) for WaterMark Model 200
    WPA4 = -(4.691 + 3.559*(r/1000)) / (1-.008456*T);

    // (8) for WaterMark Model 200SS
    WPA5 = -(4.093 + 3.213*(r/1000)) / (1-.009733*(r/1000) -.01205*T);

    // (9) for WaterMark Model 200SSX
    WPA6 = -(4.734 + 2.859*(r/1000)) / (1-.01856*(r/1000) - .01316*T);

    ////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////-Prints-///////////////////////////////////////////////////
    //"DateTime,avAnalogSig1,avAnalgoSig2,sensorVolt1,supplyVolt2,R,WPA1,WPA2,WPA3,WPA4,WPA4,WPA6")

    time_t t = now();
    Serial.print(String(year())+"-"+String(month())+"-"+String(day())+" "+String(hour())+":"+String(minute())+":"+String(second())+",");
    Serial.println(String(aveSensorValue1)+","+
    String(aveSensorValue2)+","+
    String(sensorVoltage)+","+
    String(supplyVoltage)+","+
    String(r)+","+String(WPA1)+","+String(WPA2)+","+
    String(WPA3)+","+String(WPA4)+","+String(WPA5)+","+String(WPA6));


    ///////////////////////////////////////////////////////////////////////////////////

    // delay until next round of measurements (msec)
    delay(5000);
    }