Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Manufacturing Technology >> Производственный процесс

ИК-порт Wi-Fi

Компоненты и расходные материалы

Espressif ESP8266 ESP-01
Вы можете сделать это с помощью стандартного ESP8266 или комплекта разработчика NodeMCU
× 1
Arduino Nano R3
× 1
NPN-транзистор общего назначения
× 1
ИК-светодиоды Adafruit
× 1

Необходимые инструменты и машины

Паяльник (общий)

Приложения и онлайн-сервисы

IDE Arduino
Прошивка NodeMCU

Об этом проекте

Два шага вперед ...

Похоже, что основные производители телефонов отказываются от встроенных ИК-передатчиков, поэтому я ищу способ защитить мои «глупые» устройства, которые в настоящее время не интегрируются с моей инфраструктурой IoT, в будущем. У меня есть умный дом с ячеистой сетью, но мне нужно найти физический пульт, чтобы включить телевизор? Там должен быть лучший способ.

Недавно я построил ИК-передатчик, который управляет автономными кондиционерами в моем доме, и еще одним предыдущим проектом был подключенный вентилятор HVAC с подключенным к Android веб-приложением. По сути, все, что мне нужно сделать, это объединить эти две вещи в подключенный к Интернету ИК-порт с интерфейсом веб-приложения, чтобы я мог нажимать кнопки на своем телефоне и получать ИК-сигналы, отправляемые в мои медиацентры. Их можно развернуть в любой комнате и управлять ими с помощью единого интерфейса, поэтому приложения для этого чрезвычайно широки.

Быстрое прототипирование

Я схватил неиспользуемое оборудование и подключил все, что мне нужно, чтобы подключиться к моему Wi-Fi, принимать HTTP-соединения и отправлять ИК-сигналы.

Это сработало отлично, так как я мог запросить конкретный URL-адрес на IP-адресе, назначенном ESP8266, и заставить Arduino выводить сигнал «Power» на ИК-светодиод. Мне просто нужно было выяснить, где разместить веб-приложение, отправить URL-адреса на ИК-бластер, а затем проанализировать эти запросы на определенные ИК-коды. Это было очень утомительно делать с помощью AT-команд с ESP8266, и что-то вызывало задержку в 1-2 секунды между отправкой запроса и миганием светодиода.

NodeMCU

Я выбрал плату разработчика NodeMCU ESP8266, потому что она имеет встроенную регулировку мощности, USB-последовательный интерфейс и множество контактов ввода-вывода в этом небольшом корпусе (он также удобен для макетов). Оказывается, уже существует библиотека ESP8266 WebServer, которая принимает запросы GET, которые я смог адаптировать для отправки ИК-кодов, а обычная библиотека IRremote работает из коробки.

ESP8266 на NodeMCU недостаточно мощный для размещения самого веб-приложения, поэтому я буду запускать его на недостаточно используемом C.H.I.P. Компьютер за 9 долларов, который уже подключен к моей домашней сети. Еще одним ограничением является то, что ESP8266 - это плата на 3,3 В, поэтому ИК-светодиоды, управляемые непосредственно от вывода ввода / вывода, были очень тусклыми и должны были находиться рядом с устройством, на которое он отправлял сигнал. Вместо этого я использовал вывод ввода-вывода для управления npn-транзистором для включения / выключения напряжения питания 5 В.

ОТДЫХ ... ну

Проведя небольшое исследование, я нашел отличное руководство по реализации REST API для Arduino для управления светодиодами на adafruit. Я использовал их файлы JavaScript и PHP для отправки запросов cURL и загрузил их на ЧИП, который уже запускает apache, но с таким же успехом может быть размещен в облаке. После создания базовой HTML-страницы для пульта дистанционного управления я добавил файлы manifest.json и icon, чтобы его можно было запускать как собственное веб-приложение на телефоне Android.

На стороне Arduino я обрезал веб-сервер, чтобы просто принять запрос GET, проанализировать URL-адрес, отправить 200 OK и затем отключиться. На основе URL-адреса Arduino отправит ИК-код, сопоставленный нажатой кнопке.

Универсальный Remonster

