Industriële fabricage
Industrieel internet der dingen | Industriële materialen | Onderhoud en reparatie van apparatuur | Industriële programmering |
home  MfgRobots >> Industriële fabricage >  >> Manufacturing Technology >> Productieproces

Spraakherkenning en synthese met Arduino

Componenten en benodigdheden

Arduino Due
× 1
SparkFun Electret Microfoon Breakout
× 1
SparkFun Mono Audio Amp Breakout
× 1
Luidspreker:0,25 W, 8 ohm
× 1
Broodplank (algemeen)
× 1
5 mm LED:rood
× 3
Weerstand 330 ohm
× 3
Jumperdraden (algemeen)
× 1

Benodigde gereedschappen en machines

Soldeerbout (algemeen)

Apps en online services

BitVoicer Server 1.0

Over dit project

In mijn vorige project liet ik zien hoe je een paar LED's kunt besturen met behulp van een Arduino-bord en BitVoicer Server. In dit project ga ik dingen een beetje ingewikkelder maken. Ik ga ook spraak synthetiseren met behulp van de Arduino DUE digitaal-naar-analoogomzetter (DAC). Als je geen Arduino DUE hebt, kun je andere Arduino-kaarten gebruiken, maar je hebt een externe DAC en wat extra code nodig om de DAC te bedienen (de BVSSpeaker-bibliotheek helpt je daar niet bij).

In de onderstaande video kun je zien dat ik de Arduino ook een liedje laat spelen en de LED's laat knipperen alsof het pianotoetsen zijn. Sorry voor mijn pianokunsten, maar dat is het beste wat ik kan doen :) . De LED's knipperen eigenlijk in dezelfde volgorde en timing als echte C-, D- en E-toetsen, dus als je een piano in de buurt hebt, kun je de LED's volgen en hetzelfde nummer spelen. Het is een jingle van een oude retailer (Mappin) die niet eens meer bestaat.

De volgende procedures worden uitgevoerd om spraakopdrachten om te zetten in LED-activiteit en gesynthetiseerde spraak:

  • 1. Audiogolven worden opgevangen en versterkt door het Sparkfun Electret Breakout-bord;
  • 2. Het versterkte signaal wordt gedigitaliseerd en gebufferd in de Arduino met behulp van de analoog-naar-digitaalomzetter (ADC);
  • 3. De audiosamples worden gestreamd naar BitVoicer Server met behulp van de Arduino seriële poort;
  • 4. BitVoicer Server verwerkt de audiostream en herkent de spraak die erin zit;
  • 5. De herkende spraak wordt toegewezen aan vooraf gedefinieerde opdrachten die naar de Arduino worden teruggestuurd. Als een van de opdrachten bestaat uit het synthetiseren van spraak, zal BitVoicer Server de audiostream voorbereiden en naar de Arduino sturen;
  • 6. De Arduino identificeert de opdrachten en voert de juiste actie uit. Als een audiostream wordt ontvangen, wordt deze in de wachtrij geplaatst in de BVSSpeaker-klasse en afgespeeld met de DUE DAC en DMA.
  • 7. De SparkFun Mono Audio Amp zal het DAC-signaal versterken zodat hij een luidspreker van 8 Ohm kan aansturen.

Lijst met materialen:

  • Arduino DUE:~U$ 50,00
  • Sparkfun Electret Microfoon Breakout:U$ 7,95
  • SparkFun Mono Audio Amp Breakout:U$ 7,95
  • BitVoicer Server 1.0:€ 9,90
  • Speaker van 8 Ohm:~U$ 2,00
  • Broodplankje:~€ 10,00
  • 3 x LED's:~U$ 1,00
  • 3 x 330 Ohm weerstanden:~U$ 0,75
  • Jumperdraden:~U$ 0,50

STAP 1:Bedrading

De eerste stap is om de Arduino en het breadboard te bedraden met de componenten zoals weergegeven in de onderstaande afbeeldingen. Ik moest een klein rubbertje onder de luidspreker plaatsen omdat het veel trilt en zonder het rubber wordt de kwaliteit van de audio aanzienlijk aangetast.

