Bene ragazzi, ci troveremo difronte ad un lungo script che potreste provare già a caricare sul vostro Arduino (spostando il jumper in modalità SW) questa script vi permetterà di pronunciare il comando e di ricevere un feedback di risposta con il suono base: il beep solo per i comandi appartenenti al gruppo 0 cioè i trigger.
#if defined(ARDUINO) && ARDUINO >= 100 #include "Arduino.h" #include "Platform.h" #include "SoftwareSerial.h" #ifndef CDC_ENABLED // Shield Jumper on SW SoftwareSerial port(12,13); #else // Shield Jumper on HW (for Leonardo) #define port Serial1 #endif #else // Arduino 0022 - use modified NewSoftSerial #include "WProgram.h" #include "NewSoftSerial.h" NewSoftSerial port(12,13); #endif #include "EasyVR.h" EasyVR easyvr(port); //Groups and Commands enum Groups { GROUP_3 = 3, }; enum Group3 { G3_APRI = 0, G3_CHIUDI = 1, G3_CIAO = 2, }; EasyVRBridge bridge; int8_t group, idx; void setup() { #ifndef CDC_ENABLED // bridge mode? if (bridge.check()) { cli(); bridge.loop(0, 1, 12, 13); } // run normally Serial.begin(9600); Serial.println("Bridge not started!"); #else // bridge mode? if (bridge.check()) { port.begin(9600); bridge.loop(port); } Serial.println("Bridge connection aborted!"); #endif port.begin(9600); while (!easyvr.detect()) { Serial.println("EasyVR not detected!"); delay(1000); } easyvr.setPinOutput(EasyVR::IO1, LOW); Serial.println("EasyVR detected!"); easyvr.setTimeout(5); easyvr.setLanguage(1); group = EasyVR::TRIGGER; //<-- start group (customize) } void action(); void loop() { easyvr.setPinOutput(EasyVR::IO1, HIGH); // LED on (listening) Serial.print("Say a command in Group "); Serial.println(group); easyvr.recognizeCommand(group); do { // can do some processing while waiting for a spoken command } while (!easyvr.hasFinished()); easyvr.setPinOutput(EasyVR::IO1, LOW); // LED off idx = easyvr.getWord(); if (idx >= 0) { // built-in trigger (ROBOT) // group = GROUP_X; <-- jump to another group X return; } idx = easyvr.getCommand(); if (idx >= 0) { // print debug message uint8_t train = 0; char name[32]; Serial.print("Command: "); Serial.print(idx); if (easyvr.dumpCommand(group, idx, name, train)) { Serial.print(" = "); Serial.println(name); } else Serial.println(); easyvr.playSound(0, EasyVR::VOL_FULL); // perform some action action(); } else // errors or timeout { if (easyvr.isTimeout()) Serial.println("Timed out, try again..."); int16_t err = easyvr.getError(); if (err >= 0) { Serial.print("Error "); Serial.println(err, HEX); } } } void action() { switch (group) { case GROUP_3: switch (idx) { case G3_APRI: // write your action code here // group = GROUP_X; <-- or jump to another group X for composite commands break; case G3_CHIUDI: // write your action code here // group = GROUP_X; <-- or jump to another group X for composite commands break; case G3_CIAO: // write your action code here // group = GROUP_X; <-- or jump to another group X for composite commands break; } break; } }
Passiamo ad analizzare lo script di Commander. Come vedete è abbastanza lunga come base di partenza, ma non preoccupatevi poiché molte stringhe possono (sottolineo il “possono” perché potrete anche saltare questo passaggio) essere eliminate senza causare alcun problema. Esse infatti servono per attivare alcune funzioni addizionali del nostro EasyVR (come per esempio la possibilità di connettersi a Commander senza cambiare pin) ma purtroppo il tempo non è a nostro favore quindi evitiamo per il momento di spigare intere librerie che potrebbero non interessare a tutti e passiamo direttamente al succo. Voglio precisare che ho comunque intenzione di realizzare un tutorial finale dove andrò ad analizzare tutto quello che oggi eliminerò per semplificare il tutorial ma che comunque potrebbe interessare a qualcuno che è già un po’ più esperto.
Passiamo ad alleggerire il programma, eliminiamo le righe: da 1 a 3, 5, 6, da 8 a 17, da 34 a 37, da 42 a 49, da 51 a 55, da 57 a 62
#include "SoftwareSerial.h" SoftwareSerial port(12,13); #include "EasyVR.h" EasyVR easyvr(port); //Groups and Commands enum Groups { GROUP_3 = 3, }; enum Group3 { G3_APRI = 0, G3_CHIUDI = 1, G3_CIAO = 2, }; int8_t group, idx; void setup() { Serial.begin(9600); port.begin(9600); while (!easyvr.detect()) { Serial.println("EasyVR not detected!"); delay(1000); } easyvr.setPinOutput(EasyVR::IO1, LOW); Serial.println("EasyVR detected!"); easyvr.setTimeout(5); easyvr.setLanguage(1); group = EasyVR::TRIGGER; //<-- start group (customize) } void action(); void loop() { easyvr.setPinOutput(EasyVR::IO1, HIGH); // LED on (listening) Serial.print("Say a command in Group "); Serial.println(group); easyvr.recognizeCommand(group); do { // can do some processing while waiting for a spoken command } while (!easyvr.hasFinished()); easyvr.setPinOutput(EasyVR::IO1, LOW); // LED off idx = easyvr.getWord(); if (idx >= 0) { // built-in trigger (ROBOT) // group = GROUP_X; <-- jump to another group X return; } idx = easyvr.getCommand(); if (idx >= 0) { // print debug message uint8_t train = 0; char name[32]; Serial.print("Command: "); Serial.print(idx); if (easyvr.dumpCommand(group, idx, name, train)) { Serial.print(" = "); Serial.println(name); } else Serial.println(); //easyvr.playSound(0, EasyVR::VOL_FULL); // perform some action action(); } else // errors or timeout { if (easyvr.isTimeout()) Serial.println("Timed out, try again..."); int16_t err = easyvr.getError(); if (err >= 0) { Serial.print("Error "); Serial.println(err, HEX); } } } void action() { switch (group) { case GROUP_3: switch (idx) { case G3_APRI: // write your action code here // group = GROUP_X; <-- or jump to another group X for composite commands break; case G3_CHIUDI: // write your action code here // group = GROUP_X; <-- or jump to another group X for composite commands break; case G3_CIAO: // write your action code here // group = GROUP_X; <-- or jump to another group X for composite commands break; } break; } }
Più o meno questo sarà il risultato. Come vedete abbiamo eliminato diverse librerie e passaggi che l’Arduino faceva ad ogni avvio (praticamente per il momento quasi del tutto inutili) ma iniziamo ad analizzare gli script più interessanti presenti in questo codice:
Il prima script si trova alla riga 34 e più che altro è una variabile che indica il gruppo che verrà utilizzato per l’inizio del riconoscimento vocale; io cancellerò la scritta “EasyVR::TRIGGER” ed inserirò il numero 3 perché ho salvato tutti i miei comandi in quel gruppo.
A questo punto, fate un bello scroll e passate alla riga 94 troverete il “void action; questo è il cuore dello script infatti noterete che contiene il comando “switch” per i gruppi e all’interno di ogni singolo gruppo un altro “switch” per i singoli comandi presenti nel gruppo stesso. Di conseguenza, qui potrete trovare tutti i vostri comandi divisi per gruppo ed ad ogni comando tra la scritta (per esempio) “case G3_APRI:” e la scritta “break;” potrete inserire tutto quello che volete come “digitalWrite(??, HIGH);” con al apposto di “??” il numero del pin che fa eccitare il relè dove abbiamo collegato la nostra lampadina. Ovviamente possiamo inserire anche la stringa “group= n” per cambiare il numero del gruppo d’ascolto. Questo ci tornerà molto utile quando dobbiamo formare delle frasi, per esempio: creiamo tre gruppi uno con i saluti (ciao, buongiorno, buonasera), uno con le azioni (accendi, apri, spegni, chiudi) e uno con l’oggetto interessato (luce, tapparella, porta) quindi noi potremo pronunciare “Ciao accendi luce” e per ogni singola parola far cambiare gruppo in modo tale da realizzare moltissime possibilità diverse (“Buongiorno apri tapparella”, “Buonasera chiudi porta”, “Ciao spegni luce”, ecc…).
Infine possiamo ovviamente far pronunciare quello che vogliamo al nostro shield: basterà inserire dove vogliamo “easyvr.playSound(??, EasyVR::VOL_FULL);” con al posto di “??” il numero della frase che deve pronunciare e magari eliminare il beep di default presente alla riga 89.