Skip to content

Instantly share code, notes, and snippets.

@aheil
Created May 27, 2025 22:35
Show Gist options
  • Select an option

  • Save aheil/84120aa65d703008cc074a9fcff65bfa to your computer and use it in GitHub Desktop.

Select an option

Save aheil/84120aa65d703008cc074a9fcff65bfa to your computer and use it in GitHub Desktop.
// The MIT License (MIT)
// Copyright © 2025 Andreas Heil
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the “Software”), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <Arduino.h>
#define LED_WHITE 13
#define LED_RED 12
#define LED_YELLOW_1 27
#define LED_YELLOW_2 26
#define LED_BLUE 25
// Timing constants (in milliseconds)
// YELLOW_2 timing
const unsigned long YELLOW2_MIN_INTERVAL = 200; // Minimum time between blinks
const unsigned long YELLOW2_MAX_INTERVAL = 1000; // Maximum time between blinks
const unsigned long YELLOW2_MIN_DURATION = 100; // Minimum blink duration
const unsigned long YELLOW2_MAX_DURATION = 1000; // Maximum blink duration
// YELLOW_1 timing
const unsigned long YELLOW1_INTERVAL = 1000; // 1 second interval
const unsigned long YELLOW1_DURATION = 1000; // 1 second duration
// RED LED timing (radio signal simulation)
const unsigned long RED_MIN_DURATION = 5; // 5ms minimum flicker
const unsigned long RED_MAX_DURATION = 50; // 50ms maximum flicker
const unsigned long RED_MIN_INTERVAL = 2; // 2ms minimum gap
const unsigned long RED_MAX_INTERVAL = 30; // 30ms maximum gap
const unsigned long RED_BURST_CHANCE = 20; // 20% chance of a burst
const unsigned long RED_BURST_DURATION = 200; // 200ms burst duration
// BLUE LED timing (slower flickering)
const unsigned long SLOW_MIN_DURATION = 300; // 300ms minimum flicker
const unsigned long SLOW_MAX_DURATION = 800; // 800ms maximum flicker
const unsigned long SLOW_MIN_INTERVAL = 200; // 200ms minimum gap
const unsigned long SLOW_MAX_INTERVAL = 600; // 600ms maximum gap
// WHITE LED timing (more random flickering)
const unsigned long WHITE_MIN_DURATION = 100; // 100ms minimum flicker
const unsigned long WHITE_MAX_DURATION = 1500; // 1500ms maximum flicker
const unsigned long WHITE_MIN_INTERVAL = 50; // 50ms minimum gap
const unsigned long WHITE_MAX_INTERVAL = 1200; // 1200ms maximum gap
const unsigned long WHITE_PAUSE_CHANCE = 15; // 15% chance of a long pause
const unsigned long WHITE_PAUSE_DURATION = 2000; // 2000ms pause duration
// State variables for LEDs
// YELLOW_2 states
bool yellow2State = false;
unsigned long yellow2StartTime = 0;
unsigned long yellow2NextChange = 0;
unsigned long yellow2CurrentDuration = 0;
// YELLOW_1 states
bool yellow1State = false;
unsigned long yellow1StartTime = 0;
// RED LED states
bool redState = false;
unsigned long redNextChange = 0;
unsigned long redCurrentDuration = 0;
bool redInBurst = false;
// WHITE LED states
bool whiteState = false;
unsigned long whiteNextChange = 0;
unsigned long whiteCurrentDuration = 0;
bool whiteInPause = false;
// BLUE LED states
bool blueState = false;
unsigned long blueNextChange = 0;
unsigned long blueCurrentDuration = 0;
// Timing variables
unsigned long previousMillisYELLOW2 = 0;
unsigned long previousMillisYELLOW1 = 0;
unsigned long previousMillisRED = 0;
unsigned long previousMillisWhite = 0;
unsigned long previousMillisBLUE = 0;
void setup()
{
pinMode(LED_BLUE, OUTPUT);
pinMode(LED_WHITE, OUTPUT);
pinMode(LED_RED, OUTPUT);
pinMode(LED_YELLOW_1, OUTPUT);
pinMode(LED_YELLOW_2, OUTPUT);
}
void loop()
{
unsigned long currentMillis = millis();
// Handle YELLOW_2 LED blinking with random durations
if (currentMillis >= yellow2NextChange)
{
yellow2State = !yellow2State; // Toggle state
if (yellow2State)
{
// When turning on, set a random duration
yellow2CurrentDuration = random(YELLOW2_MIN_DURATION, YELLOW2_MAX_DURATION);
yellow2NextChange = currentMillis + yellow2CurrentDuration;
}
else
{
// When turning off, set a random interval until next blink
yellow2NextChange = currentMillis + random(YELLOW2_MIN_INTERVAL, YELLOW2_MAX_INTERVAL);
}
}
// Handle YELLOW_1 LED regular blinking
if (currentMillis - previousMillisYELLOW1 >= YELLOW1_INTERVAL)
{
previousMillisYELLOW1 = currentMillis;
yellow1State = !yellow1State; // Toggle state
yellow1StartTime = currentMillis; // Record when we turned on
}
// Turn off YELLOW_1 after duration
if (yellow1State && (currentMillis - yellow1StartTime >= YELLOW1_DURATION))
{
yellow1State = false;
}
// Handle RED LED radio signal simulation
if (currentMillis >= redNextChange)
{
redState = !redState; // Toggle state
if (redState)
{
// When turning on, decide if this is a burst or normal flicker
if (!redInBurst && random(100) < RED_BURST_CHANCE)
{
// Start a burst
redInBurst = true;
redCurrentDuration = RED_BURST_DURATION;
}
else
{
// Normal flicker
redCurrentDuration = random(RED_MIN_DURATION, RED_MAX_DURATION);
}
redNextChange = currentMillis + redCurrentDuration;
}
else
{
// When turning off
if (redInBurst)
{
redInBurst = false; // End the burst
}
redNextChange = currentMillis + random(RED_MIN_INTERVAL, RED_MAX_INTERVAL);
}
}
// Handle WHITE LED more random flickering
if (currentMillis >= whiteNextChange)
{
whiteState = !whiteState; // Toggle state
if (whiteState)
{
// When turning on, decide if this is a pause or normal flicker
if (!whiteInPause && random(100) < WHITE_PAUSE_CHANCE)
{
// Start a pause
whiteInPause = true;
whiteCurrentDuration = WHITE_PAUSE_DURATION;
}
else
{
// Normal flicker with wider range
whiteCurrentDuration = random(WHITE_MIN_DURATION, WHITE_MAX_DURATION);
}
whiteNextChange = currentMillis + whiteCurrentDuration;
}
else
{
// When turning off
if (whiteInPause)
{
whiteInPause = false; // End the pause
}
// More random interval
whiteNextChange = currentMillis + random(WHITE_MIN_INTERVAL, WHITE_MAX_INTERVAL);
}
}
// Handle BLUE LED slower flickering
if (currentMillis >= blueNextChange)
{
blueState = !blueState; // Toggle state
if (blueState)
{
// When turning on, set a random duration
blueCurrentDuration = random(SLOW_MIN_DURATION, SLOW_MAX_DURATION);
blueNextChange = currentMillis + blueCurrentDuration;
}
else
{
// When turning off, set a random interval
blueNextChange = currentMillis + random(SLOW_MIN_INTERVAL, SLOW_MAX_INTERVAL);
}
}
// Update LED states
digitalWrite(LED_YELLOW_2, yellow2State ? HIGH : LOW);
digitalWrite(LED_YELLOW_1, yellow1State ? HIGH : LOW);
digitalWrite(LED_RED, redState ? HIGH : LOW);
digitalWrite(LED_WHITE, whiteState ? HIGH : LOW);
digitalWrite(LED_BLUE, blueState ? HIGH : LOW);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment