Piccoli passi per una casa domotica con Arduino - Controllo vocale (Parte 4)

arduino-veear introCiao a tutti ragazzi ben ritrovati con il nostro solito appuntamento settimanale dedicato al mondo maker. Lo so la parola “solito” non è molto appropriata dato la buca della scorsa settimana ma, per questo mi scuso (piccoli impegni lavorativi) e adesso preparate le vostre corde vocali che si inizia! Oggi inizieremo finalmente a programmare l’Arduino.

 

Vi ricordo che nel video dedicato a questo tutorial, farò vedere anche l’esempio utilizzato nella presentazione del progetto durante la prima puntata di questo tutorial:

 

 

Di seguito i link alle precedenti puntate:

Parte 1

Parte 2

Parte 3

 

 


 

In questa settimana di attesa, alcuni mi hanno mandato qualche messaggio privato, chiedendomi di inviargli in anticipo gli script di Arduino per iniziare già da soli ad analizzarli; in realtà non si sono mai accorti di averli già sotto il naso, dato che una delle funzionalità di Commander è proprio quella di creare in automatico gli script per Arduino! Infatti, una volta connesso il nostro Arduino al computer (con il jumper in modalità PC), potremo cliccare sul pulsante accanto alla porta seriale per salvare il file:

 

Nuova immagine bitmap

 

Molto probabilmente il file appena creato non sarà rilevato dal programma di Arduino dato che avrà un'estensione diversa dal solito (*.pde al posto di *.ino), ma non agitatevi questa estensione e perfettamente compatibile con Arduino quindi potrete semplicemente fare tasto destro => apri con => e selezionate il programma di Arduino oppure per settarlo come programma predefinito e quindi farlo riconoscerlo anche in futuro da Arduino tasto destro => proprietà => Cambia… => e selezionare il programma di Arduino.

 


 

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.


 Conclusioni

Bene ragazzi, in questo brevissimo tutorial in realtà ho spiegato come usare il vostro shield per far qualsiasi cosa, con questi semplici passaggi si può realizzare di tutto, effettivamente non vi servirebbe sapere più niente se non avete intenzione di complicarvi la vita ma io sono qui per farlo perché in realtà c’è ancora molto da vedere. Quello che vi ho presentato oggi è solo la “corteccia dell’albero” per il quale ho preferito scrivere una puntata dedicata, ma nel prossimo tutorial vedremo il primo strato cioè tutto quello che oggi non abbiamo eliminato e soprattutto cercheremo di capire come funziona questo script ed in fine con l’ultimo tutorial vedremo il “cuore” e quindi analizzeremo anche quello che oggi abbiamo cancellato, con un occhio più specifico alle librerie presenti in questo script.  Il Kit EasyVR più Shield è disponibile attualmente su Amazon al seguente link http://amzn.to/1W6w4xZ ad un prezzo di 57€.

Template Design © Joomla Templates | GavickPro. All rights reserved.