- Голосовое управление Web - сервером на WiFi модуле ESP8266-01

Голосовое и кнопочное управление через Интернет сервером на модуле ESP8266-01 с помощью Смартфона

Практика для студентов

Мясищев А.А.

Программирование миниатюрного WiFi модуля на базе новейшей микросхемы ESP8266 возможно с использованием среды разработки Arduino IDE, если загрузить туда программу ESP8266. Это позволит писать программы (sketch) с помощью известных для контроллера Arduino функций и библиотек, и запускать их прямо на ESP8266, без внешней платы Arduino. Таким образом, с программой ESP8266 и ее библиотеками модуль ESP8266 становиться платой Arduino. Программа ESP8266 поставляется с библиотеками, которые позволяют через интерфейс WiFi с помощью протоколов IP, TCP, UDP обмениваться данными с WEB, SSDP, mDNS и DNS серверами, использовать flash память для создания файловой системы, обеспечить работу с SD картами, сервоприводами, работать с периферийными устройствами по шинам SPI и I2C. Как и плата Arduino, модуль ESP8266 имеет свои программируемые выводы GPIO. Их можно использовать для управления внешними устройствами, получения данных с различных датчиков.

Модуль ESP8266-01

Цель работы.

1. На модуле ESP8266-01 построить Wifi web server для управления двумя устройствами и снятия данных с температурного датчика DS18B20.

2. Для Смартфона (планшета) написать программу для управления устройствами сервера в кнопочном режиме и в режиме голосовых команд.

Видео демонстрацию работы системы можно посмотреть здесь

Для решения этих задач выполним ряд подготовительных действий.

Рассмотрим установку программы ESP8266. Начиная с версии 1.6.4 Arduino IDE, появилась возможность установки сторонних пакетов с помощью Boards Manager.

Последовательность установки следующая:

1. Загружаем последний Arduino IDE с сайта https://www.arduino.cc и устанавливаем его на компьютер.

2. Запускаем Arduino IDE, переходим в папку Файл -> Настройки

3. Вводим http://arduino.esp8266.com/stable/package_esp8266com_index.json в Additional Board Manager URLs field.

4.Перейти к меню Инструменты -> Плата -> Boards Manager …->

5.Находим esp8266 и нажимаем install

6. После установки переходим в меню Инструменты Плата Generic ESP8266 Module:

7.Компилируем программу, которую можно набрать во встроенном редакторе Arduino IDE:

Ниже представлена программа для модуля ESP8266-01, которая представляет собой WiFi web server, управляющий двумя светодиодами(LED W - белый, LED R - красный) и снимающий показания температуры с датчика DS18B20. Управление выполняется через браузер клиента. Допустимые команды:

http://192.168.1.111:8080/whion, /whioff, /redon, /redoff, /temp, /status

#include <ESP8266WiFi.h>

#include <WiFiClient.h>

#include <ESP8266WebServer.h>

#include <OneWire.h>

#include <stdio.h>

const char* ssid = "OpenWrt"; //Подключается к точке доступа OpenWrt

char strok[30];

char buf[30];

long sec;

int ss;

IPAddress ip(192,168,1,111);

IPAddress gateway(192,168,1,1);

IPAddress subnet(255,255,255,0);

ESP8266WebServer server(8080);

OneWire ds(0); // Датчик температуры DS18B20 на GPIO - 0

const int led1 = 1; // GPIO - 1 LED R

const int led2 = 2; // GPIO - 2 LED W

void temper() {

byte i;

byte present = 0;

byte data[12];

byte addr[8];

float celsius;

if ( !ds.search(addr)) {

ds.reset_search();

delay(250);

return;

}

OneWire::crc8(addr, 7);

ds.reset();

ds.select(addr);

ds.write(0x44, 1); // start conversion, with parasite power on at the end

delay(800); // maybe 750ms is enough, maybe not

present = ds.reset();

ds.select(addr);

ds.write(0xBE); // Read Scratchpad

for ( i = 0; i < 9; i++) { // we need 9 bytes

data[i] = ds.read();

}

// Convert the data to actual temperature

// because the result is a 16 bit signed integer, it should

// be stored to an "int16_t" type, which is always 16 bits

// even when compiled on a 32 bit processor.

int16_t raw = (data[1] << 8) | data[0];

byte cfg = (data[4] & 0x60);

// at lower res, the low bits are undefined, so let's zero them

if (cfg == 0x00) raw = raw & ~7; // 9 bit resolution, 93.75 ms

else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms

else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms

//// default is 12 bit resolution, 750 ms conversion time

celsius = (float)raw / 16.0;

dtostrf(celsius,5,2,buf);

sprintf(strok,"<h1>Temperatura = %s Celsius</h1>",buf);

}

void tem(){

server.send(200, "text/html",strok);

}

void whi_on() {

digitalWrite(led2, 1);

server.send(200, "text/html","<h1>whi on</h1>");

}

void whi_off() {

digitalWrite(led2, 0);

server.send(200, "text/html","<h1>whi of</h1>");

}

