radio.write verifies a successful transmission?

I was messing with Robin2's simple tutorial and on the Tx side I noticed the line that mentioned rslt and radio.write. Does it verify for you automatically if a message was successfully sent and received? Like it knows if Rx received it?

I was trying to range test my modules, where one LED would turn on if it is out of range and another for if it's within range, but before I was able to go out and do so, I noticed when the two modules initially connect, both go on. Before Tx is on, though, the LED for out of range would be on

The normal behaviour of the nRf24 modules is to send an acknowledge when a message is received and that allows radio-write() to know that the message has been received and acknowledged. I put those words in bold because you must read them as a unit. It is possible for the message to be received and for the acknowledgement to fail, but the sender will not know that.

The ability of the sender to automatically retry the transmission depends on the expectation of an ack.

The error will only be reported to the Arduino after all the retries have failed.

You can disable the auto-ack feature if necessary.

The best way to verify communication is to send a message at regular intervals and if the gap between messages exceeds the interval the receiver will know there is a problem. For my own systems I allow several missed messages (about 1 second in total) before shutting things down.

I have certainly had my nRF24s show spurious results - usually when one of the pair was not working properly. But I don't recall any problems when the pair are working properly. I can switch one off and the other one recognizes that and when I switch on again communication resumes smoothly.

...R

Disabling the ack feature is done by disableAckPayload(), and it is enabled by default, right?

So the nrf24s unknowingly to the person do send and receive at virtually the same exact time. The Tx will be in receive mode right after it sends, then it awaits the ack, right?

Robin2:
I have certainly had my nRF24s show spurious results - usually when one of the pair was not working properly. But I don't recall any problems when the pair are working properly. I can switch one off and the other one recognizes that and when I switch on again communication resumes smoothly.

...R

With your code, both sides can verify if either one is on (I have tried it), but I modified it with LED stuff although I don't believe it was done correctly.

EDIT: I know this is stupid, but I can definitely use the idea of millis() to verify if out of range is achieved on Rx, right? And would it be the same? On the tutorial it was on Tx, so I'm just asking.

How can I verify on Rx if data is received or not or if Tx is out of range? Obviously, !radio.available doesn't work... I shouldn't expect that putting exclamation marks on functions makes it the flips side of the intended operation. Perhaps else might work?

JeromeAriola:
How can I verify on Rx if data is received or not or if Tx is out of range?

IMHO the only reliable way is by sending messages at regular intervals and noting the absence of a message within the appropriate interval.

I have the sense that you are pursuing a theoretical question that is not of any particular value in practice.

...R

I am considering using the millis() idea, but I have my own idea I think is worth seeing. I was working on this earlier on paper (my codes are in my school computer):

Intended for Rx

unsigned long commsDelay;

void verifySuccessfulComms(){
   if(commsDelay >= 1000){
      Serial.println("Not available");
   }
}

void loop(){
   if(radio.available()){
   radio.read(msg, &sizeof(msg));
   Serial.println(msg);
   commsDelay = 10;    //while a connection is true
   delay(10);      //commsDelay "won't" increment.
   commsDelay + 10;   //only when no connection does it "truly" add.
   }
   verifySuccessfulComms();
}

With this code

  commsDelay = 10;    //while a connection is true
   delay(10);      //commsDelay "won't" increment.
   commsDelay += 10;   //only when no connection does it "truly" add.

commsDelay will never exceed 20. And note the need for +=

Try something like this

unsigned long latestMessageMillis;

void verifySuccessfulComms(){
   if(millis() - latestMessageMillis >= 1000){
      Serial.println("Not available");
   }
}

void loop(){
   if(radio.available()){
   radio.read(msg, &sizeof(msg));
   Serial.println(msg);
   latestMessageMillis = millis();
   }
   verifySuccessfulComms();
}

Get into the habit of running your code as often as possible - ideally after every small change.

...R

