#include
#include
// set up analog pins 4 and 5 as powers supply for sensor
// so we can plug it straight in
#define VCC_PIN A5
#define GND_PIN A4
#define DLEVEL_PIN A3
#define ALEVEL_PIN A2
#define PUMP_CTRL 13
#define WATER_MILLISECONDS 3000
#define SOAK_SECONDS 32
#define SLEEP_SECONDS 640
volatile int sleep_count = 0; // Keep track of how many sleep cycles have been completed.
#define BAUD_RATE 9600
void setup(void)
{
pinMode(VCC_PIN, OUTPUT);
digitalWrite(VCC_PIN, HIGH);
pinMode(GND_PIN, OUTPUT);
digitalWrite(GND_PIN, LOW);
pinMode(DLEVEL_PIN, INPUT);
pinMode(PUMP_CTRL, OUTPUT);
digitalWrite(PUMP_CTRL, LOW); //PUMP OFF
Serial.begin(BAUD_RATE);
setup_watchdog(9);
}
void loop(void)
{
int iReading = analogRead(ALEVEL_PIN) ;
Serial.print("Soil reading ");
Serial.print(iReading);
if (iReading > 1000)
{
Serial.println(" : too dry");
waterPlant();
}
else if (iReading > 600)
{
Serial.println(" : very good");
}
else
{
Serial.println(" : too wet!");
}
Serial.println("About to sleep");
goToSleep(SLEEP_SECONDS);
Serial.println("Awake");
}
void waterPlant()
{
// turn on the motor for 5 seconds to water plant and then
// wait 30 seconds for water to filter into soil.
Serial.print("Watering ");
digitalWrite(PUMP_CTRL, HIGH);
delay(WATER_MILLISECONDS);
Serial.println("");
digitalWrite(PUMP_CTRL, LOW);
Serial.println("Waiting ");
goToSleep(SOAK_SECONDS);
Serial.println("Finished watering");
}
void goToSleep(int iSecs)
{
int sleep_total = iSecs / 8; // can't sleep for less than minimum
Serial.flush(); // ensure all serial data has gone
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // Set sleep mode.
sleep_enable(); // Enable sleep mode.
Serial.end();
while(sleep_total > 0)
{
sleep_mode(); // Enter sleep mode.
// ZZZZZZZZZZZzzzzzzzzzzzzzz.........
sleep_disable(); // Disable sleep mode after waking.
sleep_total--;
}
delay(100);
/* Re-enable the peripherals. */
power_all_enable();
Serial.begin(BAUD_RATE);
}
//****************************************************************
// 0 = 16ms
// 1 = 32ms
// 2 = 64ms
// 3 = 128ms
// 4 = 250ms
// 5 = 500ms
// 6 = 1 sec
// 7 = 2 sec
// 8 = 4 sec
// 9 = 8 sec
void setup_watchdog(int ii)
{
byte bb;
if (ii > 9)
{
ii = 9;
}
bb = ii & 7;
if (ii > 7)
{
bb |= B00100000;
}
bb |= (1<<WDCE);
// Clear the reset flag, the WDRF bit (bit 3) of MCUSR.
MCUSR &= ~(1<<WDRF);
// Set the WDCE bit (bit 4) and the WDE bit (bit 3)
// of WDTCSR. The WDCE bit must be set in order to
// change WDE or the watchdog prescalers. Setting the
// WDCE bit will allow updtaes to the prescalers and
// WDE for 4 clock cycles then it will be reset by
// hardware.
WDTCSR |= (1<<WDCE) | (1<<WDE);
// set new watchdog timeout value
WDTCSR = bb;
WDTCSR |= _BV(WDIE);
MCUSR = MCUSR & B11110111;
}
ISR(WDT_vect)
{
sleep_count ++; // keep track of how many sleep cycles have been completed.
}
One thought on “Low Power Plant Watering”