#include <Arduino.h>
#include <SevenSegmentTM1637.h>
#include <SevenSegmentExtended.h>
// ================= DISPLAY =================
#define TM_CLK 26
#define TM_DIO 25
SevenSegmentExtended display(TM_CLK, TM_DIO);
// ================= BUTTONS =================
#define BTN_MENU 35
#define BTN_UP 34
#define BTN_DOWN 33
#define BTN_ENTER 32
#define BTN_CHSEL 4
// ================= CHANNEL 1 =================
#define CH1_R 27
#define CH1_G 14
#define CH1_B 12
#define CH1_W 13
// ================= CHANNEL 2 =================
#define CH2_R 21
#define CH2_G 19
#define CH2_B 18
#define CH2_W 5
// ================= STATUS LED =================
#define LED_CH1 22
#define LED_CH2 23
// ================= MENU =================
enum MenuItem {
MENU_P = 0,
MENU_S,
MENU_C,
MENU_U,
MENU_TOTAL
};
MenuItem currentMenu = MENU_P;
bool editMode = false;
int activeChannel = 0;
// ================= CHANNEL SETTINGS =================
struct ChannelSetting {
int program;
int speed;
int color;
int sound;
};
ChannelSetting channels[2] = {
{1,5,1,5},
{1,5,1,5}
};
// ================= DEBOUNCE =================
unsigned long lastMenuPress = 0;
unsigned long lastUpPress = 0;
unsigned long lastDownPress = 0;
unsigned long lastEnterPress = 0;
unsigned long lastChPress = 0;
const int debounceDelay = 180;
// ================= BLINK =================
unsigned long blinkTimer = 0;
bool blinkState = true;
const int blinkInterval = 400;
// ================= FUNCTIONS =================
bool pressed(int pin, unsigned long &last);
void updateDisplay();
void showMenu(char letter,int value);
void showValue(int value);
void printStatus();
void handleButtons();
void updateStatusLED();
// ================= SETUP =================
void setup(){
Serial.begin(115200);
pinMode(BTN_MENU,INPUT);
pinMode(BTN_UP,INPUT);
pinMode(BTN_DOWN,INPUT);
pinMode(BTN_ENTER,INPUT);
pinMode(BTN_CHSEL,INPUT);
pinMode(CH1_R,OUTPUT);
pinMode(CH1_G,OUTPUT);
pinMode(CH1_B,OUTPUT);
pinMode(CH1_W,OUTPUT);
pinMode(CH2_R,OUTPUT);
pinMode(CH2_G,OUTPUT);
pinMode(CH2_B,OUTPUT);
pinMode(CH2_W,OUTPUT);
pinMode(LED_CH1,OUTPUT);
pinMode(LED_CH2,OUTPUT);
display.begin();
display.setBacklight(100);
display.clear();
Serial.println("PAR LIGHT CONTROLLER READY");
updateStatusLED();
updateDisplay();
}
// ================= LOOP =================
void loop(){
handleButtons();
updateDisplay();
}
// ================= BUTTON =================
bool pressed(int pin, unsigned long &last){
if(digitalRead(pin)==HIGH){
if(millis()-last > debounceDelay){
last = millis();
return true;
}
}
return false;
}
// ================= BUTTON HANDLER =================
void handleButtons(){
if(pressed(BTN_CHSEL,lastChPress)){
activeChannel = !activeChannel;
updateStatusLED();
printStatus();
}
if(!editMode){
if(pressed(BTN_MENU,lastMenuPress)){
currentMenu = (MenuItem)((currentMenu+1)%MENU_TOTAL);
printStatus();
}
if(pressed(BTN_ENTER,lastEnterPress)){
editMode = true;
blinkTimer = millis();
blinkState = true;
printStatus();
}
}
else{
if(pressed(BTN_UP,lastUpPress)){
switch(currentMenu){
case MENU_P:
channels[activeChannel].program++;
if(channels[activeChannel].program>8)channels[activeChannel].program=1;
break;
case MENU_S:
channels[activeChannel].speed++;
if(channels[activeChannel].speed>10)channels[activeChannel].speed=1;
break;
case MENU_C:
channels[activeChannel].color++;
if(channels[activeChannel].color>8)channels[activeChannel].color=1;
break;
case MENU_U:
channels[activeChannel].sound++;
if(channels[activeChannel].sound>10)channels[activeChannel].sound=1;
break;
}
printStatus();
}
if(pressed(BTN_DOWN,lastDownPress)){
switch(currentMenu){
case MENU_P:
channels[activeChannel].program--;
if(channels[activeChannel].program<1)channels[activeChannel].program=8;
break;
case MENU_S:
channels[activeChannel].speed--;
if(channels[activeChannel].speed<1)channels[activeChannel].speed=10;
break;
case MENU_C:
channels[activeChannel].color--;
if(channels[activeChannel].color<1)channels[activeChannel].color=8;
break;
case MENU_U:
channels[activeChannel].sound--;
if(channels[activeChannel].sound<1)channels[activeChannel].sound=10;
break;
}
printStatus();
}
if(pressed(BTN_ENTER,lastEnterPress)){
editMode=false;
printStatus();
}
}
}
// ================= DISPLAY =================
void updateDisplay(){
int value;
switch(currentMenu){
case MENU_P: value = channels[activeChannel].program; break;
case MENU_S: value = channels[activeChannel].speed; break;
case MENU_C: value = channels[activeChannel].color; break;
case MENU_U: value = channels[activeChannel].sound; break;
}
char letter;
switch(currentMenu){
case MENU_P: letter='P'; break;
case MENU_S: letter='S'; break;
case MENU_C: letter='C'; break;
case MENU_U: letter='U'; break;
}
if(editMode){
if(millis() - blinkTimer > blinkInterval){
blinkTimer = millis();
blinkState = !blinkState;
}
if(blinkState){
showValue(value);
}else{
display.clear();
}
}
else{
showMenu(letter,value);
}
}
// ================= SHOW MENU =================
void showMenu(char letter,int value){
char buffer[5];
sprintf(buffer,"%c%03d",letter,value);
display.clear();
display.print(buffer);
}
// ================= SHOW VALUE =================
void showValue(int value){
char buffer[4];
sprintf(buffer,"%03d",value);
display.clear();
display.print(buffer);
}
// ================= SERIAL STATUS =================
void printStatus(){
Serial.println("---------------");
Serial.print("CHANNEL: ");
Serial.println(activeChannel+1);
Serial.print("MENU: ");
switch(currentMenu){
case MENU_P: Serial.println("PROGRAM"); break;
case MENU_S: Serial.println("SPEED"); break;
case MENU_C: Serial.println("COLOR"); break;
case MENU_U: Serial.println("SOUND"); break;
}
Serial.print("EDIT MODE: ");
Serial.println(editMode);
Serial.print("Program: ");
Serial.println(channels[activeChannel].program);
Serial.print("Speed: ");
Serial.println(channels[activeChannel].speed);
Serial.print("Color: ");
Serial.println(channels[activeChannel].color);
Serial.print("Sound Sensitivity: ");
Serial.println(channels[activeChannel].sound);
Serial.println("---------------");
}
// ================= STATUS LED =================
void updateStatusLED(){
digitalWrite(LED_CH1, activeChannel==0);
digitalWrite(LED_CH2, activeChannel==1);
}SOUND SENSOR
MENU
ENTER
DOWN
UP