So I have a few motino's, they are working great. one it attached to my raspPi with out challenge, the second is happily tossing chunks of data out the little wire and being successfully plucked out of the ether with the gatewayPi.
Now the question, I have a few more nodes that I'd like to add to the mix.
Currently I'm using a "struct" to compile the radio packet and it works, but it must match the receiver and sender perfectly.
as I add nodes must I add to and copy this struct to each node I'm using even though I may or may not populate the whole structure? is there a more flexible way to accomplish the task?
Thanks!
_P
For each unique node you can define a unique structure, as long as the receiver knows WHAT kind of structure it's getting then the receiver can handle each one individually. I generally add a length byte and 'type' byte as the first two bytes of the structure so that the receiver can easily determine which structure it is.
For example:
in Node 1:
struct N1_PACKET {
byte len;
byte type;
double temp_c;
} my_packet = { sizeof(struct N1_PACKET), N1_PACKET_TYPE, 25.4 };
and in Node 2:
struct N2_PACKET {
byte len;
byte type;
char buf[20];
} n2_payload = { sizeof(struct N2_PACKET), N2_PACKET_TYPE, "some text" };
The receiver does:
switch (radio.DATA[1]) {
case N1_PACKET_TYPE:
temperature = (struct N1_PACKET *)radio.DATA->temp_c;
...
break;
case N2_PACKET_TYPE:
strcpy(mybuf, (struct N2_PACKET *)radio.DATA->buf;
...
break;
etc...
UPDATE:
I should have mentioned that the len byte serves three purposes,
- is to integrity check the packet, if its a fixed length packet then it should match DATALEN if only one packet is sent.
- is to deal with variable length packets (ie, you can know how many chars are in .buf)
- is to deal with unknown packets mixed with known ones, you can easily skip over an unknown packet if you know its len.
What TomWs suggested is fine but i think you can do this a bit easier by skipping the len byte he used and use radio.SENDERID instead:
switch (radio.SENDERID){
case Node1:
.....
and so on :)
EDIT: I just realized that Tom's approach is perfect for sending different data structures from the same node.
You sir, just inadvertently solved my problem. Thank you! :)
Quote from: Steinarrr on December 18, 2014, 07:58:06 AM
...
EDIT: I just realized that Tom's approach is perfect for sending different data structures from the same node.
You sir, just inadvertently solved my problem. Thank you! :)
uh, thanks, I think ;)
What I didn't show you was how easy it is to parse receiving multiple packets within the same transmission:
byte *pPkt = radio.DATA;
while (pPkt < &radio.DATA[DATALEN]) {
switch (pPkt->type) {
case N1_PACKET_TYPE:
temperature = (struct N1_PACKET *)pPkt->temp_c;
...
break;
case N2_PACKET_TYPE:
strcpy(mybuf, (struct N2_PACKET *)pPkt->buf;
...
break;
default: // skipping unknown packet type
break;
} // end switch
pPkt += pPkt->len; // move on to the next packet (if there is one)
} // end while
Obviously you could do this with indexes as well, but I find pointers easier to manage (just a personal preference)...
Referencing members (eg pPkt->len) rather than indexes (eg pPkt[0]) allows you to move where len and type members are in the structure. Putting them in the beginning greatly simplifies the parsing code since they don't move in a data dependent fashion.
Tom
Cool, although my problem involved sending different types of data, all of which smaller then 60 bytes.
QuoteI find pointers easier to manage (just a personal preference)...
(https://i.imgflip.com/fgs94.jpg)
Awesome! Thank you both.
I think i understand the concepts well enough to port it over.
Cheers!