Skip to content
  • MySensors
  • OpenHardware.io
  • Categories
  • Recent
  • Tags
  • Popular
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo
  1. Home
  2. Hardware
  3. Soil moisture sensor - strange readings

Soil moisture sensor - strange readings

Scheduled Pinned Locked Moved Hardware
12 Posts 5 Posters 3.3k Views 6 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • TeknorT Offline
    TeknorT Offline
    Teknor
    wrote on last edited by
    #1

    Hi all,
    I have a straight forward MySensor setup with a soil moisture sensor. I am currently at a trail and error stage, but plan to impement this in my green house for seasoning plants.

    Problem is I get strange readings in Domoticz. Very little difference in the readings between the dry and wet soil. Also the readings varies a lot.

    0_1511622977559_soil.png image url)

    alt text

    (I have not tried to tune the knob on the sensor board.)

    Is it normal with this variation and little difference between wet and dry?

    The sketch is the standard MySensor code described in the build-section of this site.

    All help is highly appreciated.

    M 1 Reply Last reply
    0
    • gohanG Offline
      gohanG Offline
      gohan
      Mod
      wrote on last edited by
      #2

      Have you tried with some different soil types? The trim pot on the sensors should set the threshold for the digital output, it shouldn't change the analog readings

      YveauxY 1 Reply Last reply
      0
      • TeknorT Teknor

        Hi all,
        I have a straight forward MySensor setup with a soil moisture sensor. I am currently at a trail and error stage, but plan to impement this in my green house for seasoning plants.

        Problem is I get strange readings in Domoticz. Very little difference in the readings between the dry and wet soil. Also the readings varies a lot.

        0_1511622977559_soil.png image url)

        alt text

        (I have not tried to tune the knob on the sensor board.)

        Is it normal with this variation and little difference between wet and dry?

        The sketch is the standard MySensor code described in the build-section of this site.

        All help is highly appreciated.

        M Offline
        M Offline
        manutremo
        wrote on last edited by
        #3

        @Teknor The sketch in that page is not designed to work with type of sensor, but with one with a voltage divider. The last comment in that page explains it.

        1 Reply Last reply
        0
        • TeknorT Offline
          TeknorT Offline
          Teknor
          wrote on last edited by
          #4

          Thanks for the answers, not sure if I am closer to a solution. I am using digital output from the sensor according the the Mysensors description. Is it recommended to use analog output, if so, are there any sketches I can use "out-of-the-box"?

          I have a FC28 sensor, not a YL-sensor mentioned above.

          alt text

          M 1 Reply Last reply
          0
          • gohanG gohan

            Have you tried with some different soil types? The trim pot on the sensors should set the threshold for the digital output, it shouldn't change the analog readings

            YveauxY Offline
            YveauxY Offline
            Yveaux
            Mod
            wrote on last edited by
            #5

            @Teknor @gohan The sketch on the build page is for analog readout, while the wiring section describes a digital connection -- very confusing :pig_nose:
            You can also get some inspiration from the soil moisture sensor I built for the dollhouse

            http://yveaux.blogspot.nl

            1 Reply Last reply
            0
            • TeknorT Teknor

              Thanks for the answers, not sure if I am closer to a solution. I am using digital output from the sensor according the the Mysensors description. Is it recommended to use analog output, if so, are there any sketches I can use "out-of-the-box"?

              I have a FC28 sensor, not a YL-sensor mentioned above.

              alt text

              M Offline
              M Offline
              manutremo
              wrote on last edited by
              #6

              @Teknor I had the same sensor, just threw the board away and used the wires and the probe. Then I hooked it with a voltage divider using a 10k resistor. You can use the sketch I shared in the same comment for inspiration, or the more recent one here

              This sketch does voltage flipping which means it takes two readings with different polarization to avoid corrosion. Without it, the probe would last only a few weeks.

              You may of course continue using the comparator board if you just want to set a warning when moisture level is too low.

              1 Reply Last reply
              0
              • TeknorT Offline
                TeknorT Offline
                Teknor
                wrote on last edited by Teknor
                #7

                Thanks @manutremo . Will give it a try, and use your sample sktetch. Just to get things right, you mean just keep the "fork"? Any documentation on the HW setup, or just a 10k resistor?

                M 1 Reply Last reply
                0
                • TeknorT Teknor

                  Thanks @manutremo . Will give it a try, and use your sample sktetch. Just to get things right, you mean just keep the "fork"? Any documentation on the HW setup, or just a 10k resistor?

                  M Offline
                  M Offline
                  manutremo
                  wrote on last edited by
                  #8

                  @Teknor Yes I meant keep the fork :blush:

                  The setup is simple: a voltage divider involves 2 resistors in series between Vcc and GND, and a sampling point in between them. In your case, the fork will be one of the resistors. Then you need to measure the voltage in the middle connection between the fork and the 10k resistor, and connect it to an analog pin in the arduino.

                  You will find a good description with images here.

                  I just made a change to that setup (in addition to using a 3.3v arduino instead of 5v) in that instead of using Vcc and GND, I used two digital pins (4 and 7 in my case) which I enable and disable so I can polarize the fork in one direction or the opposite. Be aware that the resistor should be connected to pin in this case, and the fork to pin 7; otherwise the formula of the voltage divider needs to be modified.

                  Some sources also recommend bypassing the measuring point to GND using a small cap to avoid noise in that point, but I haven't experienced that problem.

                  Then you just need to calibrate the sensor by putting the fork into a glass of water and then out in the air, and typing the values you get into the appropriate define's.

                  M 1 Reply Last reply
                  0
                  • M manutremo

                    @Teknor Yes I meant keep the fork :blush:

                    The setup is simple: a voltage divider involves 2 resistors in series between Vcc and GND, and a sampling point in between them. In your case, the fork will be one of the resistors. Then you need to measure the voltage in the middle connection between the fork and the 10k resistor, and connect it to an analog pin in the arduino.

                    You will find a good description with images here.

                    I just made a change to that setup (in addition to using a 3.3v arduino instead of 5v) in that instead of using Vcc and GND, I used two digital pins (4 and 7 in my case) which I enable and disable so I can polarize the fork in one direction or the opposite. Be aware that the resistor should be connected to pin in this case, and the fork to pin 7; otherwise the formula of the voltage divider needs to be modified.

                    Some sources also recommend bypassing the measuring point to GND using a small cap to avoid noise in that point, but I haven't experienced that problem.

                    Then you just need to calibrate the sensor by putting the fork into a glass of water and then out in the air, and typing the values you get into the appropriate define's.

                    M Offline
                    M Offline
                    Markus.
                    wrote on last edited by Markus.
                    #9

                    @manutremo
                    ….I used two digital pins (4 and 7 in my case) which I enable and disable so I can polarize the fork in one direction or the opposite. Be aware that the resistor should be connected to pin in this case, and the fork to pin 7; otherwise the formula of the voltage divider needs to be modified..

                    Hi Manutremo,
                    The resistor must be connected to D4 in your example? and the fork "end" to D7? The sampling pint then to A0? Or a equivalent Analog Input..?

                    Thanks

                    Markus

                    M 1 Reply Last reply
                    0
                    • M Markus.

                      @manutremo
                      ….I used two digital pins (4 and 7 in my case) which I enable and disable so I can polarize the fork in one direction or the opposite. Be aware that the resistor should be connected to pin in this case, and the fork to pin 7; otherwise the formula of the voltage divider needs to be modified..

                      Hi Manutremo,
                      The resistor must be connected to D4 in your example? and the fork "end" to D7? The sampling pint then to A0? Or a equivalent Analog Input..?

                      Thanks

                      Markus

                      M Offline
                      M Offline
                      Markus.
                      wrote on last edited by Markus.
                      #10

                      Would be great If someone can check this Sketch.Because its giving me Always the same results

                      Value1=219 27.37
                      Value2=0 100.00
                      Result = 63.69% (6.51cb)
                      VCC = 3.39 Volts
                      VCC% = 32 %
                      
                      #define MY_DEBUG
                      #define MY_SPECIAL_DEBUG
                      #define MY_SIGNAL_REPORT_ENABLED
                      
                      // Enable and select radio type attached 
                      //#define MY_RADIO_NRF24
                      #define MY_RADIO_RFM69
                      //#define MY_RS485
                      #define MY_RFM69_FREQUENCY RFM69_868MHZ
                      
                      #define MY_BAUD_RATE 38400
                      
                      #include <MySensors.h>
                      #include <SPI.h>
                      #include <Vcc.h>
                      #include <Streaming.h>
                      #include <math.h>
                      
                      //#define SLEEP_TIME_15min  900000    // 15min x 60s = 900000 ms -13% = 783000                (my arduinos show a delay of 8s/min = 13%)
                      #define SLEEP_TIME_15min  5000
                      #define SLEEP_TIME_1h     3600000   // 1 h = 1*60*60000 = 3600000 ms -13% = 3132000 ms
                      #define SLEEP_TIME_2h     7200000   // 2 h = 2*60*60000 = 7200000 ms -13% = 6264000 ms
                      #define SLEEP_TIME_3h     10800000  // 3 h = 3*60*60000 = 10800000 ms -13% = 9396000 ms
                      
                      #define VERSION "3.0"
                      #define PIN_ALIM1 2                                   // Connect to input of resistor
                      #define PIN_ALIM2 6                                   // Connect to input of measuring probe
                      #define PIN_LECTURA A1
                      
                      #define AGUA_DIR            800.0
                      #define AGUA_INV            160.0
                      #define AIRE_DIR            0.0
                      #define AIRE_INV            1023.0
                      #define TIEMPO_LECTURA      10
                      #define MAX_REP_LECTURA     20
                      #define MAX_REPORTING_LOOPS 4
                      
                      // Battery calibration (Li-ion)
                      const float VccMin   = 3.0;                         // Minimum expected Vcc level, in Volts.
                      const float VccMax   = 4.2;                         // Maximum expected Vcc level, in Volts.
                      const float VccCorrection = 3.82/3.74;              // Measured Vcc by multimeter divided by reported Vcc
                      
                      #define CHILD_MOIST_ID 1
                      MyMessage msgmoist(CHILD_MOIST_ID, V_LEVEL);
                      Vcc vcc(VccCorrection);
                      
                      int count=0;
                      signed int oldv1=0, oldv2=0;
                      float oldresultcb=0;
                      
                      void setup() {
                      #ifdef MY_DEBUG
                        Serial.begin(38400);
                      #endif
                        analogReference(DEFAULT);
                        pinMode(PIN_LECTURA, INPUT);
                        pinMode(PIN_ALIM1, OUTPUT);
                        pinMode(PIN_ALIM2, OUTPUT);
                      }
                      
                      void presentation(){
                          sendSketchInfo("Sensor de humedad", VERSION);
                          present(CHILD_MOIST_ID, S_MOISTURE, "Humedad suelo");
                      }
                      
                      void loop()
                      {
                        {
                         signed int value1=0, value2=0, i=0;
                          float result1, result2, resultp, resultcb;
                      
                          //Loop until readings are stable or max number of readings is reached
                          do {
                            oldv1=value1; oldv2=value2;
                            wait(TIEMPO_LECTURA);
                            digitalWrite(PIN_ALIM1, HIGH);
                            digitalWrite(PIN_ALIM2, LOW);
                            wait(TIEMPO_LECTURA);
                            value1 = analogRead(PIN_LECTURA);
                      
                            digitalWrite(PIN_ALIM1, LOW);
                            digitalWrite(PIN_ALIM2, HIGH);
                            wait(TIEMPO_LECTURA);
                            value2 = analogRead(PIN_LECTURA);;
                            digitalWrite(PIN_ALIM1, LOW);
                            digitalWrite(PIN_ALIM2, LOW);
                          } while (((oldv1 != value1) && (oldv2 != value2)) || (i == MAX_REP_LECTURA));
                      
                      /*
                            0-10 Saturated Soil. Occurs for a day or two after irrigation 
                            10-20 Soil is adequately wet (except coarse sands which are drying out at this range) 
                            20-60 Usual range to irrigate or water (most soils except heavy clay soils). 
                            60-100 Usual range to irrigate heavy clay soils 
                            100-200 Soil is becoming dangerously dry
                          */
                          result1=constrain(value1/(AGUA_DIR-AIRE_DIR)*100.0, 1, 100);
                          result2=constrain(100-(value2-AGUA_INV)/(AIRE_INV-AGUA_INV)*100.0,1,100);
                          resultp = (result1+result2)/2.0;
                          resultcb = resultcb + constrain(square((-2.96699 + 351.395/resultp)),0,200);                           //Equation fit using stat software
                          count++;
                        
                          //Send the data - only if moisture changed to save battery (send anyways once every 4 readings). If moisture sent, send battery level.
                          if ((oldresultcb!=resultcb) || (count==MAX_REPORTING_LOOPS)) {
                            send(msgmoist.set((unsigned int)resultcb));
                            oldresultcb=resultcb;
                            //Measure battery voltage and send level
                            float v = vcc.Read_Volts();  
                            int p = vcc.Read_Perc(VccMin, VccMax);
                            p=constrain(p,0,100);
                            sendBatteryLevel(p);
                            #ifdef MY_DEBUG
                              Serial << "Value1=" << value1 << " " << result1 << endl << "Value2=" << value2 << " " << result2 << endl << "Result = " << resultp << "% (" << resultcb << "cb)" << endl;
                              Serial << "VCC = " << v << " Volts" << endl << "VCC% = " << p << " %" << endl;
                            #endif
                          }
                        
                          if (count==MAX_REPORTING_LOOPS) count=0;
                          //sleep(SLEEP_TIME_3h, true);
                          sleep(SLEEP_TIME_15min, true);
                        }
                      }
                      

                      its connected on following Schema

                      D2 -> Input 10K resistor-> Output 10K Input Fork and A1-> Output fork -> D6
                      I am using a Adruino pro mini 3,3V on an Easy PCB Board.

                      Many thanks

                      Markus

                      M 1 Reply Last reply
                      0
                      • M Markus.

                        Would be great If someone can check this Sketch.Because its giving me Always the same results

                        Value1=219 27.37
                        Value2=0 100.00
                        Result = 63.69% (6.51cb)
                        VCC = 3.39 Volts
                        VCC% = 32 %
                        
                        #define MY_DEBUG
                        #define MY_SPECIAL_DEBUG
                        #define MY_SIGNAL_REPORT_ENABLED
                        
                        // Enable and select radio type attached 
                        //#define MY_RADIO_NRF24
                        #define MY_RADIO_RFM69
                        //#define MY_RS485
                        #define MY_RFM69_FREQUENCY RFM69_868MHZ
                        
                        #define MY_BAUD_RATE 38400
                        
                        #include <MySensors.h>
                        #include <SPI.h>
                        #include <Vcc.h>
                        #include <Streaming.h>
                        #include <math.h>
                        
                        //#define SLEEP_TIME_15min  900000    // 15min x 60s = 900000 ms -13% = 783000                (my arduinos show a delay of 8s/min = 13%)
                        #define SLEEP_TIME_15min  5000
                        #define SLEEP_TIME_1h     3600000   // 1 h = 1*60*60000 = 3600000 ms -13% = 3132000 ms
                        #define SLEEP_TIME_2h     7200000   // 2 h = 2*60*60000 = 7200000 ms -13% = 6264000 ms
                        #define SLEEP_TIME_3h     10800000  // 3 h = 3*60*60000 = 10800000 ms -13% = 9396000 ms
                        
                        #define VERSION "3.0"
                        #define PIN_ALIM1 2                                   // Connect to input of resistor
                        #define PIN_ALIM2 6                                   // Connect to input of measuring probe
                        #define PIN_LECTURA A1
                        
                        #define AGUA_DIR            800.0
                        #define AGUA_INV            160.0
                        #define AIRE_DIR            0.0
                        #define AIRE_INV            1023.0
                        #define TIEMPO_LECTURA      10
                        #define MAX_REP_LECTURA     20
                        #define MAX_REPORTING_LOOPS 4
                        
                        // Battery calibration (Li-ion)
                        const float VccMin   = 3.0;                         // Minimum expected Vcc level, in Volts.
                        const float VccMax   = 4.2;                         // Maximum expected Vcc level, in Volts.
                        const float VccCorrection = 3.82/3.74;              // Measured Vcc by multimeter divided by reported Vcc
                        
                        #define CHILD_MOIST_ID 1
                        MyMessage msgmoist(CHILD_MOIST_ID, V_LEVEL);
                        Vcc vcc(VccCorrection);
                        
                        int count=0;
                        signed int oldv1=0, oldv2=0;
                        float oldresultcb=0;
                        
                        void setup() {
                        #ifdef MY_DEBUG
                          Serial.begin(38400);
                        #endif
                          analogReference(DEFAULT);
                          pinMode(PIN_LECTURA, INPUT);
                          pinMode(PIN_ALIM1, OUTPUT);
                          pinMode(PIN_ALIM2, OUTPUT);
                        }
                        
                        void presentation(){
                            sendSketchInfo("Sensor de humedad", VERSION);
                            present(CHILD_MOIST_ID, S_MOISTURE, "Humedad suelo");
                        }
                        
                        void loop()
                        {
                          {
                           signed int value1=0, value2=0, i=0;
                            float result1, result2, resultp, resultcb;
                        
                            //Loop until readings are stable or max number of readings is reached
                            do {
                              oldv1=value1; oldv2=value2;
                              wait(TIEMPO_LECTURA);
                              digitalWrite(PIN_ALIM1, HIGH);
                              digitalWrite(PIN_ALIM2, LOW);
                              wait(TIEMPO_LECTURA);
                              value1 = analogRead(PIN_LECTURA);
                        
                              digitalWrite(PIN_ALIM1, LOW);
                              digitalWrite(PIN_ALIM2, HIGH);
                              wait(TIEMPO_LECTURA);
                              value2 = analogRead(PIN_LECTURA);;
                              digitalWrite(PIN_ALIM1, LOW);
                              digitalWrite(PIN_ALIM2, LOW);
                            } while (((oldv1 != value1) && (oldv2 != value2)) || (i == MAX_REP_LECTURA));
                        
                        /*
                              0-10 Saturated Soil. Occurs for a day or two after irrigation 
                              10-20 Soil is adequately wet (except coarse sands which are drying out at this range) 
                              20-60 Usual range to irrigate or water (most soils except heavy clay soils). 
                              60-100 Usual range to irrigate heavy clay soils 
                              100-200 Soil is becoming dangerously dry
                            */
                            result1=constrain(value1/(AGUA_DIR-AIRE_DIR)*100.0, 1, 100);
                            result2=constrain(100-(value2-AGUA_INV)/(AIRE_INV-AGUA_INV)*100.0,1,100);
                            resultp = (result1+result2)/2.0;
                            resultcb = resultcb + constrain(square((-2.96699 + 351.395/resultp)),0,200);                           //Equation fit using stat software
                            count++;
                          
                            //Send the data - only if moisture changed to save battery (send anyways once every 4 readings). If moisture sent, send battery level.
                            if ((oldresultcb!=resultcb) || (count==MAX_REPORTING_LOOPS)) {
                              send(msgmoist.set((unsigned int)resultcb));
                              oldresultcb=resultcb;
                              //Measure battery voltage and send level
                              float v = vcc.Read_Volts();  
                              int p = vcc.Read_Perc(VccMin, VccMax);
                              p=constrain(p,0,100);
                              sendBatteryLevel(p);
                              #ifdef MY_DEBUG
                                Serial << "Value1=" << value1 << " " << result1 << endl << "Value2=" << value2 << " " << result2 << endl << "Result = " << resultp << "% (" << resultcb << "cb)" << endl;
                                Serial << "VCC = " << v << " Volts" << endl << "VCC% = " << p << " %" << endl;
                              #endif
                            }
                          
                            if (count==MAX_REPORTING_LOOPS) count=0;
                            //sleep(SLEEP_TIME_3h, true);
                            sleep(SLEEP_TIME_15min, true);
                          }
                        }
                        

                        its connected on following Schema

                        D2 -> Input 10K resistor-> Output 10K Input Fork and A1-> Output fork -> D6
                        I am using a Adruino pro mini 3,3V on an Easy PCB Board.

                        Many thanks

                        Markus

                        M Offline
                        M Offline
                        Markus.
                        wrote on last edited by
                        #11

                        Well its measuring "something"

                        Fork in water
                        Value1=0 1.00
                        Value2=730 33.95

                        Fork dry
                        Value1=218 27.25
                        Value2=0 100.00

                        1 Reply Last reply
                        0
                        • M Offline
                          M Offline
                          Markus.
                          wrote on last edited by Markus.
                          #12

                          now it Looks better :-)
                          reversed D2 and D6

                          D2 -> Input 10K resistor-> Output 10K Input Fork and A1-> Output fork -> D6
                          The values now makes sense :-)
                          However...Would be great if someone can have a look on the Sketch because Ihave removed the OTA part and not sure If it was correct on this way.

                          Many thanks
                          Markus

                          1 Reply Last reply
                          0
                          Reply
                          • Reply as topic
                          Log in to reply
                          • Oldest to Newest
                          • Newest to Oldest
                          • Most Votes


                          12

                          Online

                          11.7k

                          Users

                          11.2k

                          Topics

                          113.1k

                          Posts


                          Copyright 2025 TBD   |   Forum Guidelines   |   Privacy Policy   |   Terms of Service
                          • Login

                          • Don't have an account? Register

                          • Login or register to search.
                          • First post
                            Last post
                          0
                          • MySensors
                          • OpenHardware.io
                          • Categories
                          • Recent
                          • Tags
                          • Popular