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. General Discussion
  3. gw.send( ) and transmission errors

gw.send( ) and transmission errors

Scheduled Pinned Locked Moved General Discussion
12 Posts 6 Posters 6.1k Views 3 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.
  • BulldogLowellB Offline
    BulldogLowellB Offline
    BulldogLowell
    Contest Winner
    wrote on last edited by BulldogLowell
    #1

    I wanted to start more of a discussion on best practices in programming.

    I have a specific example to start from, one that I have been dealing with for quite some time

    Form time to time, I experience what I'll refer to as "missed messages."

    These are commands sent to a node that:

    • may not result in a change of state or
    • a change of state may result, but the controller does not receive a message and the controller is then out of sync with the node

    To correct my missed messages problem, I have been messing around adding delays to my code (thinking it is related to the radio/power):

    gw.send(msg.set(state), true);
    delay(someSmallDelay);
    

    but still not able to get total reliability, so I tried this:

      state = !state;
      while(!gw.send(msg.set(state), true))
      {
        gw.process();
      }
    

    and it works very well. You can see an example response where the missed message gets re-transmitted:

    send: 5-5-0-0 s=1,c=1,t=2,pt=2,l=2,st=ok:1
    read: 0-0-5 s=1,c=1,t=2,pt=2,l=2:1
    send: 5-5-0-0 s=1,c=1,t=2,pt=2,l=2,st=fail:0  <<< missed
    send: 5-5-0-0 s=1,c=1,t=2,pt=2,l=2,st=fail:0  <<< missed
    send: 5-5-0-0 s=1,c=1,t=2,pt=2,l=2,st=ok:0    <<< third time's a charm!
    send: 5-5-0-0 s=1,c=1,t=2,pt=2,l=2,st=ok:1
    read: 0-0-5 s=1,c=1,t=2,pt=2,l=2:1
    

    Im working with this alternative as well:

      state = !state;
      while(!gw.process())
      {
        gw.send(msg.set(state), true);
      }
    

    now, if the radio is marginally out of range or there is some interference, well we could be sitting here for a long time hanging up the program. so I thought to ask the forum for ideas/suggestions here.

    1 Reply Last reply
    0
    • AWIA Offline
      AWIA Offline
      AWI
      Hero Member
      wrote on last edited by
      #2

      Maybe I am misunderstanding your question but what about adding a timer to the loop?

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

        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.

        BulldogLowellB R 2 Replies Last reply
        0
        • hekH hek

          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.

          BulldogLowellB Offline
          BulldogLowellB Offline
          BulldogLowell
          Contest Winner
          wrote on last edited by
          #4

          @hek

          OK, so you think like this, then?...

          state = !state;
          while(!gw.send(msg.set(state), true))
          {
            gw.wait(someSmallDelay);
          }
          
          1 Reply Last reply
          0
          • hekH hek

            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.

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

            Looks like MySensors library API docs is missing this useful wait function.

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

              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();
              }  
              
              
              barduinoB 1 Reply Last reply
              0
              • R robosensor

                Looks like MySensors library API docs is missing this useful wait function.

                BulldogLowellB Offline
                BulldogLowellB Offline
                BulldogLowell
                Contest Winner
                wrote on last edited by
                #7

                @robosensor

                and the examples are lacking this as well...

                @hek

                We'll mess around with that for a while...

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

                  Updated doc with the missing sleep call, **wait() **and a new description argument available when presenting sensors.

                  R 1 Reply Last reply
                  1
                  • hekH hek

                    Updated doc with the missing sleep call, **wait() **and a new description argument available when presenting sensors.

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

                    @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.

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

                      @robosensor

                      Damn.. Changed now and it will be deployed in the next site update.

                      1 Reply Last reply
                      0
                      • hekH hek

                        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();
                        }  
                        
                        
                        barduinoB Offline
                        barduinoB Offline
                        barduino
                        wrote on last edited by barduino
                        #11

                        @hek

                        Since we are on the subject of ack and risking going a little bit off topic, what should the controler send when it receives a message with a ack flag?

                        eg:
                        send -> 3;1;1;1;1;36.0
                        receive <-3;1;1;0;1;36.0 ?

                        1 Reply Last reply
                        0
                        • R Offline
                          R Offline
                          rickmontana83
                          wrote on last edited by
                          #12

                          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_RETRIES clause 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.

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


                          19

                          Online

                          11.7k

                          Users

                          11.2k

                          Topics

                          113.1k

                          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