ESP12: Управление RGB-светодиодом (Веб-сервер)

Описание

В данном проекте производится управление RGB-светодиодом. Модуль RGB-светодиода подключен к контролеру. Мы сможем с сайта управлять цветом его свечения, либо отключать светодиод полностью. Таким образом WiFi модуль будет являться веб-сервером для управления модулем.

В дальнейшем, Вы можете подключать к контроллеру любые устройства, которыми требуется управлять и влиять на них с сайта.

Изначально WiFi модуль настроен на работу с помощью AT-команд. Но вручную писать AT-команды очень неудобно, по нескольким причинам:

  • Очень велика вероятность ошибиться и ввести неверную AT-команду
  • Разбор ответа от контроллера будет довольно ёмким
  • Скетч будет трудно-читаемым из-за огромного количества кода
  • Сложно выявить ошибки

Поэтому, чтобы общение с модулем было наиболее эффективным, простым и быстрым, мы воспользуемся библиотекой WiFiEsp

Скачайте и установите данную библиотеку в среду разработки Arduino IDE.

Перед началом работы настройте модуль на скорость обмена в 9600 бод. О том как это сделать, рассказано на этой странице.

Шаг 1. Вам потребуется

Возьмите необходимые для проекта элементы, представленные в таблице ниже.

Шаг 2. Подключите Wifi модуль к шилду

Выполните подключение модуля в соответствии со схемой ниже.

Шаг 3. Загрузите скетч на контроллер

Загрузите скетч, представленный ниже, на контроллер. Предварительно измените значения переменных:

  • char ssid[] - здесь должно быть Ваше имя WiFi сети
  • char pass[] - здесь должен быть пароль от Вашей WiFi сети
  • rgb_pins[] - вывод контроллера, к которым подключены цвета светодиода: красный, зелёный и синий
#include "WiFiEsp.h" //подключение библиотеки WiFiEsp
 
// Эмуляция Serial соединения
#ifndef HAVE_HWSERIAL1
#include "SoftwareSerial.h"
SoftwareSerial wifiSerial(6, 7); // RX, TX
#endif
 
char ssid[] = "SmartElements"; //имя сети wifi
char pass[] = "1234567890"; //пароль от сети wifi
int status = WL_IDLE_STATUS; //статус сети wifi
const int rgb_pins[] = {3, 4, 5}; //выводы RGB светодиода
boolean rgb_states[] = {false, false, false}; //состояние выводов
 
WiFiEspServer server(80); //пересенная для создания объекта сервера
 
//использование кольцевого буфера для увеличения скорости
RingBuffer buf(8);
 
void setup()
{
  for (int i = 0; i < 3; i++) { //установка режимов выводов 
    pinMode(rgb_pins[i], OUTPUT);  
    digitalWrite(rgb_pins[i], rgb_states[i]);
  }
 
  //инициализация Serial-соединения для отладки
  Serial.begin(9600);
  //инициализация Serial-соединения для ESP-модуля
  wifiSerial.begin(9600);
  //инициализация ESP модуля
  WiFi.init(&wifiSerial);
 
  //проверка существования модуля
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi module not present");
    //если модуля нет, то не продолжать работу далее
    while (true);
  }
 
  //попытка подключения к wifi сети
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WPA SSID: "); //вывод надписи о попытке подключения
    Serial.println(ssid); //вывод названия сети
    //подключение к сети, используя имя и пароль
    status = WiFi.begin(ssid, pass);
  }
 
  Serial.println("You're connected to the network");
  printWifiStatus(); //вывод статуса подключения
 
  //инициализация веб-сервера на порту № 80
  server.begin();
}
 
 
void loop()
{
  WiFiEspClient client = server.available();  //ожидание входящих клиентов
 
  if (client) {                               //если получен клиент,
    Serial.println("New client");             //вывести сообщение в Serial-порт
    buf.init();                               //инициализация буфера
    while (client.connected()) {              //цикл, пока клиент подключен
      if (client.available()) {               //если от клиента есть байты для чтения,
        char c = client.read();               //прочитать байт, а затем
        buf.push(c);                          //добавить его в буфер
 
        //если в строке получены два символа завершения строки
        //значит - это конец HTTP запроса, так что нужно отправить ответ
        if (buf.endsWith("\r\n\r\n")) {
          sendHttpResponse(client);
          break;
        }
 
        //проверить если запрос был одним из: "GET /R", "GET /G" или "GET /B":
        if (buf.endsWith("GET /R")) { //запрос изменения состояния красного цвета
          Serial.println("Change red state"); //вывод отладочной информации
          changeStateRGB(0); //изменение статуса цвета
        } else if (buf.endsWith("GET /G")) { //запрос изменения состояния зелёного цвета
          Serial.println("Change green state"); //вывод отладочной информации
          changeStateRGB(1); //изменение статуса цвета
        } else if (buf.endsWith("GET /B")) { //запрос изменения состояния синего цвета
          Serial.println("Change blue state"); //вывод отладочной информации
          changeStateRGB(2); //изменение статуса цвета
        }
      }
    }
 
    //закрытие соединения
    client.stop();
    Serial.println("Client disconnected");
  }
}
 
