# Адаптивное освещение
При снижении уровня освещения можно компенсировать недостаток света увеличивающейся яркостью лампы.
Чтобы в полной темноте лампа горела на полной яркости, а на свету светила на минимальной яркости или вообще выключалась.
Также следует предусмотреть режим, когда по внешней команде можно будет изменять яркость вручную.
Для измерения уровня освещения используется фоторезистор, например, VT93N2 [[Datasheet](http://www.farnell.com/datasheets/919043.pdf)].
![](/assets/images/iot/sens_photores.jpg)
**Спецификация:**
| Параметр | Значение |
| ------------------------------------|----------------|
| максимальная потребляемая мощность | 100 мВт |
| спектральный пик | 540 нм |
| сопротивление при освещении 10 люкс | от 2 до 5 кОм |
| сопротивления в темноте | 500 кОм |
### Схема подключения
Для измерения сопротивления фоторезистора используется аналоговый вход A0 микроконтроллера.
Потребуется построить небольшую схему, содержащую делитель напряжения из фоторезистора.
![](/assets/images/iot/02/light_analog_shema.svg)
Используемый нами модуль с фоторезистором содержит дополнительные элементы (будут нужны в другой задаче), но при этом позволяет использовать фоторезистор напрямую.
![](/assets/images/iot/pht_module.jpg)
| Модуль | WeMos D1 |
|--------|----------|
| AO | A0 |
| GND | GND |
![](/assets/images/iot/02/light_analog.svg "Схема подключения")
Для считывания показаний достаточно использовать функцию `analogRead(A0)`, которая возвращает число в диапазоне от 0 до 1024 (напряжение от 0 до 3.3 вольта).
Для изменения яркости свечения будем использовать ШИМ регулирование.
В случае с ESP8266 функция [analogWrite](https://www.arduino.cc/reference/en/language/functions/analog-io/analogwrite/) в качестве второго параметра принимает значения от 0 до 1023.
### Пример программы
```c
#define LED_PIN D2
#define MAX_LEVEL 800 // Значение АЦП при максимальной освещенности
#define MIN_LEVEL 125 // Значение АЦП при минимальной освещенности
int delayMS = 100; // Переиод в мс
long lastMS = 0;
void setup() {
pinMode(LED_PIN, OUTPUT);
Serial.begin(115200);
}
void loop() {
if ( millis() - lastMS > delayMS) {
// Считываем значение освещенности
int lightness = analogRead(A0);
Serial.print("Read ");
Serial.println(lightness);
lightness = lightness - MIN_LEVEL;
if (lightness < 0)
lightness = 0;
lightness = lightness * 1024 / MAX_LEVEL;
if (lightness > 1023)
lightness = 1023;
// Управляем светодиодом
analogWrite(LED_PIN, lightness);
Serial.print("Write ");
Serial.println(lightness);
lastMS = millis();
}
}
```
### Итоговое устройство
![](/assets/images/iot/02/light_analog.jpg)
## Задача
Написать прошивку, которая
1. будет измерять текущий уровень освещенности и направлять его числом в топик **itschool/alight/status**;
2. рассчитывать дополнительную яркость (логику придумайте самостоятельно) и направлять её в топик **itschool/alight/pwm_value**, заодно изменяя яркость светодиода (он будет выступать в роли лампы);
3. при получении числа до 1024 в топик **itschool/alight/pwm_override **будет изменять на 10 секунд яркость светодиода, а потом возвращаться к прежнему алгоритму управления.
[к списку задач](iot/summer/tasks)