Добавление голосовых команд в ваш следующий проект с помощью Bluetooth LE
Этот проект использует Alorium Technology XLR8, внедрение Bluetooth LE HID и модуль распознавания голоса EasyVR для добавления движений, активированных голосом, в ваш следующий проект. Или вы можете использовать идеи для создания пульта дистанционного управления с голосовым управлением.
О проекте
В этом проекте используется технология Alorium XLR8 для интеграции модуля распознавания голоса с Bluetooth HID-устройством для создания удаленного голосового контроллера. На рынке много мельниц, токарных станков, плазменных столов и принтеров, которые контролируются компьютерными клавиатурами. Часто операторы обнаруживают, что часть машины необходимо перемещать во время загрузки и выгрузки машины, когда оператор обрабатывает материалы и уходит с компьютера.
Этот проект обнаруживает вербальные команды и передает нажатия клавиш через Bluetooth LE, когда руки оператора машины слишком полны, слишком грязны или слишком далеки, чтобы безопасно управлять элементами управления. Он также воссоздает отчеты HID Keyboard для «Page Up», «Page Down» и клавиатуры «Arrow Keys», которые соответствуют направлениям движения для популярного контроллера CNC Mach3.
В качестве альтернативы используйте идеи, оборудование и код, приведенные здесь, чтобы создать другой проект - пульт дистанционного управления с голосовым управлением, голосующе активированную мышь или голосовой активированный робот.
Завершенный проект не требует подключения к Интернету.
Требуется часть | Стоимость | Больше информации |
---|---|---|
Alorium Technology XLR8 | $ 75 | Обзор продукта | Веб-сайт |
Adafruit Bluefruit LE Shield | $ 20 |
Веб-сайт Веб-сайт |
EasyVR Shield и модуль | $ 52 | Руководство EasyVR |
Bluetooth 4.0 USB Dongle | ~ $ 10 | Приобретайте любой совместимый с Bluetooth 4.0 |
Динамик 8 Ом | $ 5 | Динамик не является обязательным, но рекомендуется |
Блок питания 5 В | $ 10 | Любые поставки 5V-1A (или более) должны делать. |
Alorium Technology XLR8
Alorium Technology XLR8 является заменой для Arduino Uno R3. Он был разработан, чтобы позволить пользователям Arduino Uno R3 повысить производительность и возможности без полной перестройки своих проектов для более продвинутого 16- или 32-разрядного микроконтроллера. XLR8 использует Altera MAX 10 FPGA для эмуляции функции Arduino (набор инструкций ATmega328). Плата построена по размерам UNO R3 и физически смоделирована из SparkFun RedBoard. Для этого проекта AloriumTech предоставила плату XLR8.

Развязка XLR8 от технологии Alorium
Не все 50 000 логических элементов на FPGA необходимы для воссоздания Arduino, что оставляет много возможностей для конфигурируемых «блоков Xcelerator», которые обеспечивают улучшенную производительность и реакцию на ATMega328 в нескольких областях.

Представление использования ворот на FPGA от Alorium Technology
Блоки XLR8 включаются и загружаются в виде библиотек через IDE Arduino, и конечный пользователь никогда не должен знать, что они используют FPGA вместо 8-разрядного микроконтроллера. Текущие блоки XLR8 включают в себя NeoPixel Control, сервоуправление, математику с плавающей запятой и расширенный аналого-цифровой преобразователь (ADC) (12-разрядное разрешение при 154k выборках в секунду). Дополнительные улучшения включают дополнительные порты последовательного периферийного интерфейса (SPI).
XLR8 также можно использовать для разработки FPGA, посетите эту страницу для получения дополнительной информации.
Начало работы с XLR8.
BlueFruit LE Shield
Этот экран взаимодействует с контроллером хоста через SPI. Этот модуль может быть настроен для различных применений, которые варьируются от прозрачного режима UART до эмуляции клавиатуры HID и отвечает на полный набор команд AT, реализованный Adafruit. Для этого проекта AAC приобрел Bluefruit LE Shield.

Изображение Щита Bluefruit LE от Адафрута
Чтобы использовать этот экран с XLR8, подключите SPI CLK (контакт 13) к GND с резистором 100 Ом - 200 Ом.
EasyVR
EasyVR Shield и модуль - это многоязычный модуль распознавания голоса, который может распознавать запрограммированные и запрограммированные пользователем голосовые команды и выполнять произвольный код на Arduino. Он запрограммирован через 6-контактное соединение UART (J7) или с Arduino, подключив модуль к экрану. Для этого проекта AAC приобрела щит и модуль.

Передняя и задняя части легкого модуля VR 3.0
Веб-страница продукта показывает, что этот модуль оснащен 26 независимыми от колонки командами (на английском, итальянском, японском, немецком, испанском и французском языках) и может быть запрограммирован с дополнительными командами, зависящими от динамиков. Он также может выводить 21 минуту предварительно записанных звуков или речи и может записывать и воспроизводить до 120 секунд живых сообщений. Модуль может быть запрограммирован с компьютером или без него. Я рекомендую использовать компьютер и входящее в комплект программное обеспечение EasyVR Commander.
Обзор проекта
Для этого проекта модуль EasyVR 3.0 будет подключен к экрану EasyVR Shield, его цель - распознать ключевые слова и предупредить Alorium Technology XLR8. Затем Alorium Technology XLR8 отправит соответствующие команды на Bluefruit LE Shield. Bluefruit LE Shield подключается к USB-интерфейсу Bluetooth, подключенному к компьютеру.

