/************************************************
SIMPLE 5 STEP PWM DIMMER
Single Tap Only
************************************************/
#define PWM_PIN 9
#define BUTTON_PIN 2
#define LED1 6
#define LED2 5
#define LED3 4
#define LED4 3
int steps[5] = {50, 100, 180, 255, 0};
int currentStep = 4; // Start OFF
int last_Step = 0;
bool buttonState;
bool lastButtonState = HIGH;
bool longPressHandled = false;
// ===== TIMER VARIABLES =====
unsigned long timerDuration = 15000; // 15 seconds
unsigned long timerStartTime = 0;
bool timerRunning = false;
unsigned long pressStartTime = 0;
unsigned long lastReleaseTime = 0;
int tapCount = 0;
#define DOUBLE_TAP_TIME 500
#define HOLD_TIME 3000
#define DEBOUNCE 50
void setup() {
Serial.begin(9600);
pinMode(PWM_PIN, OUTPUT);
pinMode(BUTTON_PIN, INPUT_PULLUP);
pinMode(LED1, OUTPUT);
pinMode(LED2, OUTPUT);
pinMode(LED3, OUTPUT);
pinMode(LED4, OUTPUT);
analogWrite(PWM_PIN, 0);
updateIndicators();
last_Step = 0;
Serial.println("System Booted - OFF");
}
void loop() {
buttonState = digitalRead(BUTTON_PIN);
// Button Pressed
if (lastButtonState == HIGH && buttonState == LOW) {
delay(DEBOUNCE);
if (digitalRead(BUTTON_PIN) == LOW) {
pressStartTime = millis();
longPressHandled = false; // reset for new press
Serial.println("Pressed");
}
}
// Button Released
if (lastButtonState == LOW && buttonState == HIGH) {
unsigned long pressDuration = millis() - pressStartTime;
Serial.print("Press Duration: ");
Serial.println(pressDuration);
Serial.print("tapCount: ");
Serial.println(tapCount);
// Ignore very short noise presses
if (pressDuration > 100) {
tapCount++;
Serial.print("Valid Tap Count: ");
Serial.println(tapCount);
lastReleaseTime = millis();
} else {
Serial.println("Ignored Noise Press");
}
}
// ===== LONG PRESS 5s TO FORCE OFF =====
if (buttonState == LOW && currentStep != 4 && !longPressHandled) {
if (millis() - pressStartTime >= 5000) {
Serial.println("5s Long Press → FORCE OFF");
currentStep = 4;
analogWrite(PWM_PIN, 0);
updateIndicators();
timerRunning = false;
Serial.println("Timer Stopped");
longPressHandled = true; // prevent repeat trigger
tapCount = 0;
delay(500);
}
}
// Check Tap Result
if (tapCount > 0 && millis() - lastReleaseTime > DOUBLE_TAP_TIME) {
// ===== DOUBLE TAP DETECTED =====
// ===== DOUBLE TAP DETECTED =====
if (tapCount == 2) {
Serial.println("Double Tap Detected");
if (currentStep == 4) {
Serial.println("Waiting for 3s Hold...");
unsigned long holdStart = millis();
while (digitalRead(BUTTON_PIN) == LOW) {
if (millis() - holdStart >= HOLD_TIME) {
Serial.println("3s Hold Confirmed → STEP 1");
currentStep = 0;
updateIndicators();
int target = steps[currentStep];
if (target > last_Step) {
for (int i = last_Step; i <= target; i++) {
analogWrite(PWM_PIN, i);
delay(4);
}
} else {
for (int i = last_Step; i >= target; i--) {
analogWrite(PWM_PIN, i);
delay(4);
}
}
last_Step = target;
timerStartTime = millis();
timerRunning = true;
Serial.println("Timer Started: 5 Minutes");
// IMPORTANT FIX
longPressHandled = true;
tapCount = 0;
lastReleaseTime = 0;
delay(300);
return;
}
}
Serial.println("Hold Failed");
}
}
// ===== SINGLE TAP =====
else if (tapCount == 1) {
// Ignore single tap if OFF
if (currentStep != 4) {
nextStep();
} else {
Serial.println("OFF Mode - Single tap ignored");
}
}
tapCount = 0;
}
lastButtonState = buttonState;
// ===== TIMER CHECK =====
if (timerRunning && currentStep != 4) {
if (millis() - timerStartTime >= timerDuration) {
Serial.println("Timer Finished → Auto OFF");
currentStep = 4;
analogWrite(PWM_PIN, 0);
updateIndicators();
timerRunning = false;
}
}
}
/************* STEP CONTROL *************/
void nextStep() {
currentStep++;
if (currentStep > 4) {
currentStep = 0;
}
updateIndicators();
int target = steps[currentStep];
if (target > last_Step) {
for (int i = last_Step; i <= target; i++) {
analogWrite(PWM_PIN, i);
delay(4);
}
} else {
for (int i = last_Step; i >= target; i--) {
analogWrite(PWM_PIN, i);
delay(4);
}
}
last_Step = target;
if (currentStep != 4) {
timerStartTime = millis();
timerRunning = true;
Serial.println("Timer Restarted: 5 Minutes");
}
}
/************* LED INDICATORS *************/
void updateIndicators() {
digitalWrite(LED1, LOW);
digitalWrite(LED2, LOW);
digitalWrite(LED3, LOW);
digitalWrite(LED4, LOW);
if (currentStep == 0) digitalWrite(LED1, HIGH);
if (currentStep == 1) digitalWrite(LED2, HIGH);
if (currentStep == 2) digitalWrite(LED3, HIGH);
if (currentStep == 3) digitalWrite(LED4, HIGH);
}