Все работает безотказно с нулевой задержкой. Я обнаружил, что ИК-светодиоды, которые я использую, имеют очень узкий угол, поэтому я должен следить за их правильным направлением. Некоторые промышленные липучки позволяют мне устанавливать их под полкой, вне поля зрения, и следить за тем, чтобы они оставались направленными на ИК-приемники на другом конце. Я добавил толстый провод к выводам светодиодов, чтобы их можно было точно настроить.

Из-за резисторов для ИК-светодиодов они стали практически непригодными для использования, поэтому транзистор питает их нерегулируемым напряжением 5 В. Это позволяет мне отражать ИК-излучение от стен и устанавливать бластер по всей комнате, но определенно повлияет на долговечность. Я надеюсь, что, поскольку они используются очень редко, а ИК-сигналы представляют собой сверхкороткие импульсы (более низкий рабочий цикл, чем у большинства тусклых сигналов ШИМ), мне не нужно будет заменять светодиоды в течение некоторого времени. Я заказал несколько широкоугольных ИК-светодиодов с более высокой выходной мощностью для версии 2, поэтому, когда они, наконец, умрут, я заменю их на встроенный резистор.

Обновление за 3 месяца и будущие функции

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

Планы на будущее:

  • Перенести веб-интерфейс в облачную службу
  • Интеграция с Amazon Echo для голосовых команд (Готово)
  • В следующей итерации оборудования также будет датчик температуры DHT22, и я изучаю способы передачи радиочастотного излучения для моих потолочных вентиляторов.
  • Добавьте ИК-приемник для функции обучения, чтобы вы могли "обучать" командам ИК-бластера с существующих пультов дистанционного управления.
  • Интеграция с моей домашней автоматизацией / безопасностью, чтобы отключать бытовые приборы, когда они не используются.

Этот небольшой подключенный ИК-передатчик постепенно заполняет пробел между моим умным домом и устаревшей техникой.

Код

  • WiFi IR Blaster для ESP8266 Arduino Sketch
  • script.js
  • index.html
  • curl.php
  • manifest.json
