Skip to content

Instantly share code, notes, and snippets.

@Michael-F-Ellis
Created September 25, 2021 00:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Michael-F-Ellis/afd78265d8352b020103e1727c71f0fd to your computer and use it in GitHub Desktop.
Save Michael-F-Ellis/afd78265d8352b020103e1727c71f0fd to your computer and use it in GitHub Desktop.
Arduino code to blink multiple LED's at different rates. Solution to problem posed in Sept 24, 2021 workshop at The Generator in Burlington VT.
/*
BlinkRGB
Author: Mike Ellis
Example code showing how use the millis() function to blink
3 different LED's at different rates.
This code is in the public domain.
*/
const uint32_t BLINKMS = 50; // The duration of each blink
// Pin Assignments for each LED. Change these if you use different pins.
const uint8_t RED = 12;
const uint8_t GRN = 10;
const uint8_t BLU = 9;
// macroMakeBlinker is a C preprocessor macro that generates functions. Macros are
// an old-school technique that has, for mostly good reasons,fallen into disfavor
// since the advent of C++. In this particular case, I believe the advantages outweigh
// the downsides.
//
// Macros work by text substitution. Each macro argument is substituted into a copy of
// the macro body in every place the argument occurs.
//
// Note that each line of the macro body (save the last line) must end in a backslash
// continuation character with no whitespace after it.
#define macroMakeBlinker(blinkerName, pin, intervalms) \
void blinkerName(uint32_t now) { \
const uint8_t PIN = pin; \
static uint32_t lastTime = 0; \
static uint8_t ledOn = 0; \
if (lastTime == 0 || (!ledOn && (now - lastTime) >= intervalms)) { \
digitalWrite(PIN, HIGH); \
ledOn = 1; \
lastTime = now; \
} \
if (ledOn && (now - lastTime) >= BLINKMS) { \
digitalWrite(PIN, LOW); \
ledOn = 0; \
} \
}
// Use the macro to create the four blinker functions we need. If you want to
// change the duration of the blink cycles, this is the place to do so, Note that,
// unlike most program statements, a semicolon is not required after the
// macro invocations.
macroMakeBlinker(builtinLed, LED_BUILTIN, 3000) // produces builtinLed() with a 3000 ms blink cycle
macroMakeBlinker(redLed, RED, 1000) // produces redLed() with a 1000ms blink cycle
macroMakeBlinker(grnLed, GRN, 750) // produces grnLed() with a 750ms blink cycle
macroMakeBlinker(bluLed, BLU, 600) // produces bluLed() with a 600ms blink cycle
// The setup function runs once when you press reset or power the board.
// Here, we simply specify our pins as outputs.
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
pinMode(RED, OUTPUT);
pinMode(GRN, OUTPUT);
pinMode(BLU, OUTPUT);
}
// the loop function runs over and over again forever
void loop() {
// at each pass through the loop get the current ms clock
// value and pass it to each macro-generated blinker function.
uint32_t now = millis();
bluLed(now);
grnLed(now);
redLed(now);
builtinLed(now);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment