Arduino code

Upload this code in Attiny85 module.

Text Box

/* Sketch for ATtiny85. Based on the Digispark (Use Digispark Default 16.5 MHz), no port select.

* Compile, Upload and then coonect ATtiny85 to USB.

* {ATtiny85 alone pins: 1=PB5, 2=PB3,ADC3, 3=PB4,ADC2, 4=GND, 5=PB0,MOSI,SDA, 6=PB1,MISO, 7=PB2,SCK,SCL, 8=VCC}

* ATtiny Pin 5 = PB0 (P0 on ATTiny board) = SDA

* ATtiny Pin 7 = PB2 (P2 on ATTiny board) = SCK=SCL

* ATtiny PB1 = to SWITCH power of a POLOLU MOSFET: power the Pump (6-12V)

* ATtiny PB3 = Humidity sensor output= analog read

* ATtiny PB4 = Power for the sensor (pin: 20mA = sufficient)

* Uses 26 mA for CPU, Sensor + Mosfet on + Display

* Uses 20 mA for CPU + Display (between readings)

* Uses 8 mA in deep sleep (Display on only)

* Between reads: deep sleep. Protection against over-watering by humidity sensor.

*/

#include <TinyWireM.h> // I2C Master lib for ATTinys which use USI

#include <LiquidCrystal_attiny.h> // for LCD w/ GPIO MODIFIED for the ATtiny85

#define GPIO_ADDR 0x27 // the address i2c for this 8x2 LCD

LiquidCrystal_I2C lcd(GPIO_ADDR, 8, 2); // set the I2C address & 8/16 chars / 2 lines

// Utility sleep macros

#include <avr/sleep.h>

#include <avr/wdt.h> //Needed to enable/disable watch dog timer

#define adc_disable() (ADCSRA &= ~(1<<ADEN)) // disable ADC (before power-off)

#define adc_enable() (ADCSRA |= (1<<ADEN)) // re-enable ADC

#define LED_BUILTIN PB5 // Change PB5 to PB1 only for testing delays

#define powsen PB4 // PB4 provides 4.1V to power the humidity sensor

#define sensor PB3 // Sensor data pin for analog read

#define pump PB1 // Pin for LED & MOSFET feeding the Pump

// Reading humidity once in 30min...1hour is sufficient:

int D, H, nr=100; // Attiny85 will sleep nr*9 (sec.) (E.g. 200=>30min; 400=>1h))

unsigned long psec, corr=nr*300; // time counter since start or watering

//This runs each time the watch dog wakes us up from sleep

ISR(WDT_vect) {

//Don't do anything. This is just here for wake up.

}

void setup() {

lcd.init(); lcd.backlight(); lcd.clear();

pinMode(powsen,OUTPUT); // Power to the sensor by powsen PIN

pinMode(sensor, INPUT); // Sensor read value from sensor PIN

pinMode(pump, OUTPUT); // Pump control PIN

pinMode(LED_BUILTIN, OUTPUT);

set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here

sleep_enable(); // enables the sleep bit in the mcucr register, so sleep is possible

psec=0; // Starting moment

}

void loop() {

adc_enable();

digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)

digitalWrite(powsen,HIGH); // Power on the sensor

int humidity=analogRead(sensor); // Read sensor data

delay(200); // A short time, just to read the sensor!

digitalWrite(powsen,LOW); // Power off the humidity sensor

digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW

// Convert analog values from sensor to humidity. Tested: free and short-circuit.

humidity = constrain(humidity, 85, 660); // accept values between these limits for 4.8V on sensor

humidity = map(humidity, 85, 660, 0, 100); // and map them between 0 and 100%

// The pump is started if humidity drops below a level determined for each plant!

// Then, the pump cannot restart before 'pause', waiting for water to diffuse in the pot.

// Set below the DRY Limit for Your Plant (E.G.: 95):

if (humidity<=95) {

digitalWrite(pump,HIGH); // Power the pump through a Pololu-LV-MOSFET

delay(15000); // Time [ms] to pump the tested REQUIRED volume of WATER to the plant!!

digitalWrite(pump,LOW); // Power down the pump through the MOSFET

delay(1000);

psec=0; // Reset timer of water pumping.

// Test that after [nr*9] seconds (15min in this case), water was absorbed and sensor is above threshold.

// Otherwise, the pump will start again after. Warning: too much water can be bad for your plant!

}

// Show the results on the screen

lcd.setCursor(0, 0); lcd.print("Mimosa:");

if (humidity>95)

if (humidity>97)

lcd.print(")");

else

lcd.print("|");

else

lcd.print("(");

lcd.setCursor(0, 1);

lcd.print(humidity); lcd.print("%"); // Write on LCD the humidity (%) and

D=psec/86400; // days since last watering/reset ...

H=(psec%86400)/3600; // and hours

lcd.print(D); lcd.print("d");

lcd.print(H); lcd.print("h ");

// Most of the time, go to sleep for 'nr' multiples of 8 seconds + opp. time

adc_disable(); // ADC uses ~320uA

for (int i=0; i<nr; i++){

setup_watchdog(9); //Setup watchdog to go off after 9->8s sec + opp. time

sleep_mode(); //Go to sleep! Wake up n sec later and work

}

delay(corr); // Timer correction since sleep is less than nr*9 sec.

psec+=nr*9; // Update timer after deep sleep for Half an hour

}

// ===================================================================

void setup_watchdog(int timerPrescaler) {

//Sets the watchdog timer to wake up, but not reset

//0=16ms, 1=32ms, 2=64ms, 3=128ms, 4=250ms, 5=500ms

//6=1sec, 7=2sec, 8=4sec, 9=8sec

//From: http://interface.khm.de/index.php/lab/experiments/sleep_watchdog_battery/

if (timerPrescaler > 9 ) timerPrescaler = 9; //Limit incoming amount to legal settings

byte bb = timerPrescaler & 7;

if (timerPrescaler > 7) bb |= (1<<5); //Set the special 5th bit if necessary

//This order of commands is important and cannot be combined

MCUSR &= ~(1<<WDRF); //Clear the watchdog reset

WDTCR |= (1<<WDCE) | (1<<WDE); //Set WD_change enable, set WD enable

WDTCR = bb; //Set new watchdog timeout value

WDTCR |= _BV(WDIE); //Set the interrupt enable, will keep unit from resetting after each int

}