Office plant monitoring


  • Mod

    Great.
    Arduino Pro Mini has 6 analog pins, so you can use a maximum of 6 sensors. The Nano has 8 and the Micro 12.


  • Mod

    btw, I had a bug in the code.

    for (int sensor = 0; sensor <= NUMBER_OF_SENSORS; sensor++) {
    

    needs to be changed to

    for (int sensor = 0; sensor < NUMBER_OF_SENSORS; sensor++) {
    

    I have updated the sketch, but if you copied the code before I did the change you'll need to update your code for the two for-loops.



  • Could it be possible to use different power pins? So if you have more than one senor you measure in a sequence?


  • Mod

    @Lars65 Yes, absolutely.



  • I know that I am a pain in the *ss. But I have tried to change this code to accept more than one power pin.
    But I don't know how. I know how to mill a PCB, and lot of other stuff, but programming is not my cup of thee.
    I really need to try to study how.
    Bot for now, is it anybody who could help me?


  • Mod

    How much power do your sensors need? (How many sensors can use the same pin?)


  • Mod

    This is a VERY quick and dirty solution. I'm off to the movies now. Let me know if it works 🙂
    https://codebender.cc/sketch:170297

    Edit: have updated the sketch


  • Mod

    @Lars65 Just a question before things get too crazy: Will you be running your node on battery power? If you will be using wall power you can just power all sensors continuously from Vcc and get rid of the code for turning on and off the sensors, and get rid of all the battery reporting code.



  • Hi!
    At the moment do I only have three sensors, and I will be using them on the same arduino. Those will be powered by wall power.
    But I have ordered some more sensors, and some of them will be battery powered.
    Though both me and my wife often forget to water our plants, do I really like this.
    I use Domoticz, and it's easy to get a notification when it's time to water.
    You have been really helpfull. Tomorrow will I mill a new PCB, to test this code.
    🙂



  • Hi @mfalkvidd and thank you for your nice work and sketch.
    I just have one question about the power pin, I saw on datasheet that the adruino pro mini can handle 40mA max per powerpin. I Have four of these soil moisture sensors but cant find how much current they need... they use a LM393, and the datasheet say 0.4mA..
    Did you think than i coul plug all of them on the same powerpin or i need to use your second sketch ?
    Thanks in advance !


  • Mod

    @damien: I don't know, unfortunately. Maybe @Lars65 can do a measurement on his moisture sensors?



  • @mfalkvidd Ok thanks for your reply, i will wait for @Lars65 to see if he has done the measurement, else i will do it by myself on mine when i receive them.
    Thx



  • Hi Guys!
    No I haven't made any measurements.

    { 4, 0, 1, // This assumes 2 sensors per pin. First two sensors are powered through pin 4, using analog pins 0 and 1
    **5, 2, 3, **// Second two sensors get power from pin 5 and are connected to analog pins 2 and 3
    6, 4, 5 // Third set of sensors get power from pin 6 and are connected to analog pins 4 and 5
    }
    So I did change 4,0,1, to 4,0,. What I saw with this was that I use power pin 4, to the analog input A0. So now have I made it so A0, has powerpin 4, A1 has powerpin 5, and A2 has powerpin 6.


  • Mod

    How did thinks go @Lars65 ?

    I thought a bit more about this problem and I think I have come up with a pretty neat solution:
    Throw away the chip on the moisture sensor and connect the "pitchfork" directly to the Arduino. Connect one prong to GND and one prong to an analog pin. No power pins are required.
    https://codebender.cc/sketch:177182
    The chip on the moisture sensor is basically a voltage divider. We get the same thing if we use the internal pull-up resistor on the Atmega processor.
    EDIT: This means you can buy just the "pitchforks" really cheap: http://www.aliexpress.com/item/10pcs-Soil-Hygrometer-Detection-Module-Soil-Moisture-Sensor-Probes/2051713873.html



  • @mfalkvidd , I think there has been many discussions on how these sensors corrodes over time.
    I can see that this node sleeps between the readings and thus reduces corrosion as it only is powered during reading.
    However, some threads I've read suggests that you alternate the power, as well, between readings.
    Something you might implement in the code?
    Also, do you have an estimate on the duration usage on the batteries for one of your plants?
    Cheers!


  • Mod

    @Nicklas-Starkel If a measurement is taken once per hour, the sensor will only have power 0,008% of the time.
    If corrosion still is a problem, and if the corrosion can be avoided by reversing polarity for every second measurement, I might add it. It would add complexity to the sketch though, and complexity is often the enemy of reliability.

    Also, for people wanting to use multiple sensors on the same mcu, reversing polarity would cut the possible number of connected moisture sensors in half since it would require two analog pins per sensor.

    My estimated battery time on 2xAA for a Mini Pro with removed power led and voltage regulator is 1-2 years.



  • @mfalkvidd said:

    How did thinks go @Lars65 ?

    I thought a bit more about this problem and I think I have come up with a pretty neat solution:
    Throw away the chip on the moisture sensor and connect the "pitchfork" directly to the Arduino. Connect one prong to GND and one prong to an analog pin. No power pins are required.
    https://codebender.cc/sketch:177182
    The chip on the moisture sensor is basically a voltage divider. We get the same thing if we use the internal pull-up resistor on the Atmega processor.

    Hi @mfalkvidd and thank you very very much for your new version of the skecth for moisture sensors, its very clever ! i will test it as soon as possible


  • Mod

    @Nicklas-Starkel last weekend one of my sensors broke. Both pins were completely corroded and broke just where I connect the dupont wires. I think I will use hot glue to protect the connectors, but I have also added alternating power to my single-sensor sketch. I have this sketch running on three sensors now.
    https://codebender.cc/sketch:158460



  • Newbie to controllers. I'd been looking at PanStamp for this project, and came across your post from Google. This would be my first project w/ micro controllers. How is this tied to the internet for reporting?


  • Mod

    In MySensors lingo, the Arduino is called a sensor. The part that MySensors calls a controller runs on a "real" computer, and gets information from the sensors. The controller usually handles reporting. The documentation at http://www.mysensors.org/about/network can probably give you a good overview.


  • Hardware Contributor

    Just some ideas to the corrosion issue (any photos?). If both pins were corroded, it may not be sufficient with polarity switching. Perhaps a simple active cathodic protection system could help. E.g. a +wire limited to a few uA and wrapped with some aluminium foil in the soil near the sensor?

    I haven't yet got to it, but the plant monitoring is on pretty high on my list.


  • Mod

    @m26872 said:

    (any photos?)

    DSC00564_crop.jpg DSC00561_crop.jpg DSC00558_crop.jpg



  • @mfalkvidd
    i am using your sketch for indoor plant monitoring but have modified the sleep time to one hour . the problem i am facing is that every alternate humidity reading i get is a 0
    like
    first reading ------ 67%
    second reading ----- 0%
    third reading ------65%
    fourth reading ------- 0%

    and likewise

    Please Guide

    Thanks


  • Mod

    @rajbadri which pins are your sensor connected to?



  • Hello,

    I'm on the same project personally...I using 2 battery... this part should work between 3.3 V and 5V...
    finally with 2XAA we only have 3V, and the max value for me is 750 not 1023... did you get 1023 when into the water?
    I use a gold plated sensor, and the plug will be into a seal to avoid corrosion and water to go in.
    I use a sensbender where I connected on A3 the pin use for the soil moisture sensor.
    Could you confirm that change the polarity help to avoid corrosion ???
    thanks


  • Mod

    @doblanch said:

    Could you confirm that change the polarity help to avoid corrosion ???
    thanks

    No I can not. All my sensors change the polarity, so I can't tell if there is a difference. You'll have to experiment.


  • Mod

    @doblanch said:

    the max value for me is 750 not 1023... did you get 1023 when into the water?

    I haven't tried in water. I don't care about the absolute value, I just note the reading when the plant needs watering and set a notification for that level. One of my plants needs water at about 70%, another at about 5%. It will vary wildly between different plant types, climate and soil composition.

    The value for water will probably vary as well, depending on the water. Distilled water, rain water, tap water, salt water will all have different resistance.

    And the value will vary depending on temperature and different Arduinos since the pull-up resistor is inexact.



  • @mfalkvidd ok ; thanks I willl try 🙂



  • @mfalkvidd not false 🙂 I have to make some tries also. I bought a gold platined sensor, I hope that corrosion will be less...


  • Hardware Contributor

    @mfalkvidd Thanks for sharing! By looking at your corrosion photos I'd guess galvanic corrosion of pin header.

    I think I'll solder my wires instead and put some sealing paint and/or hot glue over it. Polarity switch won't harm, but I'll wait with the cathodic protection for now.



  • @mfalkvidd
    its on analog pin A0



  • @mfalkvidd
    i have now connected two analog pins A0 and A1 of Pro Mini to the A0 pin of the soil sensor and now i am getting a constant reading of 98% humidity (in water or outside dry).

    please guide

    Thanks



  • @mfalkvidd
    this is how i have connected

    soil.jpg


  • Mod

    To use the sketch with reverse polarity you need to connect + and - on the prong to A0 and A1 on the Arduino. The chip in the middle is not used.
    moisture.png



  • @mfalkvidd
    ok will try



  • @mfalkvidd said:

    @Nicklas-Starkel last weekend one of my sensors broke. Both pins were completely corroded and broke

    Did you try to just paint the sensors ?
    I've seen that here: https://www.tindie.com/products/miceuz/i2c-soil-moisture-sensor/

    It doesn't work for me. I go double check the wiring. EDIT: not it's okay now. Great !
    0_1453567276371_IMG_20160123_173901-2.jpg

    But is it possible to use A0-A1, A2-A3, A4-A5 on a atmega328P or there is the same pullup problem ?



  • Painted fork seem to work. 0% on dry heart, and now:
    0_1453725695799_jeedom-008.png

    But the pourcentage of batterie seem to change a lot lot lot.

    ps: i'll tell you if it's corroding.


  • Mod

    @Pierre-P said

    But is it possible to use A0-A1, A2-A3, A4-A5 on a atmega328P or there is the same pullup problem ?

    A0-A5 can be used. A6 and A7 do not have built-in pullup resistors and can not be set high or low. The sketch in http://forum.mysensors.org/topic/2147/office-plant-monitoring/21 mentions that but there have been many revisions and this thread is long so I don't blame you for missing it 🙂



  • @Pierre-P
    That i2c thing is painted and works because it's capacitive (it can even sense when your finger is hovering a millimeter or two away from it, like a capacitive touch screen (your phone)). I put one of them into the soil yesterday. If I remember, I will get back regarding results.. I placed it into the same flower as a resistive fork, with the middle chip (so I have some corrosion).



  • @doblanch said:

    I'm on the same project personally...I using 2 battery... this part should work between 3.3 V and 5V...
    finally with 2XAA we only have 3V, and the max value for me is 750 not 1023... did you get 1023 when into the water?

    If you have the XD-28 sensor, I think air is about 1023 (so minimal connection). If you put it in water it will be much lower, 300 to 400. 100% water isn't realistic of course and because of that, I get my first reading with the sensor in the air and the second one I initiate with a button press when it's planted and the spot is fully watered.

    The button press is just a way to get the different readings for different soil. It does actually read the sensor 200 times and takes a median of that and set the "0" point after that.

    I'm trying to measure the centibar which is (apparently, I did not know this a week ago) the right way to measure the soil. Of course, soil temperature has something to do with it also. I'm working on that at the moment.



  • I'm already at 2.73Volts on my two AAA batteries. Is the last sketch a batteries killer ? With a 10 hours sleeping ??


  • Mod

    @Pierre-P after how long time?
    This is the battery level for my oldest sensor, which is using 2xAA and reporting every 2 hours 0_1454780283967_9nov-6feb.png



  • A week.
    New accus i think. I do it again but this time, i'm making voltage report with my voltmeter and a picture.



  • My node doesn't work anymore. Even with new set of accus. I will check again when I'll solder it.



  • @mfalkvidd Great project. Had few questions...Is it OK to provide 6V to Arduio Mini ? Can you show /explain how you have provided power supply to Mini and Moisture Controller ? In the set up you have , how long does the battery last ?

    Thanks


  • Mod

    @iotcrazy

    6V is OK if you connect power on the "raw" pin. 6V is NOT OK if you connect power to the Vcc pin.

    I use 2xAA batteries. - on the battery holder is connected to GND on the Arduino and + on the battery holder to Vcc. Power led and voltage regulator have been removed.

    My sensors report every two hours and I expect to get 1-2 years battery life.



  • Just built this sensor and it is working great. However I am seeing different results with every run. It seems as if the value is always higher with one polarity than with the other one. Is this normal?

    0_1456353874082_soil.PNG


  • Mod

    @Jan-Gatzke yes I'm seeing that as well. The built-in pullup resistors are not 100% accurate, which yields slightly different result when polarity is reversed.

    The easiest way is probably to let the Arduino report a rolling average of the last 2 readings instead of reporting the latest reading.

    0_1456394895794_humidity.png
    0_1456405610141_chart.png



  • @mfalkvidd I was looking to your sketch and could not quite understand this piece of line

    result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.110231000

    How will this above line change if I use 4 AA battery ?.

    Thanks in advance


  • Mod

    If you use 4xAA and wire power to Vcc you will break the nrf and the mcu. They are not rated for that high voltage.

    If you wire power to Raw you can not use readVcc, you'll have to use a voltage divider to one of the pins.

    Is there a reason you want to use 4xAA?



  • @mfalkvidd Yes I am connecting to RAW input. My 4 battery holder for some reason does not work with 2 or 3 batteries so connecting 6V to RAW.

    "...you'll have to use a voltage divider to one of the pins..." Can you elaborate this part ? Can you share a link which wherein Arduino Pro Mini is powered through RAW input and battery percentage is calculated. I very new to hardware but loving the mysensors projects. Kindly bear with my stupid questions.

    Appreciate your patience..



  • @iotcrazy I understood the voltage divider part by googling. So this is the only option to find the battery percentage right ? We cannot determine by connecting directly to Raw when input if more than 3.3 v.


  • Mod

    That's correct. The Arduino cannot measure voltages above it's Vcc level.

    Great that you found information on voltage dividers.

    Powering on Raw will keep the voltage regulator active all the time, so you might get worse batttery life than when using 2xAA on Vcc. Therefore I suggest you order a 2xAA battery holder for later use. In the meanwhile, you can make your 4xAA holder work by putting two wires instead of batteries in the unused slots.

    If you still want to use 4 batteries, http://www.mysensors.org/build/battery#measuring-and-reporting-battery-level has more details and code to use for battery measurement.


  • Mod

    @Jan-Gatzke I have updated my skech on codebender to report rolling average. I have not tested it yet though.
    The change is available at https://github.com/mfalkvidd/arduino-plantmoisture/commit/5e98c5e625075d62ae27956ab8dc3ea9dec4a29e


  • Mod



  • @mfalkvidd At the moment I am testing a modified version of the sketch which always does two readings. I don't think this will have a big impact on the battery life because most power is consumend by the nrf and not by the sensor. Or am I wrong? The pullups are rated at 10k Ohm. The sensors resistance will be about the same in average. So we talk about 20k at 3V which is 0.15 mA. The nrf uses abot 15 mA when sending.


  • Mod

    Yes, but the nrf needs to be active approximately 1ms while the moisture reading needs about a second to be stable. So the consumption while reading is much larger than the consumption while sending.



  • Hi.

    I have been trying to connect two sensors to the same arduino nano using this code and i have add sensor 1 pin to A0 and GND, and sensor 2 pin A1 and GND.
    But i only get the reads from sensor 1 sensor 2 doesn't appear...
    Can anyone help me with this on how to get more than one moisture sensor working.

    Thanks.


  • Mod

    @mrc-core there have been quite a few revisions of the sketch. The latest version (which can be found at github) only support one sensor, which is connected to A0 and A1 in the default configuration. Both pins are required to enable alternating the direction of the current when measuring, to try to minimize corrosion.

    Adding support for up to three sensors is technically possible (using A0-A5), but would make the code harder to read and since I have no use for multiple sensor I haven't spent the time required to program and test a sketch with multiple sensors.


  • Mod

    An update on battery life: The sensor in my bonsai tree has been reporting every 11,5 minutes since 2015-11-07, so over the last ~four months it has done 24,504 measurements. The battery level has gone from 3.187V to 3.142V, which means a drop of 0.01125V per month. Assuming I let it go down to 2.34V (limit for 8MHz according to the datasheet) and that the voltage drop is linear, I should get (3.187-2.34)/0.01125 = 75 months = ~6 years. There are several error sources in this calculation, but it looks like battery life will be quite good, even though the sensor reports much more often than necessary.

    0_1457905111939_chart.png



  • @mfalkvidd Thanks for the replay.
    Will use only one sensor per arduino.

    Once again thanks



  • @mfalkvidd since you are using 2 AA battery(3V max) with a sensor , how are you powering the sensors ? What sensors are you using ?.Most of the sensors need 5V right ? how are you providing the required voltage for sensor ?. If possible can you share a circuit diagram or close up picture for your sensor node with connection to NRF , Sensor and battery ?

    Appreciate it .


  • Mod

    @iotcrazy the fork is entirely passive so no requirements on voltage. See earlier posts in this thread for wiring information.



  • @mfalkvidd sorry if questions seems like a dump . What do you mean by passive ? every sensors needs some voltage to perform a task right ?

    I tried connecting a DHt11 Temp and humidity sensor using a arduino pro min(with led and voltage divider removed). It is connected to 2 AA battery. Unfortunate the node sends out value(proper value) only when I power on the Mini. It never sends the data again. However if I disconnect power supply and re attach it , it again sends the data. any idea what I am doing wrong ?

    Also , whats the best way to create a Node which needs to monitor a sensor which uses 5 V . Arduino Mini is 3.3 V which.

    Thanks



  • Hello,

    Thanks for this useful and simple project !
    My first node is running perfectly since 10 days.
    Next step is to create a PCB and try running on a CR2032 to minimize the size (WAF request ;))

    One question on the uses : when do you set a warning on the result ? When I need to water the flower ?

    0_1461308771999_2016-04-21 17.21.41.png

    My first node is close to 50%, is it time ? Off course it depends on the nature of the flower but I was not able to found the information on Google ...

    David.


  • Mod

    I do just like I did before I had the sensors: stick a finger into the pot to feel if it needs water. If it does, I set the warning level to whatever level the sensor reports (or slightly higher).


  • Admin

    Great idea @carlierd!

    One that has everything mounted and you just stick into the plant soil would be really useful.


  • Hardware Contributor

    yep, I think that would be a nice module!

    @mfalkvidd @hek I hope to not OT 😳 I just want to show you few old school pics, a small jump back of 20years! My dad's stuff, a real maker 😉

    This one was, I guess, the smallest soil moisture, in "virtual bulb", meaning there was no external electrodes, so no corrosion :
    0_1461316115256_2016-04-22_10-58-38.png
    2nd: still in virtual bulb, humidity, salinity, roots temperature, temperature compensated, pH tendancy
    0_1461316160275_2016-04-22_10-59-39.png
    Multi level soil moisture:
    0_1461316305917_2016-04-22_11-02-44.png
    And these old Aurel 433mhz emitter/receiver !
    0_1462008084352_IMAG0394.jpg
    I have lot of others old pics like this lol! He was selling his devices.

    Few months ago, I have started to mix some of his old project with our new techno, but not finished! I would like to have sort of flo** pow** but more professional..still open. what!!



  • @scalz : very interesting ! Will you plan to make one ? I am pretty sure that your design could be very very very small 😉


  • Hardware Contributor

    @carlierd yes this is planned, but don't know yet when ..I have already started something few months ago, but I need to think about few points mostly about the overall assembly, and to be sure of the power supply/battery I prefer..I will tell you when I will have something nice 🙂



  • Hello,

    I finally spent some hours on Eagles.

    See the result in this post !

    Do not hesitate to give me advice.

    David.


  • Mod

    Another update on battery life:
    The sensor in my bonsai tree has been reporting every 11,5 minutes since 2015-11-07, so over the last ~seven months it has done 48,965 measurements. It sends data over the radio every time, regardless if the value has changed. The battery level has gone from 3.187V to 3.134V, which means a drop of 0.0076V per month. Assuming I let it go down to 2.34V (limit for 8MHz according to the datasheet) and that the voltage drop is linear, I should get (3.187-2.34)/0.0076 = 111 months = ~9 years. There are several error sources in this calculation, but it looks like battery life will be quite good, even though the sensor reports much more often than necessary.
    0_1466870465803_Batteri plantmoisture.png


  • Hardware Contributor

    @mfalkvidd That sounds great! Are you using a pro mini too?
    I am using a 3V pro mini with power led and regulator removed and the nrf + sensor (on A0 and A1) connected and in about 1 day it dropped from 2945mV to 2907mV. Its running of of 2aa batteries and its on a breadboard for now (for testing).
    I am using your (slightly modified) code from above. Any idea why my power usage is so much higher?

    Here is my code:

    /*
    Based on https://github.com/mfalkvidd/arduino-plantmoisture
    
    This sketch uses the soilmoisture "forks" only that are found on ebay. They are connected between 2 analog pins where one gets pulled low and the other one measures.
    The pins are switched every time to avoid corrosion. Between readings the sensos sleeps to preserve batterylife.
    
    21.06.2016 V1.0 Base sketch
    */
    
    #include <SPI.h>
    #include <MySensor.h>
    
    #define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))
    
    #define CHILD_ID_MOISTURE 0
    #define CHILD_ID_BATTERY 1
    #define SLEEP_TIME 1800000 // Sleep time between reads (in milliseconds) - 30 minutes
    #define THRESHOLD 1.1 // Only make a new reading with reverse polarity if the change is larger than 10%.
    #define STABILIZATION_TIME 1000 // Let the sensor stabilize before reading
    #define BATTERY_FULL 3143 // 2xAA usually give 3.143V when full
    #define BATTERY_ZERO 1900 // 2.34V limit for 328p at 8MHz. 1.9V, limit for nrf24l01 without step-up. 2.8V limit for Atmega328 with default BOD settings.
    const int SENSOR_ANALOG_PINS[] = {A0, A1}; // Sensor is connected to these two pins. Avoid A3 if using ATSHA204. A6 and A7 cannot be used because they don't have pullups.
    
    MySensor gw;
    MyMessage msg(CHILD_ID_MOISTURE, V_HUM);
    MyMessage voltage_msg(CHILD_ID_BATTERY, V_VOLTAGE);
    long oldvoltage = 0;
    byte direction = 0;
    int oldMoistureLevel = -1;
    
    void setup()
    {
      gw.begin();
    
      gw.sendSketchInfo("Plant moisture w bat", "1.0 21062016");
    
      gw.present(CHILD_ID_MOISTURE, S_HUM);
      delay(250);
      gw.present(CHILD_ID_BATTERY, S_CUSTOM);
    
      Serial.println("Setting up pins...");  
      // init sensor pins
      pinMode(SENSOR_ANALOG_PINS[0], OUTPUT);
      pinMode(SENSOR_ANALOG_PINS[1], OUTPUT);
      digitalWrite(SENSOR_ANALOG_PINS[0], LOW);
      digitalWrite(SENSOR_ANALOG_PINS[1], LOW);
    }
    
    void loop()
    {
      int moistureLevel = readMoisture();
    
      // Send rolling average of 2 samples to get rid of the "ripple" produced by different resistance in the internal pull-up resistors
      // See http://forum.mysensors.org/topic/2147/office-plant-monitoring/55 for more information
      if (oldMoistureLevel == -1) { // First reading, save current value as old
        oldMoistureLevel = moistureLevel;
      }
      if (moistureLevel > (oldMoistureLevel * THRESHOLD) || moistureLevel < (oldMoistureLevel / THRESHOLD)) {
        // The change was large, so it was probably not caused by the difference in internal pull-ups.
        // Measure again, this time with reversed polarity.
        moistureLevel = readMoisture();
      }
    
      // send value and reset level
      gw.send(msg.set((moistureLevel + oldMoistureLevel) / 2.0 / 10.23, 1));
      oldMoistureLevel = moistureLevel;
    
    
      long voltage = readVcc();
    
      if (oldvoltage != voltage) { // Only send battery information if voltage has changed, to conserve battery.
        gw.send(voltage_msg.set(voltage / 1000.0, 3)); // redVcc returns millivolts. Set wants volts and how many decimals (3 in our case)
        gw.sendBatteryLevel(round((voltage - BATTERY_ZERO) * 100.0 / (BATTERY_FULL - BATTERY_ZERO)));
        oldvoltage = voltage;
      }
    
      // sleep to conserve energy
      gw.sleep(SLEEP_TIME);
    }
    
    /*
      Reads the current moisture level from the sensor.
      Alternates the polarity to reduce corrosion
    */
    int readMoisture() {
      pinMode(SENSOR_ANALOG_PINS[direction], INPUT_PULLUP); // Power on the sensor by activating the internal pullup
      analogRead(SENSOR_ANALOG_PINS[direction]);// Read once to let the ADC capacitor start charging
      gw.sleep(STABILIZATION_TIME);
    
      int sensorRead = analogRead(SENSOR_ANALOG_PINS[direction]);
      int moistureLevel = (1023 - sensorRead); // take the actual reading
    
      Serial.print("Sensor read: ");
      Serial.println(sensorRead);
      Serial.print("Moisture level: ");  
      Serial.println(moistureLevel);  
    
      // Turn off the sensor to conserve battery and minimize corrosion
      pinMode(SENSOR_ANALOG_PINS[direction], OUTPUT);
      digitalWrite(SENSOR_ANALOG_PINS[direction], LOW);
    
      direction = (direction + 1) % 2; // Make direction alternate between 0 and 1 to reverse polarity which reduces corrosion
      return moistureLevel;
    }
    
    long readVcc() {
      // From http://provideyourown.com/2012/secret-arduino-voltmeter-measure-battery-voltage/
      // Read 1.1V reference against AVcc
      // set the reference to Vcc and the measurement to the internal 1.1V reference
    #if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
      ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
    #elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
      ADMUX = _BV(MUX5) | _BV(MUX0);
    #elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
      ADMUX = _BV(MUX3) | _BV(MUX2);
    #else
      ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
    #endif
    
      delay(2); // Wait for Vref to settle
      ADCSRA |= _BV(ADSC); // Start conversion
      while (bit_is_set(ADCSRA, ADSC)); // measuring
    
      uint8_t low  = ADCL; // must read ADCL first - it then locks ADCH
      uint8_t high = ADCH; // unlocks both
    
      long result = (high << 8) | low;
    
      result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000
      return result; // Vcc in millivolts
    }
    

  • Mod

    @LastSamurai that drop is just two bits difference so you can't really tell anything from it. There are lots of reasons that could cause it, for example measurement noise, temperature variation in the batteries, temperature variation in the internal reference, temporary drain of the battery.


  • Hardware Contributor

    Thanks I will keep testing for some days and then report again.


  • Plugin Developer

    To get rid of the ripple effect, maybe use the rolling average of the last two measurements for the voltage measurements also?


  • Mod

    @martinhjelmare which ripple effect are you referring to?


  • Plugin Developer

    @mfalkvidd

    Looking at your chart and also my own battery reporting charts, they contain small and tight ups and downs, "ripples". I was thinking about smoothing them out to have a nicer chart. But I also think this could make the measurement more accurate, which could help in @LastSamurai 's case where there's an unexpected dip in voltage. Maybe the next measurement will be higher again? Taking an average will give you more confidence in your measurement.


  • Hardware Contributor

    Mhm so I measured it for 2 days now and I am loosing about about 25mV per day (a little over 50mV overall). Thats really strange as I am using the pro mini without regulator or led. Has anybody seen similar problems?
    Otherwise I guess I have to start measuring, although I don't know how well my multimeter can do this 😞


  • Mod

    @LastSamurai is the drop steady or does it go up and down a lot? Mine goes up and down in the last bit (9mV) quite often, but not as much as 50mV.0_1467058275738_chart.png


  • Hardware Contributor

    @mfalkvidd Its more or less stable.
    0_1467058760247_upload-947392a5-8f6d-47f4-914b-dd6de12e6d09


  • Mod

    @LastSamurai that's a pity. Can you try measuring the current consumed from the battery in different situations (disconnect power to the nrf, disconnect the moisture sensor, disconnect both the nrf and the moisture sensor)?


  • Hardware Contributor

    Thanks! I will (later) and post the results here.



  • @LastSamurai
    I think Delay will really stop the MCU, Wait(xx) will continue to work in background? can anyone confirm this please

    You can try to use Delay(2000) between each step to know if the power is low between the steps, maybe it do something that increase the power consumption.

    Try to disconnect the Sensor, maybe it is damage? When sensor is disconnected it shall report 0%.

    Can you try with another Pro Mini?




  • Admin

    @flopp said:

    Wait(xx) will continue to work in background? can anyone confirm this please

    Yes, wait() continue processing incoming messages and does not sleep the MCU.



  • Hi.

    What is the last version from this ?



  • Oops! Looks like there was a serious issue with your project.

    If you are not sure what could be wrong please contact us.

    (file in sketch) Soil moisture for houseplants - multi-sensor internal pull-up.o: In function global constructors keyed to oldvoltage': Soil moisture for houseplants - multi-sensor internal pull-up.cpp:(.text._GLOBAL__I_oldvoltage+0xc): undefined reference to MySensor::MySensor(unsigned char, unsigned char)'
    (file in sketch) Soil moisture for houseplants - multi-sensor internal pull-up.o: In function setup': Soil moisture for houseplants - multi-sensor internal pull-up.cpp:(.text.setup+0x30): undefined reference to MySensor::begin(void (*)(MyMessage const&), unsigned char, unsigned char, unsigned char, rf24_pa_dbm_e, unsigned char, rf24_datarate_e)'
    Soil moisture for houseplants - multi-sensor internal pull-up.cpp:(.text.setup+0x50): undefined reference to MySensor::present(unsigned char, unsigned char, bool)' Soil moisture for houseplants - multi-sensor internal pull-up.cpp:(.text.setup+0x78): undefined reference to MySensor::present(unsigned char, unsigned char, bool)'

    This errors.

    @mfalkvidd said:

    How did thinks go @Lars65 ?

    I thought a bit more about this problem and I think I have come up with a pretty neat solution:
    Throw away the chip on the moisture sensor and connect the "pitchfork" directly to the Arduino. Connect one prong to GND and one prong to an analog pin. No power pins are required.
    https://codebender.cc/sketch:177182
    The chip on the moisture sensor is basically a voltage divider. We get the same thing if we use the internal pull-up resistor on the Atmega processor.
    EDIT: This means you can buy just the "pitchforks" really cheap: http://www.aliexpress.com/item/10pcs-Soil-Hygrometer-Detection-Module-Soil-Moisture-Sensor-Probes/2051713873.html



  • @Fat-Fly
    I have used the latest version of this sketch and it worked perfect.
    If you use the latest version it must be something with your PC/Arduino IDE



  • I trying compile from this and these errors.


  • Mod

    @Fat-Fly as flopp said, there is something wrong with your environment.

    Are you using the development version of MySensors? If so, remove it and install 1.5 or convert the sketch to the development version by following the conversion guide.

    If you already have 1.5, remove it and re-install it closely following the instructions. You can try verifying any of the stock MySensors example sketches if you like.



  • Good morning. I try after work. I use linux. I want monitor this https://goo.gl/photos/oqnXUU8Pa5wmz8k87 . Moisture and if needed open valves and switch on pump.At the moment i have 3 goups what i can control.Left , right tomatoes and 3 raised beds in center, sweet peppers.


  • Mod

    @Fat-Fly very nice greenhouse!



  • Greenhouse

    I want to monitor soil moisture and switch on irrigation valves and pump. Windows open arduino but why not mysensors+domoticz. I can't and not want every morning go to open greenhouse windows. let this make computer 🙂

    Kastmistest nr. 007. Paprikad. – 02:04
    — Ants Kosmos



  • This post is deleted!

  • Mod

    @Fat-Fly replace

    const int SENSOR_ANALOG_PINS[] = { 0 };
    

    with

    const int SENSOR_ANALOG_PINS[] = { A0 };
    

    Connect like this, except use D8 instead of A1 (the connection displayed is for a newer version of the sketch, which supports alternating polarity)


  • Hardware Contributor

    @mfalkvidd So after running my sensor for 3 days with the "fork" connected I had a pretty big loss of voltage. So (as you suggested) I ran it for ~2 days without the fork connected (just the pro mini + radio) and the loss has gone down to ~0 (it keeps alternating between 2806 and 2799mV).
    So its obviously the fork itself that is the problem. I connected it directly to A0 and A1 and my code is above.
    Any idea where the error might be? I will try some other cables later because thats the only idea I have...

    @LastSamurai said:

    @mfalkvidd That sounds great! Are you using a pro mini too?
    I am using a 3V pro mini with power led and regulator removed and the nrf + sensor (on A0 and A1) connected and in about 1 day it dropped from 2945mV to 2907mV. Its running of of 2aa batteries and its on a breadboard for now (for testing).
    I am using your (slightly modified) code from above. Any idea why my power usage is so much higher?

    Here is my code:

    /*
    Based on https://github.com/mfalkvidd/arduino-plantmoisture
    
    This sketch uses the soilmoisture "forks" only that are found on ebay. They are connected between 2 analog pins where one gets pulled low and the other one measures.
    The pins are switched every time to avoid corrosion. Between readings the sensos sleeps to preserve batterylife.
    
    21.06.2016 V1.0 Base sketch
    */
    
    #include <SPI.h>
    #include <MySensor.h>
    
    #define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))
    
    #define CHILD_ID_MOISTURE 0
    #define CHILD_ID_BATTERY 1
    #define SLEEP_TIME 1800000 // Sleep time between reads (in milliseconds) - 30 minutes
    #define THRESHOLD 1.1 // Only make a new reading with reverse polarity if the change is larger than 10%.
    #define STABILIZATION_TIME 1000 // Let the sensor stabilize before reading
    #define BATTERY_FULL 3143 // 2xAA usually give 3.143V when full
    #define BATTERY_ZERO 1900 // 2.34V limit for 328p at 8MHz. 1.9V, limit for nrf24l01 without step-up. 2.8V limit for Atmega328 with default BOD settings.
    const int SENSOR_ANALOG_PINS[] = {A0, A1}; // Sensor is connected to these two pins. Avoid A3 if using ATSHA204. A6 and A7 cannot be used because they don't have pullups.
    
    MySensor gw;
    MyMessage msg(CHILD_ID_MOISTURE, V_HUM);
    MyMessage voltage_msg(CHILD_ID_BATTERY, V_VOLTAGE);
    long oldvoltage = 0;
    byte direction = 0;
    int oldMoistureLevel = -1;
    
    void setup()
    {
      gw.begin();
    
      gw.sendSketchInfo("Plant moisture w bat", "1.0 21062016");
    
      gw.present(CHILD_ID_MOISTURE, S_HUM);
      delay(250);
      gw.present(CHILD_ID_BATTERY, S_CUSTOM);
    
      Serial.println("Setting up pins...");  
      // init sensor pins
      pinMode(SENSOR_ANALOG_PINS[0], OUTPUT);
      pinMode(SENSOR_ANALOG_PINS[1], OUTPUT);
      digitalWrite(SENSOR_ANALOG_PINS[0], LOW);
      digitalWrite(SENSOR_ANALOG_PINS[1], LOW);
    }
    
    void loop()
    {
      int moistureLevel = readMoisture();
    
      // Send rolling average of 2 samples to get rid of the "ripple" produced by different resistance in the internal pull-up resistors
      // See http://forum.mysensors.org/topic/2147/office-plant-monitoring/55 for more information
      if (oldMoistureLevel == -1) { // First reading, save current value as old
        oldMoistureLevel = moistureLevel;
      }
      if (moistureLevel > (oldMoistureLevel * THRESHOLD) || moistureLevel < (oldMoistureLevel / THRESHOLD)) {
        // The change was large, so it was probably not caused by the difference in internal pull-ups.
        // Measure again, this time with reversed polarity.
        moistureLevel = readMoisture();
      }
    
      // send value and reset level
      gw.send(msg.set((moistureLevel + oldMoistureLevel) / 2.0 / 10.23, 1));
      oldMoistureLevel = moistureLevel;
    
    
      long voltage = readVcc();
    
      if (oldvoltage != voltage) { // Only send battery information if voltage has changed, to conserve battery.
        gw.send(voltage_msg.set(voltage / 1000.0, 3)); // redVcc returns millivolts. Set wants volts and how many decimals (3 in our case)
        gw.sendBatteryLevel(round((voltage - BATTERY_ZERO) * 100.0 / (BATTERY_FULL - BATTERY_ZERO)));
        oldvoltage = voltage;
      }
    
      // sleep to conserve energy
      gw.sleep(SLEEP_TIME);
    }
    
    /*
      Reads the current moisture level from the sensor.
      Alternates the polarity to reduce corrosion
    */
    int readMoisture() {
      pinMode(SENSOR_ANALOG_PINS[direction], INPUT_PULLUP); // Power on the sensor by activating the internal pullup
      analogRead(SENSOR_ANALOG_PINS[direction]);// Read once to let the ADC capacitor start charging
      gw.sleep(STABILIZATION_TIME);
    
      int sensorRead = analogRead(SENSOR_ANALOG_PINS[direction]);
      int moistureLevel = (1023 - sensorRead); // take the actual reading
    
      Serial.print("Sensor read: ");
      Serial.println(sensorRead);
      Serial.print("Moisture level: ");  
      Serial.println(moistureLevel);  
    
      // Turn off the sensor to conserve battery and minimize corrosion
      pinMode(SENSOR_ANALOG_PINS[direction], OUTPUT);
      digitalWrite(SENSOR_ANALOG_PINS[direction], LOW);
    
      direction = (direction + 1) % 2; // Make direction alternate between 0 and 1 to reverse polarity which reduces corrosion
      return moistureLevel;
    }
    
    long readVcc() {
      // From http://provideyourown.com/2012/secret-arduino-voltmeter-measure-battery-voltage/
      // Read 1.1V reference against AVcc
      // set the reference to Vcc and the measurement to the internal 1.1V reference
    #if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
      ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
    #elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
      ADMUX = _BV(MUX5) | _BV(MUX0);
    #elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
      ADMUX = _BV(MUX3) | _BV(MUX2);
    #else
      ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
    #endif
    
      delay(2); // Wait for Vref to settle
      ADCSRA |= _BV(ADSC); // Start conversion
      while (bit_is_set(ADCSRA, ADSC)); // measuring
    
      uint8_t low  = ADCL; // must read ADCL first - it then locks ADCH
      uint8_t high = ADCH; // unlocks both
    
      long result = (high << 8) | low;
    
      result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000
      return result; // Vcc in millivolts
    }
    


  • I correct this and try again after work. Yesterday i do not find time.

    @mfalkvidd said:

    @Fat-Fly replace

    const int SENSOR_ANALOG_PINS[] = { 0 };
    

    with

    const int SENSOR_ANALOG_PINS[] = { A0 };
    

    Connect like this, except use D8 instead of A1 (the connection displayed is for a newer version of the sketch, which supports alternating polarity)



  • @mfalkvidd : Maybe change sleeping time to 60 min and STABILIZATION_TIME 1000 to 500 ms or smaller ? This place is pure lost energy. Why not to try without stablization time ?


  • Mod

    @Fat-Fly with the current solution it looks like I will get many years of battery life. Why make the solution worse without any gain?

    Without stabilization time you will get very unreliable results. I suggest you try and see what happens. Compare readings with and without stabilization times.


Log in to reply
 

Suggested Topics

  • 8
  • 2
  • 7
  • 44
  • 5
  • 1

74
Online

11.4k
Users

11.1k
Topics

112.7k
Posts