Thanks To Those That Went Before

It’s all too easy for me to overlook the efforts by amazing folks.  I find though when I stop and express gratitude, I am much happier.  More at peace.  So for purely selfish reasons, I thank:

  • Ron Sousa  of HDE for excellent 1:1’s in which he walked me through Cortex m0 power management registers and what to look for.  I is a credit to Contextual Electronics to have such amazing folks on staff.
  • Adafruit for products like the Feather line, the  INA219 Current Sensor Breakout.  For their excellent support.  For the way they seem to care about the workers.  For their videos.  I hope more companies become like Adafruit.  
  • Rick for his comments on this blog.  I find them very useful.  The most recent one being hook up a current sensor.  Thank you Rick.  I did this.  Talk about a great thing to do!

Open Source

The Arduino code for the Moisture Puck and the Controller (v3) can be found at this GitHub location.


It is unacceptable to recharge the battery after 3 days.  The Moisture Puck was burning on average about 25mA.  Given the Feather is powered by a 2000mAh LiPo, the back of the envelope calculation (2000/25/24 = 3.3 days) is “close enough” to what I observed when the Moisture Puck was in the soil sending measurements to the Controller.

The updated Moisture Puck code cuts down the power usage considerably.  For ~ 6 seconds each hour, it draws 32mA.  For the the majority of the rest, it draws 1.2mA.  There are occasional spike of ~5mA.  Averaging the spikes with the 1.2mA, it’s at about 1.45mA for the other 54 seconds of the hour.  So: 10% of the time, the Moisture Puck draws 32mA.  This is when packets are being sent/received to/from the Controller.  The other 90% of the time the Moisture Puck is sleeping, drawing about 1.45mA.  This comes to (.1*32) + (.9*1.45)  = 4.5mA.  Given this calculation, I hope to see the Moisture Puck’s battery last (2000/4.5/24 = 18.5 days….roughly 18 days.  The key to these power management improvements included:

  • Using the rtczero library.
  • Restructuring the code so that the Moisture Puck wakes up at an AM and PM watering time then sends packets.  The rest of the time the m0 and RFM69 are sleeping.
  • Only powering the moisture probe when it is being used.  Prior, the moisture probe’s V+ was wired directly to the Feather M0’s V+.  I moved the V+ wire to the Feather M0’s 12 GPIO pin and set the pin to HIGH when taking a measurement and then low once finished taking the measurement.
While this is a significant improvement, it is still higher than it need be.  I’ll save more power reduction exploration for a later time.

New Moisture Puck Firmware

  • More accurate time of day: MoisturePuck2007_v3.ino/Controller2007_v3.ino take advantage of Adafruit io’s time feed to set the time on the Moisture Puck.  This way, the Moisture Puck has an accurate time without the need of a RTC chip.
  • Less power used:

Less Powered Used

Measuring Current Draw

An essential tool for this exploration is Adafruit’s nifty INA219 Current Sensor Breakout. I modified a USB cable so that I could insert the INA219 into the power side of the circuit over USB.  


I hooked up the INA219’s I2C to the Arduino and run the getCurrent.ino sketch (found in Examples that come with the INA219 library) on the Arduino.  I suppose I could have more easily measured current through the battery (by more easily I mean I wouldn’t need to hack up a USB cable).  However, using the USB port for building/debugging is easier.  


  • about 13mA when the Feather m0 was in upload mode.
  • about 32 mA when sending/receiving RFM69 packets
  • about 1.2-1.5 mA when in rtc.standby() and the moisture sensor is not drawing power.
I would think deep sleep would draw less power (around 700µA?) and the 5mA spikes are suspicious.  I assume there are peripherals (e.g.: Flash) that are still on needlessly sucking up power.  For now, I’ll let that go to allow exploration into other areas that I’d like to improve on.

Turn Off the Moisture Sensor

One thing I noticed that was like “oh – right – duh” was the moisture sensor was being powered by the 3.3V pin of the Feather m0.  It was on all the time.  As noted by Chris Ruppel in his “Arduino soil moisture sensor” blog post, only send power to the sensor when actively taking a reading of the soil moisture. Powering only during these short moments helps avoid corrosion caused by the constant flow of electricity between the two pads of the sensor.

Besides corrosion, power consumption is 2.15mA when the moisture sensor is on and 1.45 when off.  The moisture sensor sucks up 700µA!

I attached the v+ of the moisture pin to pin 12 of the Feather and now turn the pin HIGH right before measuring then back to LOW after measuring.  Much better.


This version of the firmware is – happily – simpler.

  • Controller sets the time from Adafruit.io: A core assumption with this experience is the Moisture Puck knows the correct current time as well as the AM and PM watering times.  Neither Controller nor Moisture Puck have a RTC.  The Controller grabs the current time from Adafruit.io’s time feed.  Once the Controller’s firmware is loaded, it subscribes to Adafruit.io’s time feed.  The Controller waits around until it receives the current hour, minute, and seconds from Adafruit.io.  It then sets it’s time to these values.  The Controller switches to listening for a Moisture Info packet.
  • Controller listens for a Moisture Info packet: Once the time is set, the Controller listens for moisture info packets. 
  • Moisture Puck sends Moisture Info Packet: The Moisture Puck takes moisture readings when the firmware is first loaded and then at the AM and the PM watering hours.  The Moisture Puck sends the Moisture Info packet to the Controller and then waits to receive a Time Info packet.
  • Moisture Puck goes to sleep: Using APIs in the rtczero library, the moisture puck sets a wake up alarm and then goes into a deep sleep.
  • Controller gets a Moisture Info packet:  When the Controller gets a Moisture Info packet, it publishes the values to Adafruit.io.  The Controller then sets up a Time Info packet and sends it to the Moisture Puck.  This way the Moisture Puck knows the correct time.




That’s it for the update.  Please see the GitHub location above to get the code.  Thank you and please find many things to smile about.