Manufaturação industrial
Internet das coisas industrial | Materiais industriais | Manutenção e reparo de equipamentos | Programação industrial |
home  MfgRobots >> Manufaturação industrial >  >> Manufacturing Technology >> Processo de manufatura

Reconhecimento de fala e síntese com Arduino

Componentes e suprimentos

Arduino Due
× 1
SparkFun Electret Microfone Breakout
× 1
SparkFun Mono Audio Amp Breakout
× 1
Alto-falante:0,25 W, 8 ohms
× 1
Breadboard (genérico)
× 1
LED de 5 mm:Vermelho
× 3
Resistor 330 ohm
× 3
Fios de jumpers (genérico)
× 1

Ferramentas e máquinas necessárias

Ferro de soldar (genérico)

Aplicativos e serviços online

BitVoicer Server 1.0

Sobre este projeto


Em meu projeto anterior, mostrei como controlar alguns LEDs usando uma placa Arduino e o BitVoicer Server. Neste projeto, vou complicar um pouco mais as coisas. Também vou sintetizar a fala usando o conversor digital para analógico (DAC) Arduino DUE. Se você não tiver um Arduino DUE, poderá usar outras placas Arduino, mas precisará de um DAC externo e algum código adicional para operar o DAC (a biblioteca BVSSpeaker não o ajudará com isso).

No vídeo abaixo, você pode ver que também faço o Arduino tocar uma musiquinha e piscar os LEDs como se fossem teclas de piano. Desculpe pelas minhas habilidades com o piano, mas isso é o melhor que posso fazer :). Os LEDs piscam na mesma sequência e tempo que as teclas C, D e E reais, portanto, se você tiver um piano por perto, poderá seguir os LEDs e tocar a mesma música. É um jingle de um antigo varejista (Mappin) que nem existe mais.

Os seguintes procedimentos serão executados para transformar comandos de voz em atividade de LED e fala sintetizada:
  • 1. As ondas de áudio serão capturadas e amplificadas pela placa Sparkfun Electret Breakout;
  • 2. O sinal amplificado será digitalizado e armazenado em buffer no Arduino usando seu conversor analógico-digital (ADC);
  • 3. As amostras de áudio serão transmitidas para o BitVoicer Server usando a porta serial do Arduino;
  • 4. O BitVoicer Server processará o fluxo de áudio e reconhecerá a fala que ele contém;
  • 5. A fala reconhecida será mapeada para comandos predefinidos que serão enviados de volta ao Arduino. Se um dos comandos consistir em sintetizar a fala, o BitVoicer Server irá preparar o stream de áudio e enviá-lo para o Arduino;
  • 6. O Arduino identificará os comandos e executará a ação apropriada. Se um fluxo de áudio for recebido, ele será enfileirado na classe BVSSpeaker e reproduzido usando DUE DAC e DMA.
  • 7. O SparkFun Mono Audio Amp amplificará o sinal DAC para que possa acionar um alto-falante de 8 Ohms.





Lista de materiais:

  • Arduino DEVIDO:~ U $ 50,00
  • Breakout do microfone de eletreto Sparkfun:U $ 7,95
  • Ampliação do amplificador de áudio mono SparkFun:U $ 7,95
  • BitVoicer Server 1.0:U $ 9,90
  • Alto-falante 8 Ohm:~ U $ 2,00
  • Breadboard:~ U $ 10,00
  • 3 x LEDs:~ U $ 1,00
  • 3 x 330 Ohm resistores:~ U $ 0,75
  • Fios de ligação:~ U $ 0,50





ETAPA 1:Fiação


A primeira etapa é conectar o Arduino e a placa de ensaio com os componentes, conforme mostrado nas imagens abaixo. Tive que colocar uma pequena borracha embaixo do alto-falante porque ela vibra muito e sem a borracha a qualidade do áudio é consideravelmente afetada.

Aqui temos uma pequena, mas importante diferença em relação ao meu projeto anterior. A maioria das placas Arduino funciona a 5V, mas o DUE funciona a 3,3V. Como obtive melhores resultados executando o Sparkfun Electret Breakout em 3,3 V, recomendo que você adicione um jumper entre o pino de 3,3 V e o pino AREF SE você estiver usando placas Arduino de 5 V. O DUE já usa uma referência analógica de 3,3 V, portanto, você não precisa de um jumper para o pino AREF. Na verdade, o pino AREF no DUE é conectado ao microcontrolador por meio de uma ponte de resistor. Para usar o pino AREF, o resistor BR1 deve ser dessoldado do PCB.