WiFi IR Blaster для ESP8266 Arduino Sketch C / C ++
Вам понадобится библиотека Wi-Fi ESP8266 и IRremote.h. Вам также следует отказаться от использования необработанных ИК-кодов, если ваш пульт поддерживается библиотекой. Я адаптировал этот набросок на основе созданного мной контроллера кондиционера, который использовал нестандартные ИК-коды.
 / * * WiFi IR Blaster от Бадди Кротти * Используйте модуль ESP8266 или плату разработчика для получения HTTP-запроса GET * и затем отправки ИК-кодов к подключенному ИК-светодиоду на основе этих запросов. * Это лучше всего работает с другим веб-сервером, выступающим в качестве внешнего интерфейса, * который отправляет запросы cURL в зависимости от того, какие кнопки нажаты. * формат cURL:http:// ESP8266 / IRcode * / # include  #include  #include  const char * ssid ="AP_SSID"; const char * password ="AP_Pass "; MDNSResponder mdns; int khz =38; // Несущая частота 38 кГц для NEC и SamsungIRsend irsend (4); // ИК-светодиод подключен к GPIO4 (вывод D2 на NodeMCU) // Вставить ИК-сигнал RAW для "TV Power" unsigned int irTVpwr [] ={4650,4250, 700,1550, 650,1550, 700,1550, 650,450 , 650,500, 600,500, 600,500, 600,550, 550,1700, 550,1650, 600,1650, 550,550, 600,500, 600,550, 550,550, 600,500, 600,550, 550,1650, 600,550, 550,550, 600,500, 600,550, 550,550, 600,500, 600 , 1650, 600, 500, 600, 1650, 550, 1700, 550, 1650, 600, 1650, 550, 1650, 600, 1650, 600}; // SAMSUNG E0E040BF // Вставить ИК-сигнал RAW для "TV Source" unsigned int irTVsrc [] ={4600,4300, 700,1550, 650,1550, 650,1600, 650,450, 650,450, 600,550, 550,550, 600,500, 600, 1650, 550,1650, 600,1650, 550,550, 600,500, 600,550, 550,550, 550,550, 600,1650, 550,550, 550,550, 600,500, 600,500, 600,550, 550,550, 600,500, 600,550, 550,1650, 550,1700, 550, 1650, 600, 1600, 600, 1650, 600, 1600, 600, 1650, 550}; // SAMSUNG E0E0807F // Вставить ИК-сигнал RAW для "TV Mute" unsigned int irTVmute [] ={4650,4250, 700,1550, 650,1550, 700,1550, 650,450, 650,500, 600,500, 600,500, 600,500, 600, 1650, 600,1600, 600,1650, 550,550, 600,500, 600,550, 550,550, 600,500, 600,1650, 550,1650, 600,1650, 550,1650, 600,550, 550,550, 550,550, 600,500, 600,550, 550,550, 550,550, 600 500, 600, 1650, 550, 1650, 600, 1650, 550, 1650, 600}; // SAMSUNG E0E0F00F // Вставьте ИК-сигнал RAW для "TV Volume Down" без знака int irTVvdn [] ={4650,4250, 700,1550, 650,1550, 700,1550, 650,450, 650,450, 650,450, 600,550, 550,550, 600 , 1650, 550,1650, 550,1650, 600,550, 550,550, 550,550, 600,500, 600,500, 600,1650, 600,1600, 600,500, 600,1650, 550,550, 600,500, 600,500, 600,550, 550,550, 600,500, 600,1650 , 550, 550, 550, 1650, 600, 1650, 550, 1650, 600, 1650, 550}; // SAMSUNG E0E0D02F // Вставьте ИК-сигнал RAW для увеличения громкости ТВ без знака int irTVvup [] ={4600,4300, 650,1600, 650,1550, 650,1600, 600,500, 600,550, 600,500, 600,550, 550,550, 550 , 1700, 550,1650, 600,1650, 550,550, 600,500, 600,550, 550,550, 600,500, 600,1650, 600,1650, 550,1650, 600,550, 550,550, 600,500, 600,550, 550,550, 600,500, 600,550, 550,550, 600 , 1600, 600, 1650, 600, 1650, 550, 1650, 600, 1650, 600}; // SAMSUNG E0E0E01F // Вставить ИК-сигнал RAW для "TV Channel Up" без знака int irTVchup [] ={4650,4250, 700,1550, 650,1600, 650,1550, 650,500, 600,500, 600,500, 650,500, 600,500, 600 , 1650, 550, 1650, 600, 1650, 600, 500, 600, 500, 600, 550, 550, 550, 600, 550, 550, 550, 550, 1650, 600, 550, 600 500, 600, 1650, 550 550, 600 500, 600, 550, 550, 1650, 600, 550, 550, 1650 , 600,1650, 600,500, 600,1650, 600,1600, 600,1650, 600}; // SAMSUNG E0E048B7 // Вставить ИК-сигнал RAW для "TV Channel Down" unsigned int irTVchdn [] ={4600,4350, 650,1550, 650,1600, 650,1600, 600,500, 600,500, 600,550, 550,550, 600,550, 550 , 1650, 600,1650, 550,1700, 550,550, 550,550, 600,500, 600,550, 550,550, 600,500, 600,550, 550,550, 550,550, 600,1650, 600,500, 600,500, 600,550, 550,1650, 600,1650, 600,1650 , 550,1650, 600,550, 550,1650, 600,1650, 600,1650, 550}; // SAMSUNG E0E008F7 // Вставить ИК-сигнал RAW для «Мощность приемника» unsigned int irRECpwr [] ={9050,4350, 650,500, 600,1600, 600,500, 650,500, 600,1600, 600,550, 600,1600, 600,1650, 550,550, 600,500, 600,1600, 650,1600, 600,500, 600,1650, 600,1600, 600,500, 600,1650, 600,1600, 600,550, 600,1600, 600,500, 600,550, 600,1600, 600,1600, 650,500, 600,500, 600,1600, 650,500, 600,1600, 600,1650, 600,500, 600,500, 600}; // NEC 4B36D32C // Вставить IR-сигнал RAW для "Receiver Power On" unsigned int irRECpwrON [] ={9000,4400, 600,550, 600,1600, 600,500, 600,550, 600,1600, 600,500, 600,1600, 650,1600 , 600,1600, 600,500, 650,1600, 600,1600, 600,500, 650,1600, 600,1600, 600,500, 600,550, 600,500, 600,1600, 600,550, 600,500, 600,500, 650,500, 600,500, 600,1600, 650 , 1600, 600,500, 600,1600, 650,1600, 600,1600, 600,1600, 600,1600, 650}; // NEC 4BB620DF // Вставить ИК-сигнал RAW для "Receiver Power Off" unsigned int irRECpwrOFF [] ={9000,4400, 600,550, 550,1650, 600,550, 550,550, 600,1650, 550,550, 600,1650, 550,1650 , 600,550, 550,550, 550,1650, 600,1650, 600,550, 550,1650, 600,1650, 550,550, 600,1650, 550,1650, 600,1650, 600,500, 600,550, 550,550, 600,1650, 550,550, 600,500 , 600,550, 550,550, 550,1700, 550,1650, 600,1650, 550,550, 600,1650, 550}; // NEC 4B36E21D // Вставить ИК-сигнал RAW для "Отключение звука приемника" unsigned int irRECmute [] ={9000,4400, 650,450, 650,1600, 600,500, 600,500, 650,1600, 600,500, 600,1650, 600,1600, 600,1600, 650,500, 600,1600, 650,1600, 600,500, 600,1600, 650,1600, 600,500, 600,1650, 600,500, 600,1600, 650,500, 600,500, 600,500, 600,500, 650,500, 600,500, 600, 1600, 650,500, 600,1600, 600,1600, 650,1600, 600,1650, 600,1600, 600}; // NEC 4BB6A05F // Вставить ИК-сигнал RAW для «Уменьшение громкости приемника» unsigned int irRECvdn [] ={9150,4250, 750,350, 700,1550, 700,400, 700,450, 650,1550, 700,450, 600,1600, 650,1600 , 600,1650, 600,500, 600,1650, 600,1600, 600,550, 600,1600, 600,1650, 600,500, 600,1650, 600,1600, 650,500, 600,500, 600,500, 650,500, 600,500, 600,500, 600,550, 600,500 , 600,1650, 600,1600, 600,1650, 600,1650, 600,1600, 600,1650, 600}; // NEC 4BB6C03F // Вставить ИК-сигнал RAW для "увеличения громкости приемника" unsigned int irRECvup [] ={9050,4400, 650,500, 600,1600, 600,550, 600,500, 600,1650, 600,500, 600,1600, 650,1600 , 600,1600, 600,550, 600,1600, 600,1600, 650,500, 600,1600, 650,1600, 600,500, 600,550, 600,1600, 600,550, 600,500, 600,550, 600,500, 600,550, 600,500, 600,1600, 650,500 , 600,1600, 600,1650, 600,1600, 600,1650, 600,1600, 600,1600, 600}; // NEC 4BB640BF // Вставить ИК-сигнал RAW для "Receiver Source CBL / SAT" unsigned int irRECsrc [] ={8950,4450, 600,500, 600,1650, 600,500, 600,500, 600,1650, 600,500, 600,1600, 600 , 1650, 600,1600, 600,550, 600,1600, 600,1650, 600,500, 600,1600, 600,1650, 600,500, 600,500, 600,1650, 600,1600, 600,1650, 600,500, 600,500, 600,500, 650,500 , 600,1600, 600,500, 600,550, 600,500, 600,1600, 600,1650, 600,1600, 600,1650, 600}; // NEC 4BB6708F // Создаем экземпляр сервера // указываем порт для прослушивания в качестве аргумента WiFiServer server (80); void setup () {Serial.begin (115200); задержка (10); irsend.begin (); // Подключаемся к сети Wi-Fi Serial.println (); Serial.println (); Serial.print («Подключение к»); Serial.println (ssid); WiFi.begin (ssid, пароль); в то время как (WiFi.status ()! =WL_CONNECTED) {задержка (500); Serial.print ("."); } Serial.println (""); Serial.println («WiFi подключен»); // Запускаем сервер server.begin (); Serial.println («HTTP-сервер запущен»); // Распечатать IP-адрес Serial.print ("IP-адрес:"); Serial.println (WiFi.localIP ()); if (mdns.begin ("IRBlasterLR", WiFi.localIP ())) {Serial.println ("Ответчик MDNS запущен"); } Serial.println (); Serial.println ();} void loop () {// Проверяем, подключился ли клиент WiFiClient client =server.available (); если (! клиент) {возврат; } // Дождитесь, пока клиент отправит данные Serial.println ("новый клиент"); в то время как (! client.available ()) {задержка (1); } // Считываем первую строку запроса String req =client.readStringUntil ('\ r'); Serial.println (требуется); client.flush (); // Соответствие запросу if (req.indexOf ("/ irTVpwr")! =-1) {irsend.sendRaw (irTVpwr, sizeof (irTVpwr) / sizeof (irTVpwr [0]), khz); Serial.println («IRreq irTVpwr отправлен»); } иначе, если (req.indexOf ("/ irTVsrc")! =-1) {irsend.sendRaw (irTVsrc, sizeof (irTVsrc) / sizeof (irTVsrc [0]), khz); Serial.println («IRreq irTVsrc отправлен»); } иначе, если (req.indexOf ("/ irTVmute")! =-1) {irsend.sendRaw (irTVmute, sizeof (irTVmute) / sizeof (irTVmute [0]), khz); Serial.println («IRreq irTVmute отправлен»); } иначе, если (req.indexOf ("/ irTVvdn")! =-1) {irsend.sendRaw (irTVvdn, sizeof (irTVvdn) / sizeof (irTVvdn [0]), khz); Serial.println («IRreq irTVvdn отправлен»); } иначе, если (req.indexOf ("/ irTVvup")! =-1) {irsend.sendRaw (irTVvup, sizeof (irTVvup) / sizeof (irTVvup [0]), khz); Serial.println («IRreq irTVvup отправлен»); } иначе, если (req.indexOf ("/ irTVchup")! =-1) {irsend.sendRaw (irTVchup, sizeof (irTVchup) / sizeof (irTVchup [0]), khz); Serial.println («IRreq irTVchup отправлен»); } иначе, если (req.indexOf ("/ irTVchdn")! =-1) {irsend.sendRaw (irTVchdn, sizeof (irTVchdn) / sizeof (irTVchdn [0]), khz); Serial.println («IRreq irTVchdn отправлен»); } else if (req.indexOf ("/ irALLpwr")! =-1) {irsend.sendRaw (irRECpwrON, sizeof (irRECpwrON) / sizeof (irRECpwrON [0]), khz); irsend.sendRaw (irTVpwr, sizeof (irTVpwr) / sizeof (irTVpwr [0]), khz); задержка (2000); irsend.sendRaw (irRECsrc, sizeof (irRECsrc) / sizeof (irRECsrc [0]), khz); Serial.println ("IRreq irALLpwr отправлен"); } else if (req.indexOf ("/ irRECpwr")! =-1) {irsend.sendRaw (irRECpwr, sizeof (irRECpwr) / sizeof (irRECpwr [0]), khz); Serial.println ("IRreq irRECpwr отправлен"); } else if (req.indexOf ("/ irRECpwrON")! =-1) {irsend.sendRaw (irRECpwrON, sizeof (irRECpwrON) / sizeof (irRECpwrON [0]), khz); Serial.println ("IRreq irRECpwrON отправлен"); } else if (req.indexOf ("/ irRECpwrOFF")! =-1) {irsend.sendRaw (irRECpwrOFF, sizeof (irRECpwrOFF) / sizeof (irRECpwrOFF [0]), khz); Serial.println ("IRreq irRECpwrOFF отправлен"); } else if (req.indexOf ("/ irRECmute")! =-1) {irsend.sendRaw (irRECmute, sizeof (irRECmute) / sizeof (irRECmute [0]), khz); Serial.println («IRreq irRECmute отправлен»); } else if (req.indexOf ("/ irRECvdn")! =-1) {irsend.sendRaw (irRECvdn, sizeof (irRECvdn) / sizeof (irRECvdn [0]), khz); Serial.println («IRreq irRECvdn отправлен»); } else if (req.indexOf ("/ irRECvup")! =-1) {irsend.sendRaw (irRECvup, sizeof (irRECvup) / sizeof (irRECvup [0]), khz); Serial.println ("IRreq irRECvup отправлен"); } else {Serial.println ("неверный запрос"); client.stop (); возвращение; } client.flush (); // Отправляем ответ клиенту //client.print(s); client.print ("HTTP / 1.1 200 OK \ r \ n"); задержка (1); Serial.println («Клиент отключен»); Serial.println (); // Клиент будет фактически отключен // когда функция вернется и объект client будет удален} 
