/* * irda_switch_04_03_2021_tb.c * * Created: 04.03.2021 21:42:42 * Author : Alle Benutzer */ /*--------------------------------------------------------------------------------------------------------------------------------------------------- * * IR-Steckdose v0.5 2012/09/16 * * ATTINY85 @ 8 MHz (int. rc-osc) * * Fuses: lfuse: 0xE2 hfuse: 0xDF efuse: 0xFF * *--------------------------------------------------------------------------------------------------------------------------------------------------- */ /*========= ToDo =============== - multiple addresses on same remote leads to not switching on relais - timeout for teachin mode - contact irmp author regarding //120908 andy - = -> |= TIMSK |= 1 << OCIE1A; // OCIE1A: Interrupt by timer compare #endif */ /*======== users guide ========== - code will be stored in eeprom to be retained after power cycle - press button for relais toggle - hold button (5sec) to enter teachin mode (slow blinking 4 times per sec) - blinks 20 times per sec if any ir code is received */ //#define MCU __AVR_ATtiny44A__ //#define __AVR_ATtiny84A__ #define _ATMEL_AVR_ #define F_CPU 8000000UL #define F_INTERRUPTS 15000 #define IRMP_PORT_LETTER A #define IRMP_BIT_NUMBER 7 #include "avr/io.h" #include "irmp.h" #include #include #include #include #include #include #ifndef F_CPU #error F_CPU unkown #endif void timer1_init (void){ #if defined (__AVR_ATtiny45__) || defined (__AVR_ATtiny85__) // ATtiny45 / ATtiny85: #if F_CPU >= 16000000L OCR1C = (F_CPU / F_INTERRUPTS / 8) - 1; // compare value: 1/15000 of CPU frequency, presc = 8 TCCR1 = (1 << CTC1) | (1 << CS12); // switch CTC Mode on, set prescaler to 8 #else OCR1C = (F_CPU / F_INTERRUPTS / 4) - 1; // compare value: 1/15000 of CPU frequency, presc = 4 TCCR1 = (1 << CTC1) | (1 << CS11) | (1 << CS10); // switch CTC Mode on, set prescaler to 4 #endif #endif #if defined (_AVR_ATmega85_) // ATmegaXX: OCR1A = (F_CPU / F_INTERRUPTS) - 1; // compare value: 1/15000 of CPU frequency TCCR1B = (1 << WGM12) | (1 << CS10); // switch CTC Mode on, set prescaler to 1 #endif #if defined (__AVR_ATtiny45__) || defined (__AVR_ATtiny85__) // ATtiny45 / ATtiny85: #ifdef TIMSK1 TIMSK1 = 1 << OCIE1A; // OCIE1A: Interrupt by timer compare #else //120908 andy - = -> |= TIMSK |= 1 << OCIE1A; // OCIE1A: Interrupt by timer compare #endif #endif #if defined (__AVR_ATtiny44__) || defined (__AVR_ATtiny44A__) || defined (__AVR_ATtiny84__) || defined (__AVR_ATtiny84A__) // ATtiny44 / ATtiny44a / ATtiny84 / ATtiny84a // Timer Setup ------------ // Interrupts ausschalten //cli(); TCCR1A = 0; // register setzen TCCR1B = 0; // Register setzen TCNT1 = 0; // register setzen OCR1A = (F_CPU / F_INTERRUPTS / 4) - 1; // compare value: 1/15000 of CPU frequency, presc = 4 TCCR1B = (1 << WGM12) | (1 << CS11) | (1 << CS10); // switch CTC Mode on, set prescaler to 4 // Output Compare Match A Interrupt Enable TIMSK1 |= (1 << OCIE1A); //Interrupt initialisieren //ISR(TIM1_COMPA_vect) #endif } /*--------------------------------------------------------------------------------------------------------------------------------------------------- * Timer 1 output compare A interrupt service routine, called every 1/15000 sec *--------------------------------------------------------------------------------------------------------------------------------------------------- */ //#ifdef TIM1_COMPA_vect // ATtiny84 //ISR(TIM1_COMPA_vect) //#else //ISR(TIM1_COMPA_vect) //#endif ISR(TIM1_COMPA_vect) { (void) irmp_ISR(); // call irmp ISR // call other timer interrupt routines... } //120809 andy - PB0 for irreceiver input (see irmpconfig.h) // define TSOP input PA0 wie beschrieben in irmpconfig.h #define LED_PIN PA1 // pin 12 #define BUTTON_PIN PA2 // pin 11 #define RELAIS_PIN PA3 // pin 10 #define LED_CONTROL_PIN PA5 // pin 8 volatile uint32_t systemtime = 0; ISR( TIM0_COMPA_vect ){ // every 1ms systemtime++; } uint32_t millis(){ return systemtime; } void EEPROM_write(unsigned char ucAddress, unsigned char ucData){ while(EECR & (1< 1ms) OCR0A = 124; TIMSK0 |= (1 << OCIE0A); // enable timer compare match interrupt (page 84) //unsigned char teached_code[5]; int buttonState = 1; // the current reading from the input pin int teachin = 0; // flag for teachin mode int oldButtonState = 0; uint32_t startTimeButton = 0; // starttime of button press DDRA |= 1 << LED_PIN; DDRA &= ~(1 << BUTTON_PIN); PORTA |= 1 << BUTTON_PIN; // internal pullup for button DDRA |= 1 << RELAIS_PIN; IRMP_DATA irmp_data; irmp_init(); // initialize irmp timer1_init(); // initialize timer 1 // anzeigen, was über den TSOP reinkommt DDRA |= (1 << LED_CONTROL_PIN); // LED pin to output DDRA |= (1 << LED_CONTROL_PIN); // switch LED off (active low) irmp_set_callback_ptr (led_callback); // ende des Blocks sei (); // enable interrupts for (;;){ buttonState = PINA & (1 << BUTTON_PIN); // important: buttonState could be > 1 ! if(oldButtonState != 0 && buttonState == 0){ // falling edge button pin when button pressed startTimeButton = millis(); } if(buttonState == 0 && (millis() - startTimeButton > 100 )){ // default 5000 ms hold 5s for teachin mode teachin = 1; } if(oldButtonState == 0 && buttonState != 0 && (millis() - startTimeButton > 10 ) && teachin == 0){ //hold 50ms for relais toggle PORTA ^= 1 << RELAIS_PIN; PORTA ^= 1 << LED_PIN; } if(teachin == 1){ PORTA ^= 1 << LED_PIN; _delay_ms(100); PORTA ^= 1 << LED_PIN; _delay_ms(100); } oldButtonState = buttonState; if (irmp_get_data (&irmp_data)){ PORTA ^= 1 << LED_PIN; //indicate any received ir code _delay_ms(50); PORTA ^= 1 << LED_PIN; _delay_ms(50); if (teachin == 1){ //store received code into eeprom //uint8_t tmp_sreg; //tmp_sreg = SREG; // save interrupt status //cli(); // disable interrupts EEPROM_write(0, irmp_data.protocol); EEPROM_write(1, irmp_data.address & 0xFF); EEPROM_write(2, irmp_data.address >> 8); EEPROM_write(3, irmp_data.command & 0xFF); EEPROM_write(4, irmp_data.command >> 8); //SREG = tmp_sreg; teachin = 0; }else{ //relais off if code in EEPROM / switch on if any button if( irmp_data.protocol == EEPROM_read(0) && (irmp_data.address & 0xFF) == EEPROM_read(1) && (irmp_data.address >> 8) == EEPROM_read(2) ){ if( (irmp_data.command & 0xFF) == EEPROM_read(3) && (irmp_data.command >> 8) == EEPROM_read(4) ){ PORTA &= ~(1 << RELAIS_PIN); //relais off / pin low PORTA &= ~(1 << LED_PIN); //led off / pin low }else{ PORTA |= 1 << RELAIS_PIN; //relais on / pin high PORTA |= 1 << LED_PIN; //led on / pin high } } } } } }