Tuesday, July 26, 2011

Simple, but works.

This is a very simple text chat over the Nordic Radios. However, there seems to be transmission issues, even at small distances. Not impressed.


#include "Nrf2401.h"
#include

Nrf2401 Radio;
unsigned char SyncByte = 128;
long LastReceiveTime=0;
ByteBuffer CircularBuffer;
byte LastByte;
byte ByteReceived;
int Outstanding=0;

void setup(void)
{
Serial.begin(9600);
pinMode(13, OUTPUT);
// start the random number generator
randomSeed(analogRead(7));
// look for rising edges on digital pin 2
attachInterrupt(0, messageReceived, RISING);
CircularBuffer.init(25);
Serial.println("RC Ping");

Radio.dataRate=0;
Radio.power=3;
Radio.txMode(1);
delay(100);
Radio.rxMode(1);
delay(100);
}//End Setup


void loop(void)
{

if (Outstanding==1)
{
if ((millis()-LastReceiveTime)>5000)
{
Serial.println("Connection Timed Out.");
LastReceiveTime=millis();
Serial.print("Attempting to Re-Send: ");
Serial.println(LastByte);
SendPacket(LastByte);

}//End Check For Timeout
}//Outstanding Packet
else
{
if (Serial.available())
{
SendPacket(Serial.read());
}
}
messageReceived();
ParsePacket();
}//End Loop



void SendPacket(byte Data)
{
Radio.txMode(1);
delay(100);

if (Data!=0x00)
{
Outstanding=1;
LastReceiveTime=millis();
LastByte=Data;
}


//Serial.print("Sending: ");
//Serial.println(Data,BYTE);

Radio.write(Data);
delay(100);
Radio.rxMode(1);
}//End SendPacket






void ParsePacket()
{
if (CircularBuffer.getSize()>0)
{
ByteReceived=CircularBuffer.get();

//ACK Packet
if (ByteReceived==0x00)
{
Outstanding=0;
//Serial.println("Received ACK.");
}
else
{
//Send ACK
Serial.print(ByteReceived,BYTE);
delay(100);
SendPacket(0x00);
}
}
}//End ParsePacket

void messageReceived(void)
{
while(Radio.available())
{
Radio.read();
CircularBuffer.put(Radio.data[0]);
//Serial.print("Received:");
//Serial.println(CircularBuffer.peek(CircularBuffer.getSize()-1),BYTE);
LastReceiveTime=millis();
}
}//End messageReceived

Tuesday, June 7, 2011

Success with Serial to RF Bridge

I had some time to re-work my TCP implementation using the Nordic nRF2401a chips. I got this pretty reliable code working.

It uses a PC to send packets over the Serial to one Arduino which then transmits the packet to the other Arduino. The receiving Arduino simply sends an ACK packet back. If the sender does not receive an ACK within 5 seconds, it assumes the packet was not received and attempts to re-send the last packet.

One of the wonderful parts about this code is that the same code is used on both Arduinos, so there's no need to create seperate Server and Client programs. It doesn't matter which Arduino is connected to the PC, either will accept Serial commands and forward them across the RF connection.


#include "Nrf2401.h"
#include "ByteBuffer.h"

Nrf2401 Radio;
unsigned char SyncByte = 128;
long LastReceiveTime=0;
ByteBuffer CircularBuffer;

int WaitForACK=0;
byte LastPacketType=0;
byte LastData=0;


void setup(void)
{
Serial.begin(9600);
pinMode(13, OUTPUT);
randomSeed(analogRead(7)); // start the random number generator
attachInterrupt(0, messageReceived, RISING); // look for rising edges on digital pin 2
CircularBuffer.init(25);
Serial.println("RC Ping");
Radio.rxMode(1);
}//End Setup


void loop(void)
{

//While in rxMode (1)
if (WaitForACK==1)
{
if ((millis()-LastReceiveTime)>5000)
{
Serial.println("Connection Timed Out.");
LastReceiveTime=millis();
SendPacket(LastPacketType,LastData);
}
}

if (Serial.available()>=3)
{
WaitForACK=1;
LastReceiveTime=millis();
SendPacket(Serial.read(),Serial.read());
Serial.read();
}

ParsePacket();
}//End Loop



