But I hope it helps people work out how to create an extensible packet system with room for 254 flags and 15 nodes (more if you want to tinker)
basically I've written two function that send and receive data via a structure. you can change the structure in the .h where i've indicated to suit your needs. Also I've only used two flags, to implement an optional simple acknowledgement system. I've put lots and lots of comments in to hopefully help anyone trying to work out what I've done.
The advantages are as follows: o you can build in actions based on flag type easily o Acknowledgements are optional o You know who sent the packet as well as who its going to. o lots of comments!
The disadvantages: o possibly not very memory efficeint o the Acknoledgements systems insn't fully tested
feel free to have a play and edit!
packet.h:
struct Packet {
//must add up to less than 65 bytes
//packet counter, will roll over, increments
unsigned int count;
//add your sexy flags here
byte packType;
//two nibbles of address
//to - from
//below is a broadcast packet from node 8
//B00001000
byte address;
//no more than 61 bytes.
//anything after this is optional, so add and remove as you see fit
char message[60];
};
//this is the data structure of the packet that gets passed about
//this packet is the one that gets sent out
extern Packet packet;
//this on is the point to the one that the node recives
extern Packet packetIn;
//this allows you to set your node ID at runtime
//node id can be from 0 to F. it only looks at the last for bits, so a bigger number will cause a suprise!
extern char NODEID;
int sendPacket (byte destAddr, byte increment = 1, byte type = B00000001);
int receivePacket(void);
and packet.cpp:
#include
//import the packet structure for the outgoing packet and the incoming one Packet packet; Packet packetIn;
//packet count, used to see if we have a fresh packet int packetId = 0; char packetAddr = 0; //this is the node's address only the last nibble is used, so there are only 16 address with 0 reserved for broadcast char NODEID = 0x0F;
//this sends the packet (cunningly called packet) to the destination address (0-15), //and the type of packet it is //returns -1 if it can send and if you've requested acknoldegements it'll return false if it doesn't get one int sendPacket (byte destAddr, byte type ){ int i = 0; receivePacket(); while(rf12canSend() == 0){ i++; Serial.println("Not ready to send"); if (i > 5){ //it means we've waited long enough to be clear to send return -1 ; } delay(300); } //if we are here, we should be clear to send, increment the packet id. packet.count++; //if left empty sets the packet type default, which is one asking for a reply packet.packType = type; //set the node ID: //shift the destination addres 4 bits to the left, then concatinate the node's address packet.address = (destAddr << 4) | NODEID; //send rf12sendStart(0, &packet, sizeof packet ); //the acknolegement mechanism if (type == 0x01){ //we are now waiting for a packet of acknolwlegement int i = 0; int n = 0; //you can wait longer if you want, although it seems like it'll just be waisting batteries while (n < 5){ delay(10); Serial.println("Waitin for packet"); i = receivePacket(); if(i == true){ //lets look shall we? Serial.println("Got PAcket"); if (packetIn->packType == 0x02){ //received ack return true; } }else if(i == -1){ //resend //if you wish you can add a flag to indicate that there was a lost packet //this can be done by OR'ing the packet.type with your flag Serial.println("Packet Bad:( resending"); rf12sendStart(0, &packet, sizeof packet ); } } //given up trying return false; } //if you want to add your own packet types, place it here. return true; } //this is the function that handles the receiveing and filtering of packets //updates packetIn with any data that arrives, even if the function returns with problems int receivePacket(){ //DO IT NOW rf12recvDone(); //use a pointer to save memory packetIn = (Packet) rf12data; //check to see if the packet is sound, and addressed to us or 0 the braodcast address if ( rf12crc == 0 && ((packetIn->address >> 4) == NODEID or (packetIn->address >> 4) == 0) ){ //update the packet count if (packetId == packetIn->count && packetAddr == packetIn->address){ //there is high chance its not new return false; } //print out the packet details Serial.print("Packet ID"); Serial.println(packetId, DEC); packetId = packetIn->count; packetAddr = packetIn->address if (packetIn->packType == 0x01){ //ping the ack packet if we need to, could cause a recursive loop with we are not carefull sendPacket(packetIn->address << 4, 1, 0x02); } return true; } if (rf12crc != 0){ //its not very well we'll assume its for us though //although this will return -1 for all packets that are buggered, even ones that arnt ours return -1; } //we've got here becuase althoguhth crc is good, its not addressed to us or the braodcast return false; }
