Skip to content
  • MySensors
  • OpenHardware.io
  • Categories
  • Recent
  • Tags
  • Popular
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo
  1. Home
  2. Development
  3. Discussion: Reliable delivery

Discussion: Reliable delivery

Scheduled Pinned Locked Moved Development
protocol
54 Posts 10 Posters 16.6k Views 17 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • mfalkviddM Offline
    mfalkviddM Offline
    mfalkvidd
    Mod
    wrote on last edited by
    #8

    Thanks @hek! Now I have something to read before I go to sleep tonight :)

    1 Reply Last reply
    0
    • mfalkviddM Offline
      mfalkviddM Offline
      mfalkvidd
      Mod
      wrote on last edited by
      #9

      I have collected some real-world use cases and read the protocol design discussions in the forum. There is something I don't understand though:

      What is the difference between hardware and software ack, and difference between the ack in present/sendSketchInfo/send/sendBatteryLevel/, mSetRequestAck and isAck() in incoming messages.
      I have read these posts but I'm unable to figure out how the library is designed.
      http://forum.mysensors.org/topic/1163/can-anyone-shed-some-clarity-in-this-ack-business-hek/4
      http://forum.mysensors.org/topic/649/rc-from-send-and-how-to-identify-an-ack-message/7

      From @hek's response in the first thread, it looks like the library is designed to support BOTH end-to-end acknowledgment and hop-to-hop acknowledgment, but how to use that isn't very clear, at least not to me. Could anyone care to explain?

      1 Reply Last reply
      0
      • hekH Offline
        hekH Offline
        hek
        Admin
        wrote on last edited by
        #10

        Low-level: When a node wants end-to-end ack, it sets a bit in the message header "req ack". The node that receives this type of message, sends an ack-message with the "req ack" bit off and "is ack" bit on. Otherwise messages would create a endless loop.

        The "hardware ack" functionality is only used to detect if a node loses connection with it's closest neighbor.. and should start looking for a new parent.

        1 Reply Last reply
        0
        • mfalkviddM Offline
          mfalkviddM Offline
          mfalkvidd
          Mod
          wrote on last edited by
          #11

          I think I'm most confused by this statement:

          @hek said

          It will first send the hardware ack and then the end-to-end software ack provided by the MySensors library.

          What is the end-to-end software ack? Was it never implemented?

          1 Reply Last reply
          0
          • mfalkviddM Offline
            mfalkviddM Offline
            mfalkvidd
            Mod
            wrote on last edited by mfalkvidd
            #12

            ok, let's see if I understand now. How much of this is correct?

            Hardware ack is what I get when using send(msg, true) and some other functions like present, sendSketchInfo and sendBatteryLevel

            • Hardware ack is hop-to-hop acknowledgment
            • Sending is a blocking function which returns true if an ack was received and false if ~70ms passed without receiving an hardware ack.
            • Sending ack is handled automatically by the library(/radio)
            • Receiving an ack is handled automatically by the library
            • Re-send needs to be handled manually in each sketch (a while-loop with a counter counting up to maxRetries and using wait() between each resend seems to be the most common solution)

            Software ack is what I get when setting msg.mSetRequestAck before sending the message (is this true? I'm unable to find any documentation on mSetRequestAck on http://www.mysensors.org/download/sensor_api_15)

            • Software ack is end-to-end acknowledgment
            • Sending is a non-blocking function (from the software ack perspective, using hardware ack together with software ack is allowed and in that case the rules for hardware ack applies to hardware ack but the call is not blocked until the software ack comes through)
            • Sending an ack needs to be handled manually in each sketch (by checking msg.mGetRequestAck in incomingMessage? I'm unable to find any documentation on mSetRequestAck on http://www.mysensors.org/download/sensor_api_15 )
            • Re-send needs to be handled manually in each sketch (setting up a timer might be a good solution)
            • Receiving an ack needs to be handled manually in each sketch (by checking msg.isAck() in incomingMessage and clearing the timer mentioned above)
            1 Reply Last reply
            0
            • hekH Offline
              hekH Offline
              hek
              Admin
              wrote on last edited by
              #13

              Nope,

              Hardware ack is always enabled in the MySensors library (except for broadcast messages).

              End-to-end ack is enabled with the true flag.

              1 Reply Last reply
              0
              • mfalkviddM Offline
                mfalkviddM Offline
                mfalkvidd
                Mod
                wrote on last edited by
                #14

                But then end-to-end ack is horribly broken? Since the next hop node will respond with an ack even if it is a repeater?

                1 Reply Last reply
                0
                • hekH Offline
                  hekH Offline
                  hek
                  Admin
                  wrote on last edited by
                  #15

                  No, only the findal destination node will answer with a soft ack message.

                  Note, the (soft) ack message has to be picked up by yourself in your incomingMessage function.

                  mfalkviddM 1 Reply Last reply
                  0
                  • hekH Offline
                    hekH Offline
                    hek
                    Admin
                    wrote on last edited by
                    #16

                    You can look at the RelayWithButton example on how to use it.
                    https://github.com/mysensors/Arduino/blob/development/libraries/MySensors/examples/RelayWithButtonActuator/RelayWithButtonActuator.ino

                    Here the node sends a message with soft ack enabled when someone presses the button. It doesn't change the local (light) state until ack message is received.

                    1 Reply Last reply
                    0
                    • hekH hek

                      No, only the findal destination node will answer with a soft ack message.

                      Note, the (soft) ack message has to be picked up by yourself in your incomingMessage function.

                      mfalkviddM Offline
                      mfalkviddM Offline
                      mfalkvidd
                      Mod
                      wrote on last edited by mfalkvidd
                      #17

                      @hek said:

                      No, only the findal destination node will answer with a soft ack message.

                      Note, the (soft) ack message has to be picked up by yourself in your incomingMessage function.

                      Thanks for explaining. Just checking if my understanding is correct:

                      bool send(MyMessage &msg, bool ack);
                      

                      will return the result of the hardware ack, regardless if the second parameter is true or false?

                      So my post above should have been like this:

                      Hardware ack is always on

                      • Hardware ack is hop-to-hop acknowledgment
                      • Sending is a blocking function which returns true if an hardware ack was received, and false if ~70ms passed without receiving an hardware ack.
                      • Sending hardware ack (when the message has reached the next-hop node) is handled automatically by the library(/radio)
                      • Receiving an hardware ack is handled automatically by the library, by setting the return value from the send call mentioned above
                      • Up to 15 tries are made automatically by the library. Further re-send needs to be handled manually in each sketch (a while-loop with a counter counting up to maxRetries and using wait() between each resend seems to be the most common solution)

                      Software ack is what I get when using send(msg, true) (and is also supported by some other functions like present(), sendSketchInfo() and sendBatteryLevel()

                      • Software ack is end-to-end acknowledgment
                      • Sending is a non-blocking function
                      • Sending ack (when the message has reached its final destination) is handled automatically by the library
                      • Re-send needs to be handled manually in each sketch (setting up a timer when sending the original message might be a good solution)
                      • Receiving an ack needs to be handled manually in each sketch (by checking msg.isAck() in incomingMessage and clearing the timer mentioned above)
                      rozpruwaczR 1 Reply Last reply
                      2
                      • hekH Offline
                        hekH Offline
                        hek
                        Admin
                        wrote on last edited by
                        #18

                        Yes! Looks correct!

                        If you want to dig even deeper you can tune the hardware ack/message burst handled by the radio here:
                        https://github.com/mysensors/Arduino/blob/development/libraries/MySensors/core/MyTransportNRF24.cpp#L59

                        The radio sends a burst of maximum 15 messages (with a 5us interval) by itself unless it picks up a respond by the other node.

                        1 Reply Last reply
                        0
                        • mfalkviddM Offline
                          mfalkviddM Offline
                          mfalkvidd
                          Mod
                          wrote on last edited by mfalkvidd
                          #19

                          Very cool! Thanks a lot @hek! Can't believe I have read several hundred forum posts about the protocol design and ack problems the last two weeks without realizing that what I needed was already included in the library.

                          From the discussions I've read it looks like almost no-one else has understood either.

                          Some ideas to help people understand how to use the built-in features for reliable delivery:

                          1. Add an example that has a complete implementation of end-to-end ack usage. This includes
                          • setting up timer(s) for re-sending
                          • storing sent messages so they can be re-sent
                          • determining which message was acked when an ack message is received (there might be several messages that haven't been acked yet)
                          • removing acked message from the sent message store and clearing the timer(s)
                          • re-sending when the timers expire
                          1. Update the documentation for bool send(MyMessage &msg, bool ack); (and similar functions) to explain that the bool returned is the result of the next-hop ack.
                          2. Rename the bool ack parameter to bool end-to-end-ack or something similar to make it clear(er) that there are two types of acks
                          3. In the documentation for send() (and similar functions), refer to the example in (1) for information on how to use end-to-end ack.
                          4. When the example in (1) is good enough, add some of the required code to the MySensors library so people don't need to copy-paste a lot of code into their sketches. Surround the code with ifdefs to make it optional.

                          (2) and (3) should be quite easy to do. Can it be done with a pull request or how are documentation improvements handled?

                          I'm willing to do 1 (will post the sketch in the forum for public scrutiny/feedback of course).

                          4 can be done when the community think the example is "good enough"

                          5 can wait until the example has been thoroughly vetted.

                          mfalkviddM 1 Reply Last reply
                          6
                          • hekH Offline
                            hekH Offline
                            hek
                            Admin
                            wrote on last edited by
                            #20

                            Sounds like a plan.

                            The code documentation could be solved with a PR as you say. But the main site isn't available on github (a messy thing) so I have to update that part when PR arrives/has been merged.

                            1 Reply Last reply
                            0
                            • mfalkviddM Offline
                              mfalkviddM Offline
                              mfalkvidd
                              Mod
                              wrote on last edited by
                              #21

                              ok. I can create the PR. From where can I clone the repo?

                              1 Reply Last reply
                              0
                              • mfalkviddM Offline
                                mfalkviddM Offline
                                mfalkvidd
                                Mod
                                wrote on last edited by
                                #22

                                After a quick chat with hek I now know that I should add code comments to the relevant functions in the code and he'll manually update the API documentation. I'll post a link to the PR when I'm done.

                                1 Reply Last reply
                                0
                                • R Offline
                                  R Offline
                                  robosensor
                                  wrote on last edited by
                                  #23

                                  Seems like it is impossible now to distinguish for which message we have received acknowledgement. For example, when you just sent two identical messages. Message should contain message ID field (also called packet id or sequence id, unique for sending side) either in protocol headers (need to change protocol and break compatibility) or in user-defined message body (also breaks compatibility).

                                  mfalkviddM 1 Reply Last reply
                                  0
                                  • R robosensor

                                    Seems like it is impossible now to distinguish for which message we have received acknowledgement. For example, when you just sent two identical messages. Message should contain message ID field (also called packet id or sequence id, unique for sending side) either in protocol headers (need to change protocol and break compatibility) or in user-defined message body (also breaks compatibility).

                                    mfalkviddM Offline
                                    mfalkviddM Offline
                                    mfalkvidd
                                    Mod
                                    wrote on last edited by
                                    #24

                                    @robosensor Yes it is impossible to distinguish between acks for two identical messages. But in which use case is that a problem?

                                    R 1 Reply Last reply
                                    0
                                    • mfalkviddM mfalkvidd

                                      @robosensor Yes it is impossible to distinguish between acks for two identical messages. But in which use case is that a problem?

                                      R Offline
                                      R Offline
                                      robosensor
                                      wrote on last edited by
                                      #25

                                      @mfalkvidd for example, to know last actuator state.

                                      Imagine that you are sending three commands:

                                      1. ON
                                      2. OFF
                                      3. ON

                                      Then you receive two confirmations: ON and OFF. For which one ON ack is received? Is current actuator state after receiving two confirmations ON or OFF? How to determine which message (first or third) is lost and what you need to resend?

                                      mfalkviddM 1 Reply Last reply
                                      0
                                      • R robosensor

                                        @mfalkvidd for example, to know last actuator state.

                                        Imagine that you are sending three commands:

                                        1. ON
                                        2. OFF
                                        3. ON

                                        Then you receive two confirmations: ON and OFF. For which one ON ack is received? Is current actuator state after receiving two confirmations ON or OFF? How to determine which message (first or third) is lost and what you need to resend?

                                        mfalkviddM Offline
                                        mfalkviddM Offline
                                        mfalkvidd
                                        Mod
                                        wrote on last edited by
                                        #26

                                        @robosensor good example. As you said before, there is no way to solve that with the current protocol. However, the example can be made even simpler, it is enough to just send OFF then ON. In-order delivery is not guaranteed so you don't know which message was received last.

                                        R 1 Reply Last reply
                                        0
                                        • mfalkviddM mfalkvidd

                                          @robosensor good example. As you said before, there is no way to solve that with the current protocol. However, the example can be made even simpler, it is enough to just send OFF then ON. In-order delivery is not guaranteed so you don't know which message was received last.

                                          R Offline
                                          R Offline
                                          robosensor
                                          wrote on last edited by
                                          #27

                                          @mfalkvidd yes, I understand that this feature will break everything.

                                          Also, message id field can help to filter out duplicate messages on receiving side (due to message acknowledgement is not received by sending side) and can help to re-order incoming messages in right way using increasing message ids.

                                          Even more, sending acknowledgement with only numeric id instead of full message data can help to remove load from MCU (need to parse full message), from RAM (need to store full message), and from 'network' (both wired and wireless, data channel will be busy less time).

                                          mfalkviddM 1 Reply Last reply
                                          0
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          20

                                          Online

                                          11.7k

                                          Users

                                          11.2k

                                          Topics

                                          113.0k

                                          Posts


                                          Copyright 2025 TBD   |   Forum Guidelines   |   Privacy Policy   |   Terms of Service
                                          • Login

                                          • Don't have an account? Register

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • MySensors
                                          • OpenHardware.io
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular