Pages: [1] 2   Go Down
Author Topic: Manchester encoding library for RF links.  (Read 19081 times)
0 Members and 1 Guest are viewing this topic.
Australia
Offline Offline
Full Member
***
Karma: 7
Posts: 210
AVR Microcontrollers
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:

Quote
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:

Quote
#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;
 MANCHESTER.Transmit(Tdata);
 delay(100);
}//end of loop


Quote
#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();
 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
Logged

UK
Offline Offline
God Member
*****
Karma: 13
Posts: 903
Twitter: @simonmonk2
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Brilliant!

Nice one, that'll come in handy smiley
Logged

--
My New Arduino Book: http://www.arduinobook.com

Australia
Offline Offline
Full Member
***
Karma: 7
Posts: 210
AVR Microcontrollers
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks Si.

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

Offline Offline
Newbie
*
Karma: 0
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Australia
Offline Offline
Full Member
***
Karma: 7
Posts: 210
AVR Microcontrollers
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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!
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Carl47,

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

Thank you.
Logged

Australia
Offline Offline
Full Member
***
Karma: 7
Posts: 210
AVR Microcontrollers
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 !
Logged

Australia
Offline Offline
Full Member
***
Karma: 7
Posts: 210
AVR Microcontrollers
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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!
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Australia
Offline Offline
Full Member
***
Karma: 7
Posts: 210
AVR Microcontrollers
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
« Last Edit: January 20, 2012, 12:50:42 am by carl47 » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 1
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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?
Logged

Pages: [1] 2   Go Up
Jump to: