The document TB045 of microchip offer code for everyone that own microchip controllers to use, and guide to the basics to Manchester decoding , through the implementation of a state machine.
I implement and test a system, based in code of TB045.
Also, implement the Manchester transmitter code, and it is enough simple.
Beyond basic systems to transceiver serial data, believe that Manchester encoding allow robust data reception, and is very stable.
However, after implement the system, the transmitter and receive, I discover that not work at all so well. Let me explain what I do..
I build the transmitter code, that is very stable and precise (interrupt based).
Also, use 2 segment display to show data being received on receiver side, with pic.
I know what data was being transmitted (by transmiter ). I check with my "ociloscope audiocard" and, all times the data are transmitted nicely (the waveform are just perfect).
So I use a typical transmitter/receiver 'made in china' to transmit and receiver the data over the air.
However, the problems begin.
Each ~10 transmitted burst of data, the receiver don’t understand one sequence of transmited data. Upon 5%. (I am talking about a complete burst of data, with many bytes). Also other times it get the data, but very wrong.
I will show to you the pictures bellow that show the transmitted code and received one.
You can implement the native code over PIC (not over arduino, microchip not allow this by this terms) too and detect this.
The problem is that anyone that try use this code, due the small percentages of problems, never will take real care about; but the problem still is there.
Maybe commercial products has been release with this bug… that disallow the perfect opration of entire system….
So let’s start!
The first problem detected was the error in receiving nice code.
I look with oscilloscope (audiocard) the received code at pin of receiver, and everything seen correct. Even when receiver PIC decode the wrong data.
And also stay tune in what the PIC-receiver are saying about the received code.
But some times the PICs lost it self, and detect wrong data.
So I start investigate the keeloq receiver routine.
Since the sender routine is nice, and my code inserted into the receive routine really not interfere in the manchester decoding, I look in the interrupt driven routine of manchester decoding routine.
But before, let me explain how I debug!
The manchester decoding routine use four (4) main state machine. State 0 to 3. Look to TB045 to learn more.
So I just insert inside each one of these states BCF and BSF instruction, to set and reset unused PIC pin.
Now I know exactly where the “pic” is running during the tests and more important, during the errors.
Using the two channel audio card I get the data and the behavior of state machine.
Bellow you see the CODE of debugged version.
After analyze code and states througt the pin that say for me the actual state, when the error occurred, I found the flow problems.
The system detects the preamble as valid signal and start to sampling data. Preamble is a sequence of 0 and 1 send by transmitter used to stabilize the receiver before start to synchronize and send the data.
Almost always 0xFF 0xFx etc and some other wrong data are received in this cases, then the data are get wrong.
But why this thing happen?
The system would be nice, and the preamble would guarantee that everything is working fine.
It was possible to detect through debug data lines that the state 2 are starting just right in preamble start. Much stranger!
But this happen sporadic.
So I go to the code try find what are happening.
I look just before the execution of state 2, in state 1, who start state 2. Bellow the code.
See the original code: (page 6 / 7)
;----------------------------------------------------------------------
; State 1
; Waiting and measuring a Synch Header
TRFSync
btfsc RFIN ; wait for a rising edge
goto TRFRise
incf RFsamp,F ; while input low count the samples
movf RFsamp,W
btfsc STATUS,Z
goto TRFReset ; check overflows (this should not happen)
incf RFSkip,F ; skip = 1
goto AsyncRFE ; remain in state 0
When the TRFReset happen, because of RFsmaple overflow, the RFsamlpe are reset to 0.
Whoever, it should not be reseted. It should stay in a high value. Think with me: during no transmission, the signal is always 0. So RFsample stay running and counting higher and higher. But if an overflow happens, (256), the RFsample is reset to 0, and start count again. If it count until 4 te, (sync), and the preamble comes soon, the machine detect as a valid sync signal, and start to sample! As the RFsamble is reseted every 255 cycles, is likely to this happen. So to fix this problem, we just maintain the counter of RFsample higher if it passes the maximum size of allowed counts. Prefer higher than constant LONG_HEAD; but bellow 255, so if not happen any preamble to force a reset, the system never get out this state, and no cause lost in data in! Ta ta! Bellow the fixed version.
. . .
;----------------------------------------------------------------------
; State 1
; Waiting and measuring a Synch Header
;
TRFSync
;bsf LED_STATUS0
;movlw 0x1
;movwf display
btfsc RFIN ; wait for a rising edge
goto TRFRise
incf RFsamp,F ; while input low count the samples
movf RFsamp,W
btfsc STATUS,Z
goto TRFCorrige ; we create a new way to code follow; If it go here, mean that a long time pass and no more valid sync will happen
;goto TRFReset ; check overflows (we eliminate this)
incf RFSkip,F ; skip = 1
goto AsyncRFE ; remain in state 0
TRFCorrige
movlw 0xf0 ; we set the “border” almost in the limit, just to make sure that never will accept any code before the first bit of preamble
movwf RFsamp ; and move to RFsample
incf RFSkip,F ; skip = 1
goto AsyncRFE ; remain in state 0
TRFRise
. . .
This force the code to stay waiting for preamble, and first bit in preamble reset the counter throught TRFRise, where is the right place for TFRReset to be called.
After this change, the receiver routine no more shows the wrong behavior.
Looking deeply I found that the routine in state 3, TRFFull have a error too: see bellow:
TRFFull ; received them all
movlw TRFReset ; next state will be Reset
movwf RFState
bsf RF_Full ; set the buffer full flag
goto AsyncRFE ; done
I smart look can reveal the problem. The variable RFState must contain just a value between 0 and 3; but here, we are assigning a pointer to memory position of TRFReset to it. And this is always a enigma data; that might be 0, may be 1, ou 10 or 60 or any pointer.
Fixed version is:
movlw 0x0 ; the state, not he memory position
; movlw TRFReset ; next state will be Reset (wrong)
movwf RFState
bsf RF_Full ; set the buffer full flag
goto AsyncRFE ; done
I think that is a simple but nice help for anyone that think in use this code.
I have the fixed version of this code; but above you can copy and paste and use the code without fear.
However I don’t responsabilyze about any problem that this fix can cause!
By now, just rest to say that I appreciate you opinion about the article.
No comments:
Post a Comment