Announcement

Collapse
No announcement yet.

Arduino function to read a Vegetronix VH400 Soil Moisture Sensor

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Arduino function to read a Vegetronix VH400 Soil Moisture Sensor

    I would like to integrate this sensor with ESP8266, could I please get some help in including Arduino plugin code? I could use any pin on the motherboard.

    I was able to find some codes over the internet that I think fit what I try to accomplish.

    Thanks,
    Aldo


    // MIT License (MIT)
    //
    // Copyright (c) 2015. Michael Ewald, GeomaticsResearch LLC.
    //
    // Permission is hereby granted, free of charge, to any person obtaining a copy
    // of this software and associated documentation files (the "Software"), to deal
    // in the Software without restriction, including without limitation the rights
    // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    // copies of the Software, and to permit persons to whom the Software is
    // furnished to do so, subject to the following conditions:
    //
    // The above copyright notice and this permission notice shall be included in
    // all copies or substantial portions of the Software.
    //
    // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    // THE SOFTWARE.
    //
    // Author: Michael Ewald (mewald@geomaticsresearch.com)
    // Web: https://GeomaticsResearch.com
    // Last-updated: 2015-07-04

    float readVH400(int analogPin) {
    // This function returns Volumetric Water Content by converting the analogPin value to voltage
    // and then converting voltage to VWC using the piecewise regressions provided by the manufacturer
    // at http://www.vegetronix.com/Products/V...se-Curve.phtml

    // NOTE: You need to set analogPin to input in your setup block
    // ex. pinMode(<analogPin>, INPUT);
    // replace <analogPin> with the number of the pin you're going to read from.

    // Read value and convert to voltage
    int sensor1DN = analogRead(analogPin);
    float sensorVoltage = sensor1DN*(3.0 / 1023.0);
    float VWC;

    // Calculate VWC
    if(sensorVoltage <= 1.1) {
    VWC = 10*sensorVoltage-1;
    } else if(sensorVoltage > 1.1 && sensorVoltage <= 1.3) {
    VWC = 25*sensorVoltage-17.5;
    } else if(sensorVoltage > 1.3 && sensorVoltage <= 1.82) {
    VWC = 48.08*sensorVoltage-47.5;
    } else if(sensorVoltage > 1.82) {
    VWC = 26.32*sensorVoltage-7.89;
    }
    return(VWC);
    }






    struct VH400 {
    double analogValue;
    double analogValue_sd;
    double voltage;
    double voltage_sd;
    double VWC;
    double VWC_sd;
    };

    struct VH400 readVH400_wStats(int analogPin, int nMeasurements = 100, int delayBetweenMeasurements = 50) {
    // This variant calculates the mean and standard deviation of 100 measurements over 5 seconds.
    // It reports mean and standard deviation for the analog value, voltage, and WVC.

    // This function returns Volumetric Water Content by converting the analogPin value to voltage
    // and then converting voltage to VWC using the piecewise regressions provided by the manufacturer
    // at http://www.vegetronix.com/Products/V...se-Curve.phtml

    // NOTE: You need to set analogPin to input in your setup block
    // ex. pinMode(<analogPin>, INPUT);
    // replace <analogPin> with the number of the pin you're going to read from.

    struct VH400 result;

    // Sums for calculating statistics
    int sensorDNsum = 0;
    double sensorVoltageSum = 0.0;
    double sensorVWCSum = 0.0;
    double sqDevSum_DN = 0.0;
    double sqDevSum_volts = 0.0;
    double sqDevSum_VWC = 0.0;

    // Arrays to hold multiple measurements
    int sensorDNs[nMeasurements];
    double sensorVoltages[nMeasurements];
    double sensorVWCs[nMeasurements];

    // Make measurements and add to arrays
    for (int i = 0; i < nMeasurements; i++) {
    // Read value and convert to voltage
    int sensorDN = analogRead(analogPin);
    double sensorVoltage = sensorDN*(3.0 / 1023.0);

    // Calculate VWC
    float VWC;
    if(sensorVoltage <= 1.1) {
    VWC = 10*sensorVoltage-1;
    } else if(sensorVoltage > 1.1 && sensorVoltage <= 1.3) {
    VWC = 25*sensorVoltage-17.5;
    } else if(sensorVoltage > 1.3 && sensorVoltage <= 1.82) {
    VWC = 48.08*sensorVoltage-47.5;
    } else if(sensorVoltage > 1.82) {
    VWC = 26.32*sensorVoltage-7.89;
    }

    // Add to statistics sums
    sensorDNsum += sensorDN;
    sensorVoltageSum += sensorVoltage;
    sensorVWCSum += VWC;

    // Add to arrays
    sensorDNs[i] = sensorDN;
    sensorVoltages[i] = sensorVoltage;
    sensorVWCs[i] = VWC;

    // Wait for next measurement
    delay(delayBetweenMeasurements);
    }

    // Calculate means
    double DN_mean = double(sensorDNsum)/double(nMeasurements);
    double volts_mean = sensorVoltageSum/double(nMeasurements);
    double VWC_mean = sensorVWCSum/double(nMeasurements);

    // Loop back through to calculate SD
    for (int i = 0; i < nMeasurements; i++) {
    sqDevSum_DN += pow((DN_mean - double(sensorDNs[i])), 2);
    sqDevSum_volts += pow((volts_mean - double(sensorVoltages[i])), 2);
    sqDevSum_VWC += pow((VWC_mean - double(sensorVWCs[i])), 2);
    }
    double DN_stDev = sqrt(sqDevSum_DN/double(nMeasurements));
    double volts_stDev = sqrt(sqDevSum_volts/double(nMeasurements));
    double VWC_stDev = sqrt(sqDevSum_VWC/double(nMeasurements));

    // Setup the output struct
    result.analogValue = DN_mean;
    result.analogValue_sd = DN_stDev;
    result.voltage = volts_mean;
    result.voltage_sd = volts_stDev;
    result.VWC = VWC_mean;
    result.VWC_sd = VWC_stDev;

    // Return the result
    return(result);
    }

  • #2
    I'm stuck with this code, I would very much appreciate any help I can get. Can you help me integrating the API code within this code in the previous post?

    Comment


    • #3
      I think something like this should work with it connected to the analog pin.
      Just copy this in your API code.

      Code:
      int analogPin = A0;
      int SendDelay = 3000;
      long LastSend;
      
      void HSSetup() {
      
      
      }
      
      
      void HSloop() {
        
        if (IsConnected == true) {//If connected to HS
          if (millis() - LastSend > SendDelay) { //if Data has not been sent to HS for the last 3000ms
            SendToHS(1, readVH400(analogPin));//Send the Data to HS after getting the results from the readVH400 function below.
            LastSend = millis();//update the last time the Data was sent to HS
          }
        }
      }
      
      
      float readVH400(int analogPin) {
        // This function returns Volumetric Water Content by converting the analogPin value to voltage
        // and then converting voltage to VWC using the piecewise regressions provided by the manufacturer
        // at http://www.vegetronix.com/Products/V...se-Curve.phtml
      
        // Read value and convert to voltage
        int sensor1DN = analogRead(analogPin);
        float sensorVoltage = sensor1DN * (3.0 / 1023.0);
        float VWC;
      
        // Calculate VWC
        if (sensorVoltage <= 1.1) {
          VWC = 10 * sensorVoltage - 1;
        } else if (sensorVoltage > 1.1 && sensorVoltage <= 1.3) {
          VWC = 25 * sensorVoltage - 17.5;
        } else if (sensorVoltage > 1.3 && sensorVoltage <= 1.82) {
          VWC = 48.08 * sensorVoltage - 47.5;
        } else if (sensorVoltage > 1.82) {
          VWC = 26.32 * sensorVoltage - 7.89;
        }
        return (VWC);
      }
      Greig.
      Zwave = Z-Stick, 3xHSM100 7xACT ZDM230, 1xEverspring SM103, 2xACT HomePro ZRP210.
      X10 = CM12U, 2xAM12, 1xAW10, 1 x TM13U, 1xMS13, 2xHR10, 2xSS13
      Other Hardware = ADI Ocelot + secu16, Global Cache GC100, RFXtrx433, 3 x Foscams.
      Plugings = RFXcom, ActiveBackup, Applied Digital Ocelot, BLDeviceMatrix, BLGarbage, BLLAN, Current Cost, Global Cache GC100,HSTouch Android, HSTouch Server, HSTouch Server Unlimited, NetCAM, PowerTrigger, SageWebcamXP, SqueezeBox, X10 CM11A/CM12U.
      Scripts =
      Various

      Comment


      • #4
        You are the best, I can't wait to test it out. Knowing that your time is very limited, I don't know how to repay you, thank you.

        Sent from my SM-G935V using Tapatalk

        Comment


        • #5
          Hi Greig,
          It work fantastically, I can not thank you enough, you make it easy for people that are just approaching Arduino, I was able to get it up to speed with you in few weeks, unfortunately still lot to learn :-)

          I have attached a picture of the final product so perhaps others may use it. I'm putting the device in a Raspberry case, it fit nice. Not sure what others use when they implement these in production. I guess they do what I'm doing. I saw someone using a 3D Printer to print the case, that was very nice.

          The end result is between - 1 to 19 when it is immerse in the water. In the soil it is about 14.

          Thanks,
          Aldo
          Attached Files

          Comment


          • #6
            Great news. Have fun!
            Zwave = Z-Stick, 3xHSM100 7xACT ZDM230, 1xEverspring SM103, 2xACT HomePro ZRP210.
            X10 = CM12U, 2xAM12, 1xAW10, 1 x TM13U, 1xMS13, 2xHR10, 2xSS13
            Other Hardware = ADI Ocelot + secu16, Global Cache GC100, RFXtrx433, 3 x Foscams.
            Plugings = RFXcom, ActiveBackup, Applied Digital Ocelot, BLDeviceMatrix, BLGarbage, BLLAN, Current Cost, Global Cache GC100,HSTouch Android, HSTouch Server, HSTouch Server Unlimited, NetCAM, PowerTrigger, SageWebcamXP, SqueezeBox, X10 CM11A/CM12U.
            Scripts =
            Various

            Comment

            Working...
            X