void red_on() {

digitalWrite(led1, 0);

server.send(200, "text/html","<h1>red on</h1>");

}

void red_off() {

digitalWrite(led1, 1);

server.send(200, "text/html","<h1>red of</h1>");

}

void whi_sta(){

if (digitalRead(led1)==0 && digitalRead(led2)==1) server.send(200, "text/html","<h1>Status: RedOn WhiOn</h1>");

if (digitalRead(led1)==1 && digitalRead(led2)==1) server.send(200, "text/html","<h1>Status: RedOf WhiOn</h1>");

if (digitalRead(led1)==0 && digitalRead(led2)==0) server.send(200, "text/html","<h1>Status: RedOn WhiOf</h1>");

if (digitalRead(led1)==1 && digitalRead(led2)==0) server.send(200, "text/html","<h1>Status: RedOf WhiOf</h1>");

}

void root(){

server.send(200, "text/html","<h1>This is web-server on Wifi-esp-01.<br>He controls two led and temperature.<br>Command:/whion /whioff /redon /redoff /temp /status</h1>");

}

void setup(void){

pinMode(led1, OUTPUT);

pinMode(led2, OUTPUT);

digitalWrite(led1, 1);

digitalWrite(led2, 0);

WiFi.config(ip,gateway,subnet);

WiFi.begin(ssid);

// Wait for connection

while (WiFi.status() != WL_CONNECTED) {

delay(500);

}

temper();

server.on("/temp", tem);

server.on("/whion", whi_on);

server.on("/whioff", whi_off);

server.on("/redon", red_on);

server.on("/redoff", red_off);

server.on("/status", whi_sta);

server.on("/", root);

server.begin();

// Serial.println("HTTP server started");

}

void loop(void){

sec=millis()/1000;

ss=sec%60; // second

if(ss==0 || ss==30 ) {temper();

}

server.handleClient();

}

Схема подключений устройств, кнопок управления и TTL выход UART на компьютер для прошивки представлена на рисунке 1.

Рис.1. Схема подключения

Вместо USB - TTL преобразователя для подключения к компьютеру для прошивки ESP8266-01 можно использовать плату Arduino UNO. На рисунке 2 показана схема подключения Arduino и модуля ESP8266-01.

4. Блочная программа (3)

3. Блочная программа (2)

2. Блочная программа (1)

Рис.2. Схема использования Arduino UNO в качестве USB - TTL преобразователя

Reset подключен к GND для предотвращения запуска микроконтроллера. Перед прошивкой необходимо нажать на кнопу Flash Button и удерживая ее нажать Reset Button. После этого отпустить обе кнопки. Таким образом эти две кнопки нужны только для программирования.

Управлять устройствами, подключенными к серверу на модуле ESP8266-01 возможно с помощью программы web - клиента, написанного для Андроид устройства на языке визуального программирования App Inventor 2. Она управляет 2-мя устройствами (светодиодами), снимает данные с температурного датчика в кнопочном режиме и голосовыми командами, определяет текущее состояния устройств (включено или выключено).

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

https://www.youtube.com/watch?v=RpbPcLt4uvA

https://www.youtube.com/watch?v=Fr4uPvt27l0

1. Дизайн с компонентами:

(если картинку трудно различить, откройте ее в новой вкладке или скопируйте)

5. Блочная программа (4)

Пояснения к программе

Ниже приведены отдельные блоки блочной программы. Описана работа блока.

1.

Объявляется глобальная переменная tem и устанавливается ее значение в символ 0.

2.

При нажатии на кнопку Button7 (save addr1) вызывается метод StoreValue компонента TinyDB1(энергонезависимая память). Он сохраняет текст, который находится в окне TextBox1 в tag(переменную) с именем aa. Текст в это окно предварительно заносится клавиатурой телефона (планшета). Далее вызывается компонент TextBox1 со свойством Text. Содержимое окна TextBox1 обнуляется.

3.

При нажатии на кнопку Button8 (see addr1) вызывается метод GetValue компонента TinyDB1. Он с переменной aa считывает значение и распечатывает его в окне TextBox1. Если в переменной aa ничего нет, то возвращается значение valueIfTagNotThere. Там установлено пустое поле.

4.

При нажатии на кнопку Button11 ( save addr) вызывается метод StoreValue компонента TinyDB1. Он сохраняет текст, который находится в окне TextBox1 в tag(переменную) с именем adr. Текст в это окно предварительно заносится после нажатия на кнопку "see addr1" или "see addr2". Далее вызывается компонент TextBox1 со свойством Text. Содержимое окна TextBox1 обнуляется.

5.

При нажатии на кнопку Button1 (Температура) вызывается метод GetValue компонента TinyDB1. Он с переменной adr считывает значение. С помощью блока join выполняется объединение строк "http://", "строки в переменной adr" и "/temp". Если было введено имя сервера webstm32.sytes.net, формируется строка http://webstm32.sytes.net/temp. Используя свойство Url, компонента Web1 формирует HTTP GET запрос и извлекает ответ(call Web1.Get).

6.

Получение ответа от сервера порождает событие GotText компонента Web1. Здесь приведена первая и вторая неполные части проверок при порождении события GotText.

