#include <Arduino.h>
// === Pin Definitions ===
#define POT_BRIGHTNESS A0
#define POT_RGB_RED A2
#define POT_RGB_GREEN A3
#define POT_RGB_BLUE A4
#define LED_RED 13
#define LED_GREEN 12
#define LED_BLUE 5 // Hardware PWM pin
#define RGB_RED 11
#define RGB_GREEN 10
#define RGB_BLUE 9
#define BTN_RED 8
#define BTN_GREEN 7
#define BTN_BLUE 6
#define BTN_RESET 2
// === State Variables ===
bool blinking[3] = {true, true, true};
bool ledState[3] = {false, false, false};
bool buttonEnabled[3] = {true, true, true};
unsigned long lastBlinkMillis = 0;
const unsigned long blinkInterval = 2000;
// Debounce handling
unsigned long lastDebounceTime[3] = {0, 0, 0};
const unsigned long debounceDelay = 50;
int lastButtonState[3] = {HIGH, HIGH, HIGH};
void resetSystem();
// === Setup function ===
void setup() {
Serial.begin(9600);
pinMode(LED_RED, OUTPUT);
pinMode(LED_GREEN, OUTPUT);
pinMode(LED_BLUE, OUTPUT);
pinMode(RGB_RED, OUTPUT);
pinMode(RGB_GREEN, OUTPUT);
pinMode(RGB_BLUE, OUTPUT);
pinMode(BTN_RED, INPUT_PULLUP);
pinMode(BTN_GREEN, INPUT_PULLUP);
pinMode(BTN_BLUE, INPUT_PULLUP);
pinMode(BTN_RESET, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(BTN_RESET), resetSystem, FALLING);
Serial.println("System Initialized");
}
// === Main loop ===
void loop() {
handleBlinking();
handleButtons();
handleRGB();
handleBlueLEDBrightness();
handleSerial();
}
// === Blink all LEDs together every 2 sec ===
void handleBlinking() {
unsigned long currentMillis = millis();
if (currentMillis - lastBlinkMillis >= blinkInterval) {
lastBlinkMillis = currentMillis;
for (int i = 0; i < 3; i++) {
if (blinking[i]) {
ledState[i] = !ledState[i];
digitalWrite(getLEDPin(i), ledState[i]);
}
}
}
}
// === Buttons Handling with debounce ===
void handleButtons() {
checkButton(BTN_RED, 0);
checkButton(BTN_GREEN, 1);
checkButton(BTN_BLUE, 2);
}
// Button debouncing
void checkButton(int buttonPin, int ledIndex) {
static unsigned long lastDebounceTime[3] = {0, 0, 0};
static int lastStableState[3] = {HIGH, HIGH, HIGH};
static int buttonState[3] = {HIGH, HIGH, HIGH};
int currentReading = digitalRead(buttonPin);
if (currentReading != buttonState[ledIndex]) {
lastDebounceTime[ledIndex] = millis();
buttonState[ledIndex] = currentReading;
}
if ((millis() - lastDebounceTime[ledIndex]) > 50) { // Debounce delay of 50ms
if (buttonState[ledIndex] == LOW && lastStableState[ledIndex] == HIGH && buttonEnabled[ledIndex]) {
blinking[ledIndex] = false;
ledState[ledIndex] = !ledState[ledIndex];
digitalWrite(getLEDPin(ledIndex), ledState[ledIndex]);
Serial.print("LED ");
Serial.print(ledIndex + 1);
Serial.println(ledState[ledIndex] ? " ON" : " OFF");
}
lastStableState[ledIndex] = buttonState[ledIndex];
}
}
// === Hardware PWM for Blue LED brightness ===
void handleBlueLEDBrightness() {
int brightness = map(analogRead(POT_BRIGHTNESS), 0, 1023, 0, 255);
if (!blinking[2]) {
analogWrite(LED_BLUE, ledState[2] ? brightness : 0);
} else {
analogWrite(LED_BLUE, ledState[2] ? brightness : 0);
}
}
// === RGB LED Color Control ===
// === Corrected RGB LED Color Control for Common-Anode LED ===
void handleRGB() {
// Read potentiometer values (0-1023)
int redValue = analogRead(POT_RGB_RED);
int greenValue = analogRead(POT_RGB_GREEN);
int blueValue = analogRead(POT_RGB_BLUE);
// Map potentiometer values to PWM (0-255) and invert for Common-Anode
redValue = map(redValue, 0, 1023, 0, 255);
greenValue = map(greenValue, 0, 1023, 0, 255);
blueValue = map(blueValue, 0, 1023, 0, 255);
// Output corrected inverted PWM signals
analogWrite(RGB_RED, redValue);
analogWrite(RGB_GREEN, greenValue);
analogWrite(RGB_BLUE, blueValue);
}
// === Serial Commands Handler ===
void handleSerial() {
if (Serial.available() > 0) {
String input = Serial.readStringUntil('\n');
input.trim();
Serial.print("> ");
Serial.println(input);
// RED LED toggle
if (input.equalsIgnoreCase("R")) {
blinking[0] = false;
ledState[0] = !ledState[0];
digitalWrite(LED_RED, ledState[0]);
Serial.print("Red LED is now ");
Serial.println(ledState[0] ? "ON" : "OFF");
}
// GREEN LED toggle
else if (input.equalsIgnoreCase("G")) {
blinking[1] = false;
ledState[1] = !ledState[1];
digitalWrite(LED_GREEN, ledState[1]);
Serial.print("Green LED is now ");
Serial.println(ledState[1] ? "ON" : "OFF");
}
// BLUE LED brightness or toggle
else if (input.startsWith("B")) {
blinking[2] = false; // stop blinking on manual control
input.remove(0,1); // remove 'B' character
input.trim();
if (input.length() == 0) { // just "B" toggles LED on/off
ledState[2] = !ledState[2];
analogWrite(LED_BLUE, ledState[2] ? 255 : 0);
Serial.print("Blue LED toggled ");
Serial.println(ledState[2] ? "ON (Max brightness)" : "OFF");
} else { // "B value" sets brightness
int brightness = input.toInt();
brightness = constrain(brightness, 0, 255);
analogWrite(LED_BLUE, brightness);
Serial.print("Blue LED brightness set to: ");
Serial.println(brightness);
}
}
// RGB ON (all LEDs active based on potentiometer)
else if (input.equalsIgnoreCase("RGB on")) {
Serial.println("RGB LED control activated (potentiometers)");
// You may add extra logic here if needed
}
// RGB OFF (turn off RGB completely)
else if (input.equalsIgnoreCase("RGB off")) {
analogWrite(RGB_RED, 255);
analogWrite(RGB_GREEN, 255);
analogWrite(RGB_BLUE, 255);
Serial.println("RGB LED turned off");
}
else if (input.equalsIgnoreCase("disable button 1")) {
buttonEnabled[0] = false;
Serial.println("Button 1 disabled");
}
else if (input.equalsIgnoreCase("enable button 1")) {
buttonEnabled[0] = true;
Serial.println("Button 1 enabled");
}
else if (input.equalsIgnoreCase("disable button 2")) {
buttonEnabled[1] = false;
Serial.println("Button 2 disabled");
}
else if (input.equalsIgnoreCase("enable button 2")) {
buttonEnabled[1] = true;
Serial.println("Button 2 enabled");
}
else if (input.equalsIgnoreCase("disable button 3")) {
buttonEnabled[2] = false;
Serial.println("Button 3 disabled");
}
else if (input.equalsIgnoreCase("enable button 3")) {
buttonEnabled[2] = true;
Serial.println("Button 3 enabled");
}
else {
Serial.println("Invalid command!");
}
}
}
// === Interrupt-based Reset ===
void resetSystem() {
for (int i = 0; i < 3; i++) {
blinking[i] = true;
buttonEnabled[i] = true;
ledState[i] = false;
digitalWrite(getLEDPin(i), LOW);
}
Serial.println("System Reset!");
}
// === Helper function ===
int getLEDPin(int index) {
switch (index) {
case 0: return LED_RED;
case 1: return LED_GREEN;
case 2: return LED_BLUE;
}
return -1;
}