===== Эксперимент 63. RGB-ночник =====
В прошлом эксперименте мы уже сделали Wi-Fi RGB-ночник. Это светодиод яркостью и цветом которого можно управлять по Wi-Fi. Его можно использовать в качестве ночника. Но в нем есть один недостаток — нет наглядного выбора цвета. Для установки цвета нам нужно вводить три цифры, три яркости R, G и B. Заранее сложно предсказать какой цвет получится в результате ввода цифр. Также не понятно какие цифры нужно вводить, чтобы получить оранжевый, бирюзовый и другие цвета.
Для упрощения выбора цветов в веб-формах есть специальные типы полей ввода. Например есть текстовые поля, есть кнопки, есть выпадающие списки. Есть и специальное поле для ввода цвета с наглядной палитрой. Можно использовать этот элемент формы для ввода цвета и у нас. Единственная проблема — в HTML принято записывать цвет совсем не так, как мы его устанавливаем в своих программах.
Мы устанавливаем яркость светодиода с помощью сигнала ШИМ со значением от 0 до 1023. А в HTML цвет записывается с помощью 6 шестнадцатеричных символов и символа # перед ними. Например
{{ :products:esp-iot:2020-06-19_11-41-37.png?nolink |}}
Первые 2 символа отвечают за красный цвет, вторые два за зеленый и последние за синий цвет. Цвета могут принимать значения от 00 до FF. Это запись в шестнадцатеричной системе счисления чисел от 0 до 255.
{{ :products:esp-iot:html_color.png?nolink |}}
Поэтому нам необходимо конвертировать цвет из формата записи в HTML в наш формат трех чисел от 0 до 255.
==== Схема эксперимента ====
Схема эксперимента остается без изменений
{{ :products:esp-iot:exp35_mont.png?direct&600 |}}
//Рисунок 1. Монтажная схема эксперимента//
==== Программный код эксперимента ====
Select color:
Код программы:
#include
#include
#define WIFI_NAME "WiFi_Name"
#define WIFI_PASSWORD "WiFi_Password"
#define PIN_LED_R 13
#define PIN_LED_G 14
#define PIN_LED_B 15
ESP8266WebServer server(80);
void indexPage() {
String html_color = "#4AD686";
if (server.hasArg("color")) html_color = server.arg("color");
int duty_r = strtol(html_color.substring(1,3).c_str(), NULL, 16);
int duty_g = strtol(html_color.substring(3,5).c_str(), NULL, 16);
int duty_b = strtol(html_color.substring(5).c_str(), NULL, 16);
analogWrite(PIN_LED_R, 255 - duty_r);
analogWrite(PIN_LED_G, 255 - duty_g);
analogWrite(PIN_LED_B, 255 - duty_b);
String page = "";
page += "";
page += "";
page += "";
page += "";
page += "Select color:
";
page += R"(";
page += "";
page += "";
page.replace("<=VALUE=>", html_color);
server.send(200, "text/html", page);
}
void setup() {
Serial.begin(9600);
Serial.println();
pinMode(PIN_LED_R, OUTPUT);
pinMode(PIN_LED_G, OUTPUT);
pinMode(PIN_LED_B, OUTPUT);
analogWriteRange(256);
analogWrite(PIN_LED_R, 255);
analogWrite(PIN_LED_G, 255);
analogWrite(PIN_LED_B, 255);
Serial.print("Connecting to WiFi");
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_NAME, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(500);
}
Serial.println();
Serial.println("WiFi connected");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
server.on("/", indexPage);
server.begin();
}
void loop() {
server.handleClient();
}
Первым делом в коде программы нужно заменить ''WiFi_Name'' на имя нужной сети, а ''WiFi_Password'' на пароль от нее.
Рассмотрим алгоритм преобразования цвета. Веб форма отправляет на наш сервер цвет в формате #FFFFFF и получает аналогичный ответ.
String html_color = "#4AD686";
if (server.hasArg("color")) html_color = server.arg("color");
Теперь в переменной ''html_color'' находится цвет в формате ''#FFFFFF''.
Для получения нужной пары символов используем метод получения подстроки ''substring()'', первый аргумент которого указывает на позицию начала подстроки, а второй — на конец (не включая). Если второй аргумент не указан, то концом подстроки считается конец строки. Полученную подстроку, преобразовав с помощью метода ''c_str()'', передаем в качестве первого аргумента в специальную функцию ''strtol()'', которая преобразует нашу пару символов в число от 0 до 255. Подробно на работе функции ''strtol()'' и метода ''c_str()'' останавливаться не будем.
int duty_r = strtol(html_color.substring(1,3).c_str(), NULL, 16);
int duty_g = strtol(html_color.substring(3,5).c_str(), NULL, 16);
int duty_b = strtol(html_color.substring(5).c_str(), NULL, 16);
Теперь мы имеем данные для управления ШИМ сигналом светодиода. Остается только не забыть, что светодиод с общим анодом, поэтому для получения нужного результата наши значения нужно вычесть из 255.
analogWrite(PIN_LED_R, 255 - duty_r);
analogWrite(PIN_LED_G, 255 - duty_g);
analogWrite(PIN_LED_B, 255 - duty_b);
При выводе страницы в браузер мы должны заменить метку в шаблоне страницы на актуальный цвет.
page.replace("<=VALUE=>", html_color);
Вот так это выглядит у нас. Но отображение может быть разным в зависимости от браузера.
{{ :products:esp-iot:7d8dda73-4239-44a1-a25b-f244770df093.jpg?nolink |}}
{{ :products:esp-iot:0bf3e531-1c1c-4b60-8add-666ffc6c9045.jpg?nolink |}}
Теперь управлять цветом светодиода легко и наглядно.