В этом посте мы опишем, как использовать голос для управления устройствами IoT . Другими словами, в этой статье мы будем использовать наш голос для отправки набора команд на устройство IoT. В этом посте мы создадим голосовой проект IoT . Это интересная тема, потому что этот проект использует другой способ взаимодействия с устройством IoT. Обычно мы привыкли взаимодействовать с устройством с помощью простого пользовательского интерфейса, представленного устройством, или с помощью приложения для смартфона, которое отправляет команды на устройство.
Как использовать голос для управления устройством IoT — Обзор проекта
Идея, стоящая за этим проектом, состоит в том, чтобы изучить, как использовать голосовые команды для управления устройством, таким как Arduino или ESP8266. Чтобы создать этот голосовой активированный проект, мы разрабатываем приложение для Android, которое позволяет захватывать голос пользователя и преобразовывать его в набор команд, отправляемых на устройство. Картинка ниже описывает обзор проекта:
Более подробно этот проект сделан двумя различными подсистемами:
- Android-приложение
- IoT приложение
Приложение Android заботится о взаимодействии с пользователем и слушает голосовые команды. Затем приложение переводит голосовые команды в команды, понятные устройству IoT. В этой статье, в качестве устройства IoT, мы будем использовать ESP8266 WeMos, который управляет NeoPixel Ring. Вы можете использовать Arduino Uno вместо ESP или MKR1000.
Как разработать приложение Android для распознавания речи
Первым шагом в этом проекте является разработка приложения для Android, которое распознает речь пользователя. К счастью, Android предоставляет встроенную систему, способную распознавать пользовательские слова. Пользовательский интерфейс приложения очень прост. Для отправки команд мы используем только одну кнопку:
Расположение очень простое, как показано ниже:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
|
< android.support.constraint.ConstraintLayout android:layout_width = "match_parent" android:layout_height = "match_parent" tools:context = "com.survivingwithandroid.voice.MainActivity" android:id = "@+id/mainView" android:background = "@drawable/bg_gradient" > < Button android:layout_width = "wrap_content" android:layout_height = "wrap_content" app:layout_constraintLeft_toRightOf = "parent" app:layout_constraintRight_toLeftOf = "parent" android:text = "Send command" android:id = "@+id/btnCommand" app:layout_constraintBottom_toBottomOf = "parent" android:layout_marginBottom = "15dp" /> </ android.support.constraint.ConstraintLayout > |
Следующим шагом является переопределение в MainActivity.java
метода onCreate
:
01
02
03
04
05
06
07
08
09
10
11
12
|
@Override protected void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); btn = (Button) findViewById(R.id.btnCommand); btn.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { startVoiceCommand(); } }); } |
где startVoiceCommand()
— это метод, который обрабатывает голосовое взаимодействие с пользователем.
В этом контексте для захвата голоса пользователя приложение использует намерение, делегирующее всю тяжелую работу ОС Android:
01
02
03
04
05
06
07
08
09
10
11
12
13
|
private void startVoiceCommand() { Log.d(TAG, "Starting Voice intent..." ); Intent i = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH); i.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM); i.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault()); i.putExtra(RecognizerIntent.EXTRA_PROMPT, "Tell me, I'm ready!" ); try { startActivityForResult(i, REQ_SPEECH_RESULT); } catch (Exception e) { Snackbar.make(v, "Speech to text not supported" , Snackbar.LENGTH_LONG).show(); } } |
Этот метод очень прост, он вызывает намерение RecognizerIntent.ACTION_RECOGNIZE_SPEECH
предоставляя некоторые параметры конфигурации в качестве текущей локали и сообщения, которое мы хотим показать пользователю. Когда пользователь нажимает на кнопку, приложение показывает диалоговое окно, ожидающее голосового ввода. Наконец, приложение запускает намерение в ожидании результата:
Для этого приложение переопределяет метод onActivityResult
:
01
02
03
04
05
06
07
08
09
10
11
12
13
|
@Override protected void onActivityResult( int requestCode, int resultCode, Intent data) { super .onActivityResult(requestCode, resultCode, data); // Check the Request code if (requestCode == REQ_SPEECH_RESULT) { Log.d(TAG, "Request speech result.." ); ArrayList<String> results = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS); String command = results.get( 0 ); Log.d(TAG, "Current command [" +command+ "]" ); // Now we send commands to the IoT device } } |
В описанном выше методе приложение извлекает команду и в соответствии с ней вызывает ESP8266, чтобы установить цвет светодиодных индикаторов. В этом примере голосовое приложение Android IoT обрабатывает простые команды, такие как красный, зеленый, синий и так далее.
Как обмениваться данными с ESP8266 из приложения для Android
На этом этапе этого проекта, объясняющего, как использовать голос для отправки команд на устройство IoT, мы реализуем сетевое взаимодействие. К настоящему времени мы можем предположить, что ESP8266 предоставляет метод, который приложение Android вызывает для установки цветов звонка. В этом контексте мы можем предположить, что ESP8266 предоставляет RESTful API. Чтобы вызвать этот API, приложение использует соединение HTTP. Для этого необходимо создать новый класс IoTConnectionHandler
который обрабатывает все детали сети. Класс показан ниже:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
public class IoTConnectionHandler { private static IoTConnectionHandler me; private OkHttpClient client; private static final String TAG = IoTConnectionHandler. class .getName(); private static final String IOT_URL = private IoTConnectionHandler() { client = new OkHttpClient(); } public static IoTConnectionHandler getInstance() { if (me == null ) me = new IoTConnectionHandler(); return me; } public void sendData(String data) { Request req = new Request.Builder() .url(IOT_URL + data) .build(); client.newCall(req).enqueue( new Callback() { @Override public void onFailure(Call call, IOException e) { Log.e(TAG, "Connection error" , e); } @Override public void onResponse(Call call, Response response) throws IOException { Log.i(TAG, "Command sent" ); } }); } } |
Это очень просто и использует библиотеку OkHTTP . Обратите внимание, что параметр data
содержит шестнадцатеричный код цвета, полученный из голосовой команды.
Следующая часть реализует сторону IoT проекта, которая получает шестнадцатеричный код цвета с помощью API, предоставляемого устройством, и устанавливает цвет светодиодов.
Как разработать IoT-устройство, управляемое голосом
На этом этапе этого IoT-устройства с голосовым управлением мы разработаем код, необходимый для:
- представить API, вызванный приложением Android
- контролировать кольцо Neopixel RGB
Прежде чем углубляться в детали проекта IoT, полезно знать, как подключить ESP8266 к кольцу Neopixel RGB :
Для упрощения разработки кода устройства IoT используют эти две библиотеки:
Первая используется для управления кольцом светодиодов, а вторая библиотека необходима для представления некоторых функций в эскизе как API. Если вы новичок в этой библиотеке, вы можете прочитать мой предыдущий пост, описывающий, как представить функции Arduino как API .
Код ниже является эскизом:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
#include <Adafruit_NeoPixel.h> #include <ESP8266WiFi.h> #include <aREST.h> #define PIN D2 #define NUMS 12 #define SERVER_PORT 8080 // Neopixel rings Adafruit_NeoPixel pixels = Adafruit_NeoPixel( 12 , PIN, NEO_GRB + NEO_KHZ800); aREST rest = aREST(); char *ssid = "xxxxx" ; char *pwd = "xxx" ; // Let us create the server WiFiServer server(SERVER_PORT); void setup() { Serial.begin( 9600 ); pixels.begin(); pixels.setBrightness( 85 ); // Register the function rest.function( "ring" , setColor); WiFi.begin(ssid, pwd); Serial.println( "Connecting to WiFi..." ); while (WiFi.status() != WL_CONNECTED) { delay( 1000 ); Serial.println( "Try again...." ); } Serial.println( "WiFi connected..." ); // let us start the server server.begin(); } void loop() { WiFiClient client = server.available(); if (!client) { return ; } while (!client.available()) { delay( 1 ); } rest.handle(client); } int setColor(String color) { Serial.println( "Hex color [" + color + "]" ); long tmpColor = strtol( &( "#" + color)[ 1 ], NULL, 16 ); Serial.println( "Int [" +String(tmpColor)+ "]" ); int r = tmpColor << 16 ; int g = tmpColor << 8 & 0xFF ; int b = tmpColor & 0xFF ; Serial.print( "Red [" + String(r) + "]" ); Serial.print( "Green [" + String(g) + "]" ); Serial.println( "Blue [" + String(b) + "]" ); for ( int i = 0 ; i < 12 ; i++) pixels.setPixelColor(i, pixels.Color(r,g,b)); pixels.show(); return 1 ; } |
Подробно, в начале, эскиз пытается подключиться к сети WiFi. Для этого вы должны предоставить WiFi SSID и пароль. Как только соединение установлено, эскиз настраивает сервер и его порт. Более того, он объявляет функцию, которую мы хотим экспортировать как API.
Последняя часть — это метод, используемый для контроля кольца Неопикселя.
Как только мы отправляем голосовую команду в приложение IoT, приложение показывает эти журналы:
Резюме
В конце этого поста вы знаете, как использовать голос для управления устройством IoT. Более подробно вы узнали, как подключить приложение Android к ESP8266 и как использовать голос для взаимодействия с ним.
Опубликовано на Java Code Geeks с разрешения Франческо Аццолы, партнера по нашей программе JCG. Смотрите оригинальную статью здесь: Как использовать Voice для управления устройствами IoT с помощью Android
Мнения, высказанные участниками Java Code Geeks, являются их собственными. |