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 & Synthese Meesteren op Arduino Due

Onderdelen en benodigdheden

Arduino Due × 1
SparkFun Electret Microfoon Breakout × 1
SparkFun Mono Audio Amp Breakout × 1
Luidspreker: 0.25W, 8 ohm × 1
Breadboard (generiek) × 1
5mm LED: Rood × 3
Weerstand 330 ohm × 3
Draadjes (jumper wires, generiek) × 1 set

Benodigde tools en machines

Solderbout (generiek)

Apps en online services

BitVoicer Server 1.0

Over dit project

In mijn vorige project toonde ik hoe je een paar LEDs kunt besturen met een Arduino-bord en BitVoicer Server. In dit project ga ik een stap verder: ik synthetiseer spraak met de Arduino Due digitale-naar-analoge omzetter (DAC). Als je geen Arduino Due hebt, kun je andere Arduino-borden gebruiken, maar je hebt dan een externe DAC en extra code nodig (de BVSSpeaker-bibliotheek helpt daar niet mee).

In de video zie je dat de Arduino een klein liedje speelt en de LEDs laat knipperen alsof het piano-toetsen zijn. Excuses voor mijn pianovoordracht, maar dat is het beste wat ik kan :) . De LEDs knipperen in dezelfde volgorde en timing als echte C, D en E toetsen, dus als je een piano hebt, kun je de LEDs volgen en hetzelfde liedje spelen. Het is een jingle van een oude detailhandelaar (Mappin) die niet meer bestaat.

Werkproces: van stemcommando tot LED-actie en gesyntheserde spraak

  1. Gelakgolven worden opgevangen en versterkt door de SparkFun Electret Breakout board.
  2. Het versterkte signaal wordt gedigitaliseerd en gebufferd in de Arduino via de ADC (analoge-naar-digitale omzetter).
  3. De audiomonsters worden via de seriële poort naar BitVoicer Server gestreamd.
  4. BitVoicer Server verwerkt de audiostroom en herkent de spraak.
  5. De herkende spraak wordt gemapt op vooraf gedefinieerde commando's die terug naar de Arduino worden gestuurd. Als een commando spraaksynthese vereist, bereidt BitVoicer Server de audiostroom voor en stuurt deze naar de Arduino.
  6. De Arduino identificeert de commando's en voert de juiste actie uit. Bij een audiostroom worden de monsters in de BVSSpeaker-klasse gequeue'd en afgespeeld via de Due DAC en DMA.
  7. De SparkFun Mono Audio Amp versterkt het DAC-signaal zodat het een 8-ohm luidspreker kan aansturen.

Materiaallijst met prijzen

  • Arduino Due: ~$50,00
  • SparkFun Electret Microfoon Breakout: $7,95
  • SparkFun Mono Audio Amp Breakout: $7,95
  • BitVoicer Server 1.0: $9,90
  • 8 Ohm luidspreker: ~$2,00
  • Breadboard: ~$10,00
  • 3× LEDs: ~$1,00
  • 3× 330 Ohm weerstanden: ~$0,75
  • Draadjes: ~$0,50

Stap 1: Bedrading

Bedraad de Arduino en het breadboard met de componenten zoals getoond in de afbeeldingen. Ik plaatste een klein rubberje onder de luidspreker omdat het veel trilt; zonder rubber is de geluidskwaliteit aanzienlijk slechter.

Spraakherkenning & Synthese Meesteren op Arduino Due
Spraakherkenning & Synthese Meesteren op Arduino Due
Spraakherkenning & Synthese Meesteren op Arduino Due
Spraakherkenning & Synthese Meesteren op Arduino Due

Belangrijk verschil met mijn vorige project: De meeste Arduino's draaien op 5V, maar de Due op 3.3V. Omdat ik betere resultaten kreeg met de SparkFun Electret Breakout op 3.3V, raad ik aan een jumper te plaatsen tussen de 3.3V-pin en de AREF-pin ALS je 5V Arduino-borden gebruikt. De Due gebruikt al een 3.3V analoge referentie, dus geen jumper naar AREF nodig. Feitelijk is de AREF-pin op de Due via een weerstandsbrug met de microcontroller verbonden. Om AREF te gebruiken, moet weerstand BR1 van de PCB gedesoldeerd worden.

Stap 2: Code uploaden naar de Arduino