Обзор подключения к проекту
На этой плате используется щит SPID Adafruit Bluefruit и экран EasyVR3.0, уложенный поверх Alorium Technology XLR8.

По часовой стрелке слева вверху: верхняя и нижняя стороны экрана Bluefruit LE, полный проект, верх и низ экрана EasyVR 3.0
Настройка экрана EasyVR
Вы можете припаять модуль непосредственно к экрану с включенными гнездами для мужчин, но его будет очень сложно удалить позже. Если это вызывает беспокойство, прикрепите гнезда к экрану и гнездам к модулю.
Вы должны переместить резисторы SMD в нижней части платы с надписью «101». Продукт отправляет соединение Tx / Rx на контакты 12/13, но чтобы избежать конфликта с другим экраном, Tx / Rx необходимо подключить к контактам 8/9.
Настройка экрана Bluefruit
Паяные штабелируемые заголовки на щите Bluefruit. Используйте острый нож, чтобы сломать трассу, соединяющую CS, с контактом 8 и снова подключить CS к контакту 10. Поместите резистор 100 Ом - 200 Ом на макет экрана экрана и используйте его для подключения штыря SPI CLK (13) к заземлению,
Bluefruit Bluetooth Справочная информация
Низкая энергия Bluetooth (BLE)

Изображение предоставлено Aislelabs
Bluetooth позволяет осуществлять передачу данных с малой дальности между совместимыми устройствами. К счастью для нашего проекта, Adafruit проделал тяжелую работу по внедрению стека протоколов и оставил нам устройства, которые можно относительно быстро и легко запрограммировать для достижения желаемой цели. Все их продукты тщательно документированы одним или несколькими примерами проектов на веб-сайте Adafruit, и все программное обеспечение и прошивку можно найти здесь.
О соединениях Bluetooth
Два устройства Bluetooth в радиодиапазоне друг друга начинают процесс запроса. Устройство отправляет запрос, а другое устройство отвечает на запрос с его MAC-адресом, именем и другими дескрипторами. Страница устройств (подключается) друг к другу по адресу, отправленному во время запроса. При подключении устройства соединяются и обмениваются информацией о безопасности друг с другом, часто с некоторыми типами аутентификации. Пока они сопряжены, устройства связывают и сохраняют информацию аутентификации, чтобы они могли автоматически подключаться, когда они находятся в пределах друг от друга.
Во время прототипирования часто необходимо вернуть устройство Bluefruit в заводское состояние, удалив сохраненную информацию о связях. К сожалению, USB-ключ Bluetooth, подключенный к компьютеру, не будет знать, что ваше устройство перезагрузилось.
Устройство Bluefruit снова начинает процесс на этапе запроса, в то время как устройство на компьютере уже завершило этап склейки, и устройства никогда не будут подключаться. Чтобы исправить это, удалите информацию устройства Bluefruit с компьютера и повторите процесс. Когда вы закончите прототипирование, удалите флаг программного обеспечения, который позволяет сбросить заводские настройки, чтобы устранить эту проблему.
Обновление Bluefruit
Оба устройства Bluefruit можно подключить и обновить по беспроводной сети с помощью приложения Adafruits «Bluefruit» и инструкций на их странице - приложение доступно в Apple App Store и в Google Play.
Конфигурация Bluefruit
Bluefruit SPI необходимо настроить как клавиатуру - это достигается с помощью серии AT-команд. Во-первых, измените имя на что-то значимое.
ble.sendCommandCheckOK ("AT + GAPDEVNAME = AllAboutCircuitsKeyboard")
Затем устройству необходимо включить службы и рекламировать, что это устройство интерфейса пользователя (HID), изменив его общий ATTribue (GATT).
ble.sendCommandCheckOK (F ("AT + BleHIDEn = Вкл.")
Затем включите функциональность клавиатуры.
ble.sendCommandCheckOK (F ("AT + BleKeyboardEn = Вкл.")
Из-за изменения услуг требуется мягкий перезапуск.
ble.reset ()
Отправка печатных и непечатаемых символов и комбинаций клавиш
Устройство Bluefruit теперь может отправлять печатные и непечатаемые символы на связанное устройство. Многие символы легко отправлять - большинство кодов символов ASCII, отправленных по линии UART Rx, будут интерпретироваться и передаваться на удаленное устройство с подключенным Bluetooth без дополнительной работы.
Микроконтроллер, который передает UART Rx Bluefruits по адресу 115200 Baud (8, N, 1), сможет печатать или записывать символы в последовательную линию и отображать их на экране компьютера. Bluefruits запрограммированы на получение кода ASCII и преобразование его в код Bluetooth HID, и этот код ключа отправляется на удаленный компьютер.
Непечатаемые символы и комбинации клавиш (Ctrl-Alt-Delete, Shift + стрелка вверх, отключение звука, громкость, функциональные клавиши и т. Д.) Должны быть доставлены на устройства Bluefruit в виде HID Keyboard Reports.
Оба устройства Bluefruit могут отправлять печатные и непечатаемые символы через отчеты Bluetooth HID. Для отправки непечатаемого символа (или символов) требуется строка шестнадцатеричных символов, за которой следует код выпуска.
ble.println ("AT + BLEKEYBOARDCODE = 02-00-04-00-00-00-00")
ble.println ("AT + BLEKEYBOARDCODE = 00-00")
** Примечание. Это эквивалентно нажатию и отпусканию (Shift) + (a) на клавиатуре и немедленному освобождению
Коды HID не совпадают с кодами American Standard Code for Information Exchange (ASCII). Коды ASCII имеют уникальный номер, назначенный каждому символу, в ASCII, «A» - 65, а «a» - 97. Ключи HID используют ключи-модификаторы для расширения ограниченного числа базовых кодов. Последовательность клавиш HID для «a» составляет «00-00-04», а для «A» - «02-00-04». Первый байт изменяет следующие символы.
Второй байт, который следует за модификатором, зарезервирован и всегда равен 0x00. Третий байт - это ключ, который вы хотите нажать (опять же, используя коды HID Key, а не ASCII). В строку может быть отправлено до четырех дополнительных кодов клавиш, что позволяет использовать сложные макрокоманды с несколькими ключами. Затем убедитесь, что клавиши освобождены, отправив «00-00». Используя этот метод, вы можете дублировать любое нажатие клавиши, любую комбинацию клавиш и любую комбинационную последовательность для управления практически любой компьютерной программой или подключенным к Bluetooth устройством - будь то добавление голосовых команд, которые позволяют быстро переадресовывать в Adobe Premiere, или создание пользовательских комбинаций игрового контроллера для игровой консоли.
Таблицы использования HID содержат полный список кодов клавиш и модификаторов.
Подготовка программного обеспечения EasyVR
Загрузите и установите программное обеспечение EasyVR Commander со страницы продукта. Он устанавливает программы QuickSynthesis (Sensory-> QuickSynthesis), Easy VR Commander (Veear-> EasyVR Commander) и QuickT2SI (Sensory-> QuickT2SI).
Quick Synthesis (дополнительно - добавляет больше звуков в ваш модуль)
Quick Synthesis позволяет вам создавать собственные звуки для вашего модуля. Модуль EasyVR имеет один встроенный звуковой сигнал, но, устанавливая дополнительные звуки, вы можете программно связать звуки с событиями, чтобы обеспечить слышимую обратную связь для успехов и ошибок распознавания голоса.
- Выберите несколько звуков WAV для использования. Используйте веб-сайт, например //www.bfxr.net/, чтобы создать и сохранить три или более пользовательских звука WAV в папку на вашем компьютере.
- Открытый сенсорный QuickSynthesis:
-
Выберите Файл »Создать
В командной строке выберите «RSC4 Family»
- Введите имя для своего проекта и сохраните как тип «.qxp»
-
Выберите «Редактировать» Добавить файл WAV
Перейдите в папку на компьютере, на которой были сохранены ваши WAV-файлы, и выберите все, что вы хотите использовать.
Нажмите Открыть.
-
В командной строке используйте значения по умолчанию:
SX-6 8K: 7800 бит / с
☑ Включить детектирование тишины
Сжатие динамического диапазона: нет
Высокочастотный предварительный упор: нет
Отказ от воспроизведения: нет
Выберите «Ok for All»
Выберите «Auto Label All»
- Выберите «Сжать» »Сжать
-
Выберите «Build» Build
☑ Создать модуль связи (в большинстве случаев)
☑ Загрузка в пространстве CONST (совместное использование ROM с программой)
☑ Нагрузка выше или равна 0
◻ Включить данные Lipsync
Выберите "Ok"
Выберите «Файл» Сохранить
Выберите «Файл» «Выход».
-
Легкий VR Commander (обязательно)
Easy VR Commander позволяет записывать слова Speaker Dependent в 15 разных группах, а также позволяет записывать пользовательское слово «Trigger» в дополнение к предопределенному триггерному слову «Robot». По умолчанию динамик Независимые слова, встроенные в модуль, включают в себя «Робот», «Действие», «Перемещение», «Поворот», «Выполнить», «Смотри», «Атака», «Стоп», «Привет», «Влево», «Вверх», «Вниз», «Вперед», «Вперед», «Нуль», «Один», «Два», «Три», «Четыре», «Пять», «Шесть», «Семь», «Восемь», «Девять» и «Десять». Все слова (зависимый от динамика и независимый динамик), если обнаружены, могут использоваться для выполнения произвольного кода на Arduino.
- Начните с подключения вашего модуля EasyVR к экрану Easy VR и экрана Easy VR в ваш XLR8. Установите перемычку на экране в положение обновления (UP).
- Выберите «Файл» Порт »COM X (где X - адрес порта UART в месте расположения платы микроконтроллера хоста):
- Выберите Справка »Обновить прошивку
- Перейдите к прошивке в каталоге установки «C: \ Program Files (x86) VeeaR \ EasyVR Commander \ EasyVR3_VW_REV4. EVRFW"
- Выберите Открыть
- ☑ Медленная передача
- Выберите Загрузить
- После завершения обновления прошивки отсоедините плату микроконтроллера хоста от питания и USB, а затем переместите перемычку на щит на «ПК». Подключите микроконтроллер хоста к электропитанию и USB.
- В Easy VR Commander выберите File »Connect
- Выберите группу «Триггер».
- Выберите «Редактировать» Добавить команду
- Введите имя для вашей команды Trigger (например, «Компьютер»)
- Выберите «Редактировать». Команда «Поезд»:
- Выберите Фазу 1.
- Говорите свое слово в микрофон.
- Выберите Фазу 2.
- Говорите свое слово в микрофон.
Программное обеспечение QuickT2SI
QuickT2SI позволяет еще больше настраивать модуль, добавляя дополнительные ключевые слова для независимого распознавания. Однако это не бесплатный продукт и не нужен для этого проекта, поэтому ничего не нужно делать. Чтобы узнать больше обо всех продуктах (и посмотреть видеоролики YouTube о том, как пройти предыдущие шаги), посетите //www.veear.eu/demos/.
Подготовка Bluefruit
- Зайдите в Apple App Store или в магазин Google Play и загрузите бесплатное приложение под названием «Bluefruit» от Adafruit Industries.
- Подключите Bluefruit к плате XLR8 и подключитесь к электросети.
- Используйте приложение Bluefruit на своем телефоне, чтобы подключиться к модулю и позволить ему обновляться.
- Перейдите в настройки Bluetooth вашего телефона и «забудьте» модуль Bluefruit.
Подготовка среды разработки Arduino
- Загрузите и установите последнюю версию IDE Arduino.
- Выбрать эскиз »Включить библиотеку» Управление библиотеками
- Найдите и установите «Easy VR»
- Поиск и установка библиотек «Adafruit nRF51»
- Выберите «Закрыть»
- Выберите «Файл» Настройки
Под URL-адресами дополнительных плат администрирования введите или добавьте (после добавления запятой) //raw.githubusercontent.com/AloriumTechnology/Arduino_Boards/master/package_aloriumtech_index.json в текстовое поле.
- Выберите Инструменты »Доска» «XLR8 Ver 2»
Тестирование XLR8
- Откройте Arduino IDE.
- Выберите Файл »Примеры» XLR8Infor »GetXLR8Version
- Выберите Инструменты »Доска» XLR8 Rev 2
- Выберите «Инструменты» FPGA Image »16 МГц Float, Servo, Neopixel r1682
- Выберите Инструменты »Программист» AVRISP mkII
- Выбрать эскиз »Загрузить
- Выберите Инструменты »Последовательный монитор
- Выберите 115200 В раскрывающемся списке в нижнем правом углу последовательного монитора
Идеи устранения неполадок XLR8
- Нет видимого COM-порта: вам необходимо установить драйверы FTDI. Посетите сайт //learn.sparkfun.com/tutorials/how-to-install-ftdi-drivers
- Данные последовательного порта искажены: убедитесь, что вы выбрали 115200 Baud
- Выберите «Инструменты» FPGA Image »16 МГц Float, Servo, Neopixel r1682. Затем выберите «Инструменты». Записать загрузчик.
- Посетите страницу поддержки AloriumTech, чтобы загрузить и прочитать последнее руководство пользователя (PDF).
Тестирование экрана EasyVR
- Присоедините экран EasyVR Shield к плате XLR8.
- Убедитесь, что перемычка находится в положении «SW».
- Подключите плату XLR8 к доступному порту USB на вашем компьютере с помощью кабеля mini-USB.
- В среде разработки Arduino:
- Выберите файл »Примеры» Easy VR »TestEasyVR
- Измените строку 64 из «SoftwareSerial port (12, 13)»; на «SoftwareSerial port (8, 9)»;
- Выбрать эскиз »Загрузить
- Выберите Инструменты »Последовательный монитор
Идеи для устранения неполадок EasyVR
- Дважды проверьте всю пайку (обратите внимание на холодные паяные соединения, мосты припоя и ошибки вокруг резистора 100 Ом).
- Двойное расположение перемычки.
- Посетите сайт //www.veear.eu/faq/.
Тестирование щита Блуфрута
- Прикрепите только щит Bluefruit к плате XLR8.
- Подключите плату XLR8 к доступному порту USB на вашем компьютере с помощью кабеля mini-USB.
- В среде разработки Arduino:
- Выбрать файл »Примеры» Adafruit nRF51 »HID Keyboard
- Выбрать эскиз »Загрузить
- Выберите Инструменты »Последовательный монитор
- Перейдите в настройки вашего компьютера, найдите и добавьте устройство.
Идеи для поиска Bluefruit
- Используйте USB-адаптер Bluetooth 4.0 или выше.
- Убедитесь, что вы можете подключиться и отключиться от Bluefruit с помощью вашего телефона (Bluefruit не будет подключаться к вашему компьютеру при подключении к вашему телефону).
- Отключите флаг «Factory Reset».
- Посетите сайт //forums.adafruit.com и //learn.adafruit.com.
Все вместе
Подключите экран Bluefruit в XLR8 и подключите экран EasyVR к экрану Bluefruit. Убедитесь, что перемычка режима находится в положении «SW». Загрузите код ниже в Arduino IDE и загрузите его на плату XLR8.
О кодексе
В этом эскизе широко используются случаи переключения, чтобы отображать ошибки, возвращенные из Easy VR, в переменную с именем «Err» и изменять значения двух изменчивых переменных, называемых «Направление» и «Повторения». Если обнаружено ключевое слово Speaker Dependent «Computer», эскиз ожидает следующего прослушивания направления, а затем несколько раз, чтобы повторить нажатие клавиши.
В разных обстоятельствах может потребоваться, чтобы клавиша нажата в течение более длительного времени, а не нажималась быстро несколько раз. Это можно сделать, вставив задержку перед отправкой команды «00-00», которая освобождает все нажатые клавиши. Эскиз делает обширные (хотя и еще не завершенные) усилия по обработке ошибок и возвращает полезную отладочную информацию пользователям через последовательный порт.
Если обнаружено ключевое слово Speaker Independent «Robot», код будет повторять все символы, введенные в последовательный монитор, до тех пор, пока не будет обнаружен CR \ NL, после чего он снова начнет прослушивать триггерные слова.
/******************************************************************************************************/ /*************** Alorium Technology XLR8, EasyVR 3.0, Adafruit Bluefruit SPI Integration *************/ /******************************************************************************************************/ /* This program allows users to create a voice-activate keyboard that can send desired keypresses and keycodes. Alorium Technology XLR8 Board | //aloriumtech.com Easy VR 3.0 Board | //Veear.eu Bluefruit SPI Shield | //adafruit.com ARDUINO IDE INSTRUCTIONS In Arduino IDE, add "Adafruit Bluefruit NRF41" and "EasyVR" libraries. Boards tested include XLR8 and Sparkfun Redboard EASYVR V3.0 or SHIELD SETUP INSTRUCTIONS If using the shield note jumper location (should be in SW position. Hot air rework component marked "101" (100Ω resistor) connecting TX/RX pins 12/13 to 8/9 to avoid conflict with Bluefruit Shield. Alternatively, remove mode jumper and wirewrap GND, 5V to Arduino Gnd and 5V, and module Tx/Rx to Arduino pins 8/9 (Tx -> 8, Rx -> 9) BLUEFRUIT SHIELD SPI SETUP INSTRUCTIONS Solder 2x6, 2x8, 2x8, and 2x10 pass-through headers on the shield. On the underside of the shield, break the trace between CS and pin 8 and reattach CS to pin 10 with wirewrap or other method. Program by Mark Hughes for AllAboutCircuits.com. Code is based and heavily influenced by examples provided by Adafruit.com (lady ada, Kevin Townsend) and Veear.eu (library examples) */ // Software Includes #include// #include#include// #include#include// #include#include// #include#include// #include#include// #include#include// #include// Pin Definitions #define BLUEFRUIT_SPI_SCK 13 // Attach 100Ω Pull-Down Resistor #define BLUEFRUIT_SPI_MISO 12 // #define BLUEFRUIT_SPI_MOSI 11 // #define BLUEFRUIT_SPI_CS 10 // Default pin 8 conflicts with EasyVR shield #define BLUEFRUIT_SPI_IRQ 7 #define BLUEFRUIT_SPI_RST 4 #define EasyVR_RX 8 // Must move resistors on shield from pins 12/13 #define EasyVR_TX 9 // to pins 8/9 to avoid SPI conflict // Constants #define BUFSIZE 128 // Size of the read buffer for incoming data #define VERBOSE_MODE false // If set to 'true' enables bluefruit debug output #define pcSerial SERIAL_PORT_MONITOR // Used to debug and send keystrokes #define FACTORYRESET_ENABLE 0 // Set to 1 to reset bluefruit #define MINIMUM_FIRMWARE_VERSION "0.6.6" // Global Variables volatile char directions; // Shortcut to pass value without rewriting function volatile char repetitions; // Shortcut to pass value without rewriting function // Create Easy VR on a Software Serial Port SoftwareSerial port(EasyVR_RX, EasyVR_TX); // Create a software serial port EasyVR easyvr(port); // Attach EasyVR to software serial port //Create Bluefruit object with SPI Adafruit_BluefruitLE_SPI ble(BLUEFRUIT_SPI_SCK, BLUEFRUIT_SPI_MISO, BLUEFRUIT_SPI_MOSI, BLUEFRUIT_SPI_CS, BLUEFRUIT_SPI_IRQ, BLUEFRUIT_SPI_RST); void error(const __FlashStringHelper*errorText) { // Print errors using pointer Serial.println(); Serial.println(errorText); } //Groups and Commands enum Groups { GROUP_0 = 0, }; // Default start keyword "Robot" enum Group0 { G0_COMPUTER = 0, }; // Trained keyword "Computer" //Grammars and Words enum Wordsets {SET_1 = -1, SET_2 = -2, SET_3 = -3}; // Action, Direction, Scale enum Wordset1 { S1_ACTION = 0, S1_MOVE = 1, S1_TURN = 2, S1_RUN = 3, S1_LOOK = 4, S1_ATTACK = 5, S1_STOP = 6, S1_HELLO = 7 }; enum Wordset2 { S2_LEFT = 0, S2_RIGHT = 1, S2_UP = 2, S2_DOWN = 3, S2_FORWARD = 4, S2_BACKWARD = 5 }; enum Wordset3 { S3_ZERO = 0, S3_ONE = 1, S3_TWO = 2, S3_THREE = 3, S3_FOUR = 4, S3_FIVE = 5, S3_SIX = 6, S3_SEVEN = 7, S3_EIGHT = 8, S3_NINE = 9, S3_TEN = 10}; int8_t group, idx; // use negative group for wordsets void setup() { pcSerial.begin(115200); // setup PC serial port Serial.print(F("Initialising the Bluefruit LE module: ")); if (!ble.begin(VERBOSE_MODE)) { error(F("Couldn't find Bluefruit, make sure it's in CoMmanD mode & check wiring?")); } Serial.println(F("OK!")); if (FACTORYRESET_ENABLE) { /* Perform a factory reset to make sure everything is in a known state */ Serial.println(F("Performing a factory reset: ")); if (! ble.factoryReset()) { error(F("Couldn't factory reset")); } // end ! ble.factoryReset() } // end FACTORYRESET_ENABLE ble.echo(false); Serial.println("Requesting Bluefruit info:"); ble.info(); // Print Bluefruit information Serial.println(F("Setting device name to 'AACVoiceKeyboard': ")); if (! ble.sendCommandCheckOK(F("AT+GAPDEVNAME=AACVoiceKeyboard"))) { pcSerial.println(F("Could not set device name!")); } /* Enable HID Service */ Serial.println(F("Enable HID Service (including Keyboard): ")); if (ble.isVersionAtLeast(MINIMUM_FIRMWARE_VERSION)) { if (!ble.sendCommandCheckOK(F("AT+BleHIDEn=On"))) { pcSerial.println(F("Could not enable Keyboard")); } else { if (! ble.sendCommandCheckOK(F("AT+BleKeyboardEn=On"))) { pcSerial.println(F("Could not enable Keyboard")); // End if } } } //end if(min version) /* Add or remove service requires a reset */ Serial.println(F("Performing a SW reset (service changes require a reset): ")); if (! ble.reset()) { pcSerial.println(F("Couldn't reset")); } Serial.println(); Serial.println(F("Go to your devices Bluetooth settings to pair your device")); Serial.println(F("then open an application that accepts keyboard input")); Serial.println(); bridge: // bridge mode? int mode = easyvr.bridgeRequested(pcSerial); switch (mode) { case EasyVR::BRIDGE_NONE: /* attempt to communicate at 115200 baud. If not, establish communication at 9600 baud and change settings */ port.begin(115200); // Communicate at 115200 baud if (!easyvr.detect()) { // If easyVR doesn't respond, port.end(); // close port port.begin(9600); // Communicate at 9600 baud if (!easyvr.detect()) { // If easy VR doesn't respond, error error(F("No EasyVR Detected at 9600 or 115200 Baud. Check Jumper Settings.")); } else { // If easy VR does respond, change baud. if (easyvr.changeBaudrate(EasyVR::B115200)) { pcSerial.println("Baud rate increased from 9600->115200 Baud"); port.end(); // Need to stop 9600 baud communication port.begin(115200); // Reestablished at 115200 baud until next reboot. } // end if(easyvr.changebaurrate) } // end else } // end if(!easyvr.detect() pcSerial.println(F("Bridge not requested, run normally")); pcSerial.println(F("---")); break; case EasyVR::BRIDGE_NORMAL: port.begin(9600); // setup EasyVR serial port (low speed) // soft-connect the two serial ports (PC and EasyVR) easyvr.bridgeLoop(pcSerial); // resume normally if aborted pcSerial.println(F("Bridge connection aborted")); pcSerial.println(F("----------------")); break; case EasyVR::BRIDGE_BOOT: // setup EasyVR serial port (high speed) port.begin(115200); pcSerial.begin(115200); // soft-connect the two serial ports (PC and EasyVR) easyvr.bridgeLoop(pcSerial); // resume normally if aborted pcSerial.println(F("Bridge connection aborted")); pcSerial.println(F("---")); break; } // end Switch mode // initialize EasyVR while (!easyvr.detect()) { pcSerial.println(F("EasyVR not detected!")); for (int i = 0; i < 10; +i) { if (pcSerial.read() == '?') goto bridge; delay(100); } } pcSerial.print(F("EasyVR detected, version ")); pcSerial.println(easyvr.getID()); if (easyvr.getID() < EasyVR::EASYVR3) easyvr.setPinOutput(EasyVR::IO1, LOW); // Shield 2.0 LED off if (easyvr.getID() < EasyVR::EASYVR) pcSerial.print(F(" = VRbot module")); else if (easyvr.getID() < EasyVR::EASYVR2) pcSerial.print(F(" = EasyVR module")); else if (easyvr.getID() < EasyVR::EASYVR3) pcSerial.print(F(" = EasyVR 2 module")); else pcSerial.print(F(" = EasyVR 3 module")); pcSerial.print(F(", FW Rev.")); pcSerial.println(easyvr.getID() &7); easyvr.setDelay(0); // speed-up replies easyvr.setTimeout(5); easyvr.setLanguage(0); group = EasyVR::TRIGGER; //<-- start group (customize) } void loop(void) { if (easyvr.getID() < EasyVR::EASYVR3) easyvr.setPinOutput(EasyVR::IO1, HIGH); // LED on (listening) if (group < 0) // SI wordset/grammar { switch (-group) { case 2: pcSerial.print("Say a Direction: "); break; case 3: pcSerial.print("Say a Distance: "); break; } easyvr.recognizeWord(-group); } else // SD group { pcSerial.println("Say a trigger word: \"Computer\" or \"Robot\" "); easyvr.recognizeCommand(group); } do { // allows Commander to request bridge on Zero (may interfere with user protocol) if (pcSerial.read() == '?') { setup(); return; } } while (!easyvr.hasFinished()); if (easyvr.getID()")); char keys(BUFSIZE + 1); getUserInput(keys, BUFSIZE); easyvr.playSound(2, EasyVR::VOL_FULL); // Custom Beep "down up down" Serial.print("\nSending "); Serial.println(keys); ble.print("AT+BleKeyboard="); ble.println(keys); keys(BUFSIZE + 1) = {}; if (ble.waitForOK()) { Serial.println(F("OK!")); } else { error(F("FAILED!")); easyvr.playSound(1, EasyVR::VOL_FULL); } return; } else if (idx >= 0) { // beep easyvr.playSound(0, EasyVR::VOL_FULL); // print debug message uint8_t flags = 0, num = 0; char name(32) = ""; pcSerial.print("Word: "); pcSerial.print(idx); if (easyvr.dumpGrammar(-group, flags, num)) { for (uint8_t pos = 0; pos < num; +pos) { if (!easyvr.getNextWordLabel(name)) break; if (pos != idx) continue; pcSerial.print(F(" = ")); pcSerial.println(name); String name(32) = ""; break; } // end for uint_8t } // end easyvr.dumpGrammar action(); // get the words and numbers for (int n = 1; n <= repetitions; n+) { ble.print(F("AT+BLEKEYBOARDCODE=")); pcSerial.print(F("AT+BLEKEYBOARDCODE=")); switch (directions) { case 1: //Left Arrow ble.println(F("00-00-50-00-00-00-00")); pcSerial.println(F("00-00-50-00-00-00-00")); break; case 2: //Right Arrow ble.println(F("00-00-4F-00-00-00-00")); pcSerial.println(F("00-00-4F-00-00-00-00")); break; case 3: //Up Torch (Page Up) ble.println(F("00-00-4B-00-00-00-00")); pcSerial.println(F("00-00-4B-00-00-00-00")); break; case 4: //Down Torch (Page Down) ble.println(F("00-00-4E-00-00-00-00")); pcSerial.println(F("00-00-4E-00-00-00-00")); break; case 5: //Forward (Up Arrow) ble.println(F("00-00-52-00-00-00-00")); pcSerial.println(F("00-00-52-00-00-00-00")); break; case 6: //Backward(Down Arrow) ble.println(F("00-00-51-00-00-00-00")); pcSerial.println(F("00-00-51-00-00-00-00")); break; } // End Switch (Directions) delay(25); // Need some delay between repetitive keypress ble.println(F("AT+BLEKEYBOARDCODE=00-00")); pcSerial.println(F("AT+BLEKEYBOARDCODE=00-00")); repetitions = 0; // Reset Repetitions to prevent unintended loop trigger } // End for loop (repetitions) return; } // end else if (idx) idx = easyvr.getCommand(); if (idx >= 0) { easyvr.playSound(0, EasyVR::VOL_FULL); // beep // print debug message uint8_t train = 0; char name(32); pcSerial.print("Command: "); // pcSerial.print(idx); if (easyvr.dumpCommand(group, idx, name, train)) { // // pcSerial.println(name); // "THREE", "DOWN", etc… } else pcSerial.println(); // perform some action action(); } // end if(idx) else // errors and timeout { if (easyvr.isTimeout()) { pcSerial.println(F("Timed out, try again…")); } int16_t err = easyvr.getError(); if (err >= 0) { pcSerial.print("Easy VR Error: "); pcSerial.print(err, HEX); easyvr.playSound(1, EasyVR::VOL_FULL); // Play error sound switch (err) { case 0x02: error(F("Too long")); break; case 0x03: error(F("Too noisy")); break; case 0x04: error(F("Spoken too softly")); break; case 0x05: error(F("Spoken too loud")); break; case 0x06: error(F("Spoken too soon")); break; case 0x07: error(F("Too complex")); break; case 0x08: error(F("Invalid SI weights")); break; case 0x09: error(F("Invalid setup")); break; case 0x11: error(F("Recognition failure")); break; case 0x12: error(F("Recognition result doubtful")); break; case 0x13: error(F("Recognition result maybe")); break; case 0x14: error(F("Invalid SD/SV template")); break; case 0x15: error(F("Invalid SI weights")); break; case 0x17: error(F("Incomplete pattern duration")); break; case 0x21: error(F("T2si state structure is too big")); break; case 0x22: error(F("T2si RSC code version/ Grammer Rom don't match")); break; case 0x23: error(F("Out of t2si Ram!")); break; case 0x24: error(F("Unexpected t2si pcSerial.print occured")); break; case 0x25: error(F("Ran out of time")); break; case 0x26: error(F("T2si bad macro or grammar parameter")); break; case 0x29: error(F("T2si layer size out of limits")); break; case 0x2A: error(F("T2si net structure incompatibility")); break; case 0x2B: error(F("T2si initialization not complete")); break; case 0x2C: error(F("T2si incorrect number of layers")); break; case 0x2D: error(F("T2si trigger recognised Out of Vocabulary")); break; case 0x2F: error(F("T2si utterance too short")); break; case 0x31: error(F("Play -- illegal compression level")); break; case 0x38: error(F("Play, erase, copy - mag doesn't exist")); break; case 0x39: error(F("Rec, copy - mag already exists")); break; case 0x4A: error(F("Bad release nubmer in speech file")); break; case 0x4E: error(F("Bad message data or SX technology file missing")); break; case 0x80: error(F("None of the above (out of grammar)")); break; case 0x81: error(F("Invalid data (for memory check)")); break; case 0xC0: error(F("No room left in software stack")); break; case 0xCC: error(F("T2si test mode error")); break; } // end switch(err) } // end if (err>=0) } // end else } // end void loop() void action() { switch (group) { case GROUP_0: switch (idx) { case G0_COMPUTER: group = -2; // goto directions (left, right, etc…) wordset. break; } break; case SET_2: switch (idx) { // directions Choice case S2_LEFT: directions = 1; group = -3; break; case S2_RIGHT: directions = 2; group = -3; break; case S2_UP: directions = 3; group = -3; break; case S2_DOWN: directions = 4; group = -3; break; case S2_FORWARD: directions = 5; group = -3; break; case S2_BACKWARD: directions = 6; group = -3; break; } // end switch(idx) break; case SET_3: switch (idx) { // Repetition choice case S3_ZERO: repetitions = 0; group = 0; break; case S3_ONE: repetitions = 1; group = 0; break; case S3_TWO: repetitions = 2; group = 0; break; case S3_THREE: repetitions = 3; group = 0; break; case S3_FOUR: repetitions = 4; group = 0; break; case S3_FIVE: repetitions = 5; group = 0; break; case S3_SIX: repetitions = 6; group = 0; break; case S3_SEVEN: repetitions = 7; group = 0; break; case S3_EIGHT: repetitions = 8; group = 0; break; case S3_NINE: repetitions = 9; group = 0; break; case S3_TEN: repetitions = 10; group = 0; break; } // end switch(idx) break; } // end switch(group) } // end action() void getUserInput(char buffer(), uint8_t maxSize) { memset(buffer, 0, maxSize); while (Serial.available() == 0) { delay(1); } uint8_t count = 0; do { count += Serial.readBytes(buffer + count, maxSize); delay(2); } while ((count < maxSize) & !(Serial.available() == 0)); } /****************************** How to Send Custom Keypresses and Macros ******************************/ /******************************************************************************************************/ /* To send custom macros and keypress combinations, send the command AT+BLEKEYBOARDCODE= followed by three to seven, dash separated bytes that consist of 2-digit hex codes that correspond to HID Keyboard codes (07). Immediately follow with AT+BLEKEYBOARDCODE=00-00 to indicate that all keys were released. For example ble.println("AT+BLEKEYBOARDCODE=02-00-04-16-06-0C-0C"); // This sends a key combination ble.println("AT+BLEKEYBOARDCODE=00-00"); // This mandatory command release all depressed keys Generically, the full command looks like this: ble.println("AT+BLEKEYBOARDCODE=XX-00-YY-NN-NN-NN-NN"); Where: MM (byte 1) is the hex code for a modifier key 00 (byte 2) is a reserved hex code (always 00) NN (byte 3) is the desired key-press PP (byte 4-7) are optional additional key-presses ble.println("AT+BLEKEYBOARDCODE=00-00"); Keyboard code format //www.usb.org/developers/hidpage/Hut1_12v2.pdf (pages 53-59) +-----------------------------------------------------------------------------------+ | HID Keyboard Code Format | +-----------------------------------------------------------------------------------+ | //www.usb.org/developers/hidpage/Hut1_12v2.pdf | +-----------------------------------------------------------------------------------+ | Byte 0x01 | Byte 0x02 | Byte 0x03 | Byte 0x04 | Byte 0x05 | Byte 0x06 | Byte 0x07 | +-----------+-----------+-----------+-----------+-----------+-----------+-----------+ | Modifer | Reserved | Keycode 1 | Keycode 2 | Keycode 3 | Keycode 4 | Keycode 5 | +-----------+-----------+-----------+-----------+-----------+-----------+-----------+ | 0xMM | 0x00 | 0xNN | 0xPP | 0xPP | 0xPP | 0xPP | +-----------+-----------+-----------+-----------+-----------+-----------+-----------+ +------------------------------------+ +----------------------------------------------------+ | Byte 01 -- Hex Modifier | | Modifier Reserved Key Code Result | +------------------------------------+ +----------------------------------------------------+ | Modifer | Binary | Hex ID | | 00 - 00 - 04 | | a | +---------------+-----------+--------+ +----------------------------------------+--+--------+ | None | B00000000 | 0x00 | | 02 - 00 - 04 | | A | +---------------+-----------+--------+ +----------------------------------------+--+--------+ | Left Control | B00000001 | 0x01 | | 00 - 00 - 1E | | 1 | +---------------+-----------+--------+ +----------------------------------------+--+--------+ | Left Shift | B00000010 | 0x02 | | 02 - 00 - 1E | | ! | +---------------+-----------+--------+ +----------------------------------------------------+ | Left Alt | B00000100 | 0x04 | +---------------+-----------+--------+ | Left Window | B00001000 | 0x08 | +---------------+-----------+--------+ | Right Control | B00010000 | 0x10 | +---------------+-----------+--------+ | Right Shift | B00100000 | 0x20 | +---------------+-----------+--------+ | Right Alt | B01000000 | 0x40 | +---------------+-----------+--------+ | Right Window | B10000000 | 0x80 | +---------------+-----------+--------+ */
Идти дальше
Если вы собираетесь создать этот проект, подумайте над добавлением кода доступа оператора и дополнительных слов, зависящих от динамика, в программном обеспечении EasyVR Commander. Кроме того, рассмотрите возможность перемещения #defines, переменных и неизменных кодов ошибок из основного эскиза - я включил их только в один файл, чтобы предотвратить потерю информации, поскольку код делает раунды в Интернете.
Звуковые файлы и коды
Вывод
Этот проект демонстрирует способ добавления клавиатуры и мыши, активированной голосом, к машине, но ее можно легко модифицировать, чтобы добавить голосовые нажатия клавиш и макросы на любое устройство, которое может интерпретировать Bluetooth LE - с плазменной таблицы CNC на контроллер XBOX One Controller, И в следующий раз, когда вы создадите проект с Arduino Uno R3 и требования проекта превысят технические возможности Arduino Uno R3, рассмотрите совет XLR8 от Alorium Tech.
Попробуйте этот проект сами! Получить спецификацию.