enum { UNKNOWN, T0, T1, T2, T3, OK, DONE }; byte state = UNKNOWN; unsigned long x_data; static unsigned int x_numBits; static boolean x_2ndbit; static unsigned int dbg_periodTime; // For debugging static void resetDecoder () { x_data = 0; x_numBits = 0; x_2ndbit = false; state = UNKNOWN; } static boolean isDone() { return state == DONE; } static void done () { state = DONE; } static void gotBit (char value) { // X x_numBits++; x_data = (x_data << 1) + (value & 0x01); if( x_2ndbit == false ) { x_2ndbit = true; } else { x_2ndbit = false; unsigned int bits = (x_data & 0x03); if( bits == 2 ) { // Bit is 1 x_data = (x_data >> 1) | 0x00000001; } else { // Bit is 0 x_data = (x_data >> 1) & 0xFFFFFFFE; } } state = OK; } static int decode (unsigned int width) { switch (state) { case UNKNOWN: // Start of frame //printf("%8u\n",width); if ( 2400 <= width && width <= 3000 ) { state = T0; //dbg_periodTime = width; } break; case T0: // First half of pulse : HIGH around 230us if ( 150 <= width && width <= 300 ) { state = T1; } else if ( x_numBits == 0 && 2400 <= width && width <= 3000 ) { state = T0; } else return -1; // error, reset break; case T1: if ( 200 <= width && width <= 400) { gotBit(0); } else if ( 1000 <= width && width <= 1500 ) { gotBit(1); } else if ( /*width > 5000 &&*/ x_numBits == 64) { // end of frame state = DONE; return 1; } else { return -1; } state = T0; break; } return 0; } #define TOO_SHORT 100 bool nextPulseNexa (unsigned int width) { /* unsigned int decodew = 0; static unsigned int totw = 0; static int mode=0; if( state != T0 ) { switch( mode ) { case 0: totw = width; mode = 1; break; case 1: if( width < TOO_SHORT ) { totw += width; mode = 2; } else { decodew = totw; totw = width; } break; case 2: totw += width; //if( width < TOO_SHORT ) { // This change caused less reception // mode = 2; //} //else { mode = 1; //} break; } } else { // T0-State, send right through decodew = totw; totw = width; if( width < TOO_SHORT ) { mode = 2; } else { mode = 1; } } */ //decodew = width; if( width > 0 ) { if (state != DONE) switch (decode(width)) { case -1: resetDecoder(); break; case 1: done(); break; } } return isDone(); }