Ciao Mondo 3!

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

Indice articoli

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.

Pubblicità



 

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.

Corsair

Articoli Correlati - Sponsored Ads