Yet another Manchester encoding / decoding library ...

Whilst working on my radio-controlled car, I developed my own versions of Manchester encoding and decoding libraries.

The sending library is here:

http://www.gammon.com.au/Arduino/ManchesterSend.zip

It uses a hardware timer (Timer 2) to clock out pulses at exactly 500 uS intervals. That is, 1000 bps (since it takes two pulses for a data bit).

Example code:

#include <ManchesterSend.h>

void setup ()
{
  ManchesterSend::begin (8);  // send on pin D8
}  // end of setup

void sendString (const char * s)
{
  while (*s)
    ManchesterSend::write (*s++);  
}  // end of sendString

void loop ()
{
  sendString ("hello, world\n");
}  // end of loop

The receiving library is here:

http://www.gammon.com.au/Arduino/ManchesterInterrupts.zip

That uses interrupts (you can choose which ones you want) to clock in bits.

Example code:

#include <ManchesterInterrupts.h>

void setup ()
{
  // incoming on pin D2
  ManchesterInterrupts::dataPin = 2;
  // need a change interrupt to detect incoming data
  attachInterrupt (0, ManchesterInterrupts::isr, CHANGE);

  Serial.begin (115200);
}  // end of setup

void loop ()
{
  if ( ManchesterInterrupts::available ())
    Serial.print ((char) ManchesterInterrupts::read ());
}  // end of loop

In a similar way to the hardware serial, you can go about your business in loop() and check if data is available, and then do something with it.

I think this is nice and simple. You can test by connecting pin D8 of the sending example on one Arduino to pin D2 on the other one for receiving.

You can even test on a single board:

#include <ManchesterSend.h>
#include <ManchesterInterrupts.h>

// digital pins
const byte RECEIVE_PIN = 2;
const byte SEND_PIN = 8;

void sendString (const char * s)
{
  while (*s)
    ManchesterSend::write (*s++);  
}

void setup ()
{
  ManchesterSend::begin (SEND_PIN);
   // incoming on pin D2
  ManchesterInterrupts::dataPin = RECEIVE_PIN;
  // need a change interrupt to detect incoming data
  attachInterrupt (0, ManchesterInterrupts::isr, CHANGE);

  Serial.begin (115200);
  Serial.println ();

  // send out on pin 8
  sendString ("hello, world\n");

}  // end of setup

void loop ()
{
   if ( ManchesterInterrupts::available ())
    Serial.print ((char) ManchesterInterrupts::read ());
}  // end of loop

Thanks to everyone who inspired me to attempt this, in particular carl47 who gave me the idea to read the Atmel application note (not an easy read) and nut out a way of doing it with interrupts.

Seems an interesting way to establish a full duplex comm between two arduinos... Thanks for sharing.

This is quite slow. Between two Arduinos I would use async serial, SPI or I2C.

But for situations like infra-red controlled gadgets, or radio control, where you want to send smallish amounts of data in a noisy environment (eg. radio noise, light noise) then it can be quite useful.

Ok, so two arduinos via IR... :-)

Thanks for the clarification.

Reminds me of the old AMPS days... ESN, MIN.

Many card access readers communicate in Manchester format.