6.1.

Этот блок из полученного с сервера текста (responseContent) находит координату начала символов h1> (номер символа h с начала полученного текста)

6.2.

Здесь из текста с сервера (responseContent) начиная с начала координаты символов h1> выделяется текст длиной 14 символов. Это будет набор символов h1>Temperatura (см. программу) если будет запрошена температура (http://webstm32.sytes.net:8080/temp).

6.3.

В этой части программы сопоставляется строка, полученная в 6.2. с набором символов h1>Temperatura . Если будет совпадение выполняется блок, идущий за командой then.

6.4.

В этом блоке к найденной координате символа T строки Temperatura прибавляется число 11. Таким образом определяется координата, находящаяся сразу за строкой Temperatura .

6.5.

Этот блок распечатывает 8 символов, которые идут за строкой Temperatura . В случае нашей задачи это строка = 24.06 .

6.6.

В этом блоке строка Температура добавляется к строке в пункте 6.6. и выводится в виде текста в Label1 на экране Смартфона (планшета). Т.е. появиться строка Температура = 24.06

Аналогичные логические проверки выполняются для включения и выключения светодиодов.

6.7.

В этом блоке, если глобальная переменная tem равна символу 2, то вызывается метод Speak компонента TextToSpeech1, который синтезирует речь текста из Label1. В нашем случае произносится фраза "Температура = 24.06". После этого переменная tem принимает значение символа "0".

7.

При нажатии на кнопку Button6 (Нажми и говори) вызывается метод Speak компонента TextToSpeech1, который синтезирует речь текста "Произнесите команду".

8.

После завершения синтеза речи (произнесения фразы) порождается событие AfterSpeaking. В случае его порождения вызывается метод GetText компонента SpeechRecognizer1. После звукового сигнала включается микрофон Смартфона и выполняется прослушивание произносимой фразы.

9.

После произнесения фразы, которая заканчивается сигналом, порождается событие AfterGetting. Результатом является распознанный текст, который на экране Смартфона помещается в Label5. Далее выполняются проверки. Если распознанный текст "температура", то на основании вышеизложенного идет обращение по адресу http://webstm32.sytes.net/temp с извлечением ответа(call Web1.Get) от сервера. Глобальная переменная устанавливается в символьное значение "2".

Таким образом программа на Смартфоне работает следующим образом:

1. Случай установки адреса сервера. Поддерживается два адреса, например, глобальный и локальный.

1.1. Нажимаем на поле TextBox1 и с клавиатуры вводим имя или адрес сервера. Например webstm32.sytes.net:8080

1.2. Нажимаем на кнопку save addr1 для запоминания имени. Вместо имени можно вводить IP адрес.

1.3. С помощью кнопки see addr1 можно вывести запомненный адрес. Нажав на кнопку save addr мы делаем этот адрес доступным Смартфону даже при его отключении.

2. Случай управления кнопками.

2.1. При нажатии на кнопки "Включить белый", "Включить красный" включаются белый и красный светодиоды. Состояние светодиодов отображается на экране в полях Label2 и Label7. При нажатии на кнопку "Температура" отображается температура в поле Label1.

2.2. Аналогично при нажатии на кнопки "Выключить белый", "Выключить красный".

2.3. При нажатии на кнопку "Состояние системы" в Label6 распечатывается состояние светодиодов.

3. Случай управления голосом.

3.1. При нажатии на кнопку "Нажми и говори" запускается синтезатор речи и Смартфоном произносится фраза "Произнесите команду". Появляется звуковой сигнал, включается микрофон и Смартфон ожидает произнесения фразы. После произнесения фразы появляется звуковой сигнал и происходит распознавание фразы серверами google. После распознавания результат выводится в поле Label5.

3.2. При произнесении по отдельности фраз "Включить белый", "Включить красный" включаются белый и красный светодиоды. Состояние светодиодов отображается на экране в поле Label2 и Label7. При произнесении фразы "Температура" отображается температура в поле Label1. После произнесения фраз синтезатор речи подтверждает исполнение команды.

3.3. Аналогично при произнесении фраз "Выключить белый", "Выключить красный".

3.4. Если произносятся фразы, входящие в перечень известных Смартфону команд, автоматически запускается голосовой распознаватель для прослушивания следующей команды. При произнесении фразы не входящей в набор команд, распознавание голоса завершается.

Выводы.

1. Относительно простое программирование модуля ESP8266-01 с помощью среды разработки Arduino IDE.

2. Простота программирования Смартфона в среде App Inventor 2.

3. Дешевизна модуля ESP8266-01 (Примерно в 2,5 раза дешевле Arduino UNO)

4. Стабильность работы для решения задач управления бытовыми устройствами через Интернет.

5. Недостатки. Ограниченное количество выводов для управления устройствами у модуля ESP8266-01(4 - вывода включая RXD, TXD). Как следствие - установка IP параметров, имени точки доступа и пароля входа в неё возможно лишь в программе с последующей ее компиляцией и перепрошивкой модуля.

Написано 11.11.2015