// Including Servo.h as permitted (even though not strictly used)
#include <Servo.h>
const int ledPin = 9; // PWM pin for LED brightness output
// Button pin definitions (using internal pull-up)
const int btn1Pin = 2; // switch to Auto Mode
const int btn2Pin = 3; // switch back to Manual Mode
// Potentiometer analog pin definitions
const int pot1Pin = A0; // Manual LED brightness control
const int pot2Pin = A1; // Auto Mode minimum brightness
const int pot3Pin = A2; // Auto Mode maximum brightness
// Timing and debounce parameters
const unsigned long debounceDelay = 150; // in milliseconds
const unsigned long statePersistDelay = 2000; // minimum 2 seconds for state persistence
// Mode state: true = Manual Mode, false = Auto Mode
bool manualMode = true;
// Variables to track last button events and mode switch time
unsigned long lastBtn1Time = 0;
unsigned long lastBtn2Time = 0;
unsigned long lastModeSwitchTime = 0;
// For auto mode brightness ramping
float autoBrightness = 0.0;
bool autoIncreasing = true;
unsigned long previousAutoUpdateTime = 0;
void setup() {
// LED output initialization
pinMode(ledPin, OUTPUT);
// Initialize pushbutton pins with internal pull up
pinMode(btn1Pin, INPUT_PULLUP);
pinMode(btn2Pin, INPUT_PULLUP);
// Start with LED off and in Manual Mode
analogWrite(ledPin, 0);
manualMode = true;
lastModeSwitchTime = millis();
// For auto mode timing
previousAutoUpdateTime = millis();
}
void loop() {
unsigned long currentTime = millis();
if (manualMode) {
// Check for mode switch to Auto Mode using btn1
if (digitalRead(btn1Pin) == LOW && (currentTime - lastBtn1Time > debounceDelay) &&
(currentTime - lastModeSwitchTime > statePersistDelay)) {
manualMode = false; // Switch to Auto Mode
lastModeSwitchTime = currentTime;
lastBtn1Time = currentTime;
// Initialize auto brightness range: read pot2 and pot3, then set brightness to the lower value.
int p2 = map(analogRead(pot2Pin), 0, 1023, 0, 255);
int p3 = map(analogRead(pot3Pin), 0, 1023, 0, 255);
if (p2 > p3) { // swap if pot2 > pot3 to ensure valid range
int temp = p2;
p2 = p3;
p3 = temp;
}
autoBrightness = p2; // start at minimum brightness
autoIncreasing = true;
previousAutoUpdateTime = currentTime;
}
// Manual Mode: LED brightness controlled by pot1
int potVal = analogRead(pot1Pin);
int brightness = map(potVal, 0, 1023, 0, 255);
analogWrite(ledPin, brightness);
} else {
// Auto Mode active
// Check for mode switch back to Manual Mode using btn2
if (digitalRead(btn2Pin) == LOW && (currentTime - lastBtn2Time > debounceDelay) &&
(currentTime - lastModeSwitchTime > statePersistDelay)) {
manualMode = true;
lastModeSwitchTime = currentTime;
lastBtn2Time = currentTime;
}
// Read the brightness range from pot2 and pot3
int p2 = map(analogRead(pot2Pin), 0, 1023, 0, 255);
int p3 = map(analogRead(pot3Pin), 0, 1023, 0, 255);
// Ensure p2 is the minimum and p3 is the maximum brightness.
if (p2 > p3) {
int temp = p2;
p2 = p3;
p3 = temp;
}
// Compute time elapsed
unsigned long now = millis();
float deltaTime = now - previousAutoUpdateTime; // in milliseconds
// Calculate rate of change: complete transition in 2000 ms.
float brightnessRange = p3 - p2;
float rate = (brightnessRange) / 2000.0; // brightness change per millisecond
// Update autoBrightness based on the current direction
if (autoIncreasing) {
autoBrightness += rate * deltaTime;
if (autoBrightness >= p3) {
autoBrightness = p3;
autoIncreasing = false; // switch direction
}
} else {
autoBrightness -= rate * deltaTime;
if (autoBrightness <= p2) {
autoBrightness = p2;
autoIncreasing = true; // switch direction
}
}
previousAutoUpdateTime = now;
analogWrite(ledPin, (int)autoBrightness);
}
}