/* Отправка и формирование страницы - ответа
 *  на сервер 
 */
void sendHttpResponse(WiFiEspClient& client)
{
  //Обычно, HTTP заголовки начинаются с кода ответа (напр. HTTP/1.1 200 OK)
  // и типа страницы чтобы клиент знал, что приходит, затем пустая строка
  client.print(
    "HTTP/1.1 200 OK\r\n"
    "Content-Type: text/html\r\n"
    "Connection: close\r\n"  //соединение будет закрыто после завершения ответа
    "\r\n");
  client.print("<!DOCTYPE HTML>\r\n");
  client.print("<html>\r\n");
 
  //заголовок страницы
  client.print("<head>\r\n");
  client.print("<meta charset=\"utf-8\">\r\n");
  client.print("<title>Данные модуля</title>\r\n");
  client.print("</head>\r\n");
 
  //тело страницы
  client.print("<h1>Привет от SmartElements!</h1>\r\n");
  client.print("<p>Данные получены с помощью ");
  client.print("<a href=\"https://smartelements.ru/collection/svyaz/product/wifi-modul-esp-12\">");
  client.print("крутого Wi-Fi модуля</a></p>\r\n");
  client.println();
 
  //затем определение текущего цвета RGB светодиода и вывод его
  printCurrentColor(client);
  client.println("<br>");
  client.println("<br>");
 
  //вывод состояния цвета в строку со ссылкой для изменения
  printLinkState(client, 0);
  printLinkState(client, 1);
  printLinkState(client, 2); 
 
  //HTTP ответы заканчиваются с пустой строки
  client.println();
}
 
/* Вывод состояния сети и адреса для подключения к моджулю  
 */
void printWifiStatus()
{
  //вывод названия сети
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());
 
  //вывод полученного модулем IP-адреса
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);
 
  //вывод информации о адресе в браузере
  Serial.println();
  Serial.print("To see this page in action, open a browser to http://");
  Serial.println(ip);
  Serial.println();
}
 
/* Изменение статуса и зажигание светодиода
 */
void changeStateRGB(const int& i)
{
  rgb_states[i] = !rgb_states[i]; //Изменение состояния светодиода
  digitalWrite(rgb_pins[i], rgb_states[i]); //Зажечь/погасить светодиод (цвет)
}
 
/* Формирование строки-ссылки для управления текущим цветом.
 *  В зависимости от номера вывода опредяется цвет и 
 *  выводится строка запроса.
 *  В зависимости от текущего состояния цвета (включен он или нет),
 *  меняется надпись ссылки. Если цвет выключен, то надпись будет "Включить цвет"
 *  и наоборот.
 */
void printLinkState(WiFiEspClient& client, const int& i)
{
  client.print("<a href=\"");
  if (i == 0) {
    client.print("/R\" style=\"color:red");
  } else if (i == 1) {
    client.print("/G\" style=\"color:green");
  } else {
    client.print("/B\" style=\"color:blue");
  }
  client.print("\">");
  if (rgb_states[i]) {
    client.print("Выключить");
  } else {
    client.print("Включить");
  }
  client.println(" цвет</a><br>");
}
 
/* Определение текущего цвета и светодиода и вывод надписи об этом
 *  соответствующим цветом.
 */
void printCurrentColor(WiFiEspClient& client) 
{
  client.print("<h2 style=\"background-color:");
  if (rgb_states[0] == true && rgb_states[1] == false && rgb_states[2] == false) {
    client.print("red");
  } else if (rgb_states[0] == false && rgb_states[1] == true && rgb_states[2] == false) {
    client.print("green");
  } else if (rgb_states[0] == false && rgb_states[1] == false && rgb_states[2] == true) {
    client.print("blue");
  } else if (rgb_states[0] == true && rgb_states[1] == true && rgb_states[2] == false) {
    client.print("yellow");
  } else if (rgb_states[0] == true && rgb_states[1] == false && rgb_states[2] == true) {
    client.print("purple");
  } else if (rgb_states[0] == false && rgb_states[1] == true && rgb_states[2] == true) {
    client.print("aqua");
  } else if (rgb_states[0] == true && rgb_states[1] == true && rgb_states[2] == true) {
    client.print("silver");
  } else if (rgb_states[0] == false && rgb_states[1] == false && rgb_states[2] == false) {
    client.print("black");
  } 
  client.print("\">Текущий цвет RGB светодиода</h2>");
}

