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. void receive(const MyMessage &message)

void receive(const MyMessage &message)

Scheduled Pinned Locked Moved General Discussion
40 Posts 6 Posters 1.9k Views 5 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.
  • skywatchS Offline
    skywatchS Offline
    skywatch
    wrote on last edited by
    #1

    If I have a 'while' loop runnig in void loop() - will the void receive(const MyMessage &message) still be called during this time?

    Essentially I need something to happen repeatedly unless a button is pressed or an incomming message arrives to stop it.

    Any ideas, I am stuck on this for some reason.

    mfalkviddM 1 Reply Last reply
    0
    • skywatchS skywatch

      If I have a 'while' loop runnig in void loop() - will the void receive(const MyMessage &message) still be called during this time?

      Essentially I need something to happen repeatedly unless a button is pressed or an incomming message arrives to stop it.

      Any ideas, I am stuck on this for some reason.

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

      @skywatch MySensors will not be able to process any incoming messages if you are hogging the cpu.

      You can call wait() from your while loop to let MySensors do its stuff.

      1 Reply Last reply
      0
      • skywatchS Offline
        skywatchS Offline
        skywatch
        wrote on last edited by skywatch
        #3

        @mfalkvidd Thanks as ever for the help. So here is my problem and I can't see a way to do it right now.

        A roller blind can be commanded to 'go down' either ....
        by pressing a 'down' button or ...
        by a 'down' command from the controller.

        This needs to move the stepper motor until a pre-defined number of steps have occured UNLESS.....
        it gets a stop message from the controller or......
        the up button is pressed. (this saves having a third button for stop!)..

        I have omitted limit switches and timers to make it simple, but I just can't find a way to make it happen - I know it's not impossible, just beyond my imagination right now! ;)

        Adding too many wait() cycles in the main loop will slow the motor down and it is slow enough already....Hmmmm.....would it be better to just have an if loop instead of while and let that run?

        Or what about putting that pesky 'while' loop within the receive section?

        mfalkviddM 1 Reply Last reply
        0
        • skywatchS skywatch

          @mfalkvidd Thanks as ever for the help. So here is my problem and I can't see a way to do it right now.

          A roller blind can be commanded to 'go down' either ....
          by pressing a 'down' button or ...
          by a 'down' command from the controller.

          This needs to move the stepper motor until a pre-defined number of steps have occured UNLESS.....
          it gets a stop message from the controller or......
          the up button is pressed. (this saves having a third button for stop!)..

          I have omitted limit switches and timers to make it simple, but I just can't find a way to make it happen - I know it's not impossible, just beyond my imagination right now! ;)

          Adding too many wait() cycles in the main loop will slow the motor down and it is slow enough already....Hmmmm.....would it be better to just have an if loop instead of while and let that run?

          Or what about putting that pesky 'while' loop within the receive section?

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

          @skywatch something like this:

          #define STOP 0
          #define UP 1
          #define DOWN 1
          
          byte state = STOP;
          
          void loop(){
            // If button is pressed, set state accordingly
            upButton.update();
            // Get the update value
            if (upButton.read()) {
              if(state == STOP){
                state = UP;
            } else {
              state = STOP // Stop if it was running
            }
            
            switch (state) {
              case STOP:
              // Stop motor
              digitalWrite(motor_pin_up, 0);
              digitalWrite(motor_pin_down, 0);
              break;
              case UP:
              // Start motor up
              digitalWrite(motor_pin_up, 1);
              break;
              case DOWN:
              // Start motor down
              digitalWrite(motor_pin_down, 1);
              break;
            }
          }
          void receive(){
           // set state to the right value depending on the message from the controller
           if (msg...) state = xxx
          }
          

          I don't know how you know for how long you need to run the motor, could you explain that part?

          skywatchS 1 Reply Last reply
          0
          • mfalkviddM mfalkvidd

            @skywatch something like this:

            #define STOP 0
            #define UP 1
            #define DOWN 1
            
            byte state = STOP;
            
            void loop(){
              // If button is pressed, set state accordingly
              upButton.update();
              // Get the update value
              if (upButton.read()) {
                if(state == STOP){
                  state = UP;
              } else {
                state = STOP // Stop if it was running
              }
              
              switch (state) {
                case STOP:
                // Stop motor
                digitalWrite(motor_pin_up, 0);
                digitalWrite(motor_pin_down, 0);
                break;
                case UP:
                // Start motor up
                digitalWrite(motor_pin_up, 1);
                break;
                case DOWN:
                // Start motor down
                digitalWrite(motor_pin_down, 1);
                break;
              }
            }
            void receive(){
             // set state to the right value depending on the message from the controller
             if (msg...) state = xxx
            }
            

            I don't know how you know for how long you need to run the motor, could you explain that part?

            skywatchS Offline
            skywatchS Offline
            skywatch
            wrote on last edited by skywatch
            #5

            @mfalkvidd Thanks for the suggestion.

            In order to minimise trouble I have a multi approach to detecting if the blind is 'down'.

            I can count the number of steps the stepper takes to get from fully 'up' to fully 'down'. This figure I can use in the sketch to see if the number of steps moved == measured steps. That way it should be 'down'.

            I can also use a watch to time the motion to get an approximate idea of time of travel. Again, this can be used to act as an indicator that it should have reached it's position and turn off motor just in case.

            I will soon add a magnet to the bottom rail of the blind and this too can be detected with reed relay or hall effect chip as up and down 'limit switches' (not really true limit switches I know, but performing the same function as limit switches).

            This way I now know that if any one thing fails, the other should still stop the motor turning indefinitly.

            Trouble is that steppers require constant commands to go to the next step (hence the while loop) - but then it blocks the receive() from working.

            I'l try and understand your soution and see if it will work with what I have.

            TsM.

            1 Reply Last reply
            1
            • T Offline
              T Offline
              tommies
              wrote on last edited by
              #6

              I had problems with incoming messages ans loop.
              If you use nrf24 @Yveaux suggested me to use irq to handle incoming messages.
              I my case it solved my problem

              https://forum.mysensors.org/topic/7190/irq-pin-for-nrf24l01

              1 Reply Last reply
              1
              • skywatchS Offline
                skywatchS Offline
                skywatch
                wrote on last edited by
                #7

                @tommies

                Thanks for the help but today I think I am nearly there with this. I am on the third version and it looks promising. I hope to test it fully this week and I'll let you (all) know if it works.

                1 Reply Last reply
                0
                • P Offline
                  P Offline
                  pjr
                  wrote on last edited by
                  #8

                  How about non blocking interrupt driven stepper library? For example: https://github.com/bjpirt/HotStepper

                  1 Reply Last reply
                  0
                  • skywatchS Offline
                    skywatchS Offline
                    skywatch
                    wrote on last edited by
                    #9

                    @pjr Thanks for the hint.

                    I believe I have what I need now, will be testing tomorrow I hope.

                    Essentially I have reduced void loop() and void receive() down to minimum so the program loops very fast. This way it only calls other void () routines as needed.

                    skywatchS 1 Reply Last reply
                    1
                    • skywatchS skywatch

                      @pjr Thanks for the hint.

                      I believe I have what I need now, will be testing tomorrow I hope.

                      Essentially I have reduced void loop() and void receive() down to minimum so the program loops very fast. This way it only calls other void () routines as needed.

                      skywatchS Offline
                      skywatchS Offline
                      skywatch
                      wrote on last edited by skywatch
                      #10

                      @skywatch Hmmmm....It didn't work as I expected.

                      So if I have a loop with a 'while' routine running, what do I need to do in the 'while' code to check if any messages have arrived?

                      something ike.....

                      while (MOVING_UP == true && stepcount < BLIND_UP) {
                      Do code to turn stepper motor.
                      Check for radio message.
                      Act on radio message (if there is one)
                      Check for button press.
                      Act on button press (if there is one)
                      update step count
                      }

                      The buttons and motor I have working, its just that radio messages are currently 'blocked' during the while loop and this isn't good if an emergency stop call is required.

                      mfalkviddM 1 Reply Last reply
                      0
                      • skywatchS skywatch

                        @skywatch Hmmmm....It didn't work as I expected.

                        So if I have a loop with a 'while' routine running, what do I need to do in the 'while' code to check if any messages have arrived?

                        something ike.....

                        while (MOVING_UP == true && stepcount < BLIND_UP) {
                        Do code to turn stepper motor.
                        Check for radio message.
                        Act on radio message (if there is one)
                        Check for button press.
                        Act on button press (if there is one)
                        update step count
                        }

                        The buttons and motor I have working, its just that radio messages are currently 'blocked' during the while loop and this isn't good if an emergency stop call is required.

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

                        @skywatch I think you're looking for the wait() function. https://www.mysensors.org/download/sensor_api_20#waiting

                        Or _process() but that's an internal function so it might not be as well documented and might undergo changes that aren't mentioned in release notes in future releases.

                        skywatchS 1 Reply Last reply
                        1
                        • mfalkviddM mfalkvidd

                          @skywatch I think you're looking for the wait() function. https://www.mysensors.org/download/sensor_api_20#waiting

                          Or _process() but that's an internal function so it might not be as well documented and might undergo changes that aren't mentioned in release notes in future releases.

                          skywatchS Offline
                          skywatchS Offline
                          skywatch
                          wrote on last edited by
                          #12

                          @mfalkvidd I was just about to say something on that! - you just beat me too it! ;)

                          I understand the wait(), but what I have no clue of is how long should a wait() be to get incomming messages? -- Would wait(25); be enough?

                          mfalkviddM YveauxY 2 Replies Last reply
                          0
                          • skywatchS skywatch

                            @mfalkvidd I was just about to say something on that! - you just beat me too it! ;)

                            I understand the wait(), but what I have no clue of is how long should a wait() be to get incomming messages? -- Would wait(25); be enough?

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

                            @skywatch it depends a bit on which platform you are using, the clock speed you are using, how often wait is called, how busy your network is, which transport you are using and how much packet loss you are willing to accept. But 25 should work.

                            I found transportProcess() which is called without any parameters. You can use that instead.

                            skywatchS 1 Reply Last reply
                            1
                            • mfalkviddM mfalkvidd

                              @skywatch it depends a bit on which platform you are using, the clock speed you are using, how often wait is called, how busy your network is, which transport you are using and how much packet loss you are willing to accept. But 25 should work.

                              I found transportProcess() which is called without any parameters. You can use that instead.

                              skywatchS Offline
                              skywatchS Offline
                              skywatch
                              wrote on last edited by
                              #14

                              @mfalkvidd pro mini @ 16MHz - I didn't mention that as I was looking at it as purely a programming issue....doh!

                              So are you saying that if I simply put transportProcess() in the while statement it will pause the while loop, check for any messages from the nrf24 and then resume the while loop? Of so, that should work if it is quick.

                              1 Reply Last reply
                              0
                              • skywatchS skywatch

                                @mfalkvidd I was just about to say something on that! - you just beat me too it! ;)

                                I understand the wait(), but what I have no clue of is how long should a wait() be to get incomming messages? -- Would wait(25); be enough?

                                YveauxY Offline
                                YveauxY Offline
                                Yveaux
                                Mod
                                wrote on last edited by
                                #15

                                @skywatch said in void receive(const MyMessage &message):

                                I understand the wait(), but what I have no clue of is how long should a wait() be to get incomming messages? -- Would wait(25); be enough?

                                Just wait as short as possible, 1ms or even 0 (not sure if that is supported).
                                It allows the stack to process any queued messages and returns as quickly as possible.
                                There is no need to wait for a longer time, as radios will queue incoming messages in hardware. The actual number of messages that can be queued depends on the radio used; for nrf24 it is 3.

                                http://yveaux.blogspot.nl

                                mfalkviddM 1 Reply Last reply
                                1
                                • skywatchS Offline
                                  skywatchS Offline
                                  skywatch
                                  wrote on last edited by
                                  #16

                                  @mfalkvidd I tried with transportProcess() and it seemed to work well initially, but then something happened (probably HW related) so it is looking promising.

                                  @Yveaux Thank you for the tip :)

                                  I will try this next and see how much of a difference it makes -would wait(1); be better in any way to calling transportProcess()?

                                  But at least it looks like the system might operate as I had intended, hurrah! ;)

                                  YveauxY 1 Reply Last reply
                                  0
                                  • skywatchS skywatch

                                    @mfalkvidd I tried with transportProcess() and it seemed to work well initially, but then something happened (probably HW related) so it is looking promising.

                                    @Yveaux Thank you for the tip :)

                                    I will try this next and see how much of a difference it makes -would wait(1); be better in any way to calling transportProcess()?

                                    But at least it looks like the system might operate as I had intended, hurrah! ;)

                                    YveauxY Offline
                                    YveauxY Offline
                                    Yveaux
                                    Mod
                                    wrote on last edited by
                                    #17

                                    @skywatch said in void receive(const MyMessage &message):

                                    would wait(1); be better in any way to calling transportProcess()?

                                    Definately! transportProcess() is a library internal call, which might change without notice or has side effects one cannot oversee. Wait() is an external api call, which won't change without notice, and is documented.

                                    http://yveaux.blogspot.nl

                                    skywatchS 1 Reply Last reply
                                    1
                                    • YveauxY Yveaux

                                      @skywatch said in void receive(const MyMessage &message):

                                      would wait(1); be better in any way to calling transportProcess()?

                                      Definately! transportProcess() is a library internal call, which might change without notice or has side effects one cannot oversee. Wait() is an external api call, which won't change without notice, and is documented.

                                      skywatchS Offline
                                      skywatchS Offline
                                      skywatch
                                      wrote on last edited by
                                      #18

                                      @yveaux Thank you for the fast response and explaination. I'll go with what you said! ;)

                                      1 Reply Last reply
                                      0
                                      • YveauxY Yveaux

                                        @skywatch said in void receive(const MyMessage &message):

                                        I understand the wait(), but what I have no clue of is how long should a wait() be to get incomming messages? -- Would wait(25); be enough?

                                        Just wait as short as possible, 1ms or even 0 (not sure if that is supported).
                                        It allows the stack to process any queued messages and returns as quickly as possible.
                                        There is no need to wait for a longer time, as radios will queue incoming messages in hardware. The actual number of messages that can be queued depends on the radio used; for nrf24 it is 3.

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

                                        There is a slight risk that wait() will return immediately without processing messages, if the parameter is lower than the increment of millis(). The increment of millis() depends on platform and clock speed. I am not sure if this risk is big enough that it needs to be considered.

                                        1 Reply Last reply
                                        0
                                        • skywatchS Offline
                                          skywatchS Offline
                                          skywatch
                                          wrote on last edited by
                                          #20

                                          Thank you both for the help - much appreciated.

                                          So I went with wait(1); and then only called it every 250 steps as otherwise it was slowing things down too much. It seems pretty reliable at the moment, but I do have dodgy duponts so have to sort them out next!

                                          One thing I do see is this......

                                          352968 !MCO:WAI:RC=3
                                          352971 !MCO:WAI:RC=3
                                          352974 !MCO:WAI:RC=3
                                          352977 !MCO:WAI:RC=3
                                          352980 !MCO:WAI:RC=3
                                          352984 !MCO:WAI:RC=3
                                          352987 !MCO:WAI:RC=3
                                          352990 !MCO:WAI:RC=3
                                          

                                          Not always, but sometimes.....what is this trying to tell me and where do I look to fix it - I can post full code if you like, but it's not for the faint of heart;)

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


                                          12

                                          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