ETAPA 2:upload do código para o Arduino


Agora você precisa fazer o upload do código abaixo para o seu Arduino. Por conveniência, o esboço do Arduino também está disponível na seção de anexos na parte inferior deste post. Antes de fazer o upload do código, você deve instalar corretamente as bibliotecas do BitVoicer Server no IDE do Arduino (Importando uma biblioteca .zip).

Arduino Sketch :BVS_Demo2.ino

Este esboço tem sete partes principais:
  • Referências de biblioteca e declaração de variável :As primeiras quatro linhas incluem referências às bibliotecas BVSP, BVSMic, BVSSpeaker e DAC. Essas bibliotecas são fornecidas pela BitSophia e podem ser encontradas na pasta de instalação do BitVoicer Server. A biblioteca DAC é incluída automaticamente quando você adiciona uma referência à biblioteca BVSSpeaker. As outras linhas declaram constantes e variáveis ​​usadas em todo o esboço. A classe BVSP é usada para se comunicar com o BitVoicer Server, a classe BVSMic é usada para capturar e armazenar amostras de áudio e a classe BVSSpeaker é usada para reproduzir áudio usando o DUE DAC.
  • Função de configuração :Esta função executa as seguintes ações:configura os modos de pin e seu estado inicial; inicializa a comunicação serial; e inicializa as classes BVSP, BVSMic e BVSSpeaker. Ele também define “manipuladores de eventos” (eles são, na verdade, ponteiros de função) para os eventos frameReceived, modeChanged e streamReceived da classe BVSP.
  • Função de loop :Esta função executa cinco ações importantes:solicita informações de status ao servidor (função keepAlive ()); verifica se o servidor enviou algum dado e processa os dados recebidos (função receive ()); controla a gravação e o envio de fluxos de áudio (funções isSREAvailable (), startRecording (), stopRecording () e sendStream ()); reproduz as amostras de áudio enfileiradas na classe BVSSpeaker (função play ()); e chama a função playNextLEDNote () que controla como os LEDs devem piscar após o comando playLEDNotes ser recebido.
  • Função BVSP_frameReceived :Esta função é chamada sempre que a função receive () identifica que um quadro completo foi recebido. Aqui eu executo os comandos enviados do BitVoicer Server. Os comandos que controlam os LEDs contêm 2 bytes. O primeiro byte indica o pino e o segundo byte indica o valor do pino. Eu uso a função analogWrite () para definir o valor apropriado para o pino. Também verifico se o comando playLEDNotes, que é do tipo Byte, foi recebido. Se tiver sido recebido, defino playLEDNotes como verdadeiro e marcar a hora atual. Este tempo será usado pela função playNextLEDNote para sincronizar os LEDs com a música.
  • função BVSP_modeChanged :Esta função é chamada toda vez que a função receive () identifica uma mudança de modo na direção de saída (Servidor -> Arduino). UAU!!! O que é aquilo?! O BitVoicer Server pode enviar dados em frames ou fluxos de áudio para o Arduino. Antes que a comunicação passe de um modo para outro, o BitVoicer Server envia um sinal. A classe BVSP identifica este sinal e dispara o evento modeChanged. Na função BVSP_modeChanged, se eu detectar que a comunicação está indo do modo stream para o modo framed, sei que o áudio terminou, então posso dizer à classe BVSSpeaker para parar de reproduzir as amostras de áudio.
  • função BVSP_streamReceived :Esta função é chamada sempre que a função receive () identifica que amostras de áudio foram recebidas. Eu simplesmente recupero as amostras e as enfileiro na classe BVSSpeaker para que a função play () possa reproduzi-las.
  • função playNextLEDNote :Esta função só é executada se a função BVSP_frameReceived identificar o comando playLEDNotes. Ele controla e sincroniza os LEDs com o áudio enviado do BitVoicer Server. Para sincronizar os LEDs com o áudio e saber o tempo correto, usei o Sonic Visualizer. Este software gratuito me permitiu ver as ondas de áudio para que eu pudesse dizer facilmente quando uma tecla de piano foi pressionada. Ele também mostra uma linha do tempo e é assim que obtive os milissegundos usados ​​nesta função. Parece um truque bobo e é. Acho que seria possível analisar o fluxo de áudio e ligar o LED correspondente, mas isso está fora do meu alcance.





ETAPA 3:Importando objetos da solução do BitVoicer Server


Agora você deve configurar o BitVoicer Server para funcionar com o Arduino. O BitVoicer Server possui quatro objetos principais de solução:Locations, Devices, BinaryData e Voice Schemas.

