Low Power Plant Watering

#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

Leave a Reply

Your email address will not be published. Required fields are marked *