Распознавание голоса на Arduino или "Do You Know What I Am Saying?"

25 апреля 2016

Фразы "О'кей, Google" и "Привет, Siri" прочно вошли в обиход у пользователей смартфонов. Голосовое управления это удобно — не надо нажимать кнопки, двигать курсором мыши в нужную область и т.д. Просто произносишь команду и ждешь ее исполнения.

Наверное каждый человек хотел бы иметь у себя дома возможность включать\выключать свет в комнате по команде, чтобы не приходилось вставать и идти к выключателю. Вариантов применения у данной технологии неизмеримое множество.

В данной статье рассмотрим один из самых простых способов научить Arduino понимать голосовые команды — Elechouse Voice Recognition Module. В качестве примера будем управлять светодиодом. Голосовой командой мы сможем его включить, выключить или заставить мигать.

Для работы нам потребуется:

Устройство собиралось на макетной плате MB-102 с джамперами.

Подключение

Подключение модуля очень простое. Всего два пина: TX и RX. Их надо подключить к выходам Arduino 2 и 3 соответственно. Запитать модуль следует от 5V.


Обучение командам

Итак, первым делом надо наш модуль обучить командам. Как было сказано выше, всего у нас три команды:

  • Зажгись
  • Выключись
  • Мигай

Откройте проект vr_simple_train, поставляем в комплекте с библиотекой VoiceRecognitionV3.

Файл — Примеры — VoiceReocgnitionV3 — vr_simple_train

Залейте этот скетч в Arduino и откройте Монитор порта (Сервис Монитор порта или нажмите Ctrl + Shift + M на клавиатуре)

Обязательно надо выставить скорость обмена (baud rate) 115200 и отправку по новой строке.

Перед нами интерфейс управления голосовыми командами. Введите в верхнее поле settings и нажмите кнопку "Послать".

Модуль ответит нам своими текущими настройками. Это значит, что все хорошо и можно приступать непосредственно к обучению команд.

За обучение командам отвечает функция sigtrain.

Введите в поле команду sigtrain 0 On и нажмите на кнопку "Послать". Команда означает, что в ячейку памяти 0 мы хотим записать команду с сигнатурой On. Сигнатура это некий уникальный ярлык, который описывает вашу команду.

Когда в окне появится фраза "Speak now", то следует проговорить в микрофон нашу команду "Зажгись".

После появления фразы "Speak again", проговорите фразу еще раз.

Если оба слова совпали, то модуль выдаст Success: 1, что означает, что мы только успешно записали команду On.

Если же модуль не смог сопоставить две голосовых команды (например, было шумно в помещении или вы произносили просто разные слова), то модуль ответит фразой "Cann't match" и предложит начать процесс записи команды еще раз до тех пор, пока не будут предоставлены верные данные.

То же самое надо проделать и с другими нашими командами "Выключись" и "Мигай", но использовать надо другие ячейки памяти (1 и 2) и другие сигнатуры (Off и Blink)

sigtrain 1 Off
sigtrain 2 Blink

Делай, что я говорю!

Модуль настроен и знает целых три команды. Залейте в Arduino следующий скетч:

#include <SoftwareSerial.h>
#include <TimerOne.h>
#include "VoiceRecognitionV3.h"
VR myVR(2, 3);    // 2:RX 3:TX, you can choose your favourite pins.
uint8_t records[7];
uint8_t buf[64];
int led = 13;
#define onRecord    (0)
#define offRecord   (1)
#define blinkRecord (2)
/**
  @brief   Print signature, if the character is invisible, 
           print hexible value instead.
  @param   buf     --> command length
           len     --> number of parameters
*/
void printSignature(uint8_t *buf, int len)
{
    int i;
    for(i = 0; i < len; i++) {
        if (buf[i]>0x19 && buf[i]<0x7F) {
            Serial.write(buf[i]);
        } else {
            Serial.print("[");
            Serial.print(buf[i], HEX);
            Serial.print("]");
        }
    }
}
/**
  @brief   Print signature, if the character is invisible, 
           print hexible value instead.
  @param   buf  -->  VR module return value when voice is recognized.
             buf[0]  -->  Group mode(FF: None Group, 0x8n: User, 0x0n:System
             buf[1]  -->  number of record which is recognized. 
             buf[2]  -->  Recognizer index(position) value of the recognized record.
             buf[3]  -->  Signature length
             buf[4]~buf[n] --> Signature
*/
void printVR(uint8_t *buf)
{
    Serial.println("VR Index\tGroup\tRecordNum\tSignature");
    Serial.print(buf[2], DEC);
    Serial.print("\t\t");
    if (buf[0] == 0xFF) {
        Serial.print("NONE");
    } else if (buf[0]&0x80) {
        Serial.print("UG ");
        Serial.print(buf[0]&(~0x80), DEC);
    } else {
        Serial.print("SG ");
        Serial.print(buf[0], DEC);
    }
    Serial.print("\t");
    Serial.print(buf[1], DEC);
    Serial.print("\t\t");
    if (buf[3] > 0) {
        printSignature(buf+4, buf[3]);
    } else {
        Serial.print("NONE");
    }
    Serial.println("\r\n");
}
void setup()
{
    myVR.begin(9600);
    Serial.begin(115200);
    Serial.println("Elechouse Voice Recognition V3 Module\r\nControl LED sample");
    pinMode(led, OUTPUT);
    if (myVR.clear() == 0) {
        Serial.println("Recognizer cleared.");
    } else {
        Serial.println("Not find VoiceRecognitionModule.");
        Serial.println("Please check connection and restart Arduino.");
        while(1);
    }
    if (myVR.load((uint8_t)onRecord) >= 0) {
        Serial.println("onRecord loaded");
    }
    if (myVR.load((uint8_t)offRecord) >= 0) {
        Serial.println("offRecord loaded");
    }
    if (myVR.load((uint8_t)blinkRecord) >= 0) {
        Serial.println("blinkRecord loaded");
    }
    Timer1.initialize(100000);
}
void timerIsr()
{
    digitalWrite(13, digitalRead(13) ^ 1);
}
void loop()
{
    int ret;
    ret = myVR.recognize(buf, 50);
    if (ret > 0) {
        switch(buf[1]){
            case onRecord:
                digitalWrite(led, HIGH);
                Timer1.detachInterrupt();
                break;
            case offRecord:
                digitalWrite(led, LOW);
                Timer1.detachInterrupt();
                break;
            case blinkRecord:
                Timer1.attachInterrupt(timerIsr);
                break;
            default:
                Timer1.detachInterrupt();
                Serial.println("Record function undefined");
                break;
        }
        printVR(buf);
    }
}

Скетч ожидает от модуля голосовую команду и исполняет ее.

Видео-демонстрация работы:


Данная статья является собственностью Amperkot.ru. При перепечатке данного материала активная ссылка на первоисточник, не закрытая для индексации поисковыми системами, обязательна.


Поделиться: