Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Manufacturing Technology >> Производственный процесс

Распознавание и синтез речи с помощью Arduino

Компоненты и расходные материалы

Arduino Due
× 1
Электретный микрофонный прорыв SparkFun
× 1
SparkFun Mono Audio Amp Breakout
× 1
Динамик:0,25 Вт, 8 Ом
× 1
Макет (общий)
× 1
5 мм светодиод:красный
× 3
Резистор 330 Ом
× 3
Перемычки (общие)
× 1

Необходимые инструменты и машины

Паяльник (общий)

Приложения и онлайн-сервисы

BitVoicer Server 1.0

Об этом проекте

В моем предыдущем проекте я показал, как управлять несколькими светодиодами с помощью платы Arduino и BitVoicer Server. В этом проекте я собираюсь немного усложнить ситуацию. Я также собираюсь синтезировать речь с помощью цифро-аналогового преобразователя (ЦАП) Arduino DUE. Если у вас нет Arduino DUE, вы можете использовать другие платы Arduino, но вам понадобится внешний ЦАП и некоторый дополнительный код для управления ЦАП (библиотека BVSSpeaker вам в этом не поможет).

В видео ниже вы можете видеть, что я также заставляю Arduino проигрывать небольшую песню и мигать светодиодами, как если бы они были клавишами пианино. Извините за мои навыки игры на фортепиано, но это лучшее, что я могу сделать :). На самом деле светодиоды мигают в той же последовательности и по времени, что и настоящие клавиши C, D и E, поэтому, если у вас есть пианино, вы можете следить за светодиодами и играть ту же песню. Это джингл от старого магазина (Mappin), которого больше не существует.

Для преобразования голосовых команд в работу светодиода и синтезированную речь будут выполнены следующие процедуры:

  • 1. Звуковые волны будут улавливаться и усиливаться платой Sparkfun Electret Breakout;
  • 2. Усиленный сигнал будет оцифрован и буферизован в Arduino с помощью его аналого-цифрового преобразователя (АЦП);
  • 3. Аудиосэмплы будут передаваться на сервер BitVoicer через последовательный порт Arduino;
  • 4. BitVoicer Server обработает аудиопоток и распознает содержащуюся в нем речь;
  • 5. Распознанная речь будет сопоставлена ​​предопределенным командам, которые будут отправлены обратно в Arduino. Если одна из команд состоит в синтезировании речи, BitVoicer Server подготовит аудиопоток и отправит его на Arduino;
  • 6. Arduino определит команды и выполнит соответствующее действие. Если аудиопоток получен, он будет помещен в очередь в класс BVSSpeaker и воспроизведен с использованием DUE DAC и DMA.
  • 7. Аудиоусилитель SparkFun Mono Audio усиливает сигнал ЦАП, так что он может управлять динамиком 8 Ом.

Список материалов:

  • DUE для Arduino:~ 50 долларов США.
  • Электретный микрофон Sparkfun Breakout:7,95 долларов США.
  • SparkFun Mono Audio Amp Breakout:7,95 долларов США.
  • BitVoicer Server 1.0:9,90 долларов США.
  • Динамик на 8 Ом:~ 2 доллара США.
  • Макетная плата:~ 10 долларов США.
  • 3 светодиода:~ 1 доллар США.
  • 3 резистора по 330 Ом:~ 0,75 $.
  • Перемычки:~ 0,50 доллара США.

ШАГ 1. Подключение

Первый шаг - подключить Arduino и макетную плату к компонентам, как показано на рисунках ниже. Мне пришлось подложить под динамик небольшую резину, потому что он сильно вибрирует, а без резины качество звука значительно ухудшается.

Здесь есть небольшое, но важное отличие от моего предыдущего проекта. Большинство плат Arduino работают от 5 В, но DUE работает от 3,3 В. Поскольку я получил лучшие результаты при использовании Sparkfun Electret Breakout при 3,3 В, я рекомендую вам добавить перемычку между контактом 3,3 В и контактом AREF, если вы используете платы Arduino 5 В. DUE уже использует аналоговое опорное напряжение 3,3 В, поэтому перемычка на вывод AREF не требуется. Фактически, вывод AREF на DUE подключен к микроконтроллеру через резисторный мост. Чтобы использовать вывод AREF, необходимо отсоединить резистор BR1 от печатной платы.

ШАГ 2. Загрузка кода в Arduino

