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. What is the good wait() time ?

What is the good wait() time ?

Scheduled Pinned Locked Moved Development
waitwait push-button
15 Posts 6 Posters 1.3k 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.
  • T Offline
    T Offline
    tommies
    wrote on last edited by
    #1

    Hello,

    i have a node with 3 push-button in loop().
    without wait() , i don't receive messages from gateway.
    With wait(50) i receive message (but not all).
    with wait(500) i receive nothing.
    Is it normal ? I thought that wait() was for spending time for receive message. larger time should be larger time for receiving messages ?
    what is the ideal waiting time ?
    THnaks

    Nca78N YveauxY 2 Replies Last reply
    0
    • T tommies

      Hello,

      i have a node with 3 push-button in loop().
      without wait() , i don't receive messages from gateway.
      With wait(50) i receive message (but not all).
      with wait(500) i receive nothing.
      Is it normal ? I thought that wait() was for spending time for receive message. larger time should be larger time for receiving messages ?
      what is the ideal waiting time ?
      THnaks

      Nca78N Offline
      Nca78N Offline
      Nca78
      Hardware Contributor
      wrote on last edited by
      #2

      Hello @tommies, do you use any delay in your loop ?
      Maybe you should post the code so it will be easier to help you fix it.

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

        Here is it

        // Enable debug prints to serial monitor
        #define MY_DEBUG  
        #define MY_DEBUG_SERIAL
        
        // Enable and select radio type attached
        #define MY_RADIO_RF24
        //#define MY_RF24_PA_LEVEL RF24_PA_HIGH
        
        //set how long to wait for transport ready. in milliseconds
        #define MY_TRANSPORT_WAIT_READY_MS 1
        #define MY_NODE_ID     14
        
        //  neopixels pin
        #define PIN 6 
        
        // pin push button
        #define BUTTON_1 3  
        #define BUTTON_2 4
        #define BUTTON_3 5
        
        // variables for my sensors presentation
        #define CHILD_ID_BUTTON_1 1
        #define CHILD_ID_BUTTON_2 2
        #define CHILD_ID_BUTTON_3 3
        #define CHILD_ID_RGB 4
        #define redMem 0 // To store red color
        #define greenMem 1 //
        #define blueMem 2 //
        
        #include <Adafruit_NeoPixel.h>
        #include <MySensors.h>
        #include <Bounce2.h>
        
        
        // Neopixels parameters
        
        // Parameter 1 = number of pixels in strip
        // Parameter 2 = Arduino pin number (most are valid)
        // Parameter 3 = pixel type flags, add together as needed:
        //   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
        //   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
        //   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
        //   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
        Adafruit_NeoPixel strip = Adafruit_NeoPixel(12, PIN, NEO_GRB + NEO_KHZ800);
        
        // IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
        // pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
        // and minimize distance between Arduino and first pixel.  Avoid connecting
        // on a live circuit...if you must, connect GND first.
        
        // variables for debounce push buttons
        
        Bounce debouncer1 = Bounce(); 
        Bounce debouncer2 = Bounce();
        Bounce debouncer3 = Bounce();
        int oldValue1=0;
        bool state1;
        int oldValue2=0;
        bool state2;
        int oldValue3=0;
        bool state3;
        
        // variables for color change
        long hexColor = -1 ;
        int red = loadState(redMem); // to load red color memory on startup
        int green = loadState(greenMem);
        int blue = loadState(blueMem);
        long startTime;// timer for ping gateway
        
        // Change to V_LIGHT if you use S_LIGHT in presentation below
        MyMessage msgbutton1(CHILD_ID_BUTTON_1,V_STATUS);
        MyMessage msgbutton2(CHILD_ID_BUTTON_2,V_STATUS);
        MyMessage msgbutton3(CHILD_ID_BUTTON_3,V_STATUS);
        MyMessage msgrgb(CHILD_ID_RGB,V_RGB);
        MyMessage msgvar(CHILD_ID_RGB,V_VAR1);
        
        void setup() {
          Serial.begin (115200);
          pinMode(BUTTON_1, INPUT_PULLUP) ;
          pinMode(BUTTON_2, INPUT_PULLUP) ;
          pinMode(BUTTON_3, INPUT_PULLUP) ;
          
           // After setting up the button, setup debouncer 1
          debouncer1.attach(BUTTON_1);
          debouncer1.interval(5);
           // After setting up the button, setup debouncer 2
          debouncer2.attach(BUTTON_2);
          debouncer2.interval(5);
           // After setting up the button, setup debouncer 3
          debouncer3.attach(BUTTON_3);
          debouncer3.interval(5);
          
          #ifdef MY_DEBUG_SERIAL
          Serial.println( "Setup");
          Serial.print(red);
          Serial.print("|");
          Serial.print(green);
          Serial.print("|");
          Serial.print(blue);
          #endif
        
          strip.begin();
          strip.show(); // Initialize all pixels to 'off'
          startColor(); // if you want to change start and finish color modify this function.
          startTime = millis(); // initialization for the counter
        }
        
        void presentation() {
          // Send the sketch version information to the gateway and Controller
          sendSketchInfo("Iron Man Reactor", "1.0");
          // Register binary input sensor to gw (they will be created as child devices)
          present(CHILD_ID_BUTTON_1, S_BINARY);
          wait(100);
          present(CHILD_ID_BUTTON_2, S_BINARY);
          wait(100);
          present(CHILD_ID_BUTTON_3, S_BINARY);    
          wait(100);
          present (CHILD_ID_RGB, S_RGB_LIGHT);
        }
        
        void loop() {
         wait(50);
         
         // ask time to gateway to test connection each 30s
         #ifdef MY_DEBUG_SERIAL
          if (millis() - startTime > 30000){
          if (requestTime()) {
            Serial.println("Connection ok");
          }
          else {
            Serial.println("Connection lost");
          }
          startTime = millis();
          }
          #endif
          
          // Push button 1 
         debouncer1.update();
          // Get the update value
          int value1 = debouncer1.read();
          if (value1 != oldValue1 && value1==0) {
            colorWipe(strip.Color(0, 0, 255), 0); // blue
            saveState(redMem,0);
            saveState(greenMem,0);
            saveState(blueMem,255);
            red = loadState(redMem);
            green = loadState(greenMem);
            blue = loadState(blueMem);
        
         #ifdef MY_DEBUG_SERIAL
            Serial.print(red);
            Serial.print("|");
            Serial.print(green);
            Serial.print("|");
            Serial.println(blue);
         #endif    
          }
          oldValue1 = value1;
        
         // Push button 2 
         debouncer2.update();
          // Get the update value
          int value2 = debouncer2.read();
          if (value2 != oldValue2 && value2==0) {
            colorWipe(strip.Color(255, 0, 0), 0); // red
            saveState(redMem,0);
            saveState(greenMem,0);
            saveState(blueMem,255);
            
         #ifdef MY_DEBUG_SERIAL
            Serial.print(red);
            Serial.print("|");
            Serial.print(green);
            Serial.print("|");
            Serial.println(blue);
         #endif    
             
          }
          oldValue2 = value2;
            
            // Push button 3
         debouncer3.update();
          // Get the update value
          int value3 = debouncer3.read();
          if (value3 != oldValue3 && value3==0) {
            theaterChase(strip.Color(127, 127, 127), 50); // White
            startColor(); // return to saved color
            }
          oldValue3 = value3;
        
        }
        
        // Neopixels effects 
         
        // Start and finish color
        void startColor() {
          red = loadState(redMem);
          green = loadState(greenMem);
          blue = loadState(blueMem);
          colorWipe(strip.Color(red, green, blue), 0); // finish with saved 
        }
        
        void colorWipe(uint32_t c, uint8_t waiting) {
          for(uint16_t i=0; i<strip.numPixels(); i++) {
              strip.setPixelColor(i, c);
              strip.show();
              wait(waiting);
          }
          #ifdef MY_DEBUG_SERIAL
            Serial.print(red);
            Serial.print("|");
            Serial.print(green);
            Serial.print("|");
            Serial.println(blue);
          #endif
        }
        
        // colorWipe fonction modified for receive()
        void colorWipeRGB(long number) {
          long r = hexColor >> 16;
          long g = hexColor >> 8 & 0xFF;
          long b = hexColor & 0xFF;
          for (uint16_t i = 0; i < strip.numPixels(); i++) {
            strip.setPixelColor(i, r,g,b);
            strip.show();
          }
          #ifdef MY_DEBUG_SERIAL
            Serial.print(red);
            Serial.print("|");
            Serial.print(green);
            Serial.print("|");
            Serial.println(blue);
          #endif
        }
        void rainbow(uint8_t waiting) {
          uint16_t i, j;
        
          for(j=0; j<256; j++) {
            for(i=0; i<strip.numPixels(); i++) {
              strip.setPixelColor(i, Wheel((i+j) & 255));
            }
            strip.show();
            wait(waiting);
            
          }
           startColor(); // return to saved color
        }
        
        // Slightly different, this makes the rainbow equally distributed throughout
        void rainbowCycle(uint8_t waiting) {
          uint16_t i, j;
        
          for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
            for(i=0; i< strip.numPixels(); i++) {
              strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
            }
            strip.show();
            wait(waiting);
          }
           startColor(); // return to saved color
        }
        
        //Theatre-style crawling lights.
        void theaterChase(uint32_t c, uint8_t waiting) {
          for (int j=0; j<10; j++) {  //do 10 cycles of chasing
            for (int q=0; q < 3; q++) {
              for (int i=0; i < strip.numPixels(); i=i+3) {
                strip.setPixelColor(i+q, c);    //turn every third pixel on
              }
              strip.show();
             
              wait(waiting);
             
              for (int i=0; i < strip.numPixels(); i=i+3) {
                strip.setPixelColor(i+q, 0);        //turn every third pixel off
              }
            }
          }
          startColor(); // return to saved color
        }
        
        //Theatre-style crawling lights with rainbow effect
        void theaterChaseRainbow(uint8_t waiting) {
          for (int j=0; j < 256; j++) {     // cycle all 256 colors in the wheel
            for (int q=0; q < 3; q++) {
                for (int i=0; i < strip.numPixels(); i=i+3) {
                  strip.setPixelColor(i+q, Wheel( (i+j) % 255));    //turn every third pixel on
                }
                strip.show();
               
                wait(waiting);
               
                for (int i=0; i < strip.numPixels(); i=i+3) {
                  strip.setPixelColor(i+q, 0);        //turn every third pixel off
                }
            }
          }
           startColor(); // return to saved color
        }
        
        // Input a value 0 to 255 to get a color value.
        // The colours are a transition r - g - b - back to r.
        uint32_t Wheel(byte WheelPos) {
          WheelPos = 255 - WheelPos;
          if(WheelPos < 85) {
           return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
          } else if(WheelPos < 170) {
            WheelPos -= 85;
           return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
          } else {
           WheelPos -= 170;
           return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
          }
           startColor(); // return to saved color
        }
        
        void receive(const MyMessage &message)
        {
          Serial.println("message received");
          int val =0 ;
          if (message.sensor == CHILD_ID_RGB && message.type == V_RGB) {
            String hexstring = message.getString();
            Serial.print(hexstring);
            Serial.print("||");
            hexColor = strtol( &hexstring[0], NULL, 16);
            saveState(redMem,(hexColor >> 16));
            saveState(greenMem,(hexColor >> 8 & 0xFF));
            saveState(blueMem,(hexColor & 0xFF)); 
            colorWipeRGB(hexColor);
            Serial.print(loadState(redMem));
            Serial.print("|"); 
            Serial.print(loadState(greenMem));
            Serial.print("|");
            Serial.println(loadState(blueMem));
          }
          if (message.sensor == CHILD_ID_RGB && message.type == V_VAR2){
            String variable = message.getString();
            String sred = variable.substring(0,3);
            String sgreen = variable.substring(3,6);
            String sblue = variable.substring(6,9);
            saveState(redMem,int(sred.toInt()));
            saveState(greenMem,int(sgreen.toInt()));
            saveState(blueMem,int(sblue.toInt())); 
            startColor();
            
          }
          if (message.sensor == CHILD_ID_RGB && message.type == V_VAR1){
            String variable = message.getString();
            if (variable = "rainbow" )
              rainbow(20);
              
            if (variable = "rainbowCycle" )
              rainbowCycle(20);
              
            if (variable = "theaterChaseRainbow")
              theaterChaseRainbow(20);
          
            if (variable = "theaterChase")
              theaterChase(strip.Color(127, 127, 127), 50); // White
        
            startColor(); // return to saved color
          }
          // reception of message for buttons
          if (message.sensor == CHILD_ID_BUTTON_1){
              colorWipe(strip.Color(0, 0, 255), 0); // Red
          }
          if (message.sensor == CHILD_ID_BUTTON_2){
              colorWipe(strip.Color(0, 255, 0), 0); // Vert
          }
          if (message.sensor == CHILD_ID_BUTTON_3){
            theaterChase(strip.Color(127, 127, 127), 50); // White
            startColor(); // return to saved color
        
            }
        }```
        1 Reply Last reply
        0
        • T Offline
          T Offline
          tommies
          wrote on last edited by
          #4

          I reply to myself.
          It works really better if i don't use the serial debug.

          1 Reply Last reply
          0
          • alowhumA Offline
            alowhumA Offline
            alowhum
            Plugin Developer
            wrote on last edited by alowhum
            #5

            Add a short wait after sendSketchInfo and your last present too.

            I usually have 150 as the wait time.

            1 Reply Last reply
            0
            • scalzS Offline
              scalzS Offline
              scalz
              Hardware Contributor
              wrote on last edited by scalz
              #6

              when it's for presentation, it's not really a big deal to add such wait time. note for a a coincell batt powered node it would be better to use sleep..

              But in others application with some "critical" timing in user tasks, you could get some troubles like missing state changes, slower polling etc. as it doesn't make your sketch asynchronous..

              For longterm, I think it's not ideal to use such hack when getting comm issues. and also makes nodes slower (and perhaps jamming's easier too ?).

              1 Reply Last reply
              0
              • T tommies

                Hello,

                i have a node with 3 push-button in loop().
                without wait() , i don't receive messages from gateway.
                With wait(50) i receive message (but not all).
                with wait(500) i receive nothing.
                Is it normal ? I thought that wait() was for spending time for receive message. larger time should be larger time for receiving messages ?
                what is the ideal waiting time ?
                THnaks

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

                @tommies You could give message queueing a try:

                • Connect the nRF24 IRQ pin to pin 2 on your Arduino
                • add #define MY_RF24_IRQ_PIN (2)
                • add #define MY_RX_MESSAGE_BUFFER_FEATURE
                • add #define MY_RX_MESSAGE_BUFFER_SIZE (10)
                • that last value may be lower (e.g. 5) when running out of memory

                This will listen to the interrupt from the nRF24 when a message comes in and immediately pause the running code to retrieve the message.
                Then your code continues and any messages stored will be processed outside the loop() function automatically.
                The wait() call(s) can be removed from your code.
                It might interfere with your NeoPixel update though, but there's only one way to find out ;-)

                Refer to e.g. https://forum.mysensors.org/topic/7190/irq-pin-for-nrf24l01 for a discussion on message queueing.

                http://yveaux.blogspot.nl

                T 1 Reply Last reply
                1
                • alowhumA Offline
                  alowhumA Offline
                  alowhum
                  Plugin Developer
                  wrote on last edited by
                  #8

                  @scalz I add the wait to make sure the radio has enough power without having to resort to adding a capacitor.

                  mfalkviddM scalzS 2 Replies Last reply
                  0
                  • alowhumA alowhum

                    @scalz I add the wait to make sure the radio has enough power without having to resort to adding a capacitor.

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

                    @alowhum I don't think any wait time will ensure sufficient power in a reliable way. The nrf is too sensitive to power fluctuations to be used without a capacitor.

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

                      @yveaux
                      interesting... i must take a look to this option.
                      Thanks. :-)

                      1 Reply Last reply
                      0
                      • alowhumA alowhum

                        @scalz I add the wait to make sure the radio has enough power without having to resort to adding a capacitor.

                        scalzS Offline
                        scalzS Offline
                        scalz
                        Hardware Contributor
                        wrote on last edited by scalz
                        #11

                        @alowhum said in What is the good wait() time ?:

                        @scalz I add the wait to make sure the radio has enough power without having to resort to adding a capacitor.

                        I already got it. But it seems you have a "design flaw", it's treating symptoms instead of root.. So it's not a great tip.
                        For very simple case like a temperature sensor, it might seem handy and work, but not for all usercases, like I said, you add latency to your nodes.

                        I prefer Yveaux advice. And if it's not enough:

                        • hardware flaws
                        • library bug..

                        I also agree with mfalkvidd. If you don't want to tweak/solder stuff on any hw, then you might get troubles, or poor range when using different power supplies sources (noisy, etc) and wait() will be ineffective.

                        1 Reply Last reply
                        1
                        • YveauxY Yveaux

                          @tommies You could give message queueing a try:

                          • Connect the nRF24 IRQ pin to pin 2 on your Arduino
                          • add #define MY_RF24_IRQ_PIN (2)
                          • add #define MY_RX_MESSAGE_BUFFER_FEATURE
                          • add #define MY_RX_MESSAGE_BUFFER_SIZE (10)
                          • that last value may be lower (e.g. 5) when running out of memory

                          This will listen to the interrupt from the nRF24 when a message comes in and immediately pause the running code to retrieve the message.
                          Then your code continues and any messages stored will be processed outside the loop() function automatically.
                          The wait() call(s) can be removed from your code.
                          It might interfere with your NeoPixel update though, but there's only one way to find out ;-)

                          Refer to e.g. https://forum.mysensors.org/topic/7190/irq-pin-for-nrf24l01 for a discussion on message queueing.

                          T Offline
                          T Offline
                          tommies
                          wrote on last edited by
                          #12

                          @yveaux Did it. wired Pin 2, removed wait() in my loop... works like a Harry Potter enchantment.
                          now i need to find another PCB board with IRQ pin connected !!
                          damned !
                          Thanks
                          now i must change my gateay

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

                            I already use PIN2 and/or PIN3 as wake up interrupt to wake up node in sleeping sensors.
                            Is there any way to use interrupt in non sleeping node ?
                            By the way, it would avoid to use loop fonction to detect push button change state.

                            YveauxY 1 Reply Last reply
                            0
                            • T tommies

                              I already use PIN2 and/or PIN3 as wake up interrupt to wake up node in sleeping sensors.
                              Is there any way to use interrupt in non sleeping node ?
                              By the way, it would avoid to use loop fonction to detect push button change state.

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

                              @tommies MySensors is using regular Arduino attachInterrupt/detachInterrupt to handle the nRF24 interrupts, so any other pin compatible with the Arduino interrupt system should work.

                              http://yveaux.blogspot.nl

                              1 Reply Last reply
                              0
                              • alowhumA Offline
                                alowhumA Offline
                                alowhum
                                Plugin Developer
                                wrote on last edited by
                                #15

                                @scalz Interesting. But in reality I do see that adding a delay results in fewer NACK issues. What could that be?

                                I also always place my radios in the Nano Wireless Board, which solves pretty much all the issues with power and wiring I had before.

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


                                11

                                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