ATtiny85 Fridge-temp-humidity alarm
This project is for displaying temperature and humidity using DHT22, along with an alarm if Temp to high. Also has PIR to save power and only alert you when you open the fridge if temp to high. To alert you it uses a piezo that plays Westminster Chimes..
Fridge-demo-with-alarm.mp4
STL files for 3d printing:
Code:
Code:
/* * ATtiney85-2022-temp-pir-dht-22-oled 4/10/22 * Sherman Stebbins * //works with attiny85 at 8mhz with or without bootloader. * Tiny4kOLED - Drivers for SSD1306 controlled dot matrix OLED/PLED 128x32 displays * * Based on ssd1306xled, re-written and extended by Stephen Denne * from 2017-04-25 at https://github.com/datacute/Tiny4kOLED * * Attiny85 +-|_|-+ RST Ain0 (D 5) PB5 1| |8 Vcc DHT22 Ain3 (D 3) PB3 2| |7 PB2 (D 2) Ain1 pin2 SCL PIR Ain2 (D 4) PB4 3| |6 PB1 (D 1) pwm1 pin1 GND 4| |5 PB0 (D 0) pwm0 pin0 SDA +-----+4/17/22 UMpate:Added piezo with Westiminster chime if temp above MAXTEMP -- and it works!! * *///works with attiny85 at 8mhz and must be set there or oled won't work.
#define F_CPU 8000000UL#include <util/delay.h>#include <avr/sleep.h> // Sleep Modes#include <avr/power.h> // Power management#include <avr/wdt.h> // Watchdog timer#include <avr/interrupt.h>#include <TinyWireM.h>#include "SDHT.h"//#define TINY4KOLED_QUICK_BEGIN#include <Tiny4kOLED.h>#include <avr/io.h>
#define MAXTMP 42//#define DEBUG
static volatile uint16_t count=0;static volatile uint8_t toneIndex=0;static volatile uint16_t myLoop=0;static volatile uint16_t pauseCount=0;static volatile uint8_t myPause = 0;const uint8_t note[8] = {74,90,91,136,91,90,74,91} ;const uint8_t timer[8] = {33,53,28,55,28,53,33,28};
volatile uint8_t flag = 0;volatile uint8_t oledActive =0;volatile uint8_t toneActive =0;double t=0.0; //tempdouble h=0.0; //humiditySDHT dht;uint32_t delayMS;
ISR(TIM1_OVF_vect){ if(!oledActive && toneActive){ //toneActive=1; TCNT1 = timer[toneIndex]; //start count from 200 instead of 0// 1 1.8khz to 238 12.1khz with 1 as prescale. if(count>note[toneIndex] && myPause==0){ PORTB |=(1<<PB1); count=0; if(myLoop++ >=300){ //max myLoops is length of note //was 2400 if(toneIndex++ >= 7){ //max tones is how many tones toneIndex=0; myPause=1; //pause after playing round of notes toneActive=0; oledActive=0; PORTB &= ~(1<<PB1); } myLoop=0; } } if(count>toneIndex){ if(myPause)pauseCount++; if(pauseCount>50000){ //max pauseCount is length of pause before sound again 30,000 is about 10sec. 60,000 is about 18 sec. myPause=0; // toneActive=0; // oledActive=0; pauseCount=0; } } count++; if(count%4==0)PORTB &= ~(1<<PB1); //PORTB &= ~(1<<PB1); }}
ISR (PCINT0_vect) { if(!toneActive){ oledActive=1; cli(); }} // end of PCINT0_vect
void oledDisplay(void){ oled.clear(); oled.on(); oled.setCursor(0, 0); //oled.print(((double(dht.celsius) / 10)-2.0)*1.8+32); oled.print("T: "); oled.print(double(t)); oled.setCursor(0, 4); oled.print("H: "); oled.print(double(h)); oledActive=0;}
//void setup() {int main(){ #ifdef DEBUG Serial.begin(19200); #endif
// This example is for a 128x64 screen oled.begin(128, 64, sizeof(tiny4koled_init_128x64br), tiny4koled_init_128x64br); oled.clear(); oled.on(); oled.setFontX2(FONT8X16P); oledDisplay(); //new: DDRB |= (1<<PB1); PORTB &= ~(1<<PB1); TCCR1 = 0b00000001; TIMSK|=(1<<TOIE1); TCNT1=0; GIMSK |=(1<<PCIE); PCMSK |=(1<<PCINT4); ADCSRA = 0; // turn off ADC
while(1){ if(!toneActive && oledActive){ if (dht.read(DHT22, 3)); t=0; h=0; for(int i=0;i<6;i++){ t+= ((double(dht.celsius) / 10)-0)*1.8+32;//-0 is were to put offset _delay_ms(50); h+= ((double(dht.humidity) / 10)-10); _delay_ms(50); } t=t/6.0; h=h/6.0; _delay_ms(50); oledDisplay(); if(t>=MAXTMP)toneActive=1; } if(!toneActive){ _delay_ms(5000); oled.off(); set_sleep_mode (SLEEP_MODE_PWR_DOWN); power_all_disable (); sleep_enable (); // ready to sleep sei(); sleep_cpu(); // Snooooorrrrrr sleep_disable (); // precaution after wake up power_all_enable (); // power everything back on } }}
#define F_CPU 8000000UL#include <util/delay.h>#include <avr/sleep.h> // Sleep Modes#include <avr/power.h> // Power management#include <avr/wdt.h> // Watchdog timer#include <avr/interrupt.h>#include <TinyWireM.h>#include "SDHT.h"//#define TINY4KOLED_QUICK_BEGIN#include <Tiny4kOLED.h>#include <avr/io.h>
#define MAXTMP 42//#define DEBUG
static volatile uint16_t count=0;static volatile uint8_t toneIndex=0;static volatile uint16_t myLoop=0;static volatile uint16_t pauseCount=0;static volatile uint8_t myPause = 0;const uint8_t note[8] = {74,90,91,136,91,90,74,91} ;const uint8_t timer[8] = {33,53,28,55,28,53,33,28};
volatile uint8_t flag = 0;volatile uint8_t oledActive =0;volatile uint8_t toneActive =0;double t=0.0; //tempdouble h=0.0; //humiditySDHT dht;uint32_t delayMS;
ISR(TIM1_OVF_vect){ if(!oledActive && toneActive){ //toneActive=1; TCNT1 = timer[toneIndex]; //start count from 200 instead of 0// 1 1.8khz to 238 12.1khz with 1 as prescale. if(count>note[toneIndex] && myPause==0){ PORTB |=(1<<PB1); count=0; if(myLoop++ >=300){ //max myLoops is length of note //was 2400 if(toneIndex++ >= 7){ //max tones is how many tones toneIndex=0; myPause=1; //pause after playing round of notes toneActive=0; oledActive=0; PORTB &= ~(1<<PB1); } myLoop=0; } } if(count>toneIndex){ if(myPause)pauseCount++; if(pauseCount>50000){ //max pauseCount is length of pause before sound again 30,000 is about 10sec. 60,000 is about 18 sec. myPause=0; // toneActive=0; // oledActive=0; pauseCount=0; } } count++; if(count%4==0)PORTB &= ~(1<<PB1); //PORTB &= ~(1<<PB1); }}
ISR (PCINT0_vect) { if(!toneActive){ oledActive=1; cli(); }} // end of PCINT0_vect
void oledDisplay(void){ oled.clear(); oled.on(); oled.setCursor(0, 0); //oled.print(((double(dht.celsius) / 10)-2.0)*1.8+32); oled.print("T: "); oled.print(double(t)); oled.setCursor(0, 4); oled.print("H: "); oled.print(double(h)); oledActive=0;}
//void setup() {int main(){ #ifdef DEBUG Serial.begin(19200); #endif
// This example is for a 128x64 screen oled.begin(128, 64, sizeof(tiny4koled_init_128x64br), tiny4koled_init_128x64br); oled.clear(); oled.on(); oled.setFontX2(FONT8X16P); oledDisplay(); //new: DDRB |= (1<<PB1); PORTB &= ~(1<<PB1); TCCR1 = 0b00000001; TIMSK|=(1<<TOIE1); TCNT1=0; GIMSK |=(1<<PCIE); PCMSK |=(1<<PCINT4); ADCSRA = 0; // turn off ADC
while(1){ if(!toneActive && oledActive){ if (dht.read(DHT22, 3)); t=0; h=0; for(int i=0;i<6;i++){ t+= ((double(dht.celsius) / 10)-0)*1.8+32;//-0 is were to put offset _delay_ms(50); h+= ((double(dht.humidity) / 10)-10); _delay_ms(50); } t=t/6.0; h=h/6.0; _delay_ms(50); oledDisplay(); if(t>=MAXTMP)toneActive=1; } if(!toneActive){ _delay_ms(5000); oled.off(); set_sleep_mode (SLEEP_MODE_PWR_DOWN); power_all_disable (); sleep_enable (); // ready to sleep sei(); sleep_cpu(); // Snooooorrrrrr sleep_disable (); // precaution after wake up power_all_enable (); // power everything back on } }}
Other projects in Electronics