I was looking for a plant moisture sensor so I knew when to water my plants but wasn't happy with what was currently available.
My requirements were:

thin shape - I didn't like how wide and stubby most sensors were
multiple LEDs - to show the moisture level in more granularity
long battery life - ideally a year on a cr2032
low cost - < £2 per unit.

I've managed to design one that meets most of these

octoplant is designed around an attiny824. A custom PCB combines it along with 12 LEDs, a wide trace that acts as a capacitive moisture sensor, a button, and a cr2032 battery (holder).

Simply press the button to light the leds. The soil moisture level is measured and then compared to the calibrated wet and dry points. By holding down the button you can save a moisture level and this led will blink on all further readings (I like to use this to save the level of moisture I usually water at).


This was the second pcb Ive designed and I'm quite happy with how it came out. If I were to do it again I'd probably use 0603 components (rather than 0805) to save space and make the sensor a little longer.

The operating principle is that a capacitor changes its capacitance depending on the dielectric. A large trace and the surrounding ground fill act as the 'plates' of the capacitor. The soil acts as the dielectric which has different properties depending on the moisture level. This acts as the capacitor in a low pass filter, which filters a high frequency pwm signal. This is then smoothed by a further capacitor allowing an analogue voltage to be read by the mcu which correlates to the moisture level.

I was really happy with the experience of using the attiny824. It requires only a decoupling capacitor and using the excellent TinyMega Arduino core you can have a great development experience. The chip also supports programming using only the rest pin so it's very easy to program in circuit and without using up any pins. It's was also an excellent price ~£0.80 and simple to hand solder. Its a shame its been a victim of the chip shortage. It could also run directly from the coin cell and at a variety of voltages.

 I managed to get quite good deep sleep current iirc ~20 microamps. But this was quite tricky due in part to not really having a multimeter capable of measuring this and also some behaviour of the chip not matching the datasheet. It turns out that the adc also needs to be separately disabled before entering deep sleep, and also unused pins should be pulled low. Battery life has been around 6 months

The moisture sensor actually works quite well and the full range of the 12 LEDs is useful. On first power up, and if you hold the button while powering up, the device enters calibration mode. Taking one reading while the sensor is in a glass of water and one while it's just in air is enough to calibrate the sensor.

To fit 12 LEDs on the device I used charlieplexing so I only needed 4 pins. Then I wrote some interrupts to correctly blink the LEDs in order for persistence of vision to take over. I'd probably use charlieplexing again for any similar projects, even though it was much tricker from a software perspective to get working. In the end I managed to write some helper functions that allow the LEDs to each be blinked a different rates and independently turned on an off. This was all interrupt based and so doesn't effect the main program execution.

I can see moisture being an issue. I've nearly already lost one sensor to corrosion (started working again after it was cleaned with isopropyl alcohol). I think more careful watering could have fixed this. I experimented with coasting the entire sensor in clear nail varnish however this made the sensor no longer work. I think a case for the top half or simply covering just the top half in nail varnish could fix this. Maybe some sort of conformal coating would be good too.


Writing the firmware was quite fun. I picked to use the arduino framework as I was familiar with it and there was a good core for the attiny (TinyMega). However I ended up needing closer control of the hardware (using timers and interrupts) and so mostly ended up reading the datasheet and manipulating registers directly. So arduino ended up getting in the way a little, so if I were to do it again I may skip using it.