Hi, I'm working with ATMEGA328P at 8Mhz..
I have Timer0 in CTC mode with COMPA enable for receiving infrared signal..the code works and I can get the address of remote button..
Seperately, I also have Timer2 in PWM with OVF to dim LED...this also works..
The problem now is..after merging these two and compiled without errors, only my LED lights up with correct brightness...meaning PWM works..but my ir remote doesn't work anymore..
I tried to uncomment Timer2 clock prescaler that disables the LED...again the ir remote works...
How can I have both LED and ir remote to work..? I would like to adjust the brightness of LED using the ir remote..
I am using ir remote code from Łukasz Marcin Podkalicki
/** * Copyright (c) 2016, Łukasz Marcin Podkalicki <lpodkalicki@gmail.com> * IR Remote for ATtiny13 */ #include <util/delay.h> #include <avr/interrupt.h> #include "ir.h" #include "Atmel/remote.h" volatile uint16_t IR_timeout = 0; volatile uint16_t IR_counter = 0; volatile uint32_t IR_rawdata = 0; uint8_t IR_event = 0; uint8_t IR_proto_event = 0; uint8_t IR_index = 0; uint32_t IR_data = 0; void IR_init() { cli(); DDRD &= ~_BV(IR_IN_PIN); // set IR IN pin as INPUT PORTD &= ~_BV(IR_IN_PIN); // set LOW level to IR IN pin TCCR0A = (1<<WGM01); // set timer counter mode to CTC TCCR0B = (0<<CS02) | (0<<CS01) | (1<<CS00); // set prescaler to 1 TIMSK0 = (1<<OCIE0A); // enable Timer COMPA interrupt OCR0A = IR_OCR0A; // set OCR0n to get ~38.222kHz timer frequency EIMSK |= _BV(INT0); // enable INT0 interrupt handler EICRA &= ~_BV(ISC01); // trigger INTO interrupt on raising and falling edge EICRA |= _BV(ISC00); sei(); // enable global interrupts } int8_t IR_read(uint8_t *address, uint8_t *command) { if (!IR_rawdata) return IR_ERROR; *address = IR_rawdata; *command = IR_rawdata >> 16; IR_rawdata = 0; return IR_SUCCESS; } static int8_t IR_NEC_process(uint16_t counter, uint8_t value) { int8_t retval = IR_ERROR; switch(IR_proto_event) { case IR_PROTO_EVENT_INIT: /* expecting a space */ if (value == HIGH) { if (counter > 330 && counter < 360) { /* a 4.5ms space for regular transmition of NEC Code; counter => 0.0045/(1.0/38222.0) * 2 = 344 (+/- 15) */ IR_proto_event = IR_PROTO_EVENT_DATA; IR_data = IR_index = 0; retval = IR_SUCCESS; } else if (counter > 155 && counter < 185) { /* a 2.25ms space for NEC Code repeat; counter => 0.00225/(1.0/38222.0) * 2 = 172 (+/- 15) */ IR_proto_event = IR_PROTO_EVENT_FINI; retval = IR_SUCCESS; } } break; case IR_PROTO_EVENT_DATA: /* Reading 4 octets (32bits) of data: 1) the 8-bit address for the receiving device 2) the 8-bit logical inverse of the address 3) the 8-bit command 4) the 8-bit logical inverse of the command Logical '0' – a 562.5µs pulse burst followed by a 562.5µs (<90 IR counter cycles) space, with a total transmit time of 1.125ms Logical '1' – a 562.5µs pulse burst followed by a 1.6875ms(>=90 IR counter cycles) space, with a total transmit time of 2.25ms */ if (IR_index < 32) { if (value == HIGH) { IR_data |= ((uint32_t)((counter < 90) ? 0 : 1) << IR_index++); if (IR_index == 32) { IR_proto_event = IR_PROTO_EVENT_HOOK; } } retval = IR_SUCCESS; } break; case IR_PROTO_EVENT_HOOK: /* expecting a final 562.5µs pulse burst to signify the end of message transmission */ if (value == LOW) { IR_proto_event = IR_PROTO_EVENT_FINI; retval = IR_SUCCESS; } break; case IR_PROTO_EVENT_FINI: /* copying data to volatile variable; raw data is ready */ IR_rawdata = IR_data; break; default: break; } return retval; } static void IR_process() { uint8_t value; uint16_t counter; /* load IR counter value to local variable, then reset counter */ counter = IR_counter; IR_counter = 0; /* read IR_IN_PIN digital value (NOTE: logical inverse value = value ^ 1 due to sensor used) */ value = (PIND & (1 << IR_IN_PIN)) > 0 ? LOW : HIGH; switch(IR_event) { case IR_EVENT_IDLE: /* awaiting for an initial signal */ if (value == HIGH) { IR_event = IR_EVENT_INIT; } break; case IR_EVENT_INIT: /* consume leading pulse burst */ if (value == LOW) { if (counter > 655 && counter < 815) { /* a 9ms leading pulse burst, NEC Infrared Transmission Protocol detected, counter = 0.009/(1.0/38222.) * 2 = 343.998 * 2 = 686 (+/- 30) */ IR_event = IR_EVENT_PROC; IR_proto_event = IR_PROTO_EVENT_INIT; IR_timeout = 7400; } else { IR_event = IR_EVENT_FINI; } } else { IR_event = IR_EVENT_FINI; } break; case IR_EVENT_PROC: /* read and decode NEC Protocol data */ if (IR_NEC_process(counter, value)) IR_event = IR_EVENT_FINI; break; case IR_EVENT_FINI: /* clear timeout and set idle mode */ IR_event = IR_EVENT_IDLE; IR_timeout = 0; break; default: break; } } extern char eKEY;//from remote.c emergency key interrupt ISR(INT0_vect) { IR_process(); } ISR(TIMER0_COMPA_vect) { /* When transmitting or receiving remote control codes using the NEC IR transmission protocol, the communications performs optimally when the carrier frequency (used for modulation/demodulation) is set to 38.222kHz. */ if (IR_counter++ > 10000) IR_event = IR_EVENT_IDLE; if (IR_timeout && --IR_timeout == 0) IR_event = IR_EVENT_IDLE; }
In main:
/* * TEST.c * * Created: 7/24/2019 2:39:37 PM * Author : User10 */ #include <avr/io.h> #include <avr/interrupt.h> #include <util/delay.h> #include <stdio.h> #include "Andy Gock/uartlibrary/uart.h" #include "Lukasz Marcin Podkalicki/013_ir_receiver_38khz_nec_proto_analyzer/ir.h" double dutyCycle = 10; char sprinf_buff[50]; int main(void) { uart_init(UART_BAUD_SELECT_DOUBLE_SPEED(9600,F_CPU)); uart_puts("ready\r\n"); //init led pin DDRD |= (1<<DDD3); //init timer TCCR2A = (1 << COM2B1) | (1 << WGM21) | (1 << WGM20); TCCR2B = (0 << CS22) | (1 << CS21) | (1 << CS20);/////////I uncommented this to get Timer0 to work TIMSK2 = (1 << TOIE2); OCR2B = (dutyCycle/100.0)*255.0; sei(); uint8_t addr, cmd; IR_init(); while(1) { //_delay_ms(1000); //dutyCycle += 10; if(dutyCycle > 100) { dutyCycle = 0; } if (IR_read(&addr, &cmd) == IR_SUCCESS) { //method 1 sprintf(sprinf_buff, "addr=0x%x\r\ncmd=0x%x\r\n", addr, cmd); uart_puts(sprinf_buff); } } } ISR(TIMER2_OVF_vect) { OCR2B = (dutyCycle/100.0)*255; }
EDIT: I meant to say Timer2..not Timer1...But even if I use Timer1 the outcome is exactly the same