Hier hebben we een klein maar belangrijk verschil met mijn vorige project. De meeste Arduino-kaarten werken op 5V, maar de DUE werkt op 3,3V. Omdat ik betere resultaten kreeg met de Sparkfun Electret Breakout op 3,3V, raad ik je aan een jumper toe te voegen tussen de 3,3V-pin en de AREF-pin ALS je 5V Arduino-kaarten gebruikt. De DUE gebruikt al een 3,3V analoge referentie, dus je hebt geen jumper naar de AREF-pin nodig. In feite is de AREF-pin op de DUE via een weerstandsbrug verbonden met de microcontroller. Om de AREF-pin te gebruiken, moet weerstand BR1 van de print worden losgemaakt.

STAP 2:De code uploaden naar de Arduino

Nu moet je de onderstaande code uploaden naar je Arduino. Voor het gemak is de Arduino-schets ook beschikbaar in het gedeelte Bijlagen onderaan dit bericht. Voordat u de code uploadt, moet u de BitVoicer Server-bibliotheken correct installeren in de Arduino IDE (een .zip-bibliotheek importeren).

Arduino-schets :BVS_Demo2.ino

Deze schets heeft zeven hoofdonderdelen:

  • Bibliotheekverwijzingen en variabele declaratie :De eerste vier regels bevatten verwijzingen naar de BVSP-, BVSMic-, BVSSpeaker- en DAC-bibliotheken. Deze bibliotheken worden geleverd door BitSophia en zijn te vinden in de installatiemap van BitVoicer Server. De DAC-bibliotheek wordt automatisch opgenomen wanneer u een verwijzing toevoegt aan de BVSSpeaker-bibliotheek. De andere regels declareren constanten en variabelen die in de schets worden gebruikt. De BVSP-klasse wordt gebruikt om te communiceren met BitVoicer Server, de BVSMic-klasse wordt gebruikt om audiosamples vast te leggen en op te slaan en de BVSSpeaker-klasse wordt gebruikt om audio te reproduceren met behulp van de DUE DAC.
  • Instelfunctie :Deze functie voert de volgende acties uit:stelt de pin-modi en hun beginstatus in; initialiseert seriële communicatie; en initialiseert de klassen BVSP, BVSMic en BVSSpeaker. Het stelt ook "event-handlers" in (het zijn eigenlijk functieaanwijzers) voor de frameReceived, modeChanged en streamReceived-gebeurtenissen van de BVSP-klasse.
  • Loop-functie :Deze functie voert vijf belangrijke acties uit:vraagt ​​statusinformatie aan de server (keepAlive() functie); controleert of de server gegevens heeft verzonden en verwerkt de ontvangen gegevens (receive()-functie); regelt het opnemen en verzenden van audiostreams (isSREAvailable(), startRecording(), stopRecording() en sendStream() functies); speelt de audiosamples af die in de BVSSpeaker-klasse zijn geplaatst (play()-functie); en roept de functie playNextLEDNote() aan die bepaalt hoe de LED's moeten knipperen nadat de opdracht playLEDNotes is ontvangen.
  • BVSP_frameReceived-functie :Deze functie wordt elke keer aangeroepen als de functie ontvangen() identificeert dat een volledig frame is ontvangen. Hier voer ik de opdrachten uit die door BitVoicer Server zijn verzonden. Commando's die de LED's besturen, bevatten 2 bytes. De eerste byte geeft de pin aan en de tweede byte geeft de pinwaarde aan. Ik gebruik de functie analogWrite() om de juiste waarde voor de pin in te stellen. Ik controleer ook of de opdracht playLEDNotes, die van het type Byte is, is ontvangen. Als het is ontvangen, stel ik playLEDNotes in op true en markeer de huidige tijd. Deze tijd wordt gebruikt door de playNextLEDNote-functie om de LED's te synchroniseren met het nummer.
  • BVSP_modeGewijzigde functie :Deze functie wordt elke keer aangeroepen als de functie ontvangen() een moduswijziging in de uitgaande richting identificeert (Server --> Arduino). WAUW!!! Wat is dat?! BitVoicer Server kan ingelijste gegevens of audiostreams naar de Arduino sturen. Voordat de communicatie van de ene modus naar de andere gaat, stuurt BitVoicer Server een signaal. De BVSP-klasse identificeert dit signaal en verhoogt de modeChanged-gebeurtenis. Als ik in de BVSP_modeChanged-functie merk dat de communicatie van de stream-modus naar de frame-modus gaat, weet ik dat de audio is beëindigd, zodat ik de BVSSpeaker-klasse kan vertellen om te stoppen met het afspelen van audiosamples.
  • BVSP_streamOntvangen functie :Deze functie wordt elke keer aangeroepen als de functie ontvangen() identificeert dat audiosamples zijn ontvangen. Ik haal gewoon de samples op en zet ze in de BVSSpeaker-klasse zodat de functie play() ze kan reproduceren.
  • playNextLEDNote-functie :Deze functie wordt alleen uitgevoerd als de functie BVSP_frameReceived de opdracht playLEDNotes identificeert. Het bestuurt en synchroniseert de LED's met de audio verzonden vanaf BitVoicer Server. Om de LED's te synchroniseren met de audio en de juiste timing te kennen, heb ik Sonic Visualizer gebruikt. Met deze gratis software kon ik de audiogolven zien, zodat ik gemakkelijk kon zien wanneer een pianotoets werd ingedrukt. Het toont ook een tijdlijn en zo kreeg ik de milliseconden die in deze functie werden gebruikt. Klinkt als een domme truc en dat is het ook. Ik denk dat het mogelijk zou zijn om de audiostream te analyseren en de bijbehorende LED aan te zetten, maar dat ligt buiten mijn bereik.

