#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); // Адрес I2C и размер дисплея
const int LIGHT_SENSOR_PIN = A0; // Аналоговый пин датчика света
const int RELAY_PIN = 13; // Пин реле
const float GAMMA = 0.7;
const float RL10 = 50;
int lastLightLevel = -1;
int lastPowerLevel = -1;
void setup() {
Serial.begin(9600);
lcd.init();
lcd.backlight();
pinMode(RELAY_PIN, OUTPUT);
updateDisplay();
}
void loop() {
static unsigned long lastCheck = 0;
if (millis() - lastCheck >= 3000) {
lastCheck = millis();
updateDisplay();
}
}
void updateDisplay() {
int analogValue = analogRead(LIGHT_SENSOR_PIN);
float voltage = analogValue / 1024. * 5;
float resistance = 2000 * voltage / (1 - voltage / 5);
float lightLevel = pow(RL10 * 1e3 * pow(10, GAMMA) / resistance, (1 / GAMMA));
if (!isfinite(lightLevel)) {
lightLevel = 100000; // Ограничиваем максимальное значение до 100000 люксов
}
int powerLevel = getLampPowerLevel(lightLevel);
float outputVoltage = map(powerLevel, 0, 7, 0, 120) / 10.0; // Преобразуем в напряжение (0-12В)
if (lightLevel != lastLightLevel || powerLevel != lastPowerLevel) {
lastLightLevel = lightLevel;
lastPowerLevel = powerLevel;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Light: ");
lcd.print(lightLevel);
lcd.print(" lx");
lcd.setCursor(0, 1);
lcd.print("Lamp: ");
lcd.print(map(powerLevel, 0, 7, 0, 100));
lcd.print("% ");
lcd.print(outputVoltage, 1);
lcd.print("V");
analogWrite(RELAY_PIN, map(powerLevel, 0, 7, 0, 255));
Serial.print("Уровень света: ");
Serial.print(lightLevel);
Serial.println(" lx");
Serial.print("Уровень мощности лампы: ");
Serial.print(map(powerLevel, 0, 7, 0, 100));
Serial.print("% (");
Serial.print(outputVoltage, 1);
Serial.println("V)");
Serial.print("Интенсивность света: ");
Serial.println(getLightIntensity(lightLevel));
Serial.println();
}
}
int getLampPowerLevel(float lux) {
if (lux < 10) return 0; // 0-1.5V
if (lux < 40) return 1; // 1.5-3V
if (lux < 300) return 2; // 3-4.5V
if (lux < 1000) return 3; // 4.5-6V
if (lux < 2000) return 4; // 6-7.5V
if (lux < 10000) return 5; // 7.5-9V
if (lux < 80000) return 6; // 9-10.5V
return 7; // 10.5-12V
}
String getLightIntensity(float lux) {
if (lux > 80000) return "Самый яркий солнечный свет";
if (lux > 10000) return "Солнечный свет в ясную погоду";
if (lux > 2000) return "Тень под прозрачным синим небом в ясный полдень";
if (lux > 1000) return "Типичный пасмурный день, полдень";
if (lux > 300) return "Восход или закат в ясный день";
if (lux >= 40) return "Плотные тёмные грозовые облака, полдень";
if (lux >= 10) return "Пасмурный восход или закат";
return "Ночь";
}