Arduino - модуль распознавания речи
|
|
Serg | Дата: Четверг, 03.01.2013, 16:53 | Сообщение # 1 |
Ампер
Группа: Модераторы
Сообщений: 510
Репутация: 28
Статус: Offline
| Приобрести можно здесь Попробуем обучить этот модуль для распознавания речи. Нам потребуется: 1. любая плата Arduino 2. дисплей 2 строки по 16 символов
Изначально предполагалось сделать управление самоходным шасси, но его у меня пока нет. Поэтому выведем команды на дисплей. Научившись это делать, легко можно будет управлять моторами или светодиодами.
Начинаем программировать модуль распознавания речи. Для это подключаем: Arduino----- модуль +5V ----------VCC GND ----------GND TX ------------TX RX ------------RX
Тем самым мы подключаем модуль к COM-порту компьютера. Далее нам потребуется терминальная программа для работы с СОМ-портом. Её можно скачать здесь Устанавливаем настройки СОМ-порта как на рисунке, изменив номер порта на свой.
Проверяем работоспособность модуля- посылаем команду AA BB через пробел и нажимаем SEND. В ответ приходит версия прошивки модуля и адрес производителя
Приступаем к обучению командам. Модуль имеет 3 ячейки памяти по 5 команд в каждой. Итого 15. Для начала нам достаточно будет 5 команд, поэтому открываем первую ячейку памяти командой из двух байт 0хАА 0х11. В терминале это будет выглядеть как АА 11
После команды START в окне терминала произносим в микрофон команду "ВПЕРЕД", появлятся надпись Again, ждем, молчим, снова появляется команда START. Второй раз произносим в микрофон команду "ВПЕРЕД" для подтверждения. Вслучае удачной записи появляется надпись Finish one, говорящая о том , что первая команда успешно записана. Надпись Different говорит о том, что вторая команда звучала не так, как первая и модуль ее не распознал. Надпись Too loud говорит о том, что вы слишком громко говорите в микрофон. Аналогично записываем 4 оставшихся команды -"НАЗАД", "ВЛЕВО", "ВПРАВО", "СТОП". Надпись Group1 finished ! говорит о том, что первая ячейка успешно записана
Вторая и третья ячейки памяти записываются с помощью команд 0хАА 0х12 и 0хАА 0х13 соответственно. Теперь проверяем работу модуля- посылаем два байта, которые вызовут из памяти записанные команды. Пишем в терминале АА 21 и видим в ответ Group1 Imported . Это значит, что первая группа команд готова для распознавания . Вторая и третья группы команд вызываются из памяти для распознания байтами 0хАА 0х22 и 0хАА 0х23 соответственно. Говорим в микрофон наши команды и наблюдаем в терминале ответ модуля на наши команды
Обучение закончено. Теперь пишем программу для Arduino, которая будет распознавать приходящие в UART интерфейс байты и выполнять нужные команды. В нашем случае она будет писать эти команды на дисплее. Повторюсь, что можно подключить любые внешние устройства, но у меня в наличии только дисплей. Да и русских букв в нем не оказалось, пришлось писать на английском
|
|
| |
Serg | Дата: Четверг, 03.01.2013, 16:57 | Сообщение # 2 |
Ампер
Группа: Модераторы
Сообщений: 510
Репутация: 28
Статус: Offline
| Программа для Arduino Есть некоторые ньюансы. Модуль, помимо байтов ответа, шлет еще и текст, который мы наблюдали в терминале. Поэтому необходимо избавится от текста и оставить только байты ответа. Сам текст для Arduino не интересен. Для этого существуют 2 байта 0xAA 0x37, включим их в программу. Когда придется модуль заново обучать командам, необходимо будет снова включить отображение текста в терминале. Для этого также существуют 2 байта 0xAA 0x36.
Код /* Программа демонстрации возможностей модуля голосового управвления DV ROBOT */ // подключаем библиотеку дисплея #include <LiquidCrystal.h> byte com = 0; // тут выводы для подключения дисплея LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
void setup() { Serial.begin(9600);// устанавливаем скорость UART для модуля delay(2000); Serial.write(0xAA);//избавляемся от текста Serial.write(0x37);// и оставляем байты delay(1000); Serial.write(0xAA); // вызываем из памяти Serial.write(0x21);// команды 1-ой группы delay(2000); // определяем тип дисплея lcd.begin(16, 2); // пишем приветствие lcd.print("< DV-ROBOT >"); delay(2000); }
void loop() { lcd.setCursor(0, 1);// устанавливаем курсор while(Serial.available()) { com = Serial.read();// читаем входящие байты и присваиваем значение переменной com switch(com) { case 0x11://получаем байт от команды "вперед" lcd.clear(); //очищаем дисплей от предыдущего текста lcd.print("-UP-"); //выводим текст на дисплей break;
case 0x12://получаем байт от команды "назад" lcd.clear();//очищаем дисплей от предыдущего текста lcd.print("-DOWN-");//выводим текст на дисплей break;
case 0x13://влево lcd.clear(); lcd.print("-LEFT-"); break;
case 0x14://вправо lcd.clear(); lcd.print("-RIGHT-"); break;
case 0x15://стой lcd.clear(); lcd.print("-STOP-"); break;
} }
}
Ответные команды второй и третьей ячеек памяти будут выглядеть 21, 22, 23, 24, 25 и 31, 32, 33, 34, 35 соответственно. Первая цифра -номер ячейки, вторая- порядковый номер команды.
|
|
| |
Serg | Дата: Четверг, 03.01.2013, 18:07 | Сообщение # 3 |
Ампер
Группа: Модераторы
Сообщений: 510
Репутация: 28
Статус: Offline
| Схема соединения
Теперь UART подключаем наоборот: Arduino----- модуль +5V ----------VCC GND ----------GND TX ------------RX RX ------------TX
Соединяем Arduino c дисплеем по этой схеме:
Переменный резистор здесь нужен для регулировки контрастности.
Проверяем нашу конструкцию в действии на видео.
Модуль практически не реагирует на голос друго человека.
|
|
| |
Dima | Дата: Пятница, 04.01.2013, 05:27 | Сообщение # 4 |
3.5 Вольт
Группа: Пользователи
Сообщений: 16
Репутация: 0
Статус: Offline
| Не дурно! Роботы-домохозяйки не за горами.
|
|
| |
Perdimonocle | Дата: Четверг, 31.01.2013, 16:48 | Сообщение # 5 |
1.5 Вольт
Группа: Пользователи
Сообщений: 6
Репутация: 0
Статус: Offline
| Добрый день! Команды из второй группы вызываются из памяти для распознания байтами 0хАА 0х22. А в скетче непосредственно к самим командам обращаться как? - первая команда 21 - вторая команда 22 - третья команда 23 - четвёртая команда 24 - пятая команда 25 Так?
И ещё... А если в одном скетче надо поочерёдно вызывать команды из разных групп, например, из 1-ой группы, а потом из 2-ой? Как быть?
|
|
| |
Serg | Дата: Четверг, 31.01.2013, 16:57 | Сообщение # 6 |
Ампер
Группа: Модераторы
Сообщений: 510
Репутация: 28
Статус: Offline
| 1. Правильно мыслите. 2. Пишите команды для любых групп в любых последовательностях. Только предварительно нужно эти группы вызвать из памяти.
|
|
| |
Perdimonocle | Дата: Четверг, 31.01.2013, 17:06 | Сообщение # 7 |
1.5 Вольт
Группа: Пользователи
Сообщений: 6
Репутация: 0
Статус: Offline
| Понял, спасибо! А вызывать группы из памяти можно одновременно? Если нет, то нужно ли между вызовами очищать или закрывать буфер последовательного соединения командами Serial.flush() и Serial.end() соответственно?
|
|
| |
Serg | Дата: Четверг, 31.01.2013, 17:15 | Сообщение # 8 |
Ампер
Группа: Модераторы
Сообщений: 510
Репутация: 28
Статус: Offline
| вызвать одновременно никак не получится. Весь код выполняется последовательно. Достаточно будет небольшой паузы между вызовами групп.
|
|
| |
Perdimonocle | Дата: Четверг, 31.01.2013, 17:24 | Сообщение # 9 |
1.5 Вольт
Группа: Пользователи
Сообщений: 6
Репутация: 0
Статус: Offline
| Спасибо за разъяснения! Интересное устройство...
|
|
| |
Serg | Дата: Четверг, 31.01.2013, 17:28 | Сообщение # 10 |
Ампер
Группа: Модераторы
Сообщений: 510
Репутация: 28
Статус: Offline
| тут таких таких интересных устройств целый сайт. пробуйте записывать команды тихим голосом на удалении от микрофона.
|
|
| |
cmept-27 | Дата: Пятница, 01.02.2013, 00:17 | Сообщение # 11 |
3.5 Вольт
Группа: Пользователи
Сообщений: 17
Репутация: 0
Статус: Offline
| А EasyVR Shield for Arduino нету ?
|
|
| |
Serg | Дата: Пятница, 01.02.2013, 01:11 | Сообщение # 12 |
Ампер
Группа: Модераторы
Сообщений: 510
Репутация: 28
Статус: Offline
| Если очень нужен- в магазине есть Раздел "ЗАКАЗ".
|
|
| |
Perdimonocle | Дата: Пятница, 01.02.2013, 10:42 | Сообщение # 13 |
1.5 Вольт
Группа: Пользователи
Сообщений: 6
Репутация: 0
Статус: Offline
| И всё-таки мне кажется, что предварительный вызов из памяти ни к чему не приведёт. Вот, например, кусок кода: Код byte com = 0;
void setup() { Serial.begin(9600); // устанавливаем скорость UART для модуля lcd.begin(16, 2); // set the LCD's number of columns and rows
Serial.write(0xAA); // избавляемся от текста и оставляем байты Serial.write(0x37); // переход в компактный режим delay(1000);
Serial.write(0xAA); // вызываем из памяти Serial.write(0x21); // команды первой группы delay(2000);
Serial.write(0xAA); // вызываем из памяти Serial.write(0x22); // команды второй группы delay(2000);
Serial.write(0xAA); // вызываем из памяти Serial.write(0x23); // команды третей группы delay(2000); }
void loop() { while(Serial.available()) { com = Serial.read(); switch(com) { case 0x11: lcd.clear(); lcd.print("1 Command Group"); break; case 0x21: lcd.clear(); lcd.print("2 Command Group"); break; case 0x31: lcd.clear(); lcd.print("3 Command Group"); break; } } delay(100); } В буфере последовательно порта/соединения будут только команды из третьей группы.
Получается, что вызвал из памяти команды первой группы - поработал с ними, а нужны команды из второй группы - вызывай их из памяти и пользуйся, но голосовые команды первой группы уже будут недоступны...
|
|
| |
Serg | Дата: Пятница, 01.02.2013, 11:41 | Сообщение # 14 |
Ампер
Группа: Модераторы
Сообщений: 510
Репутация: 28
Статус: Offline
| предварительно- это перед использованием. не заранее, не в начале программы.
|
|
| |
Perdimonocle | Дата: Пятница, 01.02.2013, 13:29 | Сообщение # 15 |
1.5 Вольт
Группа: Пользователи
Сообщений: 6
Репутация: 0
Статус: Offline
| И всё-таки не совсем непоняно как это осуществить на практике... Давай рассмотрим такой вариант: в третьей группе записаны команды: вперёд, назад, влево, вправо; а во второй группе - стоп. Команда "стоп" нужна для отмены команд вперёд, назад, влево и вправо.
Алгоритм такой: вызываем из памяти третью группу голосовых команд; опрашиваем последовательный порт и оператором switch..case обрабатываем произнесённую команду (вперёд, назад, влево, вправо); в теле каждого варианта (case) вызываем из памяти вторую группу голосовых команд, и во вложенном цикле опрашиваем последовательный порт и ждём команду "стоп" - пока нет команды "стоп", то выполняется последняя команда из case (вперёд, назад, влево и вправо); если "стоп", то выход из цикла в опрос команд из третьей группы...
Вот набросок скетча, но не уверен, что он рабочий... Код #if defined(ARDUINO) && ARDUINO >= 100 #include "Arduino.h" #else #include "WProgram.h" #endif
#include "LiquidCrystal.h"
LiquidCrystal lcd(48, 49, 50, 51, 52, 53);
byte voice_command = 0; byte command_stop = 0;
void setup() { Serial.begin(9600); lcd.begin(16, 2); Serial.write(0xAA); // избавляемся от текста и оставляем байты Serial.write(0x37); // переход в компактный режим модуля распознавания речи delay(1000); Serial.write(0xAA); // вызываем из памяти Serial.write(0x23); // команды 3-й группы delay(2000); }
void loop() { while(Serial.available()) { voice_command = Serial.read(); switch(voice_command) { case 0x31: // команда "ВПЕРЁД" lcd.clear(); lcd.print("FORWARD"); Serial.write(0xAA); // вызываем из памяти Serial.write(0x21); // команды 2-й группы delay(2000); while(Serial.available()) { command_stop = Serial.read(); switch(command_stop) { case 0x21: lcd.clear(); lcd.print("STOP"); break; default: // если не поступила команда "СТОП", то - пролдолжаем движение ВПЕРЁД break; } } delay(100); break; case 0x32: // команда "НАЗАД" lcd.clear(); lcd.print("REVERSE"); break; case 0x33: // команда "ВЛЕВО" lcd.clear(); lcd.print("to LEFT"); break; case 0x34: // команда"ВПРАВО" lcd.clear(); lcd.print("to RIGHT"); break; } } delay(100); }
|
|
| |
Serg | Дата: Пятница, 01.02.2013, 17:00 | Сообщение # 16 |
Ампер
Группа: Модераторы
Сообщений: 510
Репутация: 28
Статус: Offline
| да я бы с радостью, но у меня уже нет этого железа что модуль шлет в терминал в процессе отладки?
|
|
| |
Perdimonocle | Дата: Пятница, 01.02.2013, 18:59 | Сообщение # 17 |
1.5 Вольт
Группа: Пользователи
Сообщений: 6
Репутация: 0
Статус: Offline
| А у меня его тоже нет! Просто устройство заинтересовало, вот и размышляю как оно работает и стоит ли его приобрести...
|
|
| |
Serg | Дата: Пятница, 01.02.2013, 20:31 | Сообщение # 18 |
Ампер
Группа: Модераторы
Сообщений: 510
Репутация: 28
Статус: Offline
| все зависит от поставленных задач. сидишь на диване и командуешь- включи свет там, включи свят сям... включи компьютер, переключи телевизор... красота!!!! творить ,паять, кодить, радоваться успехам!!!! конечно стоит покупать!
|
|
| |
Ivan-771 | Дата: Пятница, 01.02.2013, 20:49 | Сообщение # 19 |
5 Вольт
Группа: Пользователи
Сообщений: 39
Репутация: 0
Статус: Offline
| Цитата (Serg) все зависит от поставленных задач. сидишь на диване и командуешь- включи свет там, включи свят сям... включи компьютер, переключи телевизор... красота!!!!творить ,паять, кодить, радоваться успехам!!!! конечно стоит покупать! Если всё это собрать, то будет напоминать вот этот клип.
http://www.youtube.com/watch?v=XaNuB52_Irc
|
|
| |
Sutsuko | Дата: Вторник, 22.04.2014, 02:28 | Сообщение # 20 |
5 Вольт
Группа: Пользователи
Сообщений: 42
Репутация: 0
Статус: Offline
| Здравствуйте. У меня такая задача....: 1.Имеется цепь светодиодов.(питание 12V) 2.Имеется модуль распознавания речи.(напряжение питания от 4,5 до 5,5 Вольт DC) Необходимо голосовой командой включить цепь светодиодов.
|
|
| |
DuZeR | Дата: Вторник, 22.04.2014, 12:01 | Сообщение # 21 |
5 Вольт
Группа: Пользователи
Сообщений: 42
Репутация: 2
Статус: Offline
| По вопросу вызова команд из разных групп - я делал так. В первой группе одна команда - кодовое слово для активации модуля, например "ардуино". Во второй группе перечень устройств которыми необходимо управлять, например "свет", "комп" и т.д. В третей группе действие, которое необходимо совершить, у меня - "включить" и "выключить". В начале работы выбирается первая группа. Как только модуль получает обращение к нему, то есть распознает слово "ардуино", сразу выбирается вторая группа, после распознавания устройства, например "свет", выбирается третья группа и распознается действие, например "включить". Таким образом фраза "ардуино, свет включить" приводит к срабатыванию нужного реле у меня в схеме. Команды отдаю с небольшой паузой, так как есть задержка в 2 секунды между переключением групп, для сброса состояния модуля если команда была неполной или не распознанной. После каждой распознанной группы команд модуль реагирует на команду и сбрасывается в начальное состояние.
Возможности машины зависят от фантазии человека...
Сообщение отредактировал DuZeR - Вторник, 22.04.2014, 12:05 |
|
| |
Serg | Дата: Вторник, 22.04.2014, 19:06 | Сообщение # 22 |
Ампер
Группа: Модераторы
Сообщений: 510
Репутация: 28
Статус: Offline
| Sutsuko, прочитайте первое сообщение темы. Как раз ваш случай. Только добавить реле, если цепь светодиодов мощная......
|
|
| |
Sutsuko | Дата: Среда, 23.04.2014, 01:08 | Сообщение # 23 |
5 Вольт
Группа: Пользователи
Сообщений: 42
Репутация: 0
Статус: Offline
| Цитата Serg ( ) Sutsuko, прочитайте первое сообщение темы. Как раз ваш случай. Только добавить реле, если цепь светодиодов мощная...... То что нужно реле добавить и так понятно. Какое именно реле....? Схема подключения..? Вот о чём я просил.
|
|
| |
Serg | Дата: Среда, 23.04.2014, 02:01 | Сообщение # 24 |
Ампер
Группа: Модераторы
Сообщений: 510
Репутация: 28
Статус: Offline
| Реле вот такое, а вот таким реле можно будет даже мощную лампу включать. Эти реле подключаются и управляются как обычный светодиод. Если найдете другие реле, то придется дополнительно ставить транзисторные ключи.
|
|
| |
Sutsuko | Дата: Воскресенье, 27.04.2014, 18:57 | Сообщение # 25 |
5 Вольт
Группа: Пользователи
Сообщений: 42
Репутация: 0
Статус: Offline
| Цитата Serg ( ) Реле вот такое А вот такое http://dvrobot.ru/shop/i16.rele_odinarnoe.htm реле подойдёт...???
--------------------------------------------- Цитата Serg ( ) Эти реле подключаются и управляются как обычный светодиод. При команде включить, сигнал будет постоянным...? В смысле мне нужно чтоб светодиоды светили пока не будет подана команда на выключение...
Сообщение отредактировал Sutsuko - Воскресенье, 27.04.2014, 19:31 |
|
| |
Serg | Дата: Воскресенье, 27.04.2014, 23:53 | Сообщение # 26 |
Ампер
Группа: Модераторы
Сообщений: 510
Репутация: 28
Статус: Offline
| Такое реле подойдет. Светодиоды будут светить ровно столько, сколько им будет указано светить в программе и пока есть электричество .
|
|
| |
Sutsuko | Дата: Понедельник, 28.04.2014, 00:03 | Сообщение # 27 |
5 Вольт
Группа: Пользователи
Сообщений: 42
Репутация: 0
Статус: Offline
| Спасибо.
|
|
| |
yur | Дата: Пятница, 23.05.2014, 20:57 | Сообщение # 28 |
1.5 Вольт
Группа: Пользователи
Сообщений: 1
Репутация: 0
Статус: Offline
| DuZeR, можно на ваш код взглянуть?! интересное решение, но сам его реализовать не могу..
|
|
| |
DuZeR | Дата: Воскресенье, 25.05.2014, 18:35 | Сообщение # 29 |
5 Вольт
Группа: Пользователи
Сообщений: 42
Репутация: 2
Статус: Offline
| yur, как доберусь до машины на которой код лежит - выложу
Возможности машины зависят от фантазии человека...
|
|
| |
DuZeR | Дата: Понедельник, 28.07.2014, 10:58 | Сообщение # 30 |
5 Вольт
Группа: Пользователи
Сообщений: 42
Репутация: 2
Статус: Offline
| Модуль существует в двух версиях. Тот что в магазе - требует дуино, тот что на последнем посте Sutsuko - нет. На сайте производителя есть все необходимое. PS yur, код который обещал - утерян вместе с машиной для которой создавался
Возможности машины зависят от фантазии человека...
Сообщение отредактировал DuZeR - Понедельник, 28.07.2014, 11:01 |
|
| |