#include <LiquidCrystal_I2C.h>
#include <Button.h>
#define I2C_ADDR 0x27
#define LCD_COLUMNS 20
#define LCD_LINES 4
LiquidCrystal_I2C lcd(I2C_ADDR, LCD_COLUMNS, LCD_LINES);
const byte motionSensor = 13;
const byte leds[3] = { 9, 10, 11 };
const byte photoresistor = A0;
const byte potensiometer = A1;
Button autoBrightnessBtn(4);
const byte autoBrightnessLed = 3;
Button motionBtn(6);
const byte motionLed = 5;
bool autoBrightness = true;
int lastPotensBrightness = 0;
int lastBrightness = 0;
bool motionDetection = true;
void setLedBrightness(int brightness) {
for (byte i=0; i<3; i++) {
analogWrite(leds[i], brightness);
}
}
int brightnessByPhotoresistor() {
int light = analogRead(photoresistor);
light = constrain(light, 8, 1016);
light = map(light, 8, 1016, 0, 255);
return light;
}
int brightnessByPotens(){
int light = analogRead(potensiometer);
light = constrain(light, 0, 1023);
return map(light, 0, 1023, 0, 255);
}
bool isPotensChanged(int brightness) {
return brightness != lastPotensBrightness;
}
void checkPotens() {
int potensBrightness = brightnessByPotens();
if (isPotensChanged(potensBrightness)){
lastPotensBrightness = potensBrightness;
autoBrightness = false;
digitalWrite(autoBrightnessLed, autoBrightness ? HIGH : LOW);
}
}
void checkAutobrightness() {
if (autoBrightnessBtn.pressed()) {
autoBrightness = !autoBrightness;
digitalWrite(autoBrightnessLed, autoBrightness ? HIGH : LOW);
Serial.print("Auto brightness: ");
Serial.println(autoBrightness ? "ON" : "OFF");
// lastBrightnessBtnState = btnState;
}
}
void checkMotion() {
if (motionBtn.pressed()) {
motionDetection = !motionDetection;
digitalWrite(motionLed, motionDetection ? HIGH : LOW);
Serial.print("Motion detection: ");
Serial.println(motionDetection ? "ON" : "OFF");
}
}
void lcdInit() {
lcd.setCursor(0, 0);
lcd.print("Auto brightness: ");
lcd.setCursor(0, 1);
lcd.print("Detect motion: ");
lcd.setCursor(0, 3);
lcd.print("Brightness: ");
}
void lcdPrintAutobrightness() {
lcd.setCursor(17, 0);
lcd.print(autoBrightness ? "ON " : "OFF");
}
void lcdPrintMotion() {
lcd.setCursor(15, 1);
lcd.print(motionDetection ? "ON " : "OFF");
}
void lcdPrintBrightness(int brightness) {
long brightnessPercentage = map(brightness, 0, 255, 0, 100);
lcd.setCursor(12, 3);
lcd.print(brightnessPercentage);
if (brightnessPercentage > 9 && brightnessPercentage <= 99) {
lcd.setCursor(14, 3);
lcd.print("% ");
}
else if (brightnessPercentage > 99) {
lcd.setCursor(15, 3);
lcd.print("%");
}
else{
lcd.setCursor(13, 3);
lcd.print("% ");
}
}
void lcdPrintParams(int brightness) {
lcdPrintAutobrightness();
lcdPrintMotion();
lcdPrintBrightness(brightness);
}
void changeBrightnessSlowly(int currentBrightness, int targetBrightness) {
int brightness = currentBrightness;
double e = 0.5;
while (brightness < targetBrightness - e || brightness > targetBrightness + e) {
if (currentBrightness > targetBrightness) {
brightness--;
}
else if(currentBrightness < targetBrightness) {
brightness++;
}
setLedBrightness(brightness);
lcdPrintBrightness(brightness);
delay(2);
}
}
void setup() {
Serial.begin(9600);
for (byte i=0; i<3; i++) {
pinMode(leds[i], OUTPUT);
}
pinMode(motionSensor, INPUT);
pinMode(photoresistor, INPUT);
pinMode(potensiometer, INPUT);
autoBrightnessBtn.begin();
motionBtn.begin();
pinMode(autoBrightnessLed, OUTPUT);
pinMode(motionLed, OUTPUT);
lcd.init();
// lcd.backlight();
lcdInit();
digitalWrite(autoBrightnessLed, autoBrightness ? HIGH : LOW);
digitalWrite(motionLed, motionDetection ? HIGH : LOW);
}
void loop() {
checkAutobrightness();
checkMotion();
int brightness = 0;
int potensBrightness = brightnessByPotens();
if (isPotensChanged(potensBrightness)){
lastPotensBrightness = potensBrightness;
autoBrightness = false;
digitalWrite(autoBrightnessLed, autoBrightness ? HIGH : LOW);
}
if (autoBrightness) {
brightness = brightnessByPhotoresistor();
}
else {
brightness = potensBrightness;
}
if (motionDetection && digitalRead(motionSensor) == LOW) {
brightness = 0;
}
if(motionDetection) {
lcdPrintMotion();
changeBrightnessSlowly(lastBrightness, brightness);
}
else {
setLedBrightness(brightness);
}
lastBrightness = brightness;
lcdPrintParams(brightness);
}