Manchester encoding library for RF links.

I had been using VirtualWire for my RF links. It's a very usefull and accurate program. It never has any problems when the TX and RX processors have Xtal clock generators.

I did have problems when I use a ATtiny85 as RX with an internal clock.

http://arduino.cc/forum/index.php/topic,60239.0.html

No matter how well I tune the TX or RX programs when ambient temperature changes we can still get the occasional dropouts.

It seems to me that the operation of VirtualWire is too sensitive to clock frequency.

I wrote a simple class based on Manchester encoding.

The class has 5 functions:

MANCHESTER.SetTxPin(char pin); //set the arduino digital pin for transmit. default 4.

MANCHESTER.Transmit(unsigned int data); //transmit 16 bits of data

MANCHESTER.SetRxPin(char pin); //set the arduino digital pin for receive. default 4.

unsigned int MANCHESTER.Receive(void); //receive 16 bits of data. 0 if times out.

MANCHESTER.SetTimeOut(unsigned int timeout); //set timeout in ms. default blocks.

The code is based on the Atmel Corporation Manchester Coding Basics Application Note.

I did not use any of their code but the program follows closely their operation.

http://www.atmel.com/dyn/resources/prod_documents/doc9164.pdf

Quotes from the application note:

"Manchester coding states that there will always be a transition of the message signal at the mid-point of the data bit frame. What occurs at the bit edges depends on the state of the previous bit frame and does not always produce a transition. A logical “1” is defined as a mid-point transition from low to high and a “0” is a mid-point transition from high to low.

I use Timing Based Manchester Decode. In this approach we will capture the time between each transition coming from the demodulation circuit."

Timer 2 is used with a ATMega328. Timer 1 is used for a ATtiny85.

Timer 2 in the ATMega328 and Timer 1 in a ATtiny85 is used to find the time between each transition coming from the demodulation circuit. Their setup is for normal count. No connections. No interupts. The divide ratio is /256 with 16 Mhz the 328 and /128 for the 85 with a 8 Mhz clock. This gives 16 usec per count.

The code gives a basic data rate as 1000 bits/s. In manchester encoding we send 1 0 for a data bit 0. We send 0 1 for a data bit 1. This ensures an average over time of a fixed DC level in the TX/RX. This is required by the ASK RF link system to ensure its correct operation. The actual data rate is then 500 bits/s.

The library has two examples:

include

define TxPin 4 //the digital pin to use to transmit data

unsigned int Tdata = 0; //the 16 bits to send

void setup() { MANCHESTER.SetTxPin(TxPin); // sets the digital pin as output default 4 }//end of setup

void loop() { Tdata +=1; MANCHESTER.Transmit(Tdata); delay(100); }//end of loop

include

define RxPin 4

void setup() { MANCHESTER.SetRxPin(RxPin); //user sets rx pin default 4 MANCHESTER.SetTimeOut(1000); //user sets timeout default blocks Serial.begin(9600); // Debugging only }//end of setup

void loop() { unsigned int data = MANCHESTER.Receive(); Serial.println(data); }//end of loop

Using an ATtiny85 with internal 8 Mhz clock as the RX I have found that I dont have any dropouts.

Download manchester.zip from:

http://code.google.com/p/mysudoku/downloads/list

Brilliant!

Nice one, that'll come in handy :)

Thanks Si.

I enjoy the mental gymnastics of putting together some useful code.

Great work! I'd like to use this library in one of my projects. However, I can't compile the examples. Obviously Arduino does not find the MANCHESTER.h file. Is there some special place to put header, cpp files and the core folder? I put the contents of the archive to sketchbook/libraries.

The cores goes in:

C:\arduino-0021\arduino-0021\hardware\arduino\cores

The manchester library goes in:

C:\arduino-0021\arduino-0021\libraries

The examples should then compile.

Thank you carl47, that worked! First I tried with Arduino 1.0 which did not work. Using 022 works flawlessly!

Hi Carl47,

I am using an ATtiny 85 (internal osc) for tx and an arduino with mega328 for rx. Using your examples all I get is 0s in the serial terminal. Any idea what I am doing wrong?

Thanks!

Hi Carl47,

I'm having the same problem Ciscoios. What are we doing wrong?

Thank you.

When we get all 0's it could be anything.

My first guess would be hardware.

What rf devices are you using?

Do you have access to a CRO to see if data is going to the Tx or being received at the Rx.

Without lots more information I cannot be more explicit.

Cheers.

I have tried connecting a wire directly between RX and TX pins.. and a led for an indicator. TX transmits once a second. The RX (arduino) shows a 0 every second in the serial terminal. The output stops if I disconnect the wire.

I dont have a CRO.

Thanks !

It sounds as though something is being sent by the 85.

How do you program the 85, I use:

http://arduino.cc/forum/index.php/topic,59968.0.html

There is a pdf which describes how to set the fuse bits.

When you dump lfuse you should get E2 this gives:

8 Mhz on the internal clock.

I mention this because the example sends data every 0.1 sec not 1 sec.

Keep at it!

Thanks for the reply.

I know it must be something small (it always is)... I use arduino as ISP .. maybe that is setting a wrong fuse bit?

I will check and report.

Just to clarify. I changed the example to send once a second.

If you are thinking of using the ATTiny85 as the transmitter checkout:

http://mchr3k-arduino.blogspot.com/2012/01/wireless-sensor-node-part-2.html

This is an excellent article by mchr3k. He uses the 85 as the Tx with this manchester library.

Hello Carl47, I tried your Manchester implementation and it works flawlessly, no dropouts. However, when I changed your example from 0.1 sec to a slower interval (0.2 sec, 1 sec or 2 sec), it had numerous dropouts. I then changed it from an interval driven to a pushbutton driven, and it works perfectly, virtually no dropouts. This is very puzzling. Initially I thought your Manchester class was fine-tuned for sending data at 0.1 sec interval, but since the randomness of a pushbutton works, my theory is obviously wrong. Why is it not working with different time interval? Or I am doing something wrong?

RobertL

THE CODE HAS A BUG

This was discovered by mchr.

I wont update my code because mchr has done a great job on improving the library.

I would now direct anyone using this code to use his modifications:

The latest version of this library is now available from the GitHub repo linked from my latest blog post: http://mchr3k-arduino.blogspot.com/2012/01/wireless-sensor-node-code-management.html

I have now added interrupt driven message reception to the Manchester library. Full details are available here: Mchr3k - Arduino: Wireless sensor node - background rx (6)

Can you show us an example of the hardware? Which RF module?

I'm using the following RF components:

http://www.alpha-crucis.com/en/wireless/1829-rf-link-transmitter-315mhz-3700386105357.html http://www.alpha-crucis.com/en/wireless/1827-rf-link-receiver-4800bps-315mhz-3700386105333.html

You can find similar parts on many sites. There is a picture of my breadboard setup in the blog post which I linked.