script.js JavaScript
javascript для webapp (требуется jquery)
 // Функция для отправки ИК-команд function buttonClick (clicked_id) {if (clicked_id =="irTVpwr") {$ .get ("curl.php", {room:"192.168.1.62" , кнопка:"irTVpwr"}); } if (clicked_id =="irTVsrc") {$ .get ("curl.php", {room:"192.168.1.62", button:"irTVsrc"}); } если (clicked_id =="irTVmute") {$ .get ("curl.php", {комната:"192.168.1.62", кнопка:"irTVmute"}); } if (clicked_id =="irTVvdn") {$ .get ("curl.php", {room:"192.168.1.62", button:"irTVvdn"}); } если (clicked_id =="irTVvup") {$ .get ("curl.php", {комната:"192.168.1.62", кнопка:"irTVvup"}); } если (clicked_id =="irTVchup") {$ .get ("curl.php", {комната:"192.168.1.62", кнопка:"irTVchup"}); } if (clicked_id =="irTVchdn") {$ .get ("curl.php", {room:"192.168.1.62", button:"irTVchdn"}); } if (clicked_id =="irRECpwr") {$ .get ("curl.php", {room:"192.168.1.62", button:"irRECpwr"}); } if (clicked_id =="irALLpwr") {$ .get ("curl.php", {room:"192.168.1.62", button:"irALLpwr"}); } if (clicked_id =="irRECpwrON") {$ .get ("curl.php", {room:"192.168.1.62", button:"irRECpwrON"}); } if (clicked_id =="irRECpwrOFF") {$ .get ("curl.php", {room:"192.168.1.62", button:"irRECpwrOFF"}); } if (clicked_id =="irRECmute") {$ .get ("curl.php", {room:"192.168.1.62", button:"irRECmute"}); } if (clicked_id =="irRECvdn") {$ .get ("curl.php", {room:"192.168.1.62", button:"irRECvdn"}); } if (clicked_id =="irRECvup") {$ .get ("curl.php", {room:"192.168.1.62", button:"irRECvup"}); }} 
