Modifying A0 value to Percentage



  • Hardware: Arduino Nano + Capacitive Moisture Sensor

    I have a nice garden irrigation project I will soon share and want the option to move from analog values to percentages for my capacitive moisture sensor. I tried my hand at it but am not getting percentages to display in HA. Below is my current sketch, followed by what I want to accomplish:

    Sketch I am using:

    /*
      AnalogReadSerial
    
      Reads an analog input on pin 0, prints the result to the Serial Monitor.
      Graphical representation is available using Serial Plotter (Tools > Serial Plotter menu).
      Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and ground.
    
      This example code is in the public domain.
    
      http://www.arduino.cc/en/Tutorial/AnalogReadSerial
    */
    #define MY_NODE_ID 3
    // Enable debug prints
    // #define MY_DEBUG
    // Enable and select radio type attached
    #define MY_RADIO_RF24
    //#define MY_RADIO_NRF5_ESB
    //#define MY_RADIO_RFM69
    //#define MY_RADIO_RFM95
    #define CHILD_ID_A0 0
    //#define CHILD_ID_A1 1
    //#define CHILD_ID_A2 2
    #include <MySensors.h>
    MyMessage msg(CHILD_ID_A0, V_LEVEL);
    //MyMessage msg2(CHILD_ID_A1, V_LEVEL);
    //MyMessage msg3(CHILD_ID_A2, V_LEVEL);
    // the setup routine runs once when you press reset:
    void setup() {
      // initialize serial communication at 9600 bits per second:
      Serial.begin(9600);
    }
    void presentation()
    {
      sendSketchInfo("Analog Soil Moisture Sensorx3", "1c.0");
      present(CHILD_ID_A0, S_MOISTURE);
     // present(CHILD_ID_A1, S_MOISTURE);
     // present(CHILD_ID_A2, S_MOISTURE);
    }
    // the loop routine runs over and over again forever:
    void loop() {
       int sensorValue = analogRead(A0);
       Serial.println(sensorValue);
        send(msg.set(sensorValue));
       delay(10000);
    }
    

    Sketch I would like to use (serial.print portion)

    /*
      AnalogReadSerial
    
      Reads an analog input on pin 0, prints the result to the Serial Monitor.
      Graphical representation is available using Serial Plotter (Tools > Serial Plotter menu).
      Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and ground.
    
      This example code is in the public domain.
    
      http://www.arduino.cc/en/Tutorial/AnalogReadSerial
    */
    #define MY_NODE_ID 3
    // Enable debug prints
    // #define MY_DEBUG
    // Enable and select radio type attached
    #define MY_RADIO_RF24
    //#define MY_RADIO_NRF5_ESB
    //#define MY_RADIO_RFM69
    //#define MY_RADIO_RFM95
    #define CHILD_ID_A0 0
    
    #include <MySensors.h>
    MyMessage msg(CHILD_ID_A0, V_LEVEL);
    void setup() {
      // initialize serial communication at 9600 bits per second:
      Serial.begin(9600);
    }
    void presentation()
    {
      sendSketchInfo("Analog Soil Moisture Sensorx3", "1c.0");
      present(CHILD_ID_A0, S_MOISTURE);
     }
    // the loop routine runs over and over again forever:
    void loop() {
      float moisture_percentage;
      int sensorValue;
      sensorValue = analogRead(A0);
      moisture_percentage = ( 100 - ( (sensorValue/1023.00) * 100 ) );
      Serial.print("Moisture Percentage = ");
      Serial.print(moisture_percentage);
      Serial.print("%\n\n");
      delay(1000);
    }
    

  • Hero Member

    @mrhutchinsonmn I think you just need to replace this line in the first sketch:

    send(msg.set(sensorValue));
    

    By this:

    float moisture_percentage;
    moisture_percentage = ( 100 - ( (sensorValue/1023.00) * 100 ) );
    send(msg.set( moisture_percentage ));
    

    I don't use HA so I don't know if something needs to be changed in HA side...


  • Plugin Developer

    Perhaps this code is of interest to you. It's the Candle plant health sensor. It's got all the bells and whistles you could want, including optional support for automated irrigation.

    One thing you'll notice in there is that the capacitive moisture sensors output voltages between 0 and 3. So in @rvendrame's code you may have to change the 1023 to 650, and also make sure no voltages higher than that would lead to percentages above 100%.

          int16_t moistureLevel = analogRead(analog_pins[i]);
          Serial.print(F("raw analog moisture value: "));
          Serial.println(moistureLevel);
    
          if( moistureLevel > 650 ){moistureLevel = 650;}
          moistureLevels[i] = map(moistureLevel,0,650,0,99); // The maximum voltage output of the capacitive sensor is 3V, so since we're measuring 0-5v about 614 is the theoretical highest value we'll ever get.
    

    I notice in your code that the title Analog Soil Moisture Sensorx3 is too long. It can't be longer than 25 characters.



  • @rvendrame That worked! I did need to change "float moisture_percentage" to init "moisture_percentage" to get passed the "Call of overloaded function is ambiguous" error. Not sure if that is the correct approach but I was able to compile and upload. Not sure how I missed the send msg but I did. Thanks again!



  • @alowhum Thank you.. I may try that code. I have found that when a sensor goes bad it either drops to a "0" reading or "1023". Currently, I use those numbers (below 175 and above 700) to tell Home Assistant to shut off the relay going to that zone, so automations do not keep calling for water.


  • Hero Member

    @mrhutchinsonmn said in Modifying A0 value to Percentage:

    @rvendrame That worked! I did need to change "float moisture_percentage" to init "moisture_percentage" to get passed the "Call of overloaded function is ambiguous" error. Not sure if that is the correct approach but I was able to compile and upload. Not sure how I missed the send msg but I did. Thanks again!

    I'm glad it worked! And right, the code I provided was to work with integers.

    if you want to keep using float (and have decimals places), you have to add the number of decimal places in send function ( I put 2 decimals in this example):

    send(msg.set( moisture_percentage , 2  ));
    


  • @alowhum I did ding around with the sketch you shared, which is really well done and full-featured. I get a reading of 50% when the sensor is immersed and 95% when it is dry. What I would like is to see 100% when immersed and near 0% when it is dry. Can the code be changed to meet that need?



  • @rvendrame That is what I was looking for.. Nice!...Thank you



  • @mrhutchinsonmn

    try changing

     moistureLevels[i] = map(moistureLevel,0,650,0,99); // The maximum voltage output of the capacitive sensor is 3V, so since we're measuring 0-5v about 614 is the theoretical highest value we'll ever get.
    

    to

     moistureLevels[i] = map(moistureLevel,325,650,99,0); // The maximum voltage output of the capacitive sensor is 3V, so since we're measuring 0-5v about 614 is the theoretical highest value we'll ever get.
    

  • Mod

    @mrhutchinsonmn said in Modifying A0 value to Percentage:

    I get a reading of 50% when the sensor is immersed and 95% when it is dry

    Could you expand on what the sensor is immersed in? Wet soil?

    The conductivity will vary depending on what minerals and how much of them are present in the soil, which will vary depeding on what type of water the soil is watered with, season, whether fertilizer is added and a bunch of other stuff. So be aware that the level that means 0% moisture will vary.



  • @mfalkvidd In this particular case, the sensor is monitoring the rain barrel of my garden irrigation system and is used to govern whether or not to fire off an automation calling to water a raised bed. The water does have a lot of iron in it, so not sure if that plays a part in what seems to be an unusual reading. I am expecting to see a number around 275-300 when completely immersed in water, but I am getting a reading of around 400+, which is strange to me. I felt using percentages would allow me to customize each sensor sketch for the environment it is being used in.


  • Mod

    Thanks for explaining @mrhutchinsonmn


Log in to reply
 

Suggested Topics

0
Online

11.4k
Users

11.1k
Topics

112.7k
Posts