void SendPacket(byte PacketType,byte Data)
{
LastPacketType=PacketType;
LastData=Data;

Radio.txMode(1);
digitalWrite(13, !digitalRead(13));

if (PacketType==0x00)
{
Serial.println("Sending RTS.");
}
if (PacketType==0x01)
{
Serial.println("Sending DATA.");
}
if (PacketType==0x02)
{
Serial.println("Sending ACK.");
}
if (PacketType==0x03)
{
Serial.println("Sending FIN.");
}



byte Checksum;
Checksum=~(byte)(PacketType+Data);

Serial.print("Sending: ");
Serial.print(PacketType,HEX);
Serial.print(",");
Serial.print(Data,HEX);
Serial.print(",");
Serial.println(Checksum,HEX);
delay(50);
Radio.write(PacketType);
delay(50);
Radio.write(Data);
delay(50);
Radio.write(Checksum);
delay(50);
Radio.rxMode(1);
}//End SendPacket

void ParsePacket()
{
while (CircularBuffer.getSize()>=3)
{

byte ReceivedPacketType;
byte ReceivedData;
byte ReceivedChecksum;

ReceivedPacketType=CircularBuffer.peek(0);
ReceivedData=CircularBuffer.peek(1);
ReceivedChecksum=CircularBuffer.peek(2);

//Does Checksum Match?
if (ReceivedChecksum==(byte)~(byte)(ReceivedPacketType+ReceivedData))
{
ReceivedPacketType=CircularBuffer.get();
ReceivedData=CircularBuffer.get();
ReceivedChecksum=CircularBuffer.get();

Serial.print("Packet = ");
Serial.print(ReceivedPacketType,HEX);
Serial.print(",");
Serial.print(ReceivedData,HEX);
Serial.print(",");
Serial.println(ReceivedChecksum,HEX);


//RTS
if (ReceivedPacketType==0x00)
{
Serial.println("Received RTS.");
delay(150);
SendPacket(0x02,0x00);
}
//DATA
if (ReceivedPacketType==0x01)
{
Serial.println("Received DATA.");
delay(150);
SendPacket(0x02,0x00);
}
//ACK
if (ReceivedPacketType==0x02)
{
Serial.println("Received ACK Type.");
WaitForACK=0;
}
//FIN
if (ReceivedPacketType==0x03)
{
Serial.println("Received FIN.");
delay(150);
SendPacket(0x02,0x00);
}
}
else
{
Serial.println("Invalid Checksum!");
Serial.print("Expected: ");
Serial.println((byte)~(byte)(ReceivedPacketType+ReceivedData),HEX);
Serial.print("Actual: ");
Serial.println(~ReceivedChecksum,HEX);
CircularBuffer.get();
}
}
}//End ParsePacket

void messageReceived(void)
{
if (Radio.available())
{
int BytesAvailable=Radio.available();
Radio.read();
for (int i=0;i {
CircularBuffer.put(Radio.data[i]);
Serial.print("Received:");
Serial.println(CircularBuffer.peek(CircularBuffer.getSize()-1),HEX);
LastReceiveTime=millis();
}
}
}//End messageReceived

Saturday, June 4, 2011

Attempt at UDP nRF2401a

Not having much luck with my TCP implementation, I decided to go back and try the UDP implementation.



#include "Nrf2401.h"

Nrf2401 Radio;
unsigned char SyncByte = 128;
long LastReceiveTime=0;

void setup(void)
{
Serial.begin(9600);
pinMode(13, OUTPUT);
randomSeed(analogRead(7)); // start the random number generator
attachInterrupt(0, messageReceived, RISING); // look for rising edges on digital pin 2
Serial.println("RC Ping");
Radio.txMode(1);

}


void loop(void)
{

//While in rxMode (1)
if (Radio.mode==1)
{
if ((millis()-LastReceiveTime)>5000)
{
Serial.println("Connection Timed Out.");
LastReceiveTime=millis();

Radio.txMode(1);
Serial.print("Attempting to Re-Send: ");
Serial.println(SyncByte,HEX);
Radio.write(SyncByte);
Radio.rxMode(1);
}
// block (or do something else) here while the radio is
// in rxMode (Radio.mode is 1 in rxMode, 0 in txMode)
}
else
{
digitalWrite(13, LOW);
delay(1000);
digitalWrite(13, HIGH);
delay(1000);
digitalWrite(13, LOW);

Serial.print("Sending: ");
Serial.println(SyncByte,HEX);
Radio.write(SyncByte);
delay(100);
Radio.rxMode(1);
}
}

void messageReceived(void)
{
while(Radio.available())
{
digitalWrite(13, LOW);
delay(500);
digitalWrite(13, HIGH);
delay(500);
digitalWrite(13, LOW);
delay(1000);
digitalWrite(13, HIGH);
delay(500);
digitalWrite(13, LOW);

Radio.read();
byte MyByte=Radio.data[0];
Serial.print("Received:");
Serial.println(MyByte,HEX);
LastReceiveTime=millis();
}
Radio.txMode(1);
delay(100);
}