boolean nec_ok = 0;
byte i, nec_state = 0, command, inv_command;
unsigned int address;
unsigned long nec_code;
byte bitSwap(byte command){
command = ((command & 0x01) << 7) |
((command & 0x02) << 5) |
((command & 0x04) << 3) |
((command & 0x08) << 1) |
((command & 0x10) >> 1) |
((command & 0x20) >> 3) |
((command & 0x40) >> 5) |
((command & 0x80) >> 7);
return command;
}
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
// Timer1 module configuration
TCCR1A = 0;
TCCR1B = 0; // Disable Timer1 module
TCNT1 = 0; // Set Timer1 preload value to 0 (reset)
TIMSK1 = 1; // enable Timer1 overflow interrupt
// Interrupt INT0
EICRA |= 1 << ISC00;
EIMSK |= 1 << INT0;
}
ISR(TIMER1_OVF_vect) { // Timer1 interrupt service routine (ISR)
nec_state = 0; // Reset decoding process
TCCR1B = 0; // Disable Timer1 module
if(nec_ok){ // If the mcu receives NEC message with successful
nec_ok = 0; // Reset decoding process
nec_state = 0;
TCCR1B = 0; // Disable Timer1 module
// address = nec_code >> 16;
command = nec_code >> 8;
// inv_command = nec_code;
// Serial.print("Address: 0x");
// Serial.println(address, HEX);
Serial.print("Command: 0x");
Serial.println(bitSwap(command), HEX);
// Serial.print("Inv_Command: 0x");
// Serial.println(inv_command, HEX);
// Serial.print("Code: 0x");
// Serial.print(nec_code, HEX);
// Serial.print(" Code: BIN: ");
// Serial.println(nec_code, BIN);
EIMSK |= 1 << INT0;
}
}
ISR(INT0_vect){
unsigned int timer_value;
if(nec_state != 0){
timer_value = TCNT1; // Store Timer1 value
TCNT1 = 0; // Reset Timer1
}
switch(nec_state){
case 0 : // Start receiving IR data (we're at the beginning of 9ms pulse)
TCNT1 = 0; // Reset Timer1
TCCR1B = 1 << CS11; // Enable Timer1 module with 1/8 prescaler (2 ticks every 1 us)
nec_state = 1; // Next state: end of 9ms pulse (start of 4.5ms space)
i = 0;
return;
case 1 : // End of 9ms pulse
if((timer_value > 19000) || (timer_value < 17000)){ // Invalid interval ==> stop decoding and reset
nec_state = 0; // Reset decoding process
TCCR1B = 0; // Disable Timer1 module
}
else
nec_state = 2; // Next state: end of 4.5ms space (start of 562µs pulse)
return;
case 2 : // End of 4.5ms space
if((timer_value > 10000) || (timer_value < 8000)){
nec_state = 0; // Reset decoding process
TCCR1B = 0; // Disable Timer1 module
}
else
nec_state = 3; // Next state: end of 562µs pulse (start of 562µs or 1687µs space)
return;
case 3 : // End of 562µs pulse
if((timer_value > 1400) || (timer_value < 800)){ // Invalid interval ==> stop decoding and reset
TCCR1B = 0; // Disable Timer1 module
nec_state = 0; // Reset decoding process
}
else
nec_state = 4; // Next state: end of 562µs or 1687µs space
return;
case 4 : // End of 562µs or 1687µs space
if((timer_value > 3600) || (timer_value < 800)){ // Time interval invalid ==> stop decoding
TCCR1B = 0; // Disable Timer1 module
nec_state = 0; // Reset decoding process
return;
}
if(timer_value > 2000){ // If space width > 1ms (short space)
nec_code |= 1UL << (31 - i); // Write 1 to bit (31 - i)
}else{ // If space width < 1ms (long space)
nec_code &= ~(1UL << (31 - i)); // Write 0 to bit (31 - i)
}
i++;
if(i > 31){ // If all bits are received
nec_ok = 1; // Decoding process OK
EIMSK &= ~(1 << INT0); // Disable external interrupt (INT0)
return;
}
nec_state = 3; // Next state: end of 562µs pulse (start of 562µs or 1687µs space)
}
}
void loop() {
// put your main code here, to run repeatedly:
}