Upload de onderstaande code naar je Arduino. De sketch is ook beschikbaar in de bijlagen. Installeer eerst de BitVoicer Server bibliotheken in de Arduino IDE (Importeren .zip Bibliotheek).

Arduino Sketch: BVS_Demo2.ino

Deze sketch heeft zeven belangrijke delen:

  1. Bibliotheekreferenties en variabele declaraties: De eerste vier regels includeren referenties naar de BVSP, BVSMic, BVSSpeaker en DAC bibliotheken (van BitSophia, te vinden in de BitVoicer Server installatiemap). De DAC-bibliotheek wordt automatisch meegenomen bij BVSSpeaker. De overige regels declareren constanten en variabelen. De BVSP-klasse communiceert met BitVoicer Server, BVSMic vangt en buffer audiomonsters, BVSSpeaker speelt audio af via de Due DAC.
  2. Setup-functie: Stelt pin-modes en beginstatus in; initialiseert seriële communicatie; initialiseert BVSP, BVSMic en BVSSpeaker klassen. Stelt event handlers in voor frameReceived, modeChanged en streamReceived events van de BVSP-klasse.
  3. Loop-functie: Voert vijf acties uit: statusinformatie opvragen bij server (keepAlive()); controleren of server data gestuurd heeft en verwerken (receive()); opname en verzending van audiostromen regelen (isSREAvailable(), startRecording(), stopRecording(), sendStream()); audiomonsters in BVSSpeaker afspelen (play()); playNextLEDNote() aanroepen voor LED-synchronisatie na playLEDNotes commando.
  4. BVSP_frameReceived functie: Wordt aangeroepen bij ontvangst van een compleet frame. Hier worden commando's van BitVoicer Server uitgevoerd. LED-commando's bevatten 2 bytes: pin-nummer en pin-waarde. analogWrite() stelt de waarde in. Controleert ook of playLEDNotes (byte-type) ontvangen is – dan playLEDNotes = true zetten en huidige tijd markeren voor synchronisatie.
  5. BVSP_modeChanged functie: Wordt aangeroepen bij moduswijziging in uitgaande richting (Server → Arduino). BitVoicer Server kan geframeerde data of audiostromen sturen. Voor overgang stuurt de server een signaal. BVSP detecteert dit en trigger modeChanged. Als communicatie van stream-modus naar frame-modus gaat, is audio klaar – BVSSpeaker stopt met afspelen.
  6. BVSP_streamReceived functie: Wordt aangeroepen bij ontvangst van audiomonsters. Haalt monsters op en queue't ze in BVSSpeaker voor afspelen via play().
  7. playNextLEDNote functie: Draait alleen als BVSP_frameReceived het playLEDNotes commando detecteert. Beheert en synchroniseert LEDs met audio van BitVoicer Server. Voor timing gebruikte ik Sonic Visualizer (gratis software) om audiogolven te zien en te bepalen wanneer een pianotoets ingedrukt werd. Het toont een tijdlijn – zo kreeg ik de milliseconden voor deze functie. Klinkt als een trucje, en dat is het ook. Het analyseren van de audiostroom en de bijbehorende LED aansturen is mogelijk, maar buiten mijn bereik.

Stap 3: BitVoicer Server Solution Objecten importeren

Stel BitVoicer Server in voor de Arduino. Vier hoofdsolution-objecten: Locations, Devices, BinaryData, Voice Schemas.

  • Locations: Fysieke locatie van device. Ik maakte Home.
  • Devices: BitVoicer Server clients. Ik maakte een Mixed device, naam ArduinoDUE, communicatie-instellingen ingevoerd. BELANGRIJK: De Due heeft beperkt geheugen voor audiobuffers. Zonder bandbreedte-limiet heb je een veel grotere buffer nodig. Ik had buffer overflows, dus Data Rate beperken tot 8000 samples per seconde in communicatie-instellingen.
  • BinaryData: Commando-type dat BitVoicer Server naar clients stuurt – byte-arrays gekoppeld aan commando's. Ik maakte een BinaryData-object per pin-waarde: ArduinoDUEGreenLedOn, ArduinoDUEGreenLedOff, etc. Totaal 18 objecten. Download en importeer vanuit VoiceSchema.sof.
  • Voice Schemas: Waar alles bijeenkomt. Definiëren welke zinnen herkend worden en welke commando's uitgevoerd worden. Per zin zoveel commando's en volgorde als je wilt, met vertragingen. Zo realiseerde ik de actie-sequenties in de video.