Шаг 4. Где запущен сервер

Далее, откройте монитор Serial-порта в Arduino IDE, и посмотрите параметры подключения. Вы увидите информацию вида:

[WiFiEsp] Initializing ESP module
[WiFiEsp] Initilization successful - 1.5.4
Attempting to connect to WPA SSID: SmartElements
[WiFiEsp] Connected to SmartElements
You're connected to the network
SSID: SmartElements
IP Address: 192.168.1.18

To see this page in action, open a browser to http://192.168.1.18

[WiFiEsp] Server started on port 80

Где:

  • SSID - имя сети, к которой подключился модуль
  • IP Address - IP адрес модуля

Скопируйте адрес сайта, в нашем случае он выглядит так:

 http://192.168.1.18 

Данный IP-адрес действует только внутри Вашей домашней WiFi сети.

Шаг 5. Результат

Откройте браузер, который Вы используете для выхода в интернет. И в строке ввода адреса сайта, вставьте адрес, скопированный из шага 4. После этого загрузится страница вида:

Где:

  1. Адрес Вашего сайта
  2. Текущий цвет RGB-светодиода (черный - означает что светодиод выключен)
  3. Ссылка для включения красного цвета свечения
  4. Ссылка для включения зелёного цвета свечения
  5. Ссылка для включения синего цвета свечения

Шаг 6. Красный цвет

На сайте, кликните по ссылке красного цвета «Включить цвет».

Технически, после выполнения клика по ссылке на наш веб сервер будет отправлен запрос «GET /R» (получить красный). Этот запрос обрабатывается контроллером. Обработку запроса мы описали в скетче, где указали что нам нужно инвертировать (сделать обратным) значение цвета. То есть, если сейчас был выключен красный, его включить. И наоборот.

Где:

  1. Адрес и выполненный запрос
  2. Значение текущего цвета светодиода
  3. Обратите внимание, что ссылка красного цвета изменилась с команды «Включить» на команду «Выключить»

После выполнения этого действия, Вы должны увидеть что светодиод загорелся красным цветом.

Всегда дожидайтесь пока страница сайта загрузится окончательно. Потому как её обновление занимает некоторое время. В эти моменты ссылки могут не отрабатывать.

Шаг 7. Фиолетовый цвет

Далее, после того как страница окончательно обновилась, давайте сделаем клик по ссылке синего цвета «Включить цвет»

Обратите внимание:

  1. Снова поменялся запрос на сервер
  2. Текущий цвет изменился на фиолетовый (сиреневый)
  3. Ссылка синего цвета изменилась с команды «Включить» на команду «Выключить»

Светодиод стал светиться фиолетовым (сиреневым) цветом

Шаг 8. Белый цвет

Ну и, наконец, добавим ещё не включенный зелёный цвет, кликнув по ссылке зелёного цвета.

И увидим следующее:

  1. Изменение запроса
  2. Изменение цвета текущего свечения (отображаем серым, так как у нас белый фон сайта и белый цвет на нём будет не виден)
  3. Ссылка зелёного цвета изменилась с команды «Включить» на команду «Выключить»

Теперь светодиод светит белым цветом - сочетание свечения красного, зелёного и синего.

Шаг 9. Выключение свечения

Далее, будем отключать включенные цвета. Нажмём на ссылку красного цвета, тем самым отключив свечение красного цвета. После выключения красного, светодиод будет светиться голубым цветом (сочетание синего и зелёного).

Ссылка красного цвета поменялась с «Выключить» на «Включить».

Технически, кликая на ссылку одного цвета, мы посылаем один и тот же запрос «GET /R» (получить красный). А далее в скетче, в зависимости от текущего состояния свечения цвета, мы его меняем на противоположное. Это гораздо проще, чем создавать отдельные кнопки (ссылки) для включения и отключения цвета.

Шаг 10. Управляйте цветом

Посмотрите, какой цвет свечения получится в сочетании красного и зелёного цветов.

Теперь Вы можете управлять цветом свечения, включая и отключая различные цвета. Не забывайте, что серверу требуется время на получение запроса и обновление веб страницы.

Таким же образом, Вы можете подключить любые устройства и управлять их работой через интернет.