radio modules manchester encoding

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,&quot;HELLO&quot;),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 &amp; %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,&quot;ready&quot;)	
	
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>
 

hippy

Ex-Staff (retired)
You could improve the speed of the encoding at the expense of code space by doing the following ...

- b0 = <i>byte to transmit </i>
-
- bit15 = bit7
- bit13 = bit6
- bit11 = bit5
- bit9 = bit4
- bit7 = bit3
- bit5 = bit2
- bit3 = bit1
- bit1 = bit0
-
- w0 = w0 AND $AAAA
- w0 = w0 XOR $AAAA / 2 OR w0
-
- SEROUT ... ,b1,b0

This takes the value in b0 and converts it into two bytes to send in b1:b0 ...<code><pre><font size=2>- b1 b0
-
- Original -------- ABCDEFGH
-
- Bit Moves A-B-C-D- EBFDGFHH
-
- AND $AAAA A0B0C0D0 E0F0G0H0
- _ _ _ _ _ _ _ _
- XOR $AAAA A0B0C0D0 E0F0G0H0
- _ _ _ _ _ _ _ _
- / 2 0A0B0C0D 0E0F0G0H
- _ _ _ _ _ _ _ _
- OR'd Result AABBCCDD EEFFGGHH </code></pre></font> Rebuilding the received code is also quite simple using the same bit moving trick ...

- SERIN ... ,b1,b0
-
- bit0 = bit1
- bit1 = bit3
- bit2 = bit5
- bit3 = bit7
- bit4 = bit9
- bit5 = bit11
- bit6 = bit13
- bit7 = bit15
-
- ' Result in b0

Edited by - hippy on 6/30/2005 2:03:47 PM
 

hippy

Ex-Staff (retired)
And error checking the received data ...

- SERIN ... ,b1,b0
-
- w1 = w0 AND $AAAA
- w1 = w1 XOR $AAAA / 2 OR w1
-
- IF w0 &lt;&gt; w1 THEN Error
 
Top