gbbickerton
Member
According to RF solutions sending plain serial data over rf modules will give very poor results as many have already found.The solutions seem to be
1. use easy radio modules (recent posts indicate this is not as straight foreward as it seems)
2. RF solutions produce chips which will do the encoding and crc for you.
3. use the code examples below this has doubled the range of my modules and improved reliability, it won't be true manchester encoding but it is good enough.
receivers need a preamle of about 16 0 to 1 transitions at 50:50 ratio to set the bit slicer level before any data is sent,ascii data is not 50:50 so this level keeps shifting which gives varying bit lengths, also some modules cannot keep a high state on the output long enough for some ascii words.
<code><pre><font size=2>
;Manchester encode by Barry Bickerton
;variables b0 number to encode b5 = loop counter
;b4 temp bit holder b2/b3 = w1 16 bit manchester encoded number
;radio modules need a 50:50 ratio of 1's and 0's to work properly ascii data does not work at all well
;manchester encoding replaces every 1 or 0 with a 10 or 01 so you get a 50:50 bit pattern which is constantly
;changing from 1 to 0 or 0 to 1.
;I have a reciever which can only maintain a high output for 3ms sending '11111111' with a high start bit at 2400 baud
;would need the output to be high for 3.75ms so this could not be done with ascii code.
;manchester code encode
;exit with number in w1 (b2 lsb b3 msb) NB number is scrambled
symbol var = b1 ;number to encode in var (b1)
main:
for b8 = 0 to 6 ;some test data to transmit
lookup b8,(254,1,"HELLO",var ;data
manencode:
let w1 = 0 ;initialise w1
let b0 = var ;data into b0
let b5 = 8 ;set loop counter
manloop:
if b5 = 0 then completed ;exit after 8 bits done
let w1 = w1*4 ;left shift w1 2 places
b5 = b5-1 ;decrement loop counter
let b4 = b0 & %00000001 ;mask to get lsb
let b0 = b0/2 ;right shift next bit to lsb position
if b4 = 1 then man1 ;if a '1' then go and add '01'(I think manchester encoding uses 10
;but it does not matter practically which way round it is)
;else it is a '0'
man0: let w1 = w1+2 ;add '10' for a '0'
goto manloop
man1: let w1 = w1+1 ;add '01'for a '1'
goto manloop
completed:
serout 3,N2400,(170,170,201,b3,b2) ;send data. 170 is '10101010' this is 50:50 1's and 0's
;and is used to condition the bit slice in the reciever
next b8 ;201 is a qualifier for the serin command, no data is accepted
;until the qualifier is received (it has 50:50 ratio also)
pause 1000 ;pause then re transmit
goto main
[\code]
1. use easy radio modules (recent posts indicate this is not as straight foreward as it seems)
2. RF solutions produce chips which will do the encoding and crc for you.
3. use the code examples below this has doubled the range of my modules and improved reliability, it won't be true manchester encoding but it is good enough.
receivers need a preamle of about 16 0 to 1 transitions at 50:50 ratio to set the bit slicer level before any data is sent,ascii data is not 50:50 so this level keeps shifting which gives varying bit lengths, also some modules cannot keep a high state on the output long enough for some ascii words.
<code><pre><font size=2>
;Manchester encode by Barry Bickerton
;variables b0 number to encode b5 = loop counter
;b4 temp bit holder b2/b3 = w1 16 bit manchester encoded number
;radio modules need a 50:50 ratio of 1's and 0's to work properly ascii data does not work at all well
;manchester encoding replaces every 1 or 0 with a 10 or 01 so you get a 50:50 bit pattern which is constantly
;changing from 1 to 0 or 0 to 1.
;I have a reciever which can only maintain a high output for 3ms sending '11111111' with a high start bit at 2400 baud
;would need the output to be high for 3.75ms so this could not be done with ascii code.
;manchester code encode
;exit with number in w1 (b2 lsb b3 msb) NB number is scrambled
symbol var = b1 ;number to encode in var (b1)
main:
for b8 = 0 to 6 ;some test data to transmit
lookup b8,(254,1,"HELLO",var ;data
manencode:
let w1 = 0 ;initialise w1
let b0 = var ;data into b0
let b5 = 8 ;set loop counter
manloop:
if b5 = 0 then completed ;exit after 8 bits done
let w1 = w1*4 ;left shift w1 2 places
b5 = b5-1 ;decrement loop counter
let b4 = b0 & %00000001 ;mask to get lsb
let b0 = b0/2 ;right shift next bit to lsb position
if b4 = 1 then man1 ;if a '1' then go and add '01'(I think manchester encoding uses 10
;but it does not matter practically which way round it is)
;else it is a '0'
man0: let w1 = w1+2 ;add '10' for a '0'
goto manloop
man1: let w1 = w1+1 ;add '01'for a '1'
goto manloop
completed:
serout 3,N2400,(170,170,201,b3,b2) ;send data. 170 is '10101010' this is 50:50 1's and 0's
;and is used to condition the bit slice in the reciever
next b8 ;201 is a qualifier for the serin command, no data is accepted
;until the qualifier is received (it has 50:50 ratio also)
pause 1000 ;pause then re transmit
goto main
[\code]
Code:
;Manchester decode by Barry Bickerton
;variables b0 decoded number b5 = loop counter
;b4 temp bit holder b2/b3 = w1 16 bit manchester encoded number
;LCD connected to outout 0 to display recieved data
;I have used 2 fets to buffer the output of the reciever and have a piezo sounder connected to monitor
;the signal, data is received even when there is noise on the output.
;range is much greater than without encoding
init: pause 500
serout 0,N2400,(254,1,"ready")
main: serin 7,n2400,(201),b3,b2 ;puts number into w1 (b3,b2) 201 has to be recieved before data
;this filters out the preamble of 170's
;Decode and exit with number in b0
let b0 = 0 ;clear b0
let b5 = 8 ;initialise loop counter
mandecode: if b5 = 0 then complete ;exit after 8 bits
let b5 = b5 - 1 ;decrement loop counter
let b4 = w1 and %11 ;mask all but 2 lsb's
let w1 = w1/4 ;shift w1 2 steps right to get next bit pair
let b0 = b0 * 2 ;left shift b0 1 place (1st time around does nothing)
if b4 = 2 then mandecode ;if a '0' do nothing
let b0 = b0 + 1 ;if a '1' add 1
goto mandecode
complete: serout 0,N2400,(b0) ;decoded output is in b0
goto main
[\code] </code></pre></font>