Теперь вам нужно загрузить приведенный ниже код в свой Arduino. Для удобства скетч Arduino также доступен в разделе «Вложения» внизу этого поста. Перед загрузкой кода необходимо правильно установить библиотеки BitVoicer Server в Arduino IDE (импорт библиотеки .zip).

Эскиз Arduino :BVS_Demo2.ino

Этот набросок состоит из семи основных частей:

  • Ссылки на библиотеки и объявление переменных :Первые четыре строки содержат ссылки на библиотеки BVSP, BVSMic, BVSSpeaker и DAC. Эти библиотеки предоставляются BitSophia и находятся в папке установки BitVoicer Server. Библиотека DAC включается автоматически, когда вы добавляете ссылку на библиотеку BVSSpeaker. В других строках объявляются константы и переменные, используемые в скетче. Класс BVSP используется для связи с BitVoicer Server, класс BVSMic используется для захвата и хранения аудиосэмплов, а класс BVSSpeaker используется для воспроизведения звука с помощью DUE DAC.
  • Функция настройки :Эта функция выполняет следующие действия:устанавливает режимы вывода и их начальное состояние; инициализирует последовательную связь; и инициализирует классы BVSP, BVSMic и BVSSpeaker. Он также устанавливает «обработчики событий» (на самом деле они являются указателями на функции) для событий frameReceived, modeChanged и streamReceived класса BVSP.
  • Функция цикла :Эта функция выполняет пять важных действий:запрашивает информацию о состоянии на сервере (функция keepAlive ()); проверяет, отправил ли сервер какие-либо данные, и обрабатывает полученные данные (функция receive ()); управляет записью и отправкой аудиопотоков (функции isSREAvailable (), startRecording (), stopRecording () и sendStream ()); воспроизводит аудиосэмплы, поставленные в очередь в класс BVSSpeaker (функция play ()); и вызывает функцию playNextLEDNote (), которая контролирует, как светодиоды должны мигать после получения команды playLEDNotes.
  • Функция BVSP_frameReceived :Эта функция вызывается каждый раз, когда функция receive () определяет, что был получен один полный кадр. Здесь я запускаю команды, отправленные с BitVoicer Server. Команды, управляющие светодиодами, содержат 2 байта. Первый байт указывает вывод, а второй байт указывает значение вывода. Я использую функцию analogWrite (), чтобы установить соответствующее значение для вывода. Я также проверяю, была ли получена команда playLEDNotes типа Byte. Если он был получен, я установил для playLEDNotes значение true . и отметьте текущее время. Это время будет использовано функцией playNextLEDNote для синхронизации светодиодов с песней.
  • Функция BVSP_modeChanged :Эта функция вызывается каждый раз, когда функция receive () определяет изменение режима в исходящем направлении (Сервер -> Arduino). УХ ТЫ!!! Это что?! BitVoicer Server может отправлять в Arduino кадрированные данные или аудиопотоки. Прежде чем связь переходит из одного режима в другой, BitVoicer Server отправляет сигнал. Класс BVSP идентифицирует этот сигнал и вызывает событие modeChanged. В функции BVSP_modeChanged, если я обнаруживаю, что связь переходит из потокового режима в режим кадрирования, я знаю, что звук закончился, поэтому я могу сказать классу BVSSpeaker прекратить воспроизведение аудиосэмплов.
  • Функция BVSP_streamReceived :Эта функция вызывается каждый раз, когда функция receive () определяет, что аудио образцы были получены. Я просто извлекаю образцы и помещаю их в класс BVSSpeaker, чтобы функция play () могла их воспроизвести.
  • Функция playNextLEDNote :Эта функция запускается только в том случае, если функция BVSP_frameReceived идентифицирует команду playLEDNotes. Он контролирует и синхронизирует светодиоды со звуком, отправленным с BitVoicer Server. Чтобы синхронизировать светодиоды со звуком и узнать правильное время, я использовал Sonic Visualizer. Это бесплатное программное обеспечение позволило мне видеть звуковые волны, чтобы я мог легко определить, когда была нажата клавиша пианино. Он также показывает временную шкалу, и именно так я получил миллисекунды, используемые в этой функции. Звучит глупо, и это так. Думаю, можно было бы проанализировать аудиопоток и включить соответствующий светодиод, но это вне моей досягаемости.

ШАГ 3. Импорт объектов серверного решения BitVoicer

Теперь вам нужно настроить BitVoicer Server для работы с Arduino. BitVoicer Server имеет четыре основных объекта решения:местоположения, устройства, двоичные данные и голосовые схемы.

Местоположение представляет собой физическое местоположение, где установлено устройство. В моем случае я создал место под названием «Дом».