Os locais representam o local físico onde um dispositivo está instalado. No meu caso, criei um local chamado Casa.

Os dispositivos são os clientes do BitVoicer Server. Criei um dispositivo Mixed, denominei-o ArduinoDUE e entrei nas configurações de comunicação. IMPORTANTE :mesmo o Arduino DUE tem uma pequena quantidade de memória para armazenar todas as amostras de áudio que o BitVoicer Server irá transmitir. Se você não limitar a largura de banda, precisará de um buffer muito maior para armazenar o áudio. Eu tive alguns estouros de buffer por esse motivo, então tive que limitar a taxa de dados nas configurações de comunicação para 8.000 amostras por segundo.

BinaryData é um tipo de comando que o BitVoicer Server pode enviar para dispositivos clientes. Eles são, na verdade, matrizes de bytes que você pode vincular a comandos. Quando o BitVoicer Server reconhece a fala relacionada àquele comando, ele envia a matriz de bytes para o dispositivo de destino. Criei um objeto BinaryData para cada valor de pino e os denominei ArduinoDUEGreenLedOn, ArduinoDUEGreenLedOff e assim por diante. Acabei com 18 objetos BinaryData em minha solução, então sugiro que você baixe e importe os objetos do VoiceSchema.sof arquivo abaixo.

Os esquemas de voz são onde tudo se junta. Eles definem quais sentenças devem ser reconhecidas e quais comandos executar. Para cada frase, você pode definir quantos comandos precisar e a ordem em que serão executados. Você também pode definir atrasos entre os comandos. Assim consegui realizar a sequência de ações que você vê no vídeo.

Uma das frases em meu esquema de voz é "tocar uma musiquinha". Esta frase contém dois comandos. O primeiro comando envia um byte que indica que o comando a seguir será um fluxo de áudio. O Arduino então começa a “tocar” os LEDs enquanto o áudio está sendo transmitido. O áudio é um pequeno jingle de piano que eu mesmo gravei e o defini como a fonte de áudio do segundo comando. O BitVoicer Server suporta apenas áudio PCM mono de 8 bits (8.000 amostras por segundo), portanto, se você precisar converter um arquivo de áudio para este formato, recomendo a seguinte ferramenta de conversão online:http://audio.online-convert.com/convert -para-wav.

Você pode importar (Importando objetos de solução) todos os objetos de solução que usei neste projeto dos arquivos abaixo. Um contém o dispositivo DUE e o outro contém o esquema de voz e seus comandos.

Arquivos de objeto de solução :
  • Device.sof
  • VoiceSchema.sof





ETAPA 4:Conclusão


Ai está! Você pode ligar tudo e fazer as mesmas coisas mostradas no vídeo.

Como fiz em meu projeto anterior, iniciei o reconhecimento de fala habilitando o dispositivo Arduino no BitVoicer Server Manager. Assim que é habilitado, o Arduino identifica um mecanismo de reconhecimento de fala disponível e começa a transmitir áudio para o BitVoicer Server. No entanto, agora você vê muito mais atividade no LED Arduino RX enquanto o áudio está sendo transmitido do BitVoicer Server para o Arduino.

No meu próximo projeto, serei um pouco mais ambicioso. Vou adicionar comunicação WiFi a um Arduino e controlar dois outros Arduinos todos juntos por voz. Estou pensando em algum tipo de jogo entre eles. As sugestões são muito bem vindas!

Código

  • Arduino Sketch
