//#define CLAS_O_DEBUG enum { UNKNOWN, T0, T1, T2, T3, OK, DONE }; static unsigned char clas_o_state = UNKNOWN; unsigned long clas_o_x_data; static unsigned int clas_o_x_numBits; void clas_o_ResetDecoder () { clas_o_x_data = 0; clas_o_x_numBits = 0; clas_o_state = UNKNOWN; } static boolean clas_o_isDone() { return clas_o_state == DONE; } static void clas_o_done () { clas_o_state = DONE; } static void clas_o_gotBit (char value) { clas_o_x_numBits++; clas_o_x_data = (clas_o_x_data << 1) + (value & 0x01); clas_o_state = OK; } static int clas_o_decode (unsigned int width) { if( clas_o_state != UNKNOWN ) { #ifdef CLAS_O_DEBUG Serial.print(width); Serial.print(" - "); #endif } switch (clas_o_state) { case UNKNOWN: // Start of frame if ( 3500 <= width && width <= 4000 ) { #ifdef CLAS_O_DEBUG Serial.print(width); Serial.print(" - "); #endif clas_o_state = T0; } else { return -1; // error, reset } break; case T0: // First half of pulse : HIGH around 230us if ( clas_o_x_numBits == 32 ) { // end of frame clas_o_state = DONE; clas_o_x_data = (clas_o_x_data >> 8); // Mask away some bits at the end return 1; } else if ( 340 <= width && width <= 540 ) { clas_o_state = T1; } else { if ( clas_o_x_numBits == 0 && 3400 <= width && width <= 3800 ) { clas_o_state = T0; } else { #ifdef CLAS_O_DEBUG Serial.println(" X1X "); #endif return -1; // error, reset } } break; case T1: if ( 800 <= width && width <= 1000) { clas_o_gotBit(0); } else if ( 1640 <= width && width <= 1940 ) { clas_o_gotBit(1); } else { #ifdef CLAS_O_DEBUG Serial.println(" X2X "); #endif return -1; // error, reset } clas_o_state = T0; break; } return 0; } boolean nextPulse_clas_o (unsigned int width) { if ( width > 0 ) { if (clas_o_state != DONE) switch (clas_o_decode(width)) { case -1: clas_o_ResetDecoder(); break; case 1: clas_o_done(); break; } } return clas_o_isDone(); }