#include <Wire.h>
#include <LiquidCrystal_I2C.h>
const int irPin = 3;
const int redPin = 4;
const int greenPin = 5;
const int bluePin = 6;
const int uv365Pin = 7;
const int uv390Pin = 8;
const int halogenPin = 9;
const int switchPin = 10; // Define the switch pin
const int xPin = A0;
const int yPin = A1;
const int buttonPin = 2;
LiquidCrystal_I2C lcd(0x27, 16, 2);
int selectedCase = 0;
int selectedTime = 1;
bool manualControl = false; // Flag for manual control
void setup() {
pinMode(irPin, OUTPUT);
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
pinMode(uv365Pin, OUTPUT);
pinMode(uv390Pin, OUTPUT);
pinMode(halogenPin, OUTPUT);
pinMode(switchPin, INPUT); // Set switch pin as input
pinMode(buttonPin, INPUT); // Set joystick button pin as input
lcd.init();
lcd.backlight();
Serial.begin(9600);
displayMenu(); // Initial display update
}
void loop() {
if (digitalRead(switchPin) == HIGH) { // Check if switch is high
manualControl = false; // Disable manual control
static int lastSelectedCase = -1;
static int lastSelectedTime = -1;
readJoystick();
// Update display only if there's a change in selected case or time
if (selectedCase != lastSelectedCase || selectedTime != lastSelectedTime) {
turnOffAllLights(); // Turn off all lights when changing case or time
displayMenu();
lastSelectedCase = selectedCase;
lastSelectedTime = selectedTime;
}
handleCase();
} else {
manualControl = true; // Enable manual control
readJoystickManual();
}
}
void readJoystick() {
int xValue = analogRead(xPin);
int yValue = analogRead(yPin);
// Change selected case
if (xValue < 400) {
selectedCase = (selectedCase + 1) % 11; // Update for 11 cases
delay(200); // debounce delay
} else if (xValue > 600) {
selectedCase = (selectedCase - 1 + 11) % 11; // Update for 11 cases
delay(200); // debounce delay
}
// Change selected time
if (yValue < 400) {
selectedTime = changeTime(selectedTime, -1);
delay(200); // debounce delay
} else if (yValue > 600) {
selectedTime = changeTime(selectedTime, 1);
delay(200); // debounce delay
}
}
void readJoystickManual() {
int xValue = analogRead(xPin);
static int lastButtonState = HIGH;
int buttonState = digitalRead(buttonPin);
// Change selected case
if (xValue < 400) {
selectedCase = (selectedCase + 1) % 7; // Update for 7 cases
displayMenu(); // Update display immediately
delay(200); // debounce delay
} else if (xValue > 600) {
selectedCase = (selectedCase - 1 + 7) % 7; // Update for 7 cases
displayMenu(); // Update display immediately
delay(200); // debounce delay
}
// Button press to toggle selected light
if (buttonState == LOW && lastButtonState == HIGH) {
toggleSelectedLight(selectedCase);
delay(200); // debounce delay
}
lastButtonState = buttonState;
}
void toggleSelectedLight(int caseNum) {
int pin;
switch (caseNum) {
case 0: pin = irPin; break;
case 1: pin = redPin; break;
case 2: pin = greenPin; break;
case 3: pin = bluePin; break;
case 4: pin = uv365Pin; break;
case 5: pin = uv390Pin; break;
case 6: pin = halogenPin; break;
default: return;
}
digitalWrite(pin, !digitalRead(pin)); // Toggle the selected light
}
int changeTime(int current, int change) {
int times[] = {1, 5, 10, 20, 20};
int index = 0;
for (int i = 0; i < 5; i++) {
if (times[i] == current) {
index = i;
break;
}
}
index = (index + change + 5) % 5;
return times[index];
}
void displayMenu() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Mode:");
lcd.print(caseName(selectedCase));
lcd.setCursor(0, 1);
lcd.print("Time: ");
lcd.print(selectedTime);
lcd.print("s");
}
const char* caseName(int caseNum) {
switch (caseNum) {
case 0: return "IR940";
case 1: return "Red";
case 2: return "Green";
case 3: return "Blue";
case 4: return "UV365";
case 5: return "UV390";
case 6: return "Halogen";
case 7: return "Sequence";
case 8: return "I_R_G_B_UV";
case 9: return "R_G_B_";
case 10: return "Cycle 5 times";
default: return "";
}
}
void handleCase() {
static unsigned long previousMillis = 0;
static bool lightState = false;
static int toggleCount = 0;
unsigned long currentMillis = millis();
unsigned long interval = selectedTime * 1000;
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
lightState = !lightState;
toggleCount++;
switch (selectedCase) {
case 0:
toggleSingleLight(irPin, lightState);
break;
case 1:
toggleSingleLight(redPin, lightState);
break;
case 2:
toggleSingleLight(greenPin, lightState);
break;
case 3:
toggleSingleLight(bluePin, lightState);
break;
case 4:
toggleSingleLight(uv365Pin, lightState);
break;
case 5:
toggleSingleLight(uv390Pin, lightState);
break;
case 6:
toggleSingleLight(halogenPin, lightState);
break;
case 7:
toggleSequence(lightState);
break;
case 8:
toggleAllLightsInSequence(lightState, false);
break;
case 9:
toggleAllLightsInSequence(lightState, true);
break;
case 10:
toggleCycleLights(lightState, toggleCount);
break;
}
}
}
void turnOffAllLights() {
int pins[] = {irPin, redPin, greenPin, bluePin, uv365Pin, uv390Pin, halogenPin};
for (int i = 0; i < 7; i++) {
digitalWrite(pins[i], LOW);
}
}
void toggleSingleLight(int pin, bool state) {
int pins[] = {irPin, redPin, greenPin, bluePin, uv365Pin, uv390Pin, halogenPin};
for (int i = 0; i < 7; i++) {
if (pins[i] == pin) {
digitalWrite(pins[i], state ? HIGH : LOW);
} else {
digitalWrite(pins[i], LOW);
}
}
}
void toggleSequence(bool state) {
static int currentLight = 0;
int pins[] = {irPin, redPin, greenPin, bluePin, uv365Pin, uv390Pin};
if (state) {
digitalWrite(pins[currentLight], HIGH);
} else {
digitalWrite(pins[currentLight], LOW);
currentLight = (currentLight + 1) % 6;
digitalWrite(pins[currentLight], HIGH); // Turn on the next light immediately
}
}
void toggleAllLightsInSequence(bool state, bool rgbOnly) {
static int currentLight = 0;
int allPins[] = {irPin, redPin, greenPin, bluePin, uv365Pin, uv390Pin};
int rgbPins[] = {redPin, greenPin, bluePin};
int* pins;
int pinCount;
if (rgbOnly) {
pins = rgbPins;
pinCount = 3;
} else {
pins = allPins;
pinCount = 6;
}
if (state) {
digitalWrite(pins[currentLight], HIGH);
} else {
digitalWrite(pins[currentLight], LOW);
currentLight = (currentLight + 1) % pinCount;
}
}
void toggleCycleLights(bool state, int count) {
int pins[] = {irPin, redPin, greenPin, bluePin, uv365Pin, uv390Pin};
static int currentIndex = 0;
static int toggleStep = 0;
static unsigned long lastToggleTime = 0;
unsigned long currentMillis = millis();
int toggleInterval = selectedTime * 1000 ; // Time per toggle step
if (currentMillis - lastToggleTime >= toggleInterval) {
lastToggleTime = currentMillis;
digitalWrite(pins[currentIndex], state ? HIGH : LOW);
// Increment toggle step
if (toggleStep < 10) {
toggleStep++;
} else {
toggleStep = 0;
// Move to the next light
digitalWrite(pins[currentIndex], LOW);
currentIndex = (currentIndex + 1) % 6;
}
}
}