| ||||||||||||||||||||||
An Efficient Algorithm for Decoding RC5 Remote Control SignalsIntroductionRC5 is an encoding standard used in infrared remote control signal transmission. RC5 was originally developed by Phillips, and uses Manchester encoding, a bi-phase code that encodes each data bit as a transition. RC5 encodes commands as 14-bit words. This article describes an efficient and robust method for decoding RC5 infrared remote control signals into 14-bit control codes. I will assume that you already have hardware interface code (such as lirc) that returns IR pulse and space durations. RC5
RC5 bi-phase encodingEach data bit in an RC5 transmission has uniform duration, and contains one transition. '0' is encoded by a high to low transition, and a '1' by a low to high transition. Each bit has a transition in the middle of the bit, and will have an additional transition at the start of the bit if it follows a bit of the same value.
TimingRC5 defines a duration of 1778μs for each bit. A feature of bi-phase encoding is that the encoded signal will consist entirely of pulses (signal high) and breaks (signal low) of either a full bit duration or ½ bit duration. Event ClassificationPulse/space events from the remote control interface are classified according to the following table, which provides generous accomodation for receiver clock errors. Any event with a duration outside of these categories is considered an error condition, and causes the state machine to reset and restart.
The State MachineThe state machine takes categorized pulse/space events as input and generates 14-bit RC5 control codes as output. When the state machine starts it immediately emits a 1, and enters the mid1 state. Emitted bits are left-shifted into a 14-bit data store. Any event not illustrated as a state transition results in an error, and the decoder should reset and restart. Decoding is complete when 14 bits have been emitted. It is also useful to continue decoding until the decoder is in state start1 or state mid0, to ensure the final pulse is consumed.
The state names reflect the position within the RC5 signal. For example "mid1" represents the middle of a '1' bit, after the pulse and before the space. The signal always change states at the middle of a bit, and the state machine always emits a decoded bit as it enters the mid-bit state. ImplementationThe decoding state machine consists of 4 states, and 4 transition types.
Sample CodeThe entire transition table can be represented in a 4 byte transition table. Any event which does not result in a state change marks an error condition.
int RC5Advance(RC5State *State, RC5EVENT Event)
{
static unsigned char trans[] = {0x01, // 00 00 00 01 from state 0: short space -> 1
0x81, // 10 01 00 01 from state 1: short pulse -> 0, long pulse -> 2
0x8B, // 10 01 10 11 from state 2: short space -> 3, long space -> 1
0xFB}; // 11 11 10 11 from state 3: short pulse -> 2
if (Event==RC5EVENT_ERROR) {
RC5Reset(State);
} else {
int newState = trans[State->state]>>Event & 0x3; // keep low 2 bits
if (newState==State->state) {
RC5Reset(State); // no transition indicates error
} else {
State->state = newState;
if (newState == RC5STATE_MID0) {
RC5Emit(State, 0); // always emit 0 when entering mid0 state
} else if (newState == RC5STATE_MID1) {
RC5Emit(State, 1); // always emit 1 when entering mid1 state
}
}
}
return State->bits == 14;
}
ContributorsThanks to Boris Yost for pointing out an error in my notes above. The times in table are in microseconds, not milliseconds as I had them originally labelled.
-Guy Carpenter | ||||||||||||||||||||||