 
 #define EEMODEADDR 0			// The address of the mode stored in EEPROM.
 #define EEMODE_CHANGETIME 5000  // The number of ms to hold the switch before the clip mode is changed.
-#define EEMODE_SYNCPULSE 45		// The Clip looks for a sync pulse on one of the LDRs.
+#define EEMODE_SYNCPULSE  45		// The Clip looks for a sync pulse on one of the LDRs.
 #define EEMODE_HEIGHTONLY 37	// The Clip uses both LDRs to estimate height, no colour involved.
+#define EEMODE_SERIAL     89
 
 #define PULSE_STATE__NOT_CHECKED  -1	// The sync-pulse routine did not bother checking, too soon since previous check.
 #define PULSE_STATE__NO_PULSE      0	// The sync-pulse check returned no pulse.. Probably off a screen.

	if (!cycleCheck(&tmrModeCheck, 10U))
		return;
	
	// State for button press detection.
	static long tmrButtonPress = -1;
	static boolean bLastState  = true;
	boolean bState = digitalRead(PIN_SWBOT) == LOW;
	
	// Store the time when we go from a not pressed to a pressed state.
	if (bState == true && bLastState == false) 
	{
		tmrButtonPress = millis();
	}
	else if (bState == false && bLastState == true)
	{
		tmrButtonPress = -1;
	}
	bLastState = bState;
	
	// If SWBOT has been pressed for X seconds, switch mode.
	if (tmrButtonPress != -1 && (millis() - tmrButtonPress) > EEMODE_CHANGETIME)
	{
		// Prevent it from triggering multiple times.
		tmrButtonPress = -1;
		
		// Toggle mode.
		int iMode = EEPROM.read(EEMODEADDR);
		if (iMode == EEMODE_SYNCPULSE)
		{
			//Serial.println("height mode");
			EEPROM.write(EEMODEADDR, EEMODE_HEIGHTONLY);
			eRGBMode  = RGBMODE_NONE;
			eClipMode = EEMODE_HEIGHTONLY;
		}
		else
		{
			//Serial.println("sync pulse mode");
			EEPROM.write(EEMODEADDR, EEMODE_SYNCPULSE);
			eRGBMode  = RGBMODE_SCREEN;
			eClipMode = EEMODE_SYNCPULSE;
		}
	}
}


/**
 * @brief Handle the clip behaviour for sync pulse mode.

	
}

static const unsigned char BitsSetTable256[256] = 
{
#   define B2(n) n,     n+1,     n+1,     n+2
#   define B4(n) B2(n), B2(n+1), B2(n+1), B2(n+2)
#   define B6(n) B4(n), B4(n+1), B4(n+1), B4(n+2)
    B6(0), B6(1), B6(1), B6(2)
};



WindowVariance * runningVariance = new WindowVariance( 20 );
int oldState = 0;
uint16_t bSerialBuffer = 0x00;
int inputIndex = 0;
int readState = 0;
void loopSerialMode()
{
  // Only allow this function to be called once every 5ms.
  static unsigned long tmr1 = 0;
//if (cycleCheck(&tmr1, 1U))
  {
    int iLDRValue[] = { analogRead( PIN_LDR1 ), analogRead( PIN_LDR2 ) };
    int iInVal = iLDRValue[0] - iLDRValue[1];
    runningVariance->push( iInVal );
    
    //iInVal = constrain( (int)runningVariance->mean(), -512, 512 ) + 512;
    int variance = runningVariance->variance();
    
    int state = constrain( map( iInVal, -450, 500, 0, 4 ), 0, 4 );
    
    //Serial.print( variance, DEC );
    //Serial.print( "\t" );
    //Serial.print( iInVal, DEC );
    //Serial.print( "\t" );
    //Serial.println( state, DEC );
    
    
    if( state != oldState )
    {
      switch( state )
      {
        case 0:
          bSerialBuffer = (bSerialBuffer << 1) | 1;
          break;
          
        case 1: inputIndex++; break;
        
        case 3:
          bSerialBuffer = (bSerialBuffer << 1);
          break;
      }
      
      byte eFrame = (byte)(bSerialBuffer & 0x01);
      byte parity = (bSerialBuffer >> 1) & 0x01;
      byte frame  = (byte)((bSerialBuffer >> 2) & 0xFF);
      byte startBit = (bSerialBuffer >> 10) & 0x01;
      byte sFrame    = (bSerialBuffer >> 11) & 0x01;

      oldState = state;
      
      if( sFrame == 0 && eFrame == 0 && startBit == 1 )
      {
        if( (BitsSetTable256[frame] % 2 == 0 && parity == 1) || (BitsSetTable256[frame] % 2 != 0 && parity == 0) )
        {
          /*Serial.print( "[" );
          Serial.print( frame, BIN );
          Serial.print( " " );
          Serial.print( frame, HEX );
          Serial.print( "]\t" );
          Serial.println( bSerialBuffer, BIN );*/
          
          Serial.println( frame, BIN );
          
          //iTargetPos = map( frame & 0x7F, 0, 0x7F, 0, MOTOR_TRAVEL );
          pRGB.setPixelColor(0,  0, 0, frame & 0x7F);
          pRGB.show();
          
          bSerialBuffer = 0;
        }
      }
    }

  }

  moveMotor();
  //updateColour();
}

/**
 * Logic loop.
 * The function performs the following tasks:
