/*
This code cycles four modes on a Arduino Mega using a pushbutton.
• Mode 1: Sets the RGB LEDs to red, green, blue and turns on led1.
• Mode 2: Displays a moving rainbow effect on RGB LEDs and turns on led2.
• Mode 3: Sets all RGB LEDs to white and turns on led3.
• Mode 4: Turns all LEDs off.
A pushbutton on digital pin 50 (INPUT_PULLUP) cycles the mode.
The program includes debouncing (150ms) and requires a minimum of 2 sec
between mode changes.
*/
///////////////////////
// Pin Definitions
///////////////////////
const int btnPin = 50; // pushbutton input pin
// Single-color LED indicator pins
const int led1Pin = 22;
const int led2Pin = 23;
const int led3Pin = 24;
// RGB LED pins for rgb1
const int rgb1R = 3;
const int rgb1G = 4;
const int rgb1B = 5;
// For rgb2
const int rgb2R = 6;
const int rgb2G = 7;
const int rgb2B = 8;
// For rgb3
const int rgb3R = 9;
const int rgb3G = 10;
const int rgb3B = 11;
///////////////////////
// Timing Variables
///////////////////////
unsigned long lastModeChangeTime = 0; // to enforce 2 sec between changes
const unsigned long modeDelay = 2000; // mode life minimum (in ms)
unsigned long lastDebounceTime = 0;
const unsigned long debounceDelay = 150; // debounce delay in ms
///////////////////////
// Button state Tracking
///////////////////////
int buttonState = HIGH;
int lastButtonReading = HIGH;
///////////////////////
// Current mode: 1,2,3,4
// Start at mode 4 (all off) so that on powerup all LEDs are off.
///////////////////////
int currentMode = 4;
///////////////////////
// Function Prototypes
///////////////////////
void updateLEDIndicators();
void setRGBColor(int r, int g, int b);
void updateRGBs_Mode1();
void updateRGBs_Mode2();
void updateRGBs_Mode3();
void turnOffRGBs();
void setup() {
// Setup button pin.
pinMode(btnPin, INPUT_PULLUP);
// Setup indicator LED pins.
pinMode(led1Pin, OUTPUT);
pinMode(led2Pin, OUTPUT);
pinMode(led3Pin, OUTPUT);
// Setup RGB LED pins (all as outputs).
pinMode(rgb1R, OUTPUT);
pinMode(rgb1G, OUTPUT);
pinMode(rgb1B, OUTPUT);
pinMode(rgb2R, OUTPUT);
pinMode(rgb2G, OUTPUT);
pinMode(rgb2B, OUTPUT);
pinMode(rgb3R, OUTPUT);
pinMode(rgb3G, OUTPUT);
pinMode(rgb3B, OUTPUT);
// At startup, ensure all LEDs are off.
digitalWrite(led1Pin, LOW);
digitalWrite(led2Pin, LOW);
digitalWrite(led3Pin, LOW);
turnOffRGBs();
lastModeChangeTime = millis();
}
void loop() {
// Read the pushbutton. (Active LOW.)
int reading = digitalRead(btnPin);
// Check for a change in the reading.
if (reading != lastButtonReading) {
lastDebounceTime = millis();
}
// Only change state if the reading has been stable for debounceDelay.
if ((millis() - lastDebounceTime) > debounceDelay) {
// Detect a button press (falling edge).
if (reading != buttonState) {
buttonState = reading;
if (buttonState == LOW) { // button is pressed
// Only update mode if 2 seconds have passed since last change.
if (millis() - lastModeChangeTime >= modeDelay) {
// Cycle from 4 back to 1.
currentMode = (currentMode % 4) + 1;
lastModeChangeTime = millis();
}
}
}
}
lastButtonReading = reading;
// Update outputs based on the current mode.
switch (currentMode) {
case 1:
// Mode 1: RGB LEDs individually:
// rgb1 -> red, rgb2 -> green, rgb3 -> blue.
updateRGBs_Mode1();
// Turn on the indicator: led1 on; led2 & led3 off.
digitalWrite(led1Pin, HIGH);
digitalWrite(led2Pin, LOW);
digitalWrite(led3Pin, LOW);
break;
case 2:
// Mode 2: Rainbow effect on all RGB LEDs.
updateRGBs_Mode2();
// Indicator: led2 on; the other two off.
digitalWrite(led1Pin, LOW);
digitalWrite(led2Pin, HIGH);
digitalWrite(led3Pin, LOW);
break;
case 3:
// Mode 3: Warm white on all RGB LEDs (equal intensity).
updateRGBs_Mode3();
// Indicator: led3 on; others off.
digitalWrite(led1Pin, LOW);
digitalWrite(led2Pin, LOW);
digitalWrite(led3Pin, HIGH);
break;
case 4:
// Mode 4: All LEDs off
turnOffRGBs();
digitalWrite(led1Pin, LOW);
digitalWrite(led2Pin, LOW);
digitalWrite(led3Pin, LOW);
break;
default:
break;
}
}
// Update RGB LEDs for Mode 1.
void updateRGBs_Mode1() {
// rgb1: red
analogWrite(rgb1R, 255); analogWrite(rgb1G, 0); analogWrite(rgb1B, 0);
// rgb2: green
analogWrite(rgb2R, 0); analogWrite(rgb2G, 255); analogWrite(rgb2B, 0);
// rgb3: blue
analogWrite(rgb3R, 0); analogWrite(rgb3G, 0); analogWrite(rgb3B, 255);
}
// Update all RGB LEDs for Mode 3 (warm white).
void updateRGBs_Mode3() {
// Here white is produced by equal intensities.
int whiteVal = 255;
// rgb1:
analogWrite(rgb1R, whiteVal); analogWrite(rgb1G, whiteVal); analogWrite(rgb1B, whiteVal);
// rgb2:
analogWrite(rgb2R, whiteVal); analogWrite(rgb2G, whiteVal); analogWrite(rgb2B, whiteVal);
// rgb3:
analogWrite(rgb3R, whiteVal); analogWrite(rgb3G, whiteVal); analogWrite(rgb3B, whiteVal);
}
// Turn off all RGB LEDs (set PWM to 0).
void turnOffRGBs() {
// rgb1:
analogWrite(rgb1R, 0); analogWrite(rgb1G, 0); analogWrite(rgb1B, 0);
// rgb2:
analogWrite(rgb2R, 0); analogWrite(rgb2G, 0); analogWrite(rgb2B, 0);
// rgb3:
analogWrite(rgb3R, 0); analogWrite(rgb3G, 0); analogWrite(rgb3B, 0);
}
// Update RGB LEDs for Mode 2 with a smoothly transitioning rainbow effect.
void updateRGBs_Mode2() {
// Define three target colors:
// yellow: (255, 255, 0)
// cyan: (0, 255, 255)
// purple: (255, 0, 255)
// We smoothly interpolate from yellow --> cyan --> purple --> yellow
const unsigned long cyclePeriod = 3000; // full cycle time (ms)
unsigned long t = millis() % cyclePeriod;
float alpha;
int r, g, b;
if (t < cyclePeriod/3) {
// Transition: yellow (255,255,0) --> cyan (0,255,255)
alpha = (float)t / (cyclePeriod/3);
r = 255 - int(255 * alpha);
g = 255;
b = int(255 * alpha);
}
else if (t < 2*(cyclePeriod/3)) {
// Transition: cyan (0,255,255) --> purple (255,0,255)
alpha = float(t - cyclePeriod/3) / (cyclePeriod/3);
r = int(255 * alpha);
g = 255 - int(255 * alpha);
b = 255;
}
else {
// Transition: purple (255,0,255) --> yellow (255,255,0)
alpha = float(t - 2*(cyclePeriod/3)) / (cyclePeriod/3);
r = 255;
g = int(255 * alpha);
b = 255 - int(255 * alpha);
}
// Update all three RGB LEDs with the same calculated color.
// rgb1:
analogWrite(rgb1R, r); analogWrite(rgb1G, g); analogWrite(rgb1B, b);
// rgb2:
analogWrite(rgb2R, r); analogWrite(rgb2G, g); analogWrite(rgb2B, b);
// rgb3:
analogWrite(rgb3R, r); analogWrite(rgb3G, g); analogWrite(rgb3B, b);
}