Устройства - это клиенты BitVoicer Server. Я создал смешанное устройство, назвал его ArduinoDUE и вошел в настройки связи. ВАЖНО :даже у Arduino DUE есть небольшой объем памяти для хранения всех аудиосэмплов, которые BitVoicer Server будет передавать. Если вы не ограничиваете пропускную способность, вам понадобится буфер гораздо большего размера для хранения звука. По этой причине у меня произошло переполнение буфера, поэтому мне пришлось ограничить скорость передачи данных в настройках связи до 8000 выборок в секунду.

BinaryData - это тип команды, которую BitVoicer Server может отправлять на клиентские устройства. На самом деле это массивы байтов, которые можно связывать с командами. Когда BitVoicer Server распознает речь, связанную с этой командой, он отправляет массив байтов на целевое устройство. Я создал по одному объекту BinaryData для каждого значения вывода и назвал их ArduinoDUEGreenLedOn, ArduinoDUEGreenLedOff и так далее. В моем решении оказалось 18 объектов BinaryData, поэтому я предлагаю вам загрузить и импортировать объекты из VoiceSchema.sof файл ниже.

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

Одно из предложений в моей голосовой схеме - «сыграй небольшую песенку». Это предложение содержит две команды. Первая команда отправляет байт, который указывает, что следующая команда будет аудиопотоком. Затем Arduino начинает «воспроизводить» светодиоды во время передачи звука. Звук представляет собой небольшой фортепианный джингл, который я записал сам и установил в качестве источника звука для второй команды. BitVoicer Server поддерживает только 8-битный моно PCM-звук (8000 выборок в секунду), поэтому, если вам нужно преобразовать аудиофайл в этот формат, я рекомендую следующий онлайн-инструмент преобразования:http://audio.online-convert.com/convert -to-wav.

Вы можете импортировать (Импорт объектов решения) все объекты решения, которые я использовал в этом проекте, из файлов ниже. Один содержит устройство DUE, а другой - схему голоса и ее команды.

Файлы объектов решения :

  • Device.sof
  • VoiceSchema.sof

ШАГ 4. Заключение

Вот так! Вы можете включить все и делать то же, что и на видео.

Как и в предыдущем проекте, я начал распознавание речи, включив устройство Arduino в BitVoicer Server Manager. Как только он включается, Arduino определяет доступный механизм распознавания речи и начинает потоковую передачу звука на сервер BitVoicer. Однако теперь вы видите гораздо большую активность светодиода Arduino RX во время потоковой передачи звука с BitVoicer Server на Arduino.

В моем следующем проекте я буду немного более амбициозным. Я собираюсь добавить Wi-Fi соединение к одному Arduino и управлять двумя другими Arduino вместе с помощью голоса. Я думаю о какой-то игре между ними. Предложения приветствуются!

Код

  • Эскиз Arduino
