void receive and while loop question.....



  • I have a new project that requires a separate function from 'loop' to handle some stuff, no problem there except within this function I need a 'while' loop that can only be exited if a value is received from the controller via the receive function.

    My question is, will the receive function be called sutomatically by mysensors or will I need to manually call it within the while loop?


  • Mod

    @skywatch the receive function will be called if your while loop calls wait() . If your while loop does not call wait(), no messages will be processed.


  • Hardware Contributor

    @skywatch
    no idea what you're trying to do, but maybe it would be better to use async/state machine.
    why not doing something simple like this:

    bool isFooEnabled= false;
    loop() {
      if (!isFooEnabled) {
         doMain();
      }
      else {
       doFoo();
      }
    }
    
    receive() {
    // on your msg, set isFooEnabled to true or false to start/stop doFoo
    }
    

    Like this nothing can block, your doFoo() doesn't need a while loop, you could just use if/then with states variables. Then on each arduino loop mysensors message will be processed and receive function called



  • Thanks for the suggestions. I got into a jam and took some time out. I'll be working on it today I hope.

    The main thing is to remotely send a calibration command to make the device read variables form the sensor once and run a calibration routine that measures max and min values for it's location. Then send an 'un-calibration' so that it runs normally and only triggers an alarm only if values outside the calibration window occur.



  • Hope ok to ask here as I am struggling a bit to understand wait() in context with loops. I have used it with success with a separate receive function but need a bit of clarification.

    I have read on another post that wait is the same as using the millis method but can't get my head around how to use it.
    If using millis I would use the state machine if else method as suggested by @scalz

    How do I use wait in one place and then get another loop or process to run in the meantime?


  • Mod

    @grumpazoid said in void receive and while loop question.....:

    How do I use wait in one place and then get another loop or process to run in the meantime?

    Simple, you don't 😉

    Wait() will block processing your code for the specified amount of milliseconds, while millis() will immediately return the current time, in milliseconds.
    Arduino is single threaded, so only one task can run at any time. To execute some code, while another piece is 'waiting' you should use millis() to determine how much time elapsed each time your code is executed, eg

    void loop() {
      static unsigned long start0 = millis();  // have a valid initial value
      unsigned long now = millis();
      if (now - start0 > 1000ul) {
        // run once every second
        //... Your code... 
        start0 = now;
      } 
      static unsigned long start1 = millis();
      now = millis();
      if (now - start1 > 2000ul) {
        // run once every 2 seconds
        //... Your other code... 
        start1 = now;
      } 
      // etc
    


  • @Yveaux

    Thanks for that explanation. Understanding this, the bit I am still confused about is how I can use wait() and still able to listen for incoming messages. Is that an exception to the rule? What stops the processing being blocked in this case?


  • Mod

    @grumpazoid wait() is a special implementation of a wait loop in the mysensors stack, that also processes messages while at the same time waiting for the requested time to elapse.
    It is in principle the same as i showed before: it checks time elapsed and if some time is still remaining it handles incoming messages.



  • @Yveaux Makes sense now. Thanks again. 🤗


Log in to reply
 

Suggested Topics

1
Online

11.4k
Users

11.1k
Topics

112.7k
Posts