Een van de zinnen in mijn Voice Schema is "play a little song". Deze bevat twee commando's: eerste stuurt een byte die aangeeft dat het volgende commando een audiostroom is. De Arduino start dan het "spelen" van de LEDs terwijl audio wordt overgedragen. De audio is een zelf opgenomen piano-jingle, ingesteld als audiobron van het tweede commando. BitVoicer Server ondersteunt alleen 8-bit mono PCM audio (8000 samples/sec). Voor conversie: audio.online-convert.com.

Importeer alle solution-objecten uit de bestanden:

  • Device.sof
  • VoiceSchema.sof

Stap 4: Conclusie

Je kunt nu alles aanzetten en de zaken uit de video nabootsen.

Net als in mijn vorige project, startte ik de spraakherkenning door het Arduino-device in de BitVoicer Server Manager in te schakelen. Zodra ingeschakeld, detecteert de Arduino een beschikbare Speech Recognition Engine en begint met streamen van audio naar BitVoicer Server. Nu zie je veel meer activiteit op de Arduino RX LED tijdens audiostroom van BitVoicer Server naar de Arduino.

In mijn volgende project ga ik ambitieuzener te werk: WiFi-communicatie toevoegen aan één Arduino en twee andere Arduinos samen per stem besturen. Ik denk aan een soort spel tussen ze. Suggesties zijn welkom!

Code

Arduino Sketch Arduino

#include <BVSP.h>
#include <BVSMic.h>
#include <BVSSpeaker.h>
#include <DAC.h>

#define BVSM_AUDIO_INPUT 7
#define RED_LED_PIN 6
#define YELLOW_LED_PIN 9
#define GREEN_LED_PIN 10

const unsigned long STATUS_REQUEST_TIMEOUT = 3000;
const unsigned long STATUS_REQUEST_INTERVAL = 4000;
const int MIC_BUFFER_SIZE = 64;
const int SPEAKER_BUFFER_SIZE = 128;
const int RECEIVE_BUFFER_SIZE = 2;

BVSP bvsp = BVSP();
BVSMic bvsm = BVSMic();
BVSSpeaker bvss = BVSSpeaker();

byte micBuffer[MIC_BUFFER_SIZE];
byte speakerBuffer[SPEAKER_BUFFER_SIZE];
byte receiveBuffer[RECEIVE_BUFFER_SIZE];

bool playLEDNotes = false;
unsigned int playStartTime = 0;

void setup() {
  pinMode(RED_LED_PIN, OUTPUT);
  pinMode(YELLOW_LED_PIN, OUTPUT);
  pinMode(GREEN_LED_PIN, OUTPUT);
  digitalWrite(RED_LED_PIN, LOW);
  digitalWrite(YELLOW_LED_PIN, LOW);
  digitalWrite(GREEN_LED_PIN, LOW);
  Serial.begin(115200);
  bvsp.begin(Serial, STATUS_REQUEST_TIMEOUT, STATUS_REQUEST_INTERVAL);
  bvsp.frameReceived = BVSP_frameReceived;
  bvsp.modeChanged = BVSP_modeChanged;
  bvsp.streamReceived = BVSP_streamReceived;
  bvsm.begin();
  bvss.begin(DAC);
}

void loop() {
  bvsp.keepAlive();
  bvsp.receive();
  if (bvsp.isSREAvailable()) {
    if (!bvsm.isRecording) {
      bvsm.setAudioInput(BVSM_AUDIO_INPUT, DEFAULT);
      bvsm.startRecording();
    }
    if (bvsm.available) {
      if (bvsp.inboundMode == FRAMED_MODE) bvsp.setInboundMode(STREAM_MODE);
      int bytesRead = bvsm.read(micBuffer, MIC_BUFFER_SIZE);
      bvsp.sendStream(micBuffer, bytesRead);
    }
  } else {
    if (bvsm.isRecording) bvsm.stopRecording();
  }
  bvss.play();
  if (playLEDNotes) playNextLEDNote();
}

