ESP8266:Примеры/Управление RGB-лампочкой с помощью ИК-передатчика и ESP8266
Поддержать проект | Содержание | Введение | Модули | AT-команды | Прошивки | Примеры | Проекты | Типовые проблемы | Библиотеки |
![]() |
Черновик |
Содержание
Управление RGB-лампочкой с помощью ИК-передатчика и ESP8266
В этом проекте мы научимся использовать ИК-передатчик для управления RGB-светодиодной ИК-лампочкой при помощи веб-сервера на базе ESP8266. Мы сможем отправлять команды для включения/выключения лампочки, уменьшения/увеличения ее яркости, переключения ее на красный, зеленый, синий, фиолетовый цвета и т.д. Проект будет поделен на 2 части:
- Расшифровка ИК-сигналов, отправляемых пультом управления лампочкой
- Настройка ESP8266 на отправление этих ИК-сигналов
Передача и прием ИК-сигналов
На фото ниже изображен ИК-приемник TSOP4838.
Как видите, он оснащен 3 контактами:
- OUT (вывод данных);
- GND (Заземление);
- VCC (Источник напряжения);
Когда вы нажимаете на кнопки на пульте управления, он отправляет модулированные ИК-сигналы. Они содержат информацию, принимаемую ИК-приемником.
Каждая кнопка отправляет собственный ИК-сигнал. Таким образом, мы можем привязать каждый из этих ИК-сигналов к кнопкам на веб-странице, обслуживаемой ESP8266. Затем эти сигналы – отправляемые ИК-передатчиком, подключенным к ESP8266 – можно будет использовать для управления лампочкой.
Необходимое оборудование
- Плата ESP8266 - 1шт.;
- ИК-приемник TSOP4838 - 1шт.;
- Светодиодный ИК-передатчик - 1шт.;
- RGB-светодиодная ИК-лампочка (E27/B22) с пультом управления - 1шт.;
- Контактная макетная плата - 1шт.;
- Провода-перемычки;
Часть 1 – Расшифровка ИК-сигналов
В этой части проекта мы расшифруем ИК-сигналы, привязанные к каждой кнопке, чтобы потом эмулировать их при помощи ESP8266.
Схема
Подключите ИК-приемник и ESP8266 друг к другу согласно схеме ниже.
![]() |
Данная схема приведена для ИК приемника TSOP4838, другие модели могут иметь различную распиновку. |
Код
Для работы с ИК-передатчиком и ИК-приемником нам нужно будет установить в IDE Arduino библиотеку «IRremoteESP8266». Для этого кликните в IDE Arduino на «Скетч» > «Подключить библиотеку» > «Управлять библиотеками...» (Sketch > Include Library > Manage Libraries…).
Затем вбейте в поиске «ir remote esp8266» и, найдя нужную библиотеку, кликните по кнопке «Установка» (Install). Или можете загрузить ее ZIP-архив отсюда и установить вручную.
Скопируйте код ниже в IDE Arduino, а затем загрузите его на ESP8266. Перед этим проверьте, правильные ли в IDE Arduino выбраны плата и COM-порт.
1 /*
2 * https://github.com/markszabo/IRremoteESP8266/blob/master/examples/IRrecvDemo/IRrecvDemo.ino
3 *
4 * IRremoteESP8266: IRrecvDemo
5 *
6 * Демонстрирует получение ИК-кодов при помощи библиотеки «IRrecv».
7 * Ко входному контакту RECV_PIN
8 * должен быть подключен ИК-детектор/демодулятор.
9 * Авторские права принадлежат Кену Ширриффу (2009), http://arcfn.com
10 * Изменения:
11 * Версия 0.2, июнь 2017
12 * - Изменен GPIO-контакт
13 (теперь он такой же, как и в других примерах);
14 * - Для печати «uint64_t» используется наш собственный метод;
15 * - Скорость передачи данных изменена на 115200 бод.
16 * Версия 0.1, сентябрь 2015
17 * - Основана на скетче «IrsendDemo» (версия 0.1, июль 2009),
18 * написанном Кеном Ширриффом
19 */
20
21 #ifndef UNIT_TEST
22 #include <Arduino.h>
23 #endif
24 #include <IRremoteESP8266.h>
25 #include <IRrecv.h>
26 #include <IRutils.h>
27
28 // ИК-детектор/демодулятор подключен к контакту GPIO14
29 // (на плате NodeMCU это контакт D5):
30 uint16_t RECV_PIN = 14;
31
32 IRrecv irrecv(RECV_PIN);
33
34 decode_results results;
35
36 void setup() {
37 Serial.begin(115200);
38 irrecv.enableIRIn(); // запускаем приемник
39 }
40
41 void loop() {
42 if (irrecv.decode(&results)) {
43 // print() и println() не умеют
44 // обрабатывать печать вместительных типов данных (uint64_t):
45 serialPrintUint64(results.value, HEX);
46 Serial.println("");
47 irrecv.resume(); // получаем следующее значение
48 }
49 delay(100);
50 }
Открываем монитор порта на скорости 115200 бод.
В этом проекте мы будем эмулировать 10 кнопок пульта управления. Нажмите на пульте на кнопку «ON». В результате в мониторе порта должен появиться код для этой кнопки.
Примечание: На одну и ту же кнопку можно нажать несколько раз – чтобы убедиться, что код получен именно для той кнопки, что вам нужна. Если вы увидите что-то вроде «FFFFFFFF», просто игнорируйте, это мусор.
Повторите этот процесс и для других кнопок. Запишите коды для всех кнопок, т.к. позже они нам еще понадобятся. На картинке ниже показаны ИК-сигналы для всех нужных нам кнопок на пульте управления.
Часть 2 – Настройка ESP8266 на отправку ИК-сигналов
В этой части мы построим цепь из светодиодного ИК-передатчика, управляемого с помощью веб-сервера на базе ESP8266.
Схема
Подключите ИК-передатчик к ESP8266 согласно схеме ниже.
ИК-передатчик нужно поместить рядом с лампочкой, чтобы она могла принимать отправляемые им ИК-сигналы.
Код
Код ниже запустит на вашей ESP8266 веб-сервер, передающий данные через порт «80». Веб-сервер будет показывать в браузере простую веб-страницу с 10 кнопками, управляющими RGB-светодиодной лампочкой.
Скопируйте код ниже в IDE Arduino, но пока не загружайте.
Сначала прочтите следующий раздел, в котором рассказывается, как отредактировать этот скетч, чтобы он заработал на вашей ESP8266.
![]() |
Если у вас код ниже работает нестабильно, то вы можете попробовать вот этот альтернативный вариант. |
1 /*
2 * Скетч для управления RGB-светодиодной ИК-лампочкой с помощью ESP8266
3 * Руи Сантос
4 * Более подробно о проекте на: http://randomnerdtutorials.com
5 */
6
7 #include <ESP8266WiFi.h>
8
9 #ifndef UNIT_TEST
10 #include <Arduino.h>
11 #endif
12 #include <IRremoteESP8266.h>
13 #include <IRsend.h>
14
15 // ИК-передатчик управляется через контакт GPIO4 (D2):
16 IRsend irsend(4);
17
18 // Вставьте здесь SSID и пароль для своей WiFi-сети:
19 const char* ssid = "REPLACE_WITH_YOUR_SSID";
20 const char* password = "REPLACE_WITH_YOUR_PASSWORD";
21
22 // Переменная для хранения информации о том,
23 // какая кнопка была последней нажата на веб-странице:
24 String lastState;
25
26 // Создаем объект для сервера с портом «80»:
27 WiFiServer server(80);
28
29 void setup() {
30 irsend.begin();
31
32 Serial.begin(115200, SERIAL_8N1, SERIAL_TX_ONLY);
33 delay(10);
34
35 // Подготавливаем контакт GPIO4:
36 pinMode(4, OUTPUT);
37 digitalWrite(4, 0);
38
39 // Подключаемся к WiFi-сети:
40 Serial.print("Connecting to "); // "Подключаемся к "
41 Serial.println(ssid);
42
43 WiFi.begin(ssid, password);
44
45 while (WiFi.status() != WL_CONNECTED) {
46 delay(500);
47 Serial.print(".");
48 }
49 Serial.println("WiFi connected"); // "Подключились к WiFi"
50
51 // Запускаем сервер:
52 server.begin();
53 Serial.println("Server started"); // "Сервер запущен"
54
55 // Печатаем IP-адрес:
56 Serial.println(WiFi.localIP());
57 }
58
59 void loop() {
60 // Проверяем, подключился ли клиент:
61 WiFiClient client = server.available();
62 if (!client) {
63 return;
64 }
65
66 // Ждем, пока клиент отправит какие-нибудь данные:
67 Serial.println("new client"); // "новый клиент"
68 while(!client.available()){
69 delay(1);
70 }
71
72 // Считываем первую строчку запроса:
73 String req = client.readStringUntil('\r');
74 Serial.println(req);
75 client.flush();
76
77 // Смотрим, какой именно запрос отправлен:
78 int irCode;
79 if (req.indexOf("/lamp/on") != -1) {
80 irCode = 0xFFE01F;
81 lastState = "on";
82 }
83 else if (req.indexOf("/lamp/off") != -1) {
84 irCode = 0xFF609F;
85 lastState = "off";
86 }
87 else if (req.indexOf("/lamp/brighten") != -1) {
88 irCode = 0xFFA05F;
89 lastState = "brighten";
90 }
91 else if (req.indexOf("/lamp/dim") != -1) {
92 irCode = 0xFF20DF;
93 lastState = "dim";
94 }
95 else if (req.indexOf("/lamp/red") != -1) {
96 irCode = 0xFF906F;
97 lastState = "red";
98 }
99 else if (req.indexOf("/lamp/green") != -1) {
100 irCode = 0xFF10EF;
101 lastState = "green";
102 }
103 else if (req.indexOf("/lamp/blue") != -1) {
104 irCode = 0xFF50AF;
105 lastState = "blue";
106 }
107 else if (req.indexOf("/lamp/yellow") != -1) {
108 irCode = 0xFF8877;
109 lastState = "yellow";
110 }
111 else if (req.indexOf("/lamp/cyan") != -1) {
112 irCode = 0xFF708F;
113 lastState = "cyan";
114 }
115 else if (req.indexOf("/lamp/purple") != -1) {
116 irCode = 0xFF6897;
117 lastState = "purple";
118 }
119 else {
120 lastState = "none";
121 Serial.println("Invalid request - IR signal not sent");
122 // "Неправильный запрос – ИК-сигнал не отправлен"
123 }
124 // Отправляем ИК-сигнал RGB-светодиодной лампочке:
125 Serial.print("NEC: ");
126 Serial.println(irCode, HEX);
127 irsend.sendNEC(irCode, 32);
128 client.flush();
129
130 // Готовим ответ клиенту (содержит веб-страницу):
131 String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>";
132 s += "<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"></head>";
133 s += "<h1>RGB Lamp</h1>Last state: ";
134 s += lastState;
135 s += "<p><a href=\"/lamp/on\"><button>ON</button></a><a href=\"/lamp/off\"><button>OFF</button></a></p>";
136 s += "<p><a href=\"/lamp/brighten\"><button>BRIGHTEN</button></a><a href=\"/lamp/dim\"><button>DIM</button></a></p>";
137 s += "<p><a href=\"/lamp/red\"><button>RED</button></a><a href=\"/lamp/green\"><button>GREEN</button></a><a href=\"/lamp/blue\"><button>BLUE</button></a></p>";
138 s += "<p><a href=\"/lamp/yellow\"><button>YELLOW</button></a><a href=\"/lamp/cyan\"><button>CYAN</button></a><a href=\"/lamp/purple\"><button>PURPLE</button></a></p>";
139 s += "</html>\n";
140
141 // Отправляем ответ клиенту и отключаем его:
142 client.print(s);
143 delay(1);
144 Serial.println("Client disconnected"); // "Клиент отключен"
145 client.stop();
146 }
Редактируем скетч
Перед загрузкой скетча в него нужно вписать SSID и пароль для своей WiFi-сети:
1 // Вставьте здесь SSID и пароль для вашей WiFi-сети:
2 const char* ssid = "REPLACE_WITH_YOUR_SSID";
3 const char* password = "REPLACE_WITH_YOUR_PASSWORD";
Теперь возьмите ИК-коды, найденные в части 1, и впишите их в переменные «irCode», соответствующие нужным командам.
1 // Смотрим, какой именно запрос отправлен:
2 int irCode;
3 if (req.indexOf("/lamp/on") != -1) {
4 irCode = 0xFFE01F;
5 lastState = "on";
6 }
7 else if (req.indexOf("/lamp/off") != -1) {
8 irCode = 0xFF609F;
9 lastState = "off";
10 }
11 else if (req.indexOf("/lamp/brighten") != -1) {
12 irCode = 0xFFA05F;
13 lastState = "brighten";
14 }
15 else if (req.indexOf("/lamp/dim") != -1) {
16 irCode = 0xFF20DF;
17 lastState = "dim";
18 }
19 (...)
Добавив новые операторы else if(), вы можете оснастить скетч и другими кнопками пульта. Но эти кнопки также нужно будет добавить на веб-страницу, и для этого в код нужно будет вписать примерно следующее (здесь показаны фрагменты для кнопок «ON», «OFF», «BRIGHTEN» и «DIM»):
1 s += "<p><a href=\"/lamp/on\"><button>ON</button></a><a href=\"/lamp/off\"><button>OFF</button></a></p>";
2 s += "<p><a href=\"/lamp/brighten\"><button>BRIGHTEN</button></a><a href=\"/lamp/dim\"><button>DIM</button></a></p>";
Внеся все необходимые изменения, загрузите скетч на ESP8266.
Узнаем IP-адрес ESP8266
Загрузив скетч на ESP8266, кликните в IDE Arduino на «Инструменты» > «Монитор порта» (Tools > Serial Monitor). Когда ESP8266 загрузится, в мониторе порта должен напечататься ее IP-адрес.
В моем случае это «192.168.1.22» (как на скриншоте выше). В вашем случае IP-адрес, скорее всего, будет другим. Сохраните его, чтобы затем с его помощью заходить на веб-страницу для управления ИК-лампочкой.
Демонстрация
Откройте веб-браузер на любом устройстве, подключенном к той же сети, что и ESP8266, введите в его адресную строку IP-адрес ESP8266 и нажмите на ↵ Enter .
Поместите светодиодный ИК-передатчик рядом с ИК-лампочкой. Понажимайте на кнопки на веб-странице для управления лампочкой – поменяйте цвет, яркость, включите/выключите ее и т.д.
Альтернативный вариант серверного кода
Если у вас предыдущий вариант работает нестабильно(частые разрывы, зависания и попросту браузер не может отобразить страницу), попробуйте более стабильный вариант:
1 #include <ESP8266WiFi.h>
2
3 #ifndef UNIT_TEST
4 #include <Arduino.h>
5 #endif
6 #include <IRremoteESP8266.h>
7 #include <IRsend.h>
8
9 // ИК-передатчик управляется через контакт GPIO4 (D2):
10 IRsend irsend(4);
11
12 // Вставьте здесь SSID и пароль для своей WiFi-сети:
13 const char* ssid = "ваш ssid";
14 const char* password = "ваш пароль";
15
16 // переменная для хранения HTTP-запроса:
17 String header;
18
19 // Переменная для хранения информации о том,
20 // какая кнопка была последней нажата на веб-странице:
21 String lastState;
22
23 // Создаем объект для сервера с портом «80»:
24 WiFiServer server(80);
25
26 void setup() {
27 irsend.begin();
28
29 Serial.begin(115200, SERIAL_8N1, SERIAL_TX_ONLY);
30 delay(10);
31
32 // Подготавливаем контакт GPIO4:
33 pinMode(4, OUTPUT);
34 digitalWrite(4, 0);
35
36 // Подключаемся к WiFi-сети:
37 Serial.print("Connecting to "); // "Подключаемся к "
38 Serial.println(ssid);
39
40 WiFi.begin(ssid, password);
41
42 while (WiFi.status() != WL_CONNECTED) {
43 delay(500);
44 Serial.print(".");
45 }
46 Serial.println("WiFi connected"); // "Подключились к WiFi"
47
48 // Запускаем сервер:
49 server.begin();
50 Serial.println("Server started"); // "Сервер запущен"
51
52 // Печатаем IP-адрес:
53 Serial.println(WiFi.localIP());
54 }
55
56
57 void loop() {
58 // начинаем прослушивать входящих клиентов:
59 WiFiClient client = server.available();
60
61 if (client) { // если подключился новый клиент,
62 Serial.println("New Client."); // печатаем сообщение
63 // «Новый клиент.»
64 // в мониторе порта;
65 String currentLine = ""; // создаем строку для хранения
66 // входящих данных от клиента;
67 while (client.connected()) { // цикл while() будет работать
68 // все то время, пока клиент
69 // будет подключен к серверу;
70 if (client.available()) { // если у клиента есть данные,
71 // которые можно прочесть,
72 char c = client.read(); // считываем байт, а затем
73 Serial.write(c); // печатаем его в мониторе порта
74 header += c;
75 if (c == '\n') { // если этим байтом является
76 // символ новой строки
77 // если получили два символа новой строки подряд,
78 // то это значит, что текущая строчка пуста;
79 // это конец HTTP-запроса клиента,
80 // а значит – пора отправлять ответ:
81 if (currentLine.length() == 0) {
82 // HTTP-заголовки всегда начинаются
83 // с кода ответа (например, «HTTP/1.1 200 OK»)
84 // и информации о типе контента
85 // (чтобы клиент понимал, что получает);
86 // в конце пишем пустую строчку:
87 client.println("HTTP/1.1 200 OK");
88 client.println("Content-type:text/html");
89 client.println("Connection: close");
90 // "Соединение: отключено"
91 client.println();
92
93
94
95 int irCode;
96
97 if (header.indexOf("GET /lamp/on") >= 0) {
98 irCode = 0xFFE01F;
99 lastState = "on";
100 }
101 else if (header.indexOf("GET /lamp/off") != -1) {
102 irCode = 0xFF609F;
103 lastState = "off";
104 }
105 else if (header.indexOf("GET /lamp/brighten") != -1) {
106 irCode = 0xFFA05F;
107 lastState = "brighten";
108 }
109 else if (header.indexOf("GET /lamp/dim") != -1) {
110 irCode = 0xFF20DF;
111 lastState = "dim";
112 }
113 else if (header.indexOf("GET /lamp/red") != -1) {
114 irCode = 0xFF906F;
115 lastState = "red";
116 }
117 else if (header.indexOf("GET /lamp/green") != -1) {
118 irCode = 0xFF10EF;
119 lastState = "green";
120 }
121 else if (header.indexOf("GET /lamp/blue") != -1) {
122 irCode = 0xFF50AF;
123 lastState = "blue";
124 }
125 else if (header.indexOf("GET /lamp/yellow") != -1) {
126 irCode = 0xFF8877;
127 lastState = "yellow";
128 }
129 else if (header.indexOf("GET /lamp/cyan") != -1) {
130 irCode = 0xFF708F;
131 lastState = "cyan";
132 }
133 else if (header.indexOf("GET /lamp/purple") != -1) {
134 irCode = 0xFF6897;
135 lastState = "purple";
136 }
137 else {
138 lastState = "none";
139 Serial.println("Invalid request - IR signal not sent");
140 // "Неправильный запрос – ИК -сигнал не отправлен"
141 }
142 // Отправляем ИК-сигнал RGB-светодиодной лампочке:
143 Serial.print("NEC: ");
144 Serial.println(irCode, HEX);
145 irsend.sendNEC(irCode, 32);
146 client.flush();
147
148 // показываем веб-страницу:
149 client.println("<!DOCTYPE html><html>");
150 client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
151 client.println("<link rel=\"icon\" href=\"data:,\">");
152
153 // веб-страница:
154 client.println("</head><body><h1>RGB Lamp</h1>Last state:" + lastState);
155 client.println("<p><a href=\"/lamp/on\"><button>ON</button></a><a href=\"/lamp/off\"><button>OFF</button></a></p>");
156 client.println("<p><a href=\"/lamp/brighten\"><button>BRIGHTEN</button></a><a href=\"/lamp/dim\"><button>DIM</button></a></p>");
157 client.println("<p><a href=\"/lamp/red\"><button>RED</button></a><a href=\"/lamp/green\"><button>GREEN</button></a><a href=\"/lamp/blue\"><button>BLUE</button></a></p>");
158 client.println("<p><a href=\"/lamp/yellow\"><button>YELLOW</button></a><a href=\"/lamp/cyan\"><button>CYAN</button></a><a href=\"/lamp/purple\"><button>PURPLE</button></a></p>");
159
160 client.println("</body></html>");
161
162 // конец HTTP-ответа задается
163 // с помощью дополнительной пустой строки:
164 client.println();
165 // выходим из цикла while():
166 break;
167 } else { // если получили символ новой строки,
168 // очищаем текущую строку «currentLine»:
169 currentLine = "";
170 }
171 } else if (c != '\r') { // если получили любые данные,
172 // кроме символа возврата каретки,
173 currentLine += c; // добавляем эти данные
174 // в конец строки «currentLine»
175 }
176 }
177 }
178 // очищаем переменную «header»:
179 header = "";
180 // отключаем соединение:
181 client.stop();
182 Serial.println("Client disconnected.");
183 // "Клиент отключился."
184 Serial.println("");
185 }
186 }
Итого
Итак, с помощью этого проекта мы научились встраивать ИК-передатчик и ИК-приемник в ESP8266-проект. Это лишь шаблон, но возможности применения этих ИК-устройств – безграничны. К примеру, вместо ИК-лампочки можно управлять телевизором, кондиционером воздуха, термостатом, лентой RGB-светодиодов и любым другим устройством, управляемым с помощью пульта дистанционного управления.
Так же вы можете по аналогии с вот этим примером сделать управление лампой не через браузер,а с помощью Android-виджетов.
См.также
Внешние ссылки