As part of my RF24 sensor revamp, I thought I’d switch from the Jeelib low power routines to the Rocketscream library. It seems a bit unmaintained so I actually made a fork and merged in some of the PR’s which add support for the ATmega1284P and ATtiny85 and fix a few typo’s too. My fork can be found on Github.

Anyway, whilst playing with my new rain sensor I thought it would be cool to save some battery power and only wake the MCU when it was raining, I didn’t need to be told it wasn’t raining every 3mins or whatever. So I decided to wire up the digital output of the sensor to pin 2 on the Nano, which is hardware interrupt 0.

The sensor has a trimpot on it that allows you to set the level to which it will give a LOW reading (as its a resistance comparator) and the LED will turn on. So I set that to about 450 which is a single drop of water on the board, it seems to max out at about 900 when the board is submerged in a glass of water!

The pinout is:

Sensor - Nano
VCC - 3.3v
GND - GND
AO - A7
DO - D2

The code is below. Essentially it completely sleeps the MCU and only wakes when its raining, it then gives us the (analogue) level of rainfall along with the millis() count to prove that its been asleep:

#include "LowPower.h"

const int dPin = 2; // interrupt 0
const int aPin = A7;

// isr function
void wakeUp()
{
}

void setup()
{
    Serial.begin(9600);
    pinMode(aPin, INPUT);
    pinMode(dPin, INPUT);
}

void loop()
{
    // allow wake up pin to trigger interrupt on low
    attachInterrupt(0, wakeUp, LOW);

    // enter power down state - wake up when wake up pin is low
    LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);

    // disable external pin interrupt on wake up pin
    detachInterrupt(0);

    // print analogue reading
    Serial.print("Uptime: ");
    Serial.println(millis());
    Serial.print("It is raining, ");
    int moisture = 1023-analogRead(aPin);
    Serial.print("moisture level: ");
    Serial.println(moisture);
    Serial.println();

    // blink led to show we are awake
    digitalWrite(13, HIGH);
    delay(200);
    digitalWrite(13, LOW);
    delay(200);
}

Makefile:

BOARD_TAG = nano328
MONITOR_PORT = /dev/ttyUSB0
ARDUINO_LIBS = LowPower

include /usr/share/arduino/Arduino.mk

The flaw in my logic here is that the MCU won’t sleep again until it stops raining, so a lot of rain could drain the battery. I’ll probably switch back to using a timer e.g. wake every 3mins, or look into double falling-edge detection with a delay in between.

Update: I found that desoldering the LED’s and regulator on the Pro Mini made Blink (without the LED) run at 3.5mA, using the LowPower sleep mode got that down to 4.5uA!