Sample sketch for test node including hardware and software acknowledgement



  • Recently, I have been trying to test out the quality of my node to gateway communication, as I know that occasionally messages from nodes don't make it through.

    I could not find a simple test sketch that had examples of how to perform the different types of message delivery checks, so I have searched the forums and produced a simple sketch that may be of use to others.

    The hardware is as simple as can be:
    Simple Mysensors node

    The sketch will send alternating 1 and 0 to simulate a switch. Each time it will check for :
    Transportready
    Radio Hardware ACK
    Software Echo.

    Results are displayed in the debug serial window.

    It it interesting to note that the results so far are different from what I expected.
    Transportready seems to report good even when lots of hardware NACKS occur.
    I've also seen the echo come back as good even though the ack did not.

    Here is the sketch

    // Mysensors test sketch 1.3 by grumpazoid
    
    #define MY_DEBUG // Enable debug prints
    
    // #define MY_PARENT_NODE_ID 0 // use this to define next node on route e.g. a repeater
    // #define MY_PARENT_NODE_IS_STATIC // dont allow node to search for other repeaters
    // #define NODE_ID 200 // enable this if you want the node to have a specific ID
    
    #define MY_RADIO_RF24 //Enable and select radio type attached
    //#define MY_RADIO_NRF5_ESB
    //#define MY_RADIO_RFM69
    //#define MY_RADIO_RFM95
    
    #define MY_RF24_PA_LEVEL RF24_PA_MAX   // Set Radio Power. Values can be MIN LOW HIGH MAX.  FOR PA+LNA MODULE LOW CAN WORK BETTER!! 
    
    #include <MySensors.h>
    
    #define CHILD_ID 1
    int STATE = 0;
     
    // Initialize motion message
    MyMessage msg(CHILD_ID, V_TRIPPED);
     
    void setup() 
    { 
      sendSketchInfo("Test sensor", "1.3");
      present(CHILD_ID, S_DOOR); 
    }
    
     
    void loop()
    {
       //TEST FOR TRANSPORT READY
       if (isTransportReady())
        {
             Serial.println ();
             Serial.println ("Tranport Ready");  
        }
     
    // SEND MESSAGE
    // send(msg.set(STATE),true); 
    
     //TEST FOR HARDWARE ACK
     if (send(msg.set(STATE), true))  // This appears to also send the message
    {                        
          Serial.println("HARDWARE ACK----UPLINK AVAILABLE");
          
    }
    else {
          Serial.println("HARDWARE ACK----UPLINK IS NOT AVAILABLE. NO HARDWARE ACK RECEIVED");
    }
    
      #ifdef MY_DEBUG
      Serial.print("current vale of STATE = ");
      Serial.println(STATE);
    #endif;
    
    // Change state ready for next time
        if (STATE==0) { 
         (STATE=1); 
          }
        else if (STATE==1){
        (STATE=0) ;
        } 
    
       #ifdef MY_DEBUG
      Serial.println("Going to wait a few seconds for echo message");
    #endif;
       wait(3000); // Wait 3 seconds
     
       
       // We shaould have WAITED long enough now for echo message so let's have a sleep.
         
         #ifdef MY_DEBUG
      Serial.println("Going to sleep for 10 seconds");
    #endif;
    
       sleep(10000); // Sleep 10 seconds   
    }
    
    // END OF MAIN LOOP
    
    
    //Listen for incoming messages
    void receive(const MyMessage &message) {
       
      if (message.isEcho()) 
      {
         Serial.println("SOFTWARE ECHO RECEIVED---- from gateway");
      }
    }
    
    

  • Mod

    @grumpazoid said in Sample sketch for test node including hardware and software acknowledgement:

    Transportready seems to report good even when lots of hardware NACKS occur.

    Transportready is just an indication that your radio is good to go. It does not depend on your link quality.

    I've also seen the echo come back as good even though the ack did not.

    Welcome to the wonderful world of radio communications! 😄

    A message can be correctly received by the target node, while the ack gets lost. The target node then echoes the message back to the source, which receives it correctly.
    Perfectly viable scenario.



  • @Yveaux said in Sample sketch for test node including hardware and software acknowledgement:

    @grumpazoid said in Sample sketch for test node including hardware and software acknowledgement:

    Transportready seems to report good even when lots of hardware NACKS occur.

    Transportready is just an indication that your radio is good to go. It does not depend on your link quality.

    I've also seen the echo come back as good even though the ack did not.

    Welcome to the wonderful world of radio communications! 😄

    Thanks. That explains why Transportready always reports good.

    In my day job I work with wired and wireless networks that mostly use TCP/IP so as long as the radio link is there failed messages are handled automatically.
    I've updated my sketch now and added an extra bool variable for when echo is received. So now the node can be set to only sleep when it hears an echo. Good stuff.

    A message can be correctly received by the target node, while the ack gets lost. The target node then echoes the message back to the source, which receives it correctly.
    Perfectly viable scenario.

    Great that's what i thought was happening. Good to have it confirmed.

    Is it possible to serial print (or store in a variable) the returned message payload? I can see how to print the other parameters but not the payload itself.


  • Mod

    @grumpazoid said in Sample sketch for test node including hardware and software acknowledgement:

    I can see how to print the other parameters but not the payload itself

    You could just print the raw bytes, which works for all payload types (eg https://github.com/Yveaux/Arduino_HexDump). Otherwise you have to print the contents depending on the type of data in the message.



  • @Yveaux Thanks for the link.
    I'm not sure if I am missing something simple?

    So I can see the echo in the monitor :

    173 TSF:MSG:READ,0-0-9,s=1,c=1,t=16,pt=2,l=2,sg=0:111
    182 TSF:MSG:ECHO
    

    In this case the original sent value was 111 and I can see it in the echo message.

    If I do

    Serial.println(message.isEcho());
    

    I get a 1 printed. Is there a message.something that contains the original sent value?



  • @grumpazoid isEcho() returns a boolean which is either true or false and tells you if the incoming message is an echo (1) or not (0).

    You can use it in the receive() function to filter out echos and print the content with any of the available getType functions provided by the MyMessage class, like getUInt() or getString(). The latter will convert any numeric type into a char array for you (if conversion isn't possible, it'll return NULL).

    void receive(const MyMessage &message)
    {
        if (message.isEcho()) {
            Serial.println(message.getString());
        }
    }
    


  • @BearWithBeard Thanks for confirming this. I had tried most of the options listed on the MyMessage page.

    I have tried both ways you suggest again just now - getString() returns nothing and getUInt always returns zero.
    At the moment it does not matter as I can see the value listed at the end of the echo(as posted previously) it would just be nice to be able to "harvest" it.
    For now I will use the value that has just been sent - for resends etc.


  • Mod

    MyMessage has a method setType but there is no corresponding getType. If getType was available, you should be able to use that to figure out which getter you should use (getLong, getInt, getFloat, getString and the others).

    But the getString does the conversion already, if you pass it a buffer to fill. Like this:

    void receive(const MyMessage &message){
      char messagestring[100];
      message.getString(messagestring);
      Serial.println(messagestring);
    

    }

    Documentation reference: https://www.mysensors.org/download/sensor_api_20#message-manipulation



  • @mfalkvidd said in Sample sketch for test node including hardware and software acknowledgement:

    char messagestring[100];
    message.getString(messagestring);
    Serial.println(messagestring);

    @mfalkvidd Fantasic. Thank you. That is what I was looking for . It works now !!!


Log in to reply
 

Suggested Topics

  • 6
  • 3
  • 1
  • 183
  • 59
  • 3
  • 10
  • 2

185
Online

9.6k
Users

10.2k
Topics

106.1k
Posts