# RF decode logic (not Manchester encoded) - Arduino

Continuing from my previous post, I am trying to decode the encoded RF data directly on Arduino. I've adopted the "sampling" approach, as against the "interrupt" based approach, reason being I believe the interrupt line will be used for some other purposes.

Having written it, and spending a good day trying to debug it (lack of real debugger is really telling, as serial-console println()'s are really limited due to their sluggishness.), but still can't seem to working.

Here I share the logic (pseudo-code), in the hope that someone can help point any obvious mistakes, or maybe a less obvious intricate timing issue (which I suspect to be more likely).

Firstly, how the data is encoded (which I am trying to decode) :-

bit-0: IIII ---- ---- ---- IIII ---- ---- ----
bit-1: IIII IIII IIII ---- IIII IIII IIII ----
bit-F: IIII ---- ---- ---- IIII IIII IIII ---- ('Floating', used only in Addr-part)
bit-S: IIII ---- ---- ---- ---- ---- ---- ---- (sync-bit)


Each I (High) or - (Low) is ~120 us (micro-sec) [actually ranges between 118-121 us].

So, I've decided to sample at 30us intervals, i.e. 4x the signal freq. On Arduino, I use delayMicroseconds(30) to get this effect, although the logic within the loop() is rather heavy, ~150 lines of code and upto 4 level of if-nesting (just to indicate complexity) of the state-machine, pattern-maching, level-transition logic. Compiled Arduino sketch is ~2KB in size, just to give an indication of the complexity.

Data transmission is a sequence of 'Codewords', where each codeword is --

[ Addr(8-bits: 0/1/F) | Data (4-bits: 0/1) | Sync-bit ]


And, a minimum of 2 codewords with same address are used for some rudimentary error checking.

Between 2 successive codewords, there is a time of all Low signal.

Also, prior-to/post valid transmission there is significant noise in the line, and my observation is that noise characteristics is such that there were no continuous high period in noise that was close to the representation of highs in encoded bit-1, but there were quite a few patterns in noise, whose continuous high period matched that of the high-period for bit-0 or first part of bit-F / bit-S, i.e. I we can (safely) assume that these patterns do not exist in noise...

---- ---- ----
IIII IIII IIII


but these do...

----
IIII


And, now my logic --

Decoding state-machine: INITIAL --> DEC_CW1 --> DONE_CW1 --> DEC_CW2 --> DONE_CW2 --> INITIAL

High-Level Pseudocode:

1) Detect RF-data pin state
2) Check if there is a transition
3) If no transition, then just increment count of samples in same state (say SampleCount)
4) If transition, then
4.1) Check, If SampleCount is in valid range to qualify towards an encoded bit
4.1.1) And, If CurrentState is INITIAL (i.e. before finding start of CW1)
4.1.1.1) Set CurrentState = DEC_CW1 (i.e. found start of CW1, potentially)
4.2.1) Or, If CurrentState is DONE_CW1 (i.e. before finding start of CW2)
4.1.1.1) Set CurrentState = DEC_CW2 (i.e. found start of CW2, potentially)
4.3.1) Or, If CurrentState is DEC_CW1 (i.e. already decoding CW1)
4.3.1.1) Is SamplePatternFor1Bit length enough to decode Bit
4.3.1.1.1) Yes, does it match 1BitPattern for 0 | 1 | F | S ?
4.3.1.1.1.1) Yes, then add it to CW1
4.3.1.1.1.2) No, then invalid pattern/error, discard all under-construction buffers, reset all counters and states & return from loop()
4.3.1.1.2) No, then continue loop()
4.4.1) Or, If CurrentState is DEC_CW2 (i.e. already decoding CW2)
4.4.1.1) Is SamplePatternFor1Bit length enough to decode Bit
4.4.1.1.1) Yes, does it match 1BitPattern for 0 | 1 | F | S ?
4.4.1.1.1.1) Yes, then add it to CW1
4.4.1.1.1.2) No, then invalid pattern/error, discard all under-construction buffers, reset all counters and states & return from loop()
4.4.1.1.2) No, then continue loop()
5) No transition,
5.1) Increment SampleCount (i.e. yet another sample in same state as before)
5.2) If SampleCount is 95-97 samples, all LOW then it indicates trailing end of S-bit pattern
5.2.1) Yes, If CurrentState is INITIAL (i.e. already decoding CW1)
5.2.1.1) Yes, means CW1 is complete, so Set CurrentState = DONE_CW1
5.2.1.2) Move under-construction CW, into saved CW1
5.2.2) Yes, If CurrentState is DEC_CW2 (i.e. already decoding CW2)
5.2.2.1) Yes, means CW1 is complete, so Set CurrentState = DONE_CW2
5.2.2.2) Move under-construction CW, into saved CW2
5.2.2.3.1) Yes, then CW match, return CW2.data as the decoded Data from CW2.Addr as Addr
5.2.2.3.2) No, then discard all under-construction buffers, reset all counters and states & return from loop()

• In what way is it not working? – Majenko Nov 27 '11 at 16:09
• @Majenko, initially I had put prints on a Codeword find (duplicate matched), but then I inserted prints on even finding a partial pattern (within a single Codeword), e.g. IIII ---- , and even this isn't detected. I know for sure that the uC is receiving the RF pattern (I've a Logic Analyzer hooked on the pin). – icarus74 Nov 27 '11 at 16:33
• Wondering if my question is better suited for Stackoverflow, since it is a bit more programming intensive ! – icarus74 Nov 28 '11 at 6:52
• It's a tough one - while it's not off-topic for here, it's questionable whether the expertise exists here to give you a good answer. – Majenko Nov 28 '11 at 9:20
• Do you fancy trying to convert the pseudocode into a flowchart? It makes it easier to follow. – Majenko Nov 28 '11 at 9:21