1

I'm trying to make a sketch where my led blinks with random delay. I have 2 functions: ledBlink() and randomBlink(). The randomBlink use as delay parameter a random number "r" generated from 1 to 499 and pass this value to the ledBlink function to make the led blink with a delay according the random number generated. But seems like that led doesn't consider the random value of blinkDelay. Any help is appreciated, thank you so much!

#include <JC_Button.h>

int ledPin = 11;

int ledState = LOW;
unsigned long blinkDelay;
unsigned long lastBlinkMillis = 0;


void setup() {

  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
}

void ledBlink()
{
  unsigned long currentMillis = millis();

  if (currentMillis - lastBlinkMillis >= blinkDelay)
  {
    // save the last time you blinked the LED
    lastBlinkMillis = currentMillis;

    // if the LED is off turn it on and vice-versa:
    ledState = !ledState;
  

    // set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState);
  }
} 

void randomBlink()
{
  unsigned long r = random(500);
  blinkDelay = r;
  ledBlink();
  
} 


void loop() {
  randomBlink();
}
2

1 Answer 1

4

Your problem descriptions is a bit unclear, though I think I see your problem.

On every loop() iteration you call randomBlink(), which generates a new random delay value and then calls ledBlink(), which in turn checks millis() for the time to toggle the LED and exits fast. So you are blinking only when the current blinkDelay has passed, but you generate new random values for blinkDelay on every loop() iteration - so really really fast. In the time needed for even the small delays you may have generated thousands of new random values, so it is very likely that some of them are rather small values. You check against these so you only get short delays.

Think of how you would do such thing in real life. Lets say you use a dice to determine the numbers of minutes to wait. You are throwing the dice every few seconds while watching the clock. Chances are that you will at some point get a 1 or 2 after waiting 1 or 2 minutes. It is unlikely that you don't get a 6 for 6 minutes straight. Instead you would want to through the dice only once per waiting period.

For the code this means, that you need to restructure it. Calculate the new delay value only when you toggle the LED. So something like this:

void ledBlink()
{
  unsigned long currentMillis = millis();

  if (currentMillis - lastBlinkMillis >= blinkDelay)
  {
    // save the last time you blinked the LED
    lastBlinkMillis = currentMillis;

    // if the LED is off turn it on and vice-versa:
    ledState = !ledState;
  

    // set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState);

    // generate new random delay
    randomBlink();
  }
} 

void randomBlink()
{
  unsigned long r = random(500);
  blinkDelay = r;
} 


void loop() {
  ledBlink();
}

Calling ledBlink() in every loop() iteration makes sure, that the toggling of the LED actually happens. A new random value for the delay is only called after the LED just got toggled. Now the range of the delay will be the full 499ms.

1
  • oh ok, gotcha! thanks!
    – tommy
    Commented Nov 30, 2021 at 10:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.