Blink w/o Delay Two Lights 230619

Hello Arduino forum,

Working with Blink w/o Delay

Using the code listed herewith below it seems like
all of the variables

  • ledState
  • previousMillis
  • interval
  • currentMillis
    must be defined separately for each
    LED output for this to work.

Experimenting with the interval variable:
Use Case One
If interval9 and interval10 are the same
const long interval9 = 1000; // interval at which to blink (milliseconds)
const long interval10 = 1000;
then both lights go on and off simultaneous at 1 second intervals

Use Case Two
If interval9 and interval10 are offset
const long interval9 = 1000; // interval at which to blink (milliseconds)
const long interval10 = 2000;
ledPin9 comes on, stays on for 1 second and
goes off exactly at the same time which led10 comes on
One second after led10 comes on led9 comes on again
and one second later they both go off together.
This cycle repeats.

Use Case Three
If interval9 and interval10 are offset
const long interval9 = 2000; // interval at which to blink (milliseconds)
const long interval10 = 1000;
then both lights go on and off simultaneous at 2 second intervals

This leads me to believe that I don't understand what is going on.
in the Use Case One, both intervals set to 1000, the fact they
act in unison seems intuitive because they are set the same.

Two questions please.

  1. In Use Case Two
    const long interval9 = 1000;
    const long interval10 = 2000;
    why does led10 wait for led9 to go off before led10 comes on?
    It was thought that the whole idea of blink w/o delay was to make
    events independent. But it seems led 10 is waiting for
    led9 to cycle before it begins.

  2. In Use Case Three
    const long interval9 = 2000;
    const long interval10 = 1000;
    It would seem that because the intervals are from
    const long interval9 = 1000;
    const long interval10 = 2000;
    that the operation would be inverse. That is,
    led9 would stay on longer than led10.
    But instead, they are acting simultaneously
    similar to the first case where the
    intervals were set the same.

Thanks

Allen

/* Blink without Delay Turns on and off a light emitting diode (LED) connected to a digital pin, 
without using the delay() function. This means that other code can run at the same 
time without being interrupted by the LED code.*/

const int ledPin9 =9; // the number of the LED pin
const int ledPin10 =10; // the number of the LED pin
int ledState9 = LOW; // ledState used to set the LED
int ledState10 = LOW; // ledState used to set the LED
unsigned long previousMillis9 = 0; // will store last time LED was updated
const long interval9 = 1000; // interval at which to blink (milliseconds)
unsigned long previousMillis10 = 0; // will store last time LED was updated
const long interval10 = 1000; // interval at which to blink (milliseconds)

void setup() {
  pinMode(ledPin9, OUTPUT); // set the digital pin as output
  pinMode(ledPin10, OUTPUT); // set the digital pin as output
}

void loop() {
  unsigned long currentMillis9 = millis(); // get current time
  unsigned long currentMillis10 = millis(); // get current time


  if (currentMillis9 - previousMillis9 >= interval9) { // check if interval has passed
    previousMillis9 = currentMillis9; // save last time LED was updated

    if (ledState9 == LOW) {
      ledState9 = HIGH; // turn on LED
    } else {
      ledState9 = LOW; // turn off LED
    }

    digitalWrite(ledPin9, ledState9); // set the LED with the ledState

    if (currentMillis10 - previousMillis10 >= interval10) { // check if interval has passed
    previousMillis10 = currentMillis10; // save last time LED was updated

    if (ledState10 == LOW) {
      ledState10 = HIGH; // turn on LED
    } else {
      ledState10 = LOW; // turn off LED
    }

    digitalWrite(ledPin10, ledState10); // set the LED with the ledState
  }
  }   
}

Your LED10 portion is included in the LED9 portion so it only acts when it does. Take one of your curly brackets at the end and move it to after the LED9 digitalWrite. It compiles, but isn't tested.

const int ledPin9 = 9; // the number of the LED pin
const int ledPin10 = 10; // the number of the LED pin
int ledState9 = LOW; // ledState used to set the LED
int ledState10 = LOW; // ledState used to set the LED
unsigned long previousMillis9 = 0; // will store last time LED was updated
const long interval9 = 1000; // interval at which to blink (milliseconds)
unsigned long previousMillis10 = 0; // will store last time LED was updated
const long interval10 = 1000; // interval at which to blink (milliseconds)

void setup() {
  pinMode(ledPin9, OUTPUT); // set the digital pin as output
  pinMode(ledPin10, OUTPUT); // set the digital pin as output
}

