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