I stripped down my example and tried to capsulate it in its own wrapper class. This is by no means complete or ready to use .. it is just there to give interested people some kind of input on how to work with the wait/autoack stuff if you can't use your radios autoretry feature like me.
If you need some comments to understand parts of the code feel free to ask.
LightSensorSoftwareAckNRF24_class.ino
#define MY_NODE_ID 10
#define MY_BAUD_RATE 57600
// Enable debug prints to serial monitor
//#define MY_DEBUG
// Enable and select radio type attached
#define MY_RADIO_NRF24
//#define MY_RADIO_RFM69
#include <SPI.h>
#include <MySensors.h>
#define LIGHT_SENSOR_ANALOG_PIN A3
#define MINUTES 60000UL
#define CHILD_ID_LIGHT 0
#include "helper.cpp"
void before()
{
// LightSensor
// http://akizukidenshi.com/download/ds/senba/GL55%20Series%20Photoresistor.pdf
// GL5549
pinMode(A3,INPUT_PULLUP); // 20-50 kOhm
pinMode(A2,OUTPUT);
digitalWrite(A2,LOW);
}
MySensorChild photoSensor = MySensorChild(CHILD_ID_LIGHT,S_LIGHT_LEVEL,"Photoresistor GL5549");
void setup()
{
}
void presentation() {
// Send the sketch version information to the gateway and Controller
sendSketchInfo("LightClass_Test", "0.1");
photoSensor.do_present();
}
void loop()
{
// Set Message
photoSensor.message()->set(random(0,100));
// Print Result
photoSensor.print(photoSensor.waitsend(250));
delay(1000);
}
helper.cpp
#include "core/MySensorsCore.h"
#include "core/MyTransport.h"
#include "drivers/RF24/RF24.h"
#include <stdarg.h>
class MySensorChild
{
public:
typedef struct {
uint8_t rpd;
unsigned long long elapsedtime;
uint8_t success;
uint8_t retrycount;
} return_struct;
void print(return_struct r)
{
Serial.print(r.success == 1 ? "success" : "fail "); Serial.print(" | ");
Serial.print("time: "); p(F("%8d"),r.elapsedtime); Serial.print("uS | ");
Serial.print("retr.: "); p(F("%2d"),r.retrycount); Serial.print(" | ");
Serial.print("rpd: "); Serial.print(r.rpd); Serial.print(" | ");
Serial.println();
}
public:
MySensorChild(uint8_t childid, uint8_t valuetype, char * description)
{
// Base Values that define a Message
this->description = description;
this->childid = childid;
this->valuetype = valuetype;
this->message_internal = MyMessage(childid, valuetype);
}
MyMessage * MySensorChild::message()
{
return &this->message_internal;
}
void do_present()
{
present(this->childid, this->valuetype, this->description);
}
return_struct MySensorChild::waitsend(unsigned long ms)
{
bool ok = false;
const uint8_t retrycountlimit = 10;
unsigned long long starttime = micros();
return_struct r;
send(message_internal,true);
uint8_t c = retrycountlimit;
while(!ok && c)
{
// Ack?!
if(wait(ms,message_internal.getCommand(),message_internal.type))
{
r.rpd = RF24_readByteRegister(RPD);
r.elapsedtime = micros()-starttime;
r.success = true;
r.retrycount = retrycountlimit-c;
return r;
//Serial.print(" | rpd: "); Serial.print(RF24_readByteRegister(RPD));
// Return!
//return true;
}
else
{
if(!isTransportOK())
{
Serial.print(" | Transport broken! ");
wait(100);
}
//Serial.print("~");
send(message_internal,true);
}
c--;
}
if(c == 0)
{
r.elapsedtime = micros()-starttime;
r.success = false;
r.retrycount = retrycountlimit-c;
return r;
//return false;
}
}
private:
// Base Values that define a Message
MyMessage message_internal;
char * description;
uint8_t childid;
uint8_t valuetype;
unsigned long lastSend;
void p(const __FlashStringHelper *fmt, ... ){
char buf[128]; // resulting string limited to 128 chars
va_list args;
va_start (args, fmt);
#ifdef __AVR__
vsnprintf_P(buf, sizeof(buf), (const char *)fmt, args); // progmem for AVR
#else
vsnprintf(buf, sizeof(buf), (const char *)fmt, args); // for the rest of the world
#endif
va_end(args);
Serial.print(buf);
};
};
Example output (mydebug enabled @ gateway)
success | time: 16mS | retr.: 0 | rpd: 1 | <\r><\n>
success | time: 17mS | retr.: 0 | rpd: 1 | <\r><\n>
success | time: 13mS | retr.: 0 | rpd: 1 | <\r><\n>
success | time: 10mS | retr.: 0 | rpd: 1 | <\r><\n>
success | time: 12mS | retr.: 0 | rpd: 1 | <\r><\n>
success | time: 11mS | retr.: 0 | rpd: 1 | <\r><\n>
success | time: 12mS | retr.: 0 | rpd: 1 | <\r><\n>
success | time: 12mS | retr.: 0 | rpd: 1 | <\r><\n>
success | time: 10mS | retr.: 0 | rpd: 1 | <\r><\n>
success | time: 13mS | retr.: 0 | rpd: 1 | <\r><\n>
success | time: 12mS | retr.: 0 | rpd: 1 | <\r><\n>
success | time: 10mS | retr.: 0 | rpd: 1 | <\r><\n>
success | time: 12mS | retr.: 0 | rpd: 1 | <\r><\n>
success | time: 11mS | retr.: 0 | rpd: 1 | <\r><\n>
success | time: 12mS | retr.: 0 | rpd: 1 | <\r><\n>
success | time: 12mS | retr.: 0 | rpd: 1 | <\r><\n>
fail | time: 2504mS | retr.: 10 | rpd: 0 | <\r><\n>
fail | time: 2505mS | retr.: 10 | rpd: 0 | <\r><\n>
Always a good idea to disable debugging if you are happy with the performance. Debugging output on serial on the mqtt-gateway (esp8266) takes quite a while.
success | time: 4mS | retr.: 0 | rpd: 1 | <\r><\n>
success | time: 2mS | retr.: 0 | rpd: 1 | <\r><\n>
success | time: 4mS | retr.: 0 | rpd: 1 | <\r><\n>
success | time: 4mS | retr.: 0 | rpd: 1 | <\r><\n>
success | time: 4mS | retr.: 0 | rpd: 1 | <\r><\n>
success | time: 2mS | retr.: 0 | rpd: 1 | <\r><\n>
success | time: 4mS | retr.: 0 | rpd: 1 | <\r><\n>
success | time: 5mS | retr.: 0 | rpd: 1 | <\r><\n>