Go Down

Topic: Manchester encoding library for RF links. (Read 36974 times) previous topic - next topic


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.


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.


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

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 <MANCHESTER.h>

#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;
}//end of loop


#include <MANCHESTER.h>

#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();
}//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:




Nice one, that'll come in handy :)
I write books about Arduino and Electronics: http://simonmonk.org


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:


The manchester library goes in:


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?



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.



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:


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.


Jan 20, 2012, 06:48 am Last Edit: Jan 20, 2012, 06:50 am by carl47 Reason: 1
If you are thinking of using the  ATTiny85 as the transmitter checkout:


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?

Go Up