Эскиз Arduino Arduino
 #include  #include  #include  #include  // Определяет вывод Arduino, который будет использоваться для захвата звука #define BVSM_AUDIO_INPUT 7 // Определяет выводы светодиода # define RED_LED_PIN 6 # define YELLOW_LED_PIN 9 #define GREEN_LED_PIN 10 // Определяет константы, которые будут переданы в качестве параметров // функции BVSP.beginconst unsigned long STATUS_REQUEST_TIMEOUT =3000; const unsigned long STATUS_REQUEST 4000_INTERVAL =Определяет размер аудиобуфера микрофона const int MIC_BUFFER_SIZE =64; // Определяет размер аудиобуфера динамика const int SPEAKER_BUFFER_SIZE =128; // Определяет размер приемного буфераconst int RECEIVE_BUFFER_SIZE =2; // Инициализирует новый глобальный экземпляр класса BVSP BVSP bvsp =BVSP (); // Инициализирует новый глобальный экземпляр класса BVSMic BVSMic bvsm =BVSMic (); // Инициализирует новый глобальный экземпляр класса BVSSpeaker BVSSpeaker bvss =BVSSpeaker (); // Создает буфер, который будет использоваться для чтения записанных семплов // из t he BVSMic class byte micBuffer [MIC_BUFFER_SIZE]; // Создает буфер, который будет использоваться для записи аудиосэмплов // в класс BVSSpeaker byte speakerBuffer [SPEAKER_BUFFER_SIZE]; // Создает буфер, который будет использоваться для чтения отправленных команд // с сервера BitVoicer. // Байт 0 =номер контакта // Байт 1 =значение контакта, байт receiveBuffer [RECEIVE_BUFFER_SIZE]; // Эти переменные используются для управления, когда воспроизводить // «LED Notes». Эти ноты будут проигрываться вместе с // песней, передаваемой с сервера BitVoicer. Bool playLEDNotes =false; unsigned int playStartTime =0; void setup () {// Устанавливает режимы вывода pinMode (RED_LED_PIN, OUTPUT); pinMode (YELLOW_LED_PIN, ВЫХОД); pinMode (GREEN_LED_PIN, ВЫХОД); // Устанавливаем начальное состояние всех светодиодов digitalWrite (RED_LED_PIN, LOW); digitalWrite (YELLOW_LED_PIN, LOW); digitalWrite (GREEN_LED_PIN, LOW); // Запуск последовательной связи со скоростью 115200 бит / с Serial.begin (115200); // Устанавливает последовательный порт Arduino, который будет использоваться // для связи, сколько времени пройдет до истечения времени // запроса статуса и как часто запросы статуса должны отправляться на // сервер BitVoicer. bvsp.begin (серийный, STATUS_REQUEST_TIMEOUT, STATUS_REQUEST_INTERVAL); // Определяет функцию, которая будет обрабатывать событие frameReceived // bvsp.frameReceived =BVSP_frameReceived; // Устанавливает функцию, которая будет обрабатывать событие modeChanged // bvsp.modeChanged =BVSP_modeChanged; // Устанавливает функцию, которая будет обрабатывать событие streamReceived // bvsp.streamReceived =BVSP_streamReceived; // Подготавливает таймер класса BVSMic bvsm.begin (); // Устанавливает DAC, который будет использоваться классом BVSSpeaker bvss.begin (DAC);} void loop () {// Проверяет, истек ли интервал запроса статуса, и, // если да, отправляет запрос статуса на сервер BitVoicer bvsp.keepAlive (); // Проверяет наличие данных в буфере последовательного порта // и обрабатывает их содержимое в соответствии со спецификациями // протокола сервера BitVoicer bvsp.receive (); // Проверяет, доступен ли один SRE. Если есть, // начинает запись. if (bvsp.isSREAvailable ()) {// Если класс BVSMic не записывает, устанавливает аудиовход // и начинает запись if (! bvsm.isRecording) {bvsm.setAudioInput (BVSM_AUDIO_INPUT, DEFAULT); bvsm.startRecording (); } // Проверяет, есть ли у класса BVSMic доступные образцы if (bvsm.available) {// Проверяет, что входящий режим - STREAM_MODE, перед // передачей потока if (bvsp.inboundMode ==FRAMED_MODE) bvsp.setInboundMode (STREAM_MODE); // Считывает образцы аудио из класса BVSMic int bytesRead =bvsm.read (micBuffer, MIC_BUFFER_SIZE); // Отправляет аудиопоток на сервер BitVoicer bvsp.sendStream (micBuffer, bytesRead); }} else {// Нет доступных SRE. Если класс BVSMic записывает, // останавливает его. если (bvsm.isRecording) bvsm.stopRecording (); } // Воспроизводит все аудиосэмплы, доступные во внутреннем буфере // класса BVSSpeaker. Эти образцы записываются в обработчике событий // BVSP_streamReceived. Если во внутреннем буфере нет // доступных семплов, ничего не воспроизводится. bvss.play (); // Если для playLEDNotes установлено значение true, // воспроизводятся «светодиодные ноты» вместе с музыкой. if (playLEDNotes) playNextLEDNote ();} // Обрабатывает событие frameReceived void BVSP_frameReceived (byte dataType, int payloadSize) {// Проверяет, содержит ли полученный кадр двоичные данные // 0x07 =двоичные данные (массив байтов) if (dataType ==DATA_TYPE_BINARY) {// Если было получено 2 байта, обрабатываем команду. если (bvsp.getReceivedBytes (receiveBuffer, RECEIVE_BUFFER_SIZE) ==RECEIVE_BUFFER_SIZE) {analogWrite (receiveBuffer [0], receiveBuffer [1]); }} // Проверяет, содержит ли полученный фрейм байтовый тип данных // 0x01 =байтовый тип данных else if (dataType ==DATA_TYPE_BYTE) {// Если полученное байтовое значение равно 255, устанавливает playLEDNotes // и отмечает текущее время. если (bvsp.getReceivedByte () ==255) {playLEDNotes =true; playStartTime =millis (); }}} // Обрабатывает событие modeChanged void BVSP_modeChanged () {// Если outboundMode (Сервер -> Устройство) изменился на // FRAMED_MODE, аудиопоток не должен приниматься. // Сообщает классу BVSSpeaker о завершении воспроизведения, когда // его внутренний буфер становится пустым. if (bvsp.outboundMode ==FRAMED_MODE) bvss.finishPlaying ();} // Обрабатывает событие streamReceived void BVSP_streamReceived (int size) {// Получает полученный поток от класса BVSP int bytesRead =bvsp.getReceivedStream (speakerBuffer, SPEAKER_; // Ставит полученный поток в очередь для воспроизведения bvss.enqueue (speakerBuffer, bytesRead);} // Загорается соответствующий светодиод в зависимости от времени, // команда для начала воспроизведения светодиодных нот была получена. // Используемые здесь тайминги синхронизируются с the music.void playNextLEDNote () {// Получает время, прошедшее между playStartTime и // текущим временем. беззнаковое длинное истекшее время =millis () - playStartTime; // Выключаем все светодиоды allLEDsOff (); // Последняя нота сыграна. // Выключает последний светодиод и останавливает воспроизведение светодиодных нот. если (истекло> =11500) {analogWrite (RED_LED_PIN, 0); playLEDNotes =false; } else if (elapsed> =9900) analogWrite (RED_LED_PIN, 255); // C примечание else if (elapsed> =9370) analogWrite (RED_LED_PIN, 255); // C примечание else if (elapsed> =8900) analogWrite (YELLOW_LED_PIN, 255); // Обратите внимание, иначе if (elapsed> =8610) analogWrite (RED_LED_PIN, 255); // C примечание else if (elapsed> =8230) analogWrite (YELLOW_LED_PIN, 255); // Обратите внимание, иначе if (elapsed> =7970) analogWrite (YELLOW_LED_PIN, 255); // Обратите внимание, иначе if (elapsed> =7470) analogWrite (RED_LED_PIN, 255); // C примечание else if (elapsed> =6760) analogWrite (GREEN_LED_PIN, 255); // Обратите внимание, иначе if (elapsed> =6350) analogWrite (RED_LED_PIN, 255); // C примечание else if (elapsed> =5880) analogWrite (YELLOW_LED_PIN, 255); // Обратите внимание, иначе if (elapsed> =5560) analogWrite (RED_LED_PIN, 255); // C примечание else if (elapsed> =5180) analogWrite (YELLOW_LED_PIN, 255); // Обратите внимание, иначе if (elapsed> =4890) analogWrite (YELLOW_LED_PIN, 255); // Обратите внимание, иначе if (elapsed> =4420) analogWrite (RED_LED_PIN, 255); // C примечание else if (elapsed> =3810) analogWrite (GREEN_LED_PIN, 255); // Обратите внимание, иначе if (elapsed> =3420) analogWrite (RED_LED_PIN, 255); // C примечание else if (elapsed> =2930) analogWrite (YELLOW_LED_PIN, 255); // Обратите внимание, иначе if (elapsed> =2560) analogWrite (RED_LED_PIN, 255); // C примечание else if (elapsed> =2200) analogWrite (YELLOW_LED_PIN, 255); // Обратите внимание, иначе if (elapsed> =1930) analogWrite (YELLOW_LED_PIN, 255); // Обратите внимание, иначе if (elapsed> =1470) analogWrite (RED_LED_PIN, 255); // C примечание else if (elapsed> =1000) analogWrite (GREEN_LED_PIN, 255); // E note} // Выключает все светодиоды. Void allLEDsOff () {analogWrite (RED_LED_PIN, 0); analogWrite (YELLOW_LED_PIN, 0); analogWrite (GREEN_LED_PIN, 0);} 

Схема


Производственный процесс

  1. Система посещаемости с использованием Arduino и RFID с Python
  2. Датчик DHT11 со светодиодами и пьезо-динамиком
  3. Удовольствие от гироскопа с кольцом NeoPixel
  4. Arduino Temp. Монитор и часы реального времени с дисплеем 3.2
  5. Управление роботом Roomba с помощью Arduino и устройства Android
  6. DIY вольтметр с Arduino и дисплеем Nokia 5110
  7. Управление серводвигателем с помощью Arduino и MPU6050
  8. u-blox LEA-6H 02 GPS-модуль с Arduino и Python
  9. Как читать температуру и влажность на Blynk с DHT11
  10. Светодиодный куб 4x4x4 с Arduino Uno и 1sheeld