Skip to content
Permalink
Browse files

Handle large moisture changes immediately

This effectively bypasses the rolling average on large changes
by making two measurements, one for each direction/polarity.

Otherwise, the increase of moisture when watering will be smeared
out over two readings, which will make the graph look strange.

On small changes only one reading is performed, just as before.
Always doing two readings would almost halve battery life.
  • Loading branch information...
mfalkvidd committed Feb 28, 2016
1 parent 5e98c5e commit 299a4b273aee49b27a4cb3363574afec83ac2cd5
Showing with 23 additions and 13 deletions.
  1. +23 −13 arduino-plantmoisture.ino
@@ -7,6 +7,7 @@
#define CHILD_ID_MOISTURE 0
#define CHILD_ID_BATTERY 1
#define SLEEP_TIME 1800000 // Sleep time between reads (in milliseconds)
#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 3000 // 3,000 millivolts for 2xAA
#define BATTERY_ZERO 2800 // 1,900 millivolts (1.9V, limit for nrf24l01 without step-up. 2.8V limit for Atmega328 without BOD disabled))
@@ -36,24 +37,19 @@ void setup()

void loop()
{
pinMode(SENSOR_ANALOG_PINS[direction], INPUT_PULLUP); // Power on the sensor
analogRead(SENSOR_ANALOG_PINS[direction]);// Read once to let the ADC capacitor start charging
gw.sleep(STABILIZATION_TIME);
int moistureLevel = (1023 - analogRead(SENSOR_ANALOG_PINS[direction]));

// 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
// Always send moisture information so the controller sees that the node is alive
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 value
if (oldMoistureLevel == -1) { // First reading, save current value as old
oldMoistureLevel = moistureLevel;
}
gw.send(msg.set((moistureLevel + oldMoistureLevel + 0.5) / 2 / 10.23, 1));
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();
}
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.
@@ -64,6 +60,20 @@ void loop()
gw.sleep(SLEEP_TIME);
}

int readMoisture() {
pinMode(SENSOR_ANALOG_PINS[direction], INPUT_PULLUP); // Power on the sensor
analogRead(SENSOR_ANALOG_PINS[direction]);// Read once to let the ADC capacitor start charging
gw.sleep(STABILIZATION_TIME);
int moistureLevel = (1023 - analogRead(SENSOR_ANALOG_PINS[direction]));

// 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

0 comments on commit 299a4b2

Please sign in to comment.
You can’t perform that action at this time.