void BVSP_frameReceived(byte dataType, int payloadSize) {
  if (dataType == DATA_TYPE_BINARY) {
    if (bvsp.getReceivedBytes(receiveBuffer, RECEIVE_BUFFER_SIZE) == RECEIVE_BUFFER_SIZE) {
      analogWrite(receiveBuffer[0], receiveBuffer[1]);
    }
  } else if (dataType == DATA_TYPE_BYTE) {
    if (bvsp.getReceivedByte() == 255) {
      playLEDNotes = true;
      playStartTime = millis();
    }
  }
}

void BVSP_modeChanged() {
  if (bvsp.outboundMode == FRAMED_MODE) bvss.finishPlaying();
}

void BVSP_streamReceived(int size) {
  int bytesRead = bvsp.getReceivedStream(speakerBuffer, SPEAKER_BUFFER_SIZE);
  bvss.enqueue(speakerBuffer, bytesRead);
}

void playNextLEDNote() {
  unsigned long elapsed = millis() - playStartTime;
  allLEDsOff();
  if (elapsed >= 11500) {
    analogWrite(RED_LED_PIN, 0);
    playLEDNotes = false;
  } else if (elapsed >= 9900) analogWrite(RED_LED_PIN, 255);
  else if (elapsed >= 9370) analogWrite(RED_LED_PIN, 255);
  else if (elapsed >= 8900) analogWrite(YELLOW_LED_PIN, 255);
  else if (elapsed >= 8610) analogWrite(RED_LED_PIN, 255);
  else if (elapsed >= 8230) analogWrite(YELLOW_LED_PIN, 255);
  else if (elapsed >= 7970) analogWrite(YELLOW_LED_PIN, 255);
  else if (elapsed >= 7470) analogWrite(RED_LED_PIN, 255);
  else if (elapsed >= 6760) analogWrite(GREEN_LED_PIN, 255);
  else if (elapsed >= 6350) analogWrite(RED_LED_PIN, 255);
  else if (elapsed >= 5880) analogWrite(YELLOW_LED_PIN, 255);
  else if (elapsed >= 5560) analogWrite(RED_LED_PIN, 255);
  else if (elapsed >= 5180) analogWrite(YELLOW_LED_PIN, 255);
  else if (elapsed >= 4890) analogWrite(YELLOW_LED_PIN, 255);
  else if (elapsed >= 4420) analogWrite(RED_LED_PIN, 255);
  else if (elapsed >= 3810) analogWrite(GREEN_LED_PIN, 255);
  else if (elapsed >= 3420) analogWrite(RED_LED_PIN, 255);
  else if (elapsed >= 2930) analogWrite(YELLOW_LED_PIN, 255);
  else if (elapsed >= 2560) analogWrite(RED_LED_PIN, 255);
  else if (elapsed >= 2200) analogWrite(YELLOW_LED_PIN, 255);
  else if (elapsed >= 1930) analogWrite(YELLOW_LED_PIN, 255);
  else if (elapsed >= 1470) analogWrite(RED_LED_PIN, 255);
  else if (elapsed >= 1000) analogWrite(GREEN_LED_PIN, 255);
}

void allLEDsOff() {
  analogWrite(RED_LED_PIN, 0);
  analogWrite(YELLOW_LED_PIN, 0);
  analogWrite(GREEN_LED_PIN, 0);
}

Schema

Spraakherkenning & Synthese Meesteren op Arduino Due

Productieproces

  1. Betrouwbaar Arduino RFID Aanwezigheidssysteem Aangedreven door Python
  2. DHT11 Temperatuur- & Vochtigheidsensor Project met LED-indicatoren en Piezo-luidspreker
  3. Interactieve gyroscoop LED-display met NeoPixel-ring en Arduino
  4. Arduino Temperatuurbewaking & Realtime Klok met 3.2" TFT-display
  5. Bestuur Je Roomba Create 2 Met Arduino En Android: Stapsgewijze Handleiding
  6. Bouw een DIY Voltmeter met Arduino en Nokia 5110 Display – Stap-voor-Stap Handleiding
  7. Arduino & MPU6050: Precieze Servomotor Besturing met SG90 & MG996R
  8. u-blox LEA‑6H GPS Module: Arduino & Python Integratie Handleiding
  9. Temperatuur en Vochtigheid met DHT11 op Blynk - Stap-voor-Stap Arduino Tutorial
  10. Bouw een 4x4x4 LED-kubus met Arduino Uno & 1Sheeld – Interactief LED-project
  11. Arduino GPS en TFT Touchscreen Shield Project: Real-Time Locatieweergave