Costs:
< 2 Euro if you are using ic-sockets for soldering the components together
(like here http://interface.khm.de/index.php/lab/experiments/sleep_watchdog_battery/)
Used Sensor (Homemade):
http://forum.arduino.cc//index.php?topic=195258.msg1441018#msg1441018
Resistors for the LEDs are not needed when using <=3V.
Programing:
You need to know how to program an ATtiny with an Arduino or ISP-Programmer
http://forum.arduino.cc//index.php?topic=194184.msg1434240#msg1434240
/*
//************************************************
* Damp/Wet Wall detector with ATtiny13a and two LED
* by Enam
* no warrantys or guarantees at all
//***********************************************
ATtiny13 8Pin Pins:
// +-\/-+
//Reset ADC0 (D 5) PB5 1| |8 Vcc
// ADC3 (D 3) PB3 2| |7 PB2 (D 2) ADC1
// ADC2 (D 4) PB4 3| |6 PB1 (D 1) PWM1
// GND 4| |5 PB0 (D 0) PWM0
// +----+
Program objective:
Wet Wall Alarm (Red LED flashing, quicker if more damp) if moisture is to high and condenses at the wall
(dewpoint / broken "tube")
Hardware/Pins:
3Volt Batterie (2-2,7V with 2x "ready2use" NIMH rechargable Batteries)
Voltagedivider between
two pins in the wall (Rwall) (D1) (>30M dry 22,5-30M=ok <22,5M Wet)
and 20MOhm (D0)
sensing with (D2)
Outputpins (D0, D1)are toggling for squarewave AC
to prevent corrosive layers increasing resistance of the pins.
D3 Red LED (to GND)
D4 Green LED (to GND)
D2 /AD1 = ADC in
D1 = toggle output pinA
D0 = toggle output pinB
Program:
Part1:
Outputpins on
(a high, b low)
read adc
to have same amount of time used in both parts:
do as if writing to led, write 0
sleep as in part2
Part2:
toggle output pins
(a low, b high)
read adc ()
blink very slow green when dry (to see its working at all), quicker when getting weter
blink red when too wet
sleep in LED on time
sleep in LED off time (up to 8 sec)
Mainparts of the "sleep" code are from Lab3, Academy of Media Arts Cologne "Nightingale" and "elabz"
http://interface.khm.de/index.php/lab/experiments/sleep_watchdog_battery/
http://www.elabz.com/attiny13-12-led-blinker-with-motion-detection-and-scripted-blinks/
Todo:
Trafficlight LED
// Green Red
// 3 Areas: dry normal wet
// >30M <30->22,5 <22,5 = G GR R
// 613 541 (not 460)
// Green Yellow Red with 3Led on 2Pins+Supply
//5 Areas: dry -- normal normalwet wet -- wetwet
// 100-30M 30-22,5 22,5-15 15-7,5 7,5-0 = G GY Y YR R
*/
//################# for Sleep ##########
#include <avr/sleep.h> // sleep code by insidegadgets.com
volatile boolean f_wdt=1;
//#####################################
//Variable Sensor
int Sensorval=0;
int delayforsleep=0;
//Led Pins
byte LedRedPin=3;
byte LedGreenPin=4;
//Output Pins (toggle pins)
byte APin=1;
byte BPin=0;
//Sens Pin (ADC1)
byte ADCPin=A1;
// Defining state of wetness in ADC Values, calculated by voltage divider resitances of wall
int dry=613; //
//int normalw=292; // not nedded
int wet=541; // not 460
void setup()
{
pinMode(LedRedPin, OUTPUT); //
pinMode(LedGreenPin, OUTPUT); //
pinMode(ADCPin, INPUT); //
pinMode(APin, OUTPUT); //
pinMode(BPin, OUTPUT); //
//#######################for Sleep, part void setup()
//from http://interface.khm.de/index.php/lab/experiments/sleep_watchdog_battery/
// CPU Sleep Modes
// SM2 SM1 SM0 Sleep Mode
// 0 0 0 Idle
// 0 0 1 ADC Noise Reduction
// 0 1 0 Power-down
// 0 1 1 Power-save
// 1 0 0 Reserved
// 1 0 1 Reserved
// 1 1 0 Standby(1)
/*
cbi( MCUCR,SE ); // sleep enable, power down mode
cbi( MCUCR,SM0 ); // power down mode
sbi( MCUCR,SM1 ); // power down mode
cbi( MCUCR,SM2 ); // power down mode
*/
// from http://elabz.com/attiny13-12-led-blinker-with-motion-detection-and-scripted-blinks/
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
//##############################################
}
void loop()
{
// ------- Part1, result not displayed on leds, but both parts should need same amount of time
// use same prg as part2 for same amount of time, but dont light leds
// values would be "wrong", because of inverted voltage supply compared to part2
// The lower wetness, the higher delaytime for blinking (saving energy by blinkin seldom,see its working, )
// Output pins on a=high b=low
digitalWrite(APin,1);
digitalWrite(BPin,0);
sleepuntil(0);
analogRead (ADCPin);
show(0);
// -----Part2,
digitalWrite(APin,0);
digitalWrite(BPin,1);
sleepuntil(0);
Sensorval = analogRead (ADCPin);
show(1);
}
//------- subprg show(), tell it if leds should show result or not with show(1); or show(0); in void loop
void show(int onoff)
{
// Trafficlight
// >30M <30->22,5 <22,5 = G GR R
// dry=613 wet=460
// Lits GR together from 22.5 tro 30MOhm
if (Sensorval <= dry)
{
digitalWrite(LedRedPin, onoff);
}
if (Sensorval >= wet)
{
digitalWrite(LedGreenPin,onoff);
}
/// on-time with sleep
sleepuntil(0);
digitalWrite(LedGreenPin,0);
digitalWrite(LedRedPin, 0);
// The lower wetness (dryer), the higher delaytime for blinking (saving energy by blinkin seldom,see its working, )
//calc delay for sleep
delayforsleep= Sensorval/113;
//sleepuntil() knows only 0-9 different delay times
//1023/123=9.... 126/127=0...
sleepuntil(delayforsleep);
// 0=16ms, 1=32ms,2=64ms,3=128ms,4=250ms,5=500ms
// 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec
}
//#################Sleep Subprgs######################
// Call for sleep
// 0=16ms, 1=32ms,2=64ms,3=128ms,4=250ms,5=500ms
// 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec
void sleepuntil(int timer)
{
setup_watchdog(timer);
system_sleep();
}
// From http://interface.khm.de/index.php/lab/experiments/sleep_watchdog_battery/
//****************************************************************
// set system into the sleep state
// system wakes up when watchdog is timed out
void system_sleep()
{
cbi(ADCSRA,ADEN); // switch Analog to Digitalconverter OFF
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here
sleep_enable();
sleep_mode(); // System sleeps here
sleep_disable(); // System continues execution here when watchdog timed out
sbi(ADCSRA,ADEN); // switch Analog to Digitalconverter ON
}
//****************************************************************
// 0=16ms, 1=32ms,2=64ms,3=128ms,4=250ms,5=500ms
// 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec
void setup_watchdog(int ii)
{
byte bb;
if (ii > 9 ) ii=9;
bb=ii & 7;
if (ii > 7) bb|= (1<<5);
bb|= (1<<WDCE);
MCUSR &= ~(1<<WDRF);
// start timed sequence
WDTCR |= (1<<WDCE) | (1<<WDE);
// set new watchdog timeout value
WDTCR = bb;
//---------- WDTIE instead of WDIE (Datasheet Attiny page42)
WDTCR |= _BV(WDTIE);
}
//****************************************************************
// Watchdog Interrupt Service / is executed when watchdog timed out
ISR(WDT_vect)
{
f_wdt=1; // set global flag
}
//##########################################################
Kind Regards
Enam
Any advice for improving / correcting mistakes is welcome!
If it is of any Interest, I can give advice how the code should work also on Arduino with an ATmega168/328.