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...
And, now my logic --
Decoding state-machine: INITIAL --> DEC_CW1 --> DONE_CW1 --> DEC_CW2 --> DONE_CW2 --> INITIAL
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) 126.96.36.199) 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) 188.8.131.52) 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) 184.108.40.206) Is SamplePatternFor1Bit length enough to decode Bit 220.127.116.11.1) Yes, does it match 1BitPattern for 0 | 1 | F | S ? 18.104.22.168.1.1) Yes, then add it to CW1 22.214.171.124.1.2) No, then invalid pattern/error, discard all under-construction buffers, reset all counters and states & return from loop() 126.96.36.199.2) No, then continue loop() 4.4.1) Or, If CurrentState is DEC_CW2 (i.e. already decoding CW2) 188.8.131.52) Is SamplePatternFor1Bit length enough to decode Bit 184.108.40.206.1) Yes, does it match 1BitPattern for 0 | 1 | F | S ? 220.127.116.11.1.1) Yes, then add it to CW1 18.104.22.168.1.2) No, then invalid pattern/error, discard all under-construction buffers, reset all counters and states & return from loop() 22.214.171.124.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) 126.96.36.199) Yes, means CW1 is complete, so Set CurrentState = DONE_CW1 188.8.131.52) Move under-construction CW, into saved CW1 5.2.2) Yes, If CurrentState is DEC_CW2 (i.e. already decoding CW2) 184.108.40.206) Yes, means CW1 is complete, so Set CurrentState = DONE_CW2 220.127.116.11) Move under-construction CW, into saved CW2 18.104.22.168) If CW1.Addr = CW2.Addr (same pattern) ? 22.214.171.124.1) Yes, then CW match, return CW2.data as the decoded Data from CW2.Addr as Addr 126.96.36.199.2) No, then discard all under-construction buffers, reset all counters and states & return from loop()