STAP 3:BitVoicer Server-oplossingsobjecten importeren

Nu moet je BitVoicer Server instellen om met de Arduino te werken. BitVoicer Server heeft vier belangrijke oplossingsobjecten:locaties, apparaten, binaire gegevens en spraakschema's.

Locaties vertegenwoordigen de fysieke locatie waar een apparaat is geïnstalleerd. In mijn geval heb ik een locatie gemaakt met de naam Thuis.

Apparaten zijn de BitVoicer Server-clients. Ik heb een gemengd apparaat gemaakt, het ArduinoDUE genoemd en de communicatie-instellingen ingevoerd. BELANGRIJK :zelfs de Arduino DUE heeft een kleine hoeveelheid geheugen om alle audiosamples op te slaan die BitVoicer Server zal streamen. Als je de bandbreedte niet beperkt, heb je een veel grotere buffer nodig om de audio op te slaan. Ik kreeg om deze reden wat buffer-overflows, dus ik moest de gegevenssnelheid in de communicatie-instellingen beperken tot 8000 samples per seconde.

BinaryData is een type opdracht dat BitVoicer Server naar clientapparaten kan sturen. Het zijn eigenlijk byte-arrays die u aan opdrachten kunt koppelen. Wanneer BitVoicer Server spraak herkent die verband houdt met die opdracht, verzendt het de bytearray naar het doelapparaat. Ik heb een BinaryData-object gemaakt voor elke pinwaarde en heb ze ArduinoDUEGreenLedOn, ArduinoDUEGreenLedOff enzovoort genoemd. Ik eindigde met 18 BinaryData-objecten in mijn oplossing, dus ik raad u aan de objecten te downloaden en te importeren uit de VoiceSchema.sof bestand hieronder.

Stemschema's zijn waar alles samenkomt. Ze definiëren welke zinnen moeten worden herkend en welke opdrachten moeten worden uitgevoerd. Voor elke zin kun je zoveel commando's definiëren als je nodig hebt en de volgorde waarin ze zullen worden uitgevoerd. U kunt ook vertragingen tussen opdrachten definiëren. Zo ben ik erin geslaagd om de reeks acties uit te voeren die je in de video ziet.

Een van de zinnen in mijn Stemschema is 'speel een liedje'. Deze zin bevat twee commando's. De eerste opdracht stuurt een byte die aangeeft dat de volgende opdracht een audiostream wordt. De Arduino begint dan met het "afspelen" van de LED's terwijl de audio wordt verzonden. De audio is een kleine pianojingle die ik zelf heb opgenomen en ingesteld als de audiobron van het tweede commando. BitVoicer Server ondersteunt alleen 8-bit mono PCM-audio (8000 samples per seconde), dus als u een audiobestand naar dit formaat moet converteren, raad ik de volgende online conversietool aan:http://audio.online-convert.com/convert -naar-wav.

