Статьи

Как использовать Voice для управления устройствами IoT с помощью Android

В этом посте мы опишем, как использовать голос для управления устройствами 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
    xmlns:tools="http://schemas.android.com/tools"
    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, являются их собственными.