I have fiddled with this some more this afternoon and have learned a lot. Hopefully I'm also making changes that are helpful.
First off, I had made the changes suggested by panosnl above. Sorry but those changes cause problems. Timw has it correct. The reason why he made those variables private is that they change meaning in compatibility mode. Instead, change the sketch not the library. Specifically, in RFM12B_Struct_node.ino use the accessor functions. Do not access the variables directly.
In Loop()
Change this:
Serial.print('[');Serial.print(radio.GetSender(), DEC);Serial.print("] ");
for (byte i = 0; i < *radio.DataLen; i++)
Serial.print((char)radio.Data[i]);
to this:
Serial.print('[');Serial.print(radio.GetSender(), DEC);Serial.print("] ");
for (byte i = 0; i < *radio.GetDataLen(); i++)
Serial.print((char)radio.GetData()[i]);
Now we can make changes to the library. Here are the changes to address the issues I noticed before, plus I found one more.
in RFM12B.h
Change this:
// shorthands to simplify sending out the proper ACK when requested
#define RF12_WANTS_ACK ((rf12_hdr2 & RF12_HDR_ACKCTLMASK) && !(rf12_hdr1 & RF12_HDR_ACKCTLMASK))
to this:
// shorthands to simplify sending out the proper ACK when requested
#if !defined(RF69_COMPAT)
#define RF12_WANTS_ACK ((rf12_hdr2 & RF12_HDR_ACKCTLMASK) && !(rf12_hdr1 & RF12_HDR_ACKCTLMASK))
#else
#define RF12_WANTS_ACK ((rf12_hdr3 & 0x40) && !(rf12_hdr3 & 0x80))
#endif
In RFM12B.cpp
In ACKReceived()
Change this:
#if !defined(RF69_COMPAT)
(rf12_hdr3 & 0x40) &&
!(rf12_hdr3 & 0x80);
#else
(rf12_hdr1 & RF12_HDR_ACKCTLMASK) &&
!(rf12_hdr2 & RF12_HDR_ACKCTLMASK);
#endif
to this:
#if !defined(RF69_COMPAT)
(rf12_hdr1 & RF12_HDR_ACKCTLMASK) &&
!(rf12_hdr2 & RF12_HDR_ACKCTLMASK);
#else
(rf12_hdr3 & 0x80) &&
!(rf12_hdr3 & 0x40);
#endif
In RFM12B.cpp
In SendStart()
Change this:
rf12_hdr3 = (sendACK ? 0x40 : 0) | (requestACK ? 0x80 : 0);
to this:
rf12_hdr3 = (sendACK ? 0x80 : 0) | (requestACK ? 0x40 : 0);
With these changes the logic seems correct, however most ACK messages are still lost. This is because the other side (Struct_receive.ino) does several Serial.print()s before sending the ACK. This delays when the ACK is sent and the RFM12B_Struct_node side times out. I don't know if everyone sees this problem or if it's something unique to my environment. If I change the define for the timeout from 30mS to 150mS about 95% of the ACKs make it in time.
Change this:
#define ACK_TIME 30 // # of ms to wait for an ack
To this:
#define ACK_TIME 150 // # of ms to wait for an ack
I would still like to see Tim's fork merged back into the LPL mainstream as the two have already diverged a little.
Oh, and for what it's worth, I really like the restructuring done in the RFM69 library. It's much easier to read and understand.
Thanks,
- Chip