В прошлом эксперименте мы уже сделали Wi-Fi RGB-ночник. Это светодиод яркостью и цветом которого можно управлять по Wi-Fi. Его можно использовать в качестве ночника. Но в нем есть один недостаток — нет наглядного выбора цвета. Для установки цвета нам нужно вводить три цифры, три яркости R, G и B. Заранее сложно предсказать какой цвет получится в результате ввода цифр. Также не понятно какие цифры нужно вводить, чтобы получить оранжевый, бирюзовый и другие цвета.
Для упрощения выбора цветов в веб-формах есть специальные типы полей ввода. Например есть текстовые поля, есть кнопки, есть выпадающие списки. Есть и специальное поле для ввода цвета с наглядной палитрой. Можно использовать этот элемент формы для ввода цвета и у нас. Единственная проблема — в HTML принято записывать цвет совсем не так, как мы его устанавливаем в своих программах.
Мы устанавливаем яркость светодиода с помощью сигнала ШИМ со значением от 0 до 1023. А в HTML цвет записывается с помощью 6 шестнадцатеричных символов и символа # перед ними. Например
Первые 2 символа отвечают за красный цвет, вторые два за зеленый и последние за синий цвет. Цвета могут принимать значения от 00 до FF. Это запись в шестнадцатеричной системе счисления чисел от 0 до 255.
Поэтому нам необходимо конвертировать цвет из формата записи в HTML в наш формат трех чисел от 0 до 255.
Код программы:
#include <ESP8266WiFi.h> #include <ESP8266WebServer.h> #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); String page = "<!DOCTYPE html>"; page += "<html>"; page += "<head>"; page += "</head>"; page += "<body>"; page += "<h3>Select color:</h3>"; page += R"(<form action="/">)"; page += R"(<input type="color" style="height:50px;width:50%;" value="<=VALUE=>" name="color">)"; page += R"(<input type="submit" value="Send">)"; page += "</form>"; page += "</body>"; page += "</html>"; page.replace("<=VALUE=>", html_color); server.send(200, "text/html", page); } void setup() { analogWriteRange(256); WiFi.mode(WIFI_STA); WiFi.begin(WIFI_NAME, WIFI_PASSWORD); while (WiFi.status() != WL_CONNECTED) { } 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);
Вот так это выглядит у нас. Но отображение может быть разным в зависимости от браузера.
Теперь управлять цветом светодиода легко и наглядно.