Untitled

mail@pastecode.io avatar
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)
}
}