index.html HTML
Базовый HTML для отображения кнопок.
           



TV





       


Получатель





curl.php PHP
php-скрипт для отправки запросов GET на ESP8266
  
manifest.json JSON
Это позволит веб-странице работать как собственное веб-приложение в Android.
 {"name":"WiFi Remote", "icons":[{"src":"remote_icon_36.png", "sizes":"36x36" , "тип":"изображение / png", "плотность":0,75}, {"src":"remote_icon_48.png", "размеры":"48x48", "тип":"изображение / png", "плотность" :1.0}, {"src":"remote_icon_128.png", "sizes":"128x128", "type":"image / png", "density":1.0}, {"src":"remote_icon_192.png" , "sizes":"192x192", "type":"image / png", "density":1.0}], "scope":"/ remote /", "start_url":"/remote/index.html", "дисплей":"полноэкранный", "ориентация":"портрет"} 

Схема

Ничего особенного, просто питание и один контакт, подключенный к транзистору NPN, для последовательного управления двумя ИК-светодиодами (без резисторов) от напряжения питания 5 В. Если вы хотите использовать дополнительные светодиоды или требуется меньшее падение напряжения от источника 3,3 В, вы можете использовать NPN транзистор для переключения нескольких транзисторов PNP (по одному на светодиод). Эта конфигурация позволяет вам использовать столько светодиодов, для которых ваш источник напряжения может обеспечивать ток.

Производственный процесс

  1. Недостатки Wi-Fi RTLS
  2. Новая беспроводная технология 2015 г.
  3. Как установить защищенный встроенный веб-сервер на устройство Wi-Fi стоимостью 3 доллара
  4. Связь MQTT между NodeMCU и Raspberry Pi 3 B +
  5. РОБОТ МАЛИНЫ PI WIFI, УПРАВЛЯЕМЫЙ С СМАРТ-ТЕЛЕФОНА ANDROID
  6. Робот, управляемый Wi-Fi и использующий Raspberry Pi
  7. Что такое звонки по WiFi? Как это работает?
  8. IOT - Smart Jar с использованием ESP8266, Arduino и ультразвукового датчика
  9. Умный дверной замок с использованием страницы входа в WiFi от Arduino и ESP8266
  10. Что такое бисерный взрыв? Руководство по дробеструйной очистке