Arduino Sketch Arduino
 #include  #include  #include  #include  // Define o pino Arduino que será usado para capturar áudio #define BVSM_AUDIO_INPUT 7 // Define os pinos do LED # define RED_LED_PIN 6 # define YELLOW_LED_PIN 9 # define GREEN_LED_PIN 10 // Define as constantes que serão passadas como parâmetros para // a função BVSP.beginconst unsigned long STATUS_REQUEST_TIMEOUT =3000; const unsigned long STATUS_REQUEST_INTERVAL =4000; Define o tamanho do buffer de áudio do microfone const int MIC_BUFFER_SIZE =64; // Define o tamanho do buffer de áudio do alto-falante int SPEAKER_BUFFER_SIZE =128; // Define o tamanho do buffer de recepção int RECEIVE_BUFFER_SIZE =2; // Inicializa uma nova instância global da classe BVSP BVSP bvsp =BVSP (); // Inicializa uma nova instância global da classe BVSMic BVSMic bvsm =BVSMic (); // Inicializa uma nova instância global da classe BVSSpeaker BVSSpeaker bvss =BVSSpeaker (); // Cria um buffer que será usado para ler as amostras gravadas // de t O byte micBuffer da classe BVSMic [MIC_BUFFER_SIZE]; // Cria um buffer que será usado para escrever amostras de áudio // na classe BVSSpeaker byte speakerBuffer [SPEAKER_BUFFER_SIZE]; // Cria um buffer que será usado para ler os comandos enviados // from BitVoicer Server.// Byte 0 =número do pino // Byte 1 =pino valuebyte receiveBuffer [RECEIVE_BUFFER_SIZE]; // Essas variáveis ​​são usadas para controlar quando reproduzir // "LED Notes". Essas notas serão tocadas junto com // a música transmitida do BitVoicer Server.bool playLEDNotes =false; unsigned int playStartTime =0; void setup () {// Define os modos de pin pinMode (RED_LED_PIN, OUTPUT); pinMode (YELLOW_LED_PIN, OUTPUT); pinMode (GREEN_LED_PIN, OUTPUT); // Define o estado inicial de todos os LEDs digitalWrite (RED_LED_PIN, LOW); digitalWrite (YELLOW_LED_PIN, LOW); digitalWrite (GREEN_LED_PIN, LOW); // Inicia a comunicação serial em 115200 bps Serial.begin (115200); // Define a porta serial do Arduino que será usada para // comunicação, quanto tempo levará antes que uma solicitação de status // atinja o tempo limite e com que freqüência as solicitações de status devem ser enviadas para // BitVoicer Server. bvsp.begin (Serial, STATUS_REQUEST_TIMEOUT, STATUS_REQUEST_INTERVAL); // Define a função que tratará o evento frameReceived // bvsp.frameReceived =BVSP_frameReceived; // Define a função que tratará o evento modeChanged // bvsp.modeChanged =BVSP_modeChanged; // Define a função que tratará o evento streamReceived // bvsp.streamReceived =BVSP_streamReceived; // Prepara o cronômetro da classe BVSMic bvsm.begin (); // Define o DAC que será usado pela classe BVSSpeaker bvss.begin (DAC);} void loop () {// Verifica se o intervalo de solicitação de status já passou e // foi, envia uma solicitação de status ao BitVoicer Server bvsp.keepAlive (); // Verifica se há dados disponíveis no buffer da porta serial // e processa seu conteúdo conforme especificações // do BitVoicer Server Protocol bvsp.receive (); // Verifica se há um SRE disponível. Se houver, // inicia a gravação. if (bvsp.isSREAvailable ()) {// Se a classe BVSMic não estiver gravando, configura a entrada de áudio // e inicia a gravação if (! bvsm.isRecording) {bvsm.setAudioInput (BVSM_AUDIO_INPUT, DEFAULT); bvsm.startRecording (); } // Verifica se a classe BVSMic tem amostras disponíveis if (bvsm.available) {// Certifica-se de que o modo de entrada é STREAM_MODE antes de // transmitir o fluxo if (bvsp.inboundMode ==FRAMED_MODE) bvsp.setInboundMode (STREAM_MODE); // Lê as amostras de áudio da classe BVSMic int bytesRead =bvsm.read (micBuffer, MIC_BUFFER_SIZE); // Envia o stream de áudio para o BitVoicer Server bvsp.sendStream (micBuffer, bytesRead); }} else {// Nenhum SRE está disponível. Se a classe BVSMic estiver gravando, // para. if (bvsm.isRecording) bvsm.stopRecording (); } // Reproduz todas as amostras de áudio disponíveis na classe BVSSpeaker // buffer interno. Esses exemplos são gravados no manipulador de eventos // BVSP_streamReceived. Se nenhuma amostra estiver // disponível no buffer interno, nada será reproduzido. bvss.play (); // Se playLEDNotes tiver sido definido como verdadeiro, // reproduz as "notas do LED" junto com a música. if (playLEDNotes) playNextLEDNote ();} // Manipula o evento frameReceived void BVSP_frameReceived (byte dataType, int payloadSize) {// Verifica se o frame recebido contém dados binários // 0x07 =Dados binários (matriz de bytes) if (dataType ==DATA_TYPE_BINARY) {// Se 2 bytes foram recebidos, processa o comando. if (bvsp.getReceivedBytes (receiveBuffer, RECEIVE_BUFFER_SIZE) ==RECEIVE_BUFFER_SIZE) {analogWrite (receiveBuffer [0], receiveBuffer [1]); }} // Verifica se o quadro recebido contém tipo de dados byte // 0x01 =Tipo de dados byte else if (dataType ==DATA_TYPE_BYTE) {// Se o valor do byte recebido for 255, define playLEDNotes // e marca a hora atual. if (bvsp.getReceivedByte () ==255) {playLEDNotes =true; playStartTime =millis (); }}} // Manipula o evento modeChanged void BVSP_modeChanged () {// Se o outboundMode (Servidor -> Dispositivo) mudou para // FRAMED_MODE, nenhum fluxo de áudio deve ser recebido. // Diz à classe BVSSpeaker para terminar de jogar quando seu // buffer interno ficar vazio. if (bvsp.outboundMode ==FRAMED_MODE) bvss.finishPlaying ();} // Lida com o evento streamReceived void BVSP_streamReceived (int size) {// Obtém o fluxo recebido da classe BVSP int bytesRead =bvsp.getReceivedStream (speakerBuffer, SPEAKER_BUFFER_SIZE); // Enfileira o fluxo recebido para reproduzir bvss.enqueue (speakerBuffer, bytesRead);} // Acende o LED apropriado com base na hora // o comando para começar a tocar as notas do LED foi recebido.// Os tempos usados ​​aqui são sincronizados com the music.void playNextLEDNote () {// Obtém o tempo decorrido entre playStartTime e // a hora atual. transcorrido longo sem sinal =millis () - playStartTime; // Desliga todos os LEDs allLEDsOff (); // A última nota foi tocada. // Desliga o último LED e para de tocar as notas do LED. if (decorrido> =11500) {analogWrite (RED_LED_PIN, 0); playLEDNotes =false; } else if (decorrido> =9900) analogWrite (RED_LED_PIN, 255); // C nota mais if (elapsed> =9370) analogWrite (RED_LED_PIN, 255); // C nota mais if (decorrido> =8900) analogWrite (YELLOW_LED_PIN, 255); // D nota mais if (decorrido> =8610) analogWrite (RED_LED_PIN, 255); // C nota mais if (decorrido> =8230) analogWrite (YELLOW_LED_PIN, 255); // D nota mais if (decorrido> =7970) analogWrite (YELLOW_LED_PIN, 255); // D nota mais if (decorrido> =7470) analogWrite (RED_LED_PIN, 255); // C nota mais if (decorrido> =6760) analogWrite (GREEN_LED_PIN, 255); // E nota mais if (decorrido> =6350) analogWrite (RED_LED_PIN, 255); // C nota mais if (decorrido> =5880) analogWrite (YELLOW_LED_PIN, 255); // D nota mais if (decorrido> =5560) analogWrite (RED_LED_PIN, 255); // C nota mais if (decorrido> =5180) analogWrite (YELLOW_LED_PIN, 255); // D nota mais if (decorrido> =4890) analogWrite (YELLOW_LED_PIN, 255); // D nota mais if (decorrido> =4420) analogWrite (RED_LED_PIN, 255); // C nota mais if (elapsed> =3810) analogWrite (GREEN_LED_PIN, 255); // E nota mais if (decorrido> =3420) analogWrite (RED_LED_PIN, 255); // C nota mais if (decorrido> =2930) analogWrite (YELLOW_LED_PIN, 255); // D nota mais if (decorrido> =2560) analogWrite (RED_LED_PIN, 255); // C nota mais if (decorrido> =2200) analogWrite (YELLOW_LED_PIN, 255); // D nota mais if (decorrido> =1930) analogWrite (YELLOW_LED_PIN, 255); // D nota mais if (decorrido> =1470) analogWrite (RED_LED_PIN, 255); // C nota mais if (elapsed> =1000) analogWrite (GREEN_LED_PIN, 255); // E note} // Desliga todos os LEDs.void allLEDsOff () {analogWrite (RED_LED_PIN, 0); analogWrite (YELLOW_LED_PIN, 0); analogWrite (GREEN_LED_PIN, 0);} 

Esquemas


Processo de manufatura

  1. Sistema de atendimento usando Arduino e RFID com Python
  2. Sensor DHT11 com LEDs e um alto-falante Piezo
  3. Diversão do giroscópio com anel NeoPixel
  4. Arduino Temp. Monitor e relógio em tempo real com tela 3.2
  5. Controle de um robô Roomba com Arduino e dispositivo Android
  6. Voltímetro DIY com Arduino e um visor Nokia 5110
  7. Controle do Servo Motor com Arduino e MPU6050
  8. u-blox LEA-6H 02 Módulo GPS com Arduino e Python
  9. Como ler a temperatura e umidade em Blynk com DHT11
  10. Cubo de LED 4x4x4 com Arduino Uno e 1sheeld