gw.send( ) and transmission errors
-
Maybe I am misunderstanding your question but what about adding a timer to the loop?
-
If you want to wait a bit (and still want to receive messages) you should use the provided
gw.wait(<msec>). Calling delay() will halt everything and you will lose incoming messages.OK, so you think like this, then?...
state = !state; while(!gw.send(msg.set(state), true)) { gw.wait(someSmallDelay); } -
If you want to wait a bit (and still want to receive messages) you should use the provided
gw.wait(<msec>). Calling delay() will halt everything and you will lose incoming messages.Looks like MySensors library API docs is missing this useful wait function.
-
To be absolutely sure you're message has been received you must use the ack-functionality. Here are some untested pseudo-like code that should do re-send unless ack is received (with the correct payload).
int lastReceivedState = -1; void setup() { gw.begin(incomingMessage); } void loop() { int newState = readSomSateYouWantToSend(); if (newState != lastReceivedState) { gw.send(msg.set(newState), true); // Enable ack gw.wait(500); // Wait 500 msec before sending another message } gw.process(); } void incomingMessage(const MyMessage &message) { // Assuming we only receive ack for one message here. lastReceivedState = message.getInt(); } -
Looks like MySensors library API docs is missing this useful wait function.
and the examples are lacking this as well...
We'll mess around with that for a while...
-
Updated doc with the missing sleep call, **wait() **and a new description argument available when presenting sensors.
@hek thank you!
I want to note what you changed order of ack and description arguments here: https://github.com/mysensors/Arduino/commit/b482a8eb7a09fe46f8b58d38fb5944f5d651892a
Site documentation uses old argument order. -
To be absolutely sure you're message has been received you must use the ack-functionality. Here are some untested pseudo-like code that should do re-send unless ack is received (with the correct payload).
int lastReceivedState = -1; void setup() { gw.begin(incomingMessage); } void loop() { int newState = readSomSateYouWantToSend(); if (newState != lastReceivedState) { gw.send(msg.set(newState), true); // Enable ack gw.wait(500); // Wait 500 msec before sending another message } gw.process(); } void incomingMessage(const MyMessage &message) { // Assuming we only receive ack for one message here. lastReceivedState = message.getInt(); } -
Just my $0.02...
Be careful with any while loops that could go on forever under "perfect storm" conditions. It's usually a safe bet that eventually your device will get into a state where comms will fail forever. If you're stuck in a while loop waiting for a successful send then you have no chance to detect or correct the error, and given how tricky it is to debug Arduinos you'll probably never figure out what went wrong. The device will just go silent, and a little while later the batteries will run out (because it's sitting there trying to send over and over). Do yourself a favor and put a fail-safe
&& retries++ < MAX_RETRIESclause on your while loop.This doesn't speak directly to your case, but in a broad sense my assumption going in to any wireless design is that packets will be dropped, so I always design with that constraint in mind, rather than trying to design a system where no drops occur. For example, you might consider adding a "resync" timer that sends the current state regardless of changes every so often. So even if something is dropped you have a bounded amount of time where things are in the wrong state. I do this with my presentations: Every 5 minutes my sensors retransmit all presentation messages just in case the controller missed the first set, or the controller reset, or whatever...
Handling lossy comms is not usually too hard if you aren't trying to back-engineer that into a system that was designed with the assumption that messages would always succeed.
Incidentally, this is more or less the same as "UDP" vs "TCP" networking, if you've ever worked in that realm. So strategies would overlap pretty nicely.