Untitled
unknown
plain_text
a year ago
3.3 kB
7
Indexable
Never
volatile boolean nec_ok = 0; volatile byte i, nec_state = 0, command, inv_command; unsigned int address; unsigned long nec_code; volatile unsigned long pulseLengthLastUs = 0, enteredAtUs = 0; void setup() { Serial.begin(9600); attachInterrupt(digitalPinToInterrupt(2), remote_read, CHANGE); // Enable external interrupt (INT0) } void remote_read() { unsigned long pulseLengthUs = micros() - enteredAtUs; // Calculate pulse length enteredAtUs = micros(); // Store current time for next entry switch(nec_state){ case 0 : // Start receiving IR data (we're at the beginning of 9ms pulse) nec_state = 1; // Next state: end of 9ms pulse (start of 4.5ms space) i = 0; break; case 1 : // End of 9ms pulse if((pulseLengthLastUs > 19000) || (pulseLengthLastUs < 17000)){ // Invalid interval ==> stop decoding and reset nec_state = 0; // Reset decoding process } else nec_state = 2; // Next state: end of 4.5ms space (start of 562µs pulse) break; case 2 : // End of 4.5ms space if((pulseLengthLastUs > 10000) || (pulseLengthLastUs < 8000)){ nec_state = 0; // Reset decoding process } else nec_state = 3; // Next state: end of 562µs pulse (start of 562µs or 1687µs space) break; case 3 : // End of 562µs pulse if((pulseLengthLastUs > 1400) || (pulseLengthLastUs < 800)){ // Invalid interval ==> stop decoding and reset nec_state = 0; // Reset decoding process } else nec_state = 4; // Next state: end of 562µs or 1687µs space break; case 4 : // End of 562µs or 1687µs space if((pulseLengthLastUs > 3600) || (pulseLengthLastUs < 800)){ // Time interval invalid ==> stop decoding nec_state = 0; // Reset decoding process return; } if( pulseLengthUs > 2000) // If space width > 1ms (short space) bitSet(nec_code, (31 - i)); // Write 1 to bit (31 - i) else // If space width < 1ms (long space) bitClear(nec_code, (31 - i)); // Write 0 to bit (31 - i) i++; if(i > 31){ // If all bits are received nec_ok = 1; // Decoding process OK detachInterrupt(0); // Disable external interrupt (INT0) } nec_state = 3; // Next state: end of 562µs pulse (start of 562µs or 1687µs space) break; } pulseLengthLastUs = pulseLengthUs; // Store current pulse length for next iteration } void loop() { if(nec_ok){ address = (nec_code >> 16) & 0xFF; // Extract address from received code inv_command = (nec_code >> 8) & 0xFF; // Extract inverted command from received code command = nec_code & 0xFF; // Extract command from received code if(command == ((~inv_command) & 0xFF)){ // Verify command validity Serial.print("Received valid NEC code: "); Serial.print(address, HEX); Serial.print(", "); Serial.print(command, HEX); Serial.print(", "); Serial.println(inv_command, HEX); } else{ Serial.println("Received invalid NEC code!"); } nec_ok = 0; // Reset decoding process nec_state = 0; // Reset decoding state pulseLengthLastUs = 0; // Reset pulse length variable enteredAtUs = 0; // Reset time stamp variable attachInterrupt(digitalPinToInterrupt(2), remote_read, CHANGE); // Re-enable external interrupt (INT0) } }