U kunt alle oplossingsobjecten die ik in dit project heb gebruikt, importeren (Importeren van oplossingsobjecten) uit de onderstaande bestanden. De ene bevat het DUE-apparaat en de andere bevat het spraakschema en de bijbehorende opdrachten.

Bestanden met oplossingsobjecten :

  • Device.sof
  • VoiceSchema.sof

STAP 4:Conclusie

Daar ga je! Je kunt alles aanzetten en dezelfde dingen doen die in de video worden getoond.

Zoals ik deed in mijn vorige project, begon ik de spraakherkenning door het Arduino-apparaat in de BitVoicer Server Manager in te schakelen. Zodra het wordt ingeschakeld, identificeert de Arduino een beschikbare spraakherkenningsengine en begint hij met het streamen van audio naar BitVoicer Server. Nu zie je echter veel meer activiteit in de Arduino RX LED terwijl audio wordt gestreamd van BitVoicer Server naar de Arduino.

In mijn volgende project zal ik wat ambitieuzer zijn. Ik ga wifi-communicatie toevoegen aan één Arduino en twee andere Arduino's allemaal samen met spraak bedienen. Ik denk aan een soort spel tussen hen. Suggesties zijn van harte welkom!

Code

  • Arduino-schets
Arduino SchetsArduino
#include #include #include #include // Definieert de Arduino-pin die zal worden gebruikt om audio vast te leggen #define BVSM_AUDIO_INPUT 7// Definieert de LED-pinnen#define RED_LED_PIN 6#define YELLOW_LED_PIN 9#define GREEN_LED_PIN 10// Definieert de constanten die als parameters worden doorgegeven aan // de BVSP.begin functieconst unsigned long STATUS_REQUEST_TIMEOUT =3000;const unsigned long STATUS_VALREQUEST; Definieert de grootte van de microfoon audio buffer const int MIC_BUFFER_SIZE =64;// Definieert de grootte van de speaker audio bufferconst int SPEAKER_BUFFER_SIZE =128;// Definieert de grootte van de ontvangst bufferconst int RECEIVE_BUFFER_SIZE =2;// Initialiseert een nieuwe globale instantie van de BVSP klasse BVSP bvsp =BVSP();// Initialiseert een nieuwe globale instantie van de BVSMic klasse BVSMic bvsm =BVSMic();// Initialiseert een nieuwe globale instantie van de BVSSpeaker klasse BVSSpeaker bvss =BVSSpeaker();// Creëert een buffer die zal worden gebruikt om opgenomen samples te lezen // van t de BVSMic class byte micBuffer [MIC_BUFFER_SIZE];// Creëert een buffer die zal worden gebruikt om audiosamples te schrijven // in de BVSSpeaker class byte speakerBuffer [SPEAKER_BUFFER_SIZE];// Creëert een buffer die zal worden gebruikt om de verzonden opdrachten te lezen// van BitVoicer Server.// Byte 0 =pinnummer// Byte 1 =pinwaardebyte ReceiveBuffer [RECEIVE_BUFFER_SIZE];// Deze variabelen worden gebruikt om te bepalen wanneer te spelen// "LED Notes". Deze noten worden gespeeld samen met // het nummer dat wordt gestreamd vanaf BitVoicer Server.bool playLEDNotes =false; unsigned int playStartTime =0; void setup () { // Stelt de pin-modi in pinMode (RED_LED_PIN, OUTPUT); pinMode (GELE_LED_PIN, UITGANG); pinMode (GROEN_LED_PIN, UITGANG); // Stelt de beginstatus in van alle LED's digitalWrite (RED_LED_PIN, LOW); digitalWrite (GELE_LED_PIN, LAAG); digitalWrite (GROEN_LED_PIN, LAAG); // Start seriële communicatie op 115200 bps Serial.begin (115200); // Stelt de Arduino seriële poort in die zal worden gebruikt voor // communicatie, hoe lang het duurt voordat een statusverzoek // time-out en hoe vaak statusverzoeken naar // BitVoicer Server moeten worden verzonden. bvsp.begin (serieel, STATUS_REQUEST_TIMEOUT, STATUS_REQUEST_INTERVAL); // Definieert de functie die de frameReceived zal verwerken // event bvsp.frameReceived =BVSP_frameReceived; // Stelt de functie in die de modeChanged zal afhandelen // event bvsp.modeChanged =BVSP_modeChanged; // Stelt de functie in die de streamReceived // event bvsp.streamReceived =BVSP_streamReceived; // Bereidt de BVSMic class timer bvsm.begin() voor; // Stelt de DAC in die zal worden gebruikt door de BVSSpeaker-klasse bvss.begin(DAC);}void loop() { // Controleert of het statusverzoekinterval is verstreken en als het // is, stuurt het een statusverzoek naar BitVoicer Server bvsp.keepAlive(); // Controleert of er gegevens beschikbaar zijn op de seriële poortbuffer // en verwerkt de inhoud ervan volgens de specificaties // van het BitVoicer Server Protocol bvsp.receive(); // Controleert of er één SRE beschikbaar is. Als er een is, begint // de opname. if (bvsp.isSREAvailable()) { // Als de BVSMic-klasse niet opneemt, stelt u de audio //-invoer in en begint met opnemen if (!bvsm.isRecording) { bvsm.setAudioInput (BVSM_AUDIO_INPUT, DEFAULT); bvsm.startRecording(); } // Controleert of de BVSMic-klasse beschikbare samples heeft als (bvsm.available) { // Zorgt ervoor dat de inkomende modus STREAM_MODE is voordat // de stream verzendt als (bvsp.inboundMode ==FRAMED_MODE) bvsp.setInboundMode(STREAM_MODE); // Leest de audiosamples van de BVSMic-klasse int bytesRead =bvsm.read (micBuffer, MIC_BUFFER_SIZE); // Stuurt de audiostream naar BitVoicer Server bvsp.sendStream (micBuffer, bytesRead); } } else { // Er is geen SRE beschikbaar. Als de BVSMic-klasse aan het opnemen is, stopt // deze. if (bvsm.isRecording) bvsm.stopRecording(); } // Speelt alle audiosamples af die beschikbaar zijn in de BVSSpeaker-klasse // interne buffer. Deze voorbeelden zijn geschreven in de // BVSP_streamReceived gebeurtenishandler. Als er geen samples // beschikbaar zijn in de interne buffer, wordt er niets afgespeeld. bvss.play(); // Als playLEDNotes is ingesteld op true, // speelt de "LED-noten" samen met de muziek. if (playLEDNotes) playNextLEDNote ();}// Verwerkt de frameReceived-gebeurtenis void BVSP_frameReceived (byte dataType, int payloadSize) { // Controleert of het ontvangen frame binaire gegevens bevat // 0x07 =Binaire gegevens (byte-array) if (dataType ==DATA_TYPE_BINARY) { // Als er 2 bytes zijn ontvangen, verwerk dan de opdracht. if (bvsp.getReceivedBytes (receiveBuffer, RECEIVE_BUFFER_SIZE) ==RECEIVE_BUFFER_SIZE) { analogWrite (receiveBuffer [0], ReceiveBuffer [1]); } } // Controleert of het ontvangen frame byte-gegevenstype bevat // 0x01 =Byte-gegevenstype else if (dataType ==DATA_TYPE_BYTE) { // Als de ontvangen bytewaarde 255 is, stelt playLEDNotes // in en markeert de huidige tijd. if (bvsp.getReceivedByte() ==255) { playLEDNotes =true; playStartTime =millis(); } }}// Verwerkt de modeChanged-gebeurtenis void BVSP_modeChanged() { // Als de outboundMode (Server --> Device) is veranderd in // FRAMED_MODE, wordt verondersteld dat er geen audiostream wordt ontvangen. // Vertelt de BVSSpeaker-klasse om te stoppen met spelen wanneer zijn // interne buffer leeg is. if (bvsp.outboundMode ==FRAMED_MODE) bvss.finishPlaying();} // Verwerkt de streamReceived-gebeurtenis void BVSP_streamReceived (int size) {// Haalt de ontvangen stream op van de BVSP-klasse int bytesRead =bvsp.getReceivedStream (speakerBuffer, SPEAKER_BUFFER_SIZE); // Zet de ontvangen stream in de wachtrij om bvss.enqueue (speakerBuffer, bytesRead);}// Licht op de juiste LED op basis van de tijd // de opdracht om te beginnen met het spelen van LED-noten is ontvangen.// De timings die hier worden gebruikt, zijn gesynchroniseerd met the music.void playNextLEDNote(){ // Haalt de verstreken tijd op tussen playStartTime en de // huidige tijd. niet-ondertekend lang verstreken =millis() - playStartTime; // Schakelt alle LED's uit allLEDsOff(); // De laatste noot is gespeeld. // Schakelt de laatste LED uit en stopt met het spelen van LED-noten. if (verstreken>=11500) { analogWrite (RED_LED_PIN, 0); playLEDNotes =onwaar; } else if (verstreken>=9900) analogWrite(RED_LED_PIN, 255); // C let op else if (verstreken>=9370) analogWrite (RED_LED_PIN, 255); // C let op else if (verstreken>=8900) analogWrite (YELLOW_LED_PIN, 255); // D let anders op als (verstreken>=8610) analogWrite (RED_LED_PIN, 255); // C let op else if (verstreken>=8230) analogWrite (YELLOW_LED_PIN, 255); // D merk anders op als (verstreken> =7970) analogWrite (YELLOW_LED_PIN, 255); // D let anders op als (verstreken>=7470) analogWrite (RED_LED_PIN, 255); // C let op else if (verstreken>=6760) analogWrite (GREEN_LED_PIN, 255); // E let anders op als (verstreken>=6350) analogWrite (RED_LED_PIN, 255); // C let op else if (verstreken>=5880) analogWrite (YELLOW_LED_PIN, 255); // D merk anders op als (verstreken> =5560) analogWrite (RED_LED_PIN, 255); // C let op else if (verstreken>=5180) analogWrite (YELLOW_LED_PIN, 255); // D let anders op als (verstreken>=4890) analogWrite (YELLOW_LED_PIN, 255); // D let anders op als (verstreken> =4420) analogWrite (RED_LED_PIN, 255); // C let op else if (verstreken>=3810) analogWrite (GREEN_LED_PIN, 255); // E let anders op als (verstreken>=3420) analogWrite (RED_LED_PIN, 255); // C let op else if (verstreken>=2930) analogWrite (YELLOW_LED_PIN, 255); // D let anders op als (verstreken> =2560) analogWrite (RED_LED_PIN, 255); // C let op else if (verstreken>=2200) analogWrite (YELLOW_LED_PIN, 255); // D let anders op als (verstreken>=1930) analogWrite (YELLOW_LED_PIN, 255); // D merk anders op als (verstreken> =1470) analogWrite (RED_LED_PIN, 255); // C let op else if (verstreken>=1000) analogWrite (GREEN_LED_PIN, 255); // E opmerking}// Schakelt alle LED's uit.void allLEDsOff(){ analogWrite(RED_LED_PIN, 0); analogWrite (GELE_LED_PIN, 0); analoogWrite(GREEN_LED_PIN, 0);}

Schema's


Productieproces

  1. Aanwezigheidssysteem met Arduino en RFID met Python
  2. DHT11-sensor met LED's en een piëzo-luidspreker
  3. Gyroscoopplezier met NeoPixel Ring
  4. Arduino Temp. Monitor en realtimeklok met 3.2-weergave
  5. Een Roomba-robot besturen met Arduino en Android-apparaat
  6. DIY voltmeter met Arduino en een Nokia 5110-display
  7. Besturing van servomotor met Arduino en MPU6050
  8. u-blox LEA-6H 02 GPS-module met Arduino en Python
  9. De temperatuur en vochtigheid op Blynk aflezen met DHT11
  10. 4x4x4 LED-kubus met Arduino Uno en 1sheeld
  11. GPS-locatieweergave met GPS- en TFT-schermschilden