/* * 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 } }}