How to blink a light without blocking other functionality

I am trying to make a simple program to run on a raspberry pi pico in C on the Arduino IDE that can track soil and air properties around plants (which I have done) and blink a led continuously if certain thresholds are violated (where I am struggling). (I can make the led blink, but then I cant also continue the measurements).

The goal is that when soil is too dry, or other measurements indicate the conditions are outside desired thresholds, a led would begin blinking and continue blinking, while the program would continue running and taking its readings. So I need the constant blinking to be handled concurrently with the main objective of taking measurements not impacted. I am not sure if I need multi-threading for this (it seems to have it's own issues) or if there is a simpler way to achieve my goal?

Most of my research has seemed to return answers only for micropython or requiring adoption of another IDE which i would like to avoid if possible. Mostly just looking for a direction to research in or an example of a similar project I can study. Thanks all.

Check the example in the IDE: Examples → Digital → BlinkWithoutDelay.

1 Like

For extra information and examples look at

you might benefit from studying state machines. Here is a small introduction to the topic: Yet another Finite State Machine introduction

1 Like

millis() provides the time in milliseconds since the processor started running. It overflows in 49 days.

a timestamp can be captured at some point in time.

within loop() the timestamp can be subtracted from the current time and compared (>=) to some period (e.g. 500 msec), and when true, perform some action

the timestamp can be reset to the current value of millis() to perform some periodic action.

of course there can be multiple timestamps and period to invoke a various actions, either periodic or aperiodic

Demo-Code that shows how to do "blink" without blocking other functionality.

This is called non-blocking timing.

explaining non-blocking timing
I want to comment on the basic blink_without_delay example-code.

The basic basic blink_without_delay example-code makes understanding non-blocking timing
harder than it must be for multiple reasons:

It starts with postings that have sentences like "use function millis() instead of delay()"
There is a pretty high danger that this sentence creates a totally wrong picture of how non-blocking timing works.
Such a sentence initiates a wrong picture of

replace delay() with millis() and you are done.

non-blocking timing requires more than a simple replacing.

  1. the blink without delay-example does NOT mention that there is a fundamental difference
    between delay() and non-blocking timing
    Without explicitly explaining this difference newcomers are in danger to see a delay()-similar-Thing
    And trying to see a delay()-similar thing will cause extra confusion because there is NO similarity!

  2. a part of the variable-names is badly chosen.

  3. the demo-code distributes the variables to mutliple places

The variable-distribution makes it harder to understand the basic principle.

I suggest that you watch this video as the introduction to non-blocking timing
It will guide you on the right track and explain it step by step

Hello mcunkelman

I have read your system description.

My recommendation:
A timer function based on the millis() function is actually always required in every project.
The timer function can be easily derived from the BLINKWITHOUTDELAY example, the mother of all Arduino timers, in the IDE.
What does the timer function do?
The timer function provides time slots in which actions are executed without blocking the programme as with the delay() function.
The timer function should be scalable and offer the following services:

  1. make()
  2. start()
  3. stop()
  4. isExpired()
  5. isRunning()

Try it out and programme your own timer function first.

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

p.s. Arrays and structs are your friends.

2 Likes

call this from loop():

static const int blinkSpeed = 200;      // speed of blink
static const int LEDPin = LED_BUILTIN;  // which LED

void blinkLED() {
  static uint32_t lastBlink;  // time at which the last LED state change occurred
  uint32_t now = millis();    // time it is NOW.
  if (now - lastBlink > blinkSpeed) {  // now - lastblink is elapsed time
    digitalWrite(LEDPin, digitalRead(LEDPin) == HIGH ? LOW : HIGH);  // toggle LED
    lastBlink = now;          // update time of state change
  }
}

(This is essentially, the "Blink without Delay" example, only ... all encapsulated with locally meaningful names and such.)

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