Reading some documentation gives me a slight idea of millis(). Here goes.

If let's say the Rx detects Tx at 4500ms, but has been running for 4000ms, 4500 will be the value of latestMessageMillis, right? That number will then be subtracted by how long the Rx has been running to show the delay, correct?

Just saying what I see it does to make you see if I understand it.

But for the sake of improving my programming skills, how can I make my code work? I thought that adding the delay allows the variable to increment 10 per 10ms...

JeromeAriola:
But for the sake of improving my programming skills, how can I make my code work? I thought that adding the delay allows the variable to increment 10 per 10ms...

Arduino programs (and almost all programs on all computers) start at the top and work their way to the bottom, line by line. In the Arduino when the program gets to the bottom of the loop() function it goes back to the top of loop() and repeats. Now, take a pencil and paper and pretend that your brain is the computer and your paper is the computer memory. Do the calculation on each line and write down the answer. And work your way through setup() and a few iterations of loop().

Also, very important, keep in mind that a computer is monumentally stupid and it only does exactly what the instruction on a line tells it to do.

...R

I'm not saying that I'm not listening to you, but I just want to make my own code correct... It's bugging me.

I figured this: what if the commsDelay increment is outside the if statement. That way, commsDelay will be only 10 if and only if a message is received. Now if there is no available() is a true value (meaning no message), in loop() commsDelay will continue to increment. That is if it does increment (like +10 per 10ms delay)

void loop(){
   if(radio.available()){
      //instructions
      commsDelay = 10;
     }
   commsDelay += 10;
   delay(10);
   verifySuccessfulComms();
}

I am going to use your suggestion, but I wish to "debug" this one.

JeromeAriola:

void loop(){

if(radio.available()){
     //instructions
     commsDelay = 10;
    }
  commsDelay += 10;
  delay(10);
  verifySuccessfulComms();
}




I am going to use your suggestion, but I wish to "debug" this one.

Before asking that question you should have tried your program to see what happens. The Arduino system is designed to make that very easy. Debugging is the art of trying things out and trying to make sense of the results as an indication of what is wrong. Get into the habit of testing your code very frequently.

In general, your code should function very like the code I suggested as the timer gets reset when a message is received but the timer value accumulates when a message is not received. Note how the words in bold describe the behaviour without using any code. That sort of description is usually the best starting point for figuring out a solution.

The downside, however, is that by using delay() it is not checking the "incoming mail" very often and also time is being wasted that might be used to do something else useful.

Thinking and planning is essential for successful debugging. You need to have an expectation of how some code will work and have an expectation of what will demonstrate that it is not working. For example you might include code to print a variable so you can see if it is behaving as you expect it to.

...R

In the part where you talk about delay, that tiny 10ms delay can be used to do something for productive. That is what you're trying to say, right? And are you saying that some sort of "buffer overflow" may occur, even if the timer resets?

Thank you for the advice, though. Really appreciate it, sir.

I think that this is the wrong neighborhood for programming advice though... But thanks anyway!

I feel more enlightened in a programming sense now :wink:

JeromeAriola:
In the part where you talk about delay, that tiny 10ms delay can be used to do something for productive. That is what you're trying to say, right?

In 10 millisecs a 16MHz Arduino can do 160,000 instructions if my maths is correct. I have a program that detects revolutions of a small DC motor. At high speed there are only about 4 millisecs between revolutions and all the other program calculations happen within that time period so that it can control the speed of the motor and receive nRF24 messages to change the speed.

And are you saying that some sort of "buffer overflow" may occur, even if the timer resets?

An nRF24 message only takes 1 or 2 millisecs so it is possible that several could arrive during the 10msec delay. That has nothing to do with the timer resetting. Of course if you write the transmitting program(s) you could ensure that that can't happen.

...R

Perhaps delay(1) would work :slight_smile:

In other words, my code works, but is not as efficient as yours.

Many thanks for the help, sir.