void loop() {
  unsigned long currentMillis9 = millis(); // get current time
  unsigned long currentMillis10 = millis(); // get current time


  if (currentMillis9 - previousMillis9 >= interval9) { // check if interval has passed
    previousMillis9 = currentMillis9; // save last time LED was updated

    if (ledState9 == LOW) {
      ledState9 = HIGH; // turn on LED
    } else {
      ledState9 = LOW; // turn off LED
    }

    digitalWrite(ledPin9, ledState9); // set the LED with the ledState

  }

  if (currentMillis10 - previousMillis10 >= interval10) { // check if interval has passed
    previousMillis10 = currentMillis10; // save last time LED was updated

    if (ledState10 == LOW) {
      ledState10 = HIGH; // turn on LED
    } else {
      ledState10 = LOW; // turn off LED
    }

    digitalWrite(ledPin10, ledState10); // set the LED with the ledState
  }

}
1 Like

Not currentMillis, no. The others, yes.

1 Like

Hello @AllenPitts ,

Not a direct answer to your questions but you might find this useful:

1 Like

No.
Now is now, globally.

Actually, time is relative. :stuck_out_tongue:

Think about using arrays for the pin, delay, and timeout. Then you can cycle thru, looking for timed out led's, xor them to toggle state, and reset timeout to now + delay. Easy peasy and code simplifies to one loop.

With using a function for the non-blocking timing the code boils down to

const int ledPin9  = 9; // the number of the LED pin
const int ledPin10 = 10; // the number of the LED pin

const unsigned long interval9  = 1000; // interval at which to blink (milliseconds)
const unsigned long interval10 =  500; // interval at which to blink (milliseconds)

unsigned long LED09_Timer;  // just a SINGLE variable for non-blocking timing
unsigned long LED10_Timer; 

void setup() {
  pinMode(ledPin9, OUTPUT); // set the digital pin as output
  pinMode(ledPin10, OUTPUT); // set the digital pin as output
  LED09_Timer = millis();  // just a SINGLE variable for non-blocking timing
  LED10_Timer = millis(); 
}


void loop() {
  if ( TimePeriodIsOver(LED09_Timer,interval9) ) {
    digitalWrite(ledPin9,!digitalRead(ledPin9) ); 
  }

  if ( TimePeriodIsOver(LED10_Timer,interval10) ) {
    digitalWrite(ledPin10,!digitalRead(ledPin10) ); 
  }
}

// the attention mark "!" is the NOT-operator which inverts LOW to HIGH and HIGH to LOW
// digitalRead() can be done for outputs too  
// and it delivers the actual logic state 
// example digitalRead(ledPin9) = LOW    
// inverting with the NOT-operator !LOW results in HIGH
// which means digitalWrite(ledPin10,!digitalRead(ledPin10) )
// digitalWrite(ledPin10,!LOW )
// digitalWrite(ledPin10,HIGH )
// which toggles the state of the IO-pin

// easy to use helper-function for non-blocking timing
boolean TimePeriodIsOver (unsigned long &startOfPeriod, unsigned long TimePeriod) {
  unsigned long currentMillis  = millis();
  if ( currentMillis - startOfPeriod >= TimePeriod ) {
    // more time than TimePeriod has elapsed since last time if-condition was true
    startOfPeriod = currentMillis; // a new period starts right here so set new starttime
    return true;
  }
  else return false;            // actual TimePeriod is NOT yet over
}

which can be watched in this WokSim

best regards Stefan

Here's a simulation on how you can independently change two LED blink rates.

Hello AllenPitts

Consider this small MultiBlinker sketch for your model railway.

#define ProjectName "MultiBlinker"
//variables
//-----------------------------------------------
// the Leds and the flashing times can be adjusted here
constexpr uint8_t LedPins[] {9, 10, 11};
constexpr uint32_t FlashTimes[] {333, 666, 999};
//-----------------------------------------------
//structures
struct MULTIBLINKER
{
  uint8_t ledPin;
  uint32_t previousMillis;
  uint32_t blinkMillis;
  void make(uint8_t ledPin_, uint32_t flashTime,  uint8_t element)
  {
    Serial.print(__func__), Serial.print(" for Blinker "), Serial.println(element);
    ledPin = ledPin_;
    pinMode(ledPin, OUTPUT);
    blinkMillis = flashTime;
  }
  void run(uint32_t currentMillis)
  {
    if (currentMillis - previousMillis >= blinkMillis)
    {
      previousMillis = currentMillis;
      digitalWrite(ledPin, digitalRead(ledPin) ? LOW : HIGH);
    }
  }
} multiBlinkers[sizeof(LedPins)];
void setup()
{
  Serial.begin(115200);
  Serial.println(ProjectName);
  uint8_t element = 0;
  for (auto &multiBlinker : multiBlinkers)
  {
    multiBlinker.make(LedPins[element] , FlashTimes[element], element);
    element++;
  }
}
void loop()
{
  uint32_t currentMillis = millis();
  for (auto &multiBlinker : multiBlinkers) multiBlinker.run(currentMillis);
}

hth

Have a nice day and enjoy coding in C++.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.