Data & asynchronous transmission to use in wireless communications

sbright33:
Manchester coding can be a reliable method of sending, but it is not the fastest.

The reason i use manchester coding is to be able to recover clock on the receiving device. I think 100-150khz wouldn't be that fast... Also a decoder wouldn't be so difficult to achieve using a PLL, for example.

Show us the scope output so we know what you're talking about.

Will do once i get home, probably tomorrow.

You have to get very clear what you're trying to achieve and what constraints you have. In frequencies above 100kHz you have to take care about the timing of individual statements. To have a balanced output of 0s and 1s you may have to insert calculations on one side just to use an equal amount of time as the other side.

I agree completely and that is what i was trying to do but i wasn't getting the expected results.
If you look closely the files that i put at the end of this post you will notice i don't have any code related to receiver.
If you compare my modified library with original, (only the transmitting part) you will see:

  • statement 'if' changed to a 'switch' (i think LABELS and/or switch statement are equally timed);
  • digitalWrite(..) changed to PORTB statements (faster pin writes);
  • lastsend was used as a way to time correctly port writes and it worked really well at low frequencies. But, at the frequencies i want to transmit the introduced delay was too much. I probably have to re-think or re-work this solution...

You seem to have modified the library quite heavily. To enable us to reproduce your setup you have to show us all the code you're using, else we always talk about different things.

NOTICE: I haven't wrote, changed or used any part for receiving side. Right now i'm more worried on having Tx freq above 200kHz with 50% Duty-cycle.
Files are as follows:
Transmit.ino (Main program)
VLC.cpp & VLC.h (Modified Libraries)

TRANSMISSION.INO

 #include <VLC.h>

#define TxPin 8  //the digital pin to use to transmit data

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

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

void loop()
{
  cli();
  MANCHESTER.Transmit(Tdata);
  sei();
}//end of loop

VLC.H

 /*
This code is based on the Atmel Corporation Manchester
Coding Basics Application Note.

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.
*/

#ifndef VLC_h
#define VLC_h

#define TxDefault 4 //the digital pin to use to transmit data

#define TimeOutDefault -1 //the timeout in msec default blocks

#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#include <pins_arduino.h>
#endif

class MANCHESTERClass
{
  public:
    MANCHESTERClass(); //the constructor
	void SetPW(unsigned int interval); //  user sets the pulse width of half bit
    void SetTxPin(char pin); //set the arduino digital pin for transmit. default 4.
    void Transmit(unsigned int data); //transmit 16 bits of data
    void TransmitBytes(unsigned char numBytes, unsigned char *data); // transmit a byte array
    
  private:
    void sendzero(void);
    void sendone(void);
    unsigned char TxPin;
	unsigned int HALF_BIT_INTERVAL;
};//end of class MANCHESTER


extern MANCHESTERClass MANCHESTER;

#endif

VLC.cpp

#include "VLC.h"

MANCHESTERClass::MANCHESTERClass() //constructor
{
  TxPin = TxDefault;
  pinMode(TxPin, OUTPUT); // sets the digital pin 4 default as output
}//end of constructor

void MANCHESTERClass::SetPW(unsigned int interval)
{
	HALF_BIT_INTERVAL = interval; // user sets the pulse width of half bit
}//end of set half pulse width

void MANCHESTERClass::SetTxPin(char pin)
{
	if (pin <=7)
		TxPin = pin; // user sets the digital pin as output
	else if ((pin >= 8) || (pin <= 13))
		TxPin = pin - 8; // user sets the digital pin as output
	DDRB = DDRB | B0000001 | (1 << TxPin);
  //pinMode(TxPin, OUTPUT); // sets the digital pin 4 default as output
}//end of set transmit pin

void MANCHESTERClass::Transmit(unsigned int data)
{
  unsigned char byteData[2] = { data  >> 8, data & 0xFF};
  TransmitBytes(2, byteData);
}

void MANCHESTERClass::TransmitBytes(unsigned char numBytes, unsigned char *data)
{
  // Setup last send time so we start transmitting in 10us
  //lastSend = micros() - HALF_BIT_INTERVAL + 10;
   
  // Send 14 0's
  for( int i = 0; i < 14; i++) //send capture pulses
     sendzero(); //end of capture pulses
    
  // Send a single 1
  sendone(); //start data pulse
 
  // Send the user data
  for (unsigned char i = 0; i < numBytes; i++)
  {
    unsigned int mask = 0x01; //mask to send bits
	
	for (char j = 0; j < 8; j++)
    {
	unsigned int c = data[i] & mask;
		switch( c ) 
		{
			case 0:
				sendzero();
				break;
			case 1 :
				sendone();
				break;
		}
      mask = mask << 1; //get next bit
    }//end of byte
  }//end of data
  sendzero(); //end of capture pulses
  sendzero(); //end of capture pulses
}//end of send the data

void MANCHESTERClass::sendzero(void)
{
  //digitalWrite(TxPin, HIGH);
  PORTB = B00000001;
 
  delayMicroseconds(HALF_BIT_INTERVAL);
  //digitalWrite(TxPin, LOW);
  PORTB = B00000000;

}//end of send a zero

void MANCHESTERClass::sendone(void)
{
  //digitalWrite(TxPin, LOW);
  PORTB = B00000000;

delayMicroseconds(HALF_BIT_INTERVAL);
  //digitalWrite(TxPin, HIGH);
  PORTB = B00000001;
}//end of send one

MANCHESTERClass MANCHESTER;

Thanks for support,
Fernando Oliveira