#include <LiquidCrystal.h>
#define BTN_UP 2
#define BTN_LEFT 3
#define BTN_OK 4
#define BTN_RIGHT 13
#define BTN_DOWN 6
#define PHOTOR A0
#define LED 5
LiquidCrystal lcd(12, 11, 10, 9, 8, 7);
enum StateMachine { Menu, Led, Photo, Brightness, ProgressBar };
StateMachine state = Menu;
String names[5] = {"Led", "Photo", "Brightness", "Prog.Bar"};
String leds[4] = {"OFF", "ON", "BLINK", "BEACON"};
int ledMode = 0;
int bright = 255;
bool photoAuto = false;
int photoValue = 0;
bool UpWas = true, DownWas = true, LeftWas = true, RightWas = true, OkWas = true;
unsigned long timer = 0;
int index = 0;
void setup() {
lcd.begin(16, 2);
pinMode(BTN_UP, INPUT_PULLUP);
pinMode(BTN_DOWN, INPUT_PULLUP);
pinMode(BTN_LEFT, INPUT_PULLUP);
pinMode(BTN_RIGHT, INPUT_PULLUP);
pinMode(BTN_OK, INPUT_PULLUP);
pinMode(LED, OUTPUT);
}
void loop() {
readPhotoSensor();
updateLed();
switch (state) {
case Menu: setMenu(); break;
case Led: setLed(); break;
case Photo: setPhoto(); break;
case Brightness: setBrightness(); break;
case ProgressBar: setProgressBar(); break;
}
}
void readPhotoSensor() {
photoValue = analogRead(PHOTOR);
}
void updateLed() {
int autoBright = map(photoValue, 0, 1023, 0, 255);
switch (ledMode) {
case 0: // OFF
analogWrite(LED, 0);
break;
case 1: // ON
analogWrite(LED, photoAuto ? autoBright : bright);
break;
case 2: // Blink
if (millis() - timer < 1000)
analogWrite(LED, photoAuto ? autoBright : bright);
else
analogWrite(LED, 0);
if (millis() - timer >= 2000) timer = millis();
break;
case 3: // Beacon
if (millis() - timer < 100)
analogWrite(LED, photoAuto ? autoBright : bright);
else
analogWrite(LED, 0);
if (millis() - timer >= 1000) timer = millis();
break;
}
}
void setMenu() {
lcd.setCursor(0, 0);
lcd.print("Menu");
lcd.setCursor(0, 1);
lcd.print(names[index]);
for (int i = names[index].length(); i < 16; i++) lcd.print(" ");
bool up = digitalRead(BTN_UP);
if (up != UpWas && !up) index = (index + 1) % 4;
UpWas = up;
bool down = digitalRead(BTN_DOWN);
if (down != DownWas && !down) index = (index == 0 ? 3 : index - 1);
DownWas = down;
bool ok = digitalRead(BTN_OK);
if (ok != OkWas && !ok) {
state = (StateMachine)(index + 1);
lcd.clear();
}
OkWas = ok;
}
void setLed() {
lcd.setCursor(0, 0);
lcd.print("LED Mode:");
lcd.setCursor(0, 1);
lcd.print(leds[ledMode]);
for (int i = leds[ledMode].length(); i < 16; i++) lcd.print(" ");
bool right = digitalRead(BTN_RIGHT);
if (right != RightWas && !right) ledMode = (ledMode + 1) % 4;
RightWas = right;
bool left = digitalRead(BTN_LEFT);
if (left != LeftWas && !left) ledMode = (ledMode == 0 ? 3 : ledMode - 1);
LeftWas = left;
bool ok = digitalRead(BTN_OK);
if (ok != OkWas && !ok) { state = Menu; lcd.clear(); }
OkWas = ok;
}
void setPhoto() {
lcd.setCursor(0, 0);
lcd.print("Photo:");
lcd.print(photoAuto ? "Auto " : "Manual");
lcd.setCursor(0, 1);
lcd.print(photoValue);
lcd.print(" ");
bool right = digitalRead(BTN_RIGHT);
if (right != RightWas && !right) photoAuto = true;
RightWas = right;
bool left = digitalRead(BTN_LEFT);
if (left != LeftWas && !left) photoAuto = false;
LeftWas = left;
bool ok = digitalRead(BTN_OK);
if (ok != OkWas && !ok) { state = Menu; lcd.clear(); }
OkWas = ok;
}
void setBrightness() {
lcd.setCursor(0, 0);
lcd.print("Brightness:");
int percent = bright * 100 / 255;
lcd.setCursor(0, 1);
lcd.print(percent); lcd.print("% ");
bool right = digitalRead(BTN_RIGHT);
if (right != RightWas && !right && !photoAuto && bright < 255) bright += 5;
RightWas = right;
bool left = digitalRead(BTN_LEFT);
if (left != LeftWas && !left && !photoAuto && bright > 0) bright -= 5;
LeftWas = left;
bool ok = digitalRead(BTN_OK);
if (ok != OkWas && !ok) { state = Menu; lcd.clear(); }
OkWas = ok;
}
void setProgressBar() {
lcd.setCursor(0, 0);
lcd.print("Light Level");
int percent = map(photoValue, 0, 1023, 0, 100);
int bars = percent / 10;
lcd.setCursor(0, 1);
for (int i = 0; i < 10; i++) lcd.write(i < bars ? 255 : ' ');
lcd.print(" ");
lcd.print(percent);
lcd.print(" %");
bool ok = digitalRead(BTN_OK);
if (ok != OkWas && !ok) { state = Menu; lcd.clear(); }
OkWas = ok;
}