Problema con String.substring()

Salve ragazzi,
ho scritto questo sketch per provare un po' ad usare arduino con il comando vocale tramite bitvoicer, però ho due problemi:

  1. Quando gli passo un intero, il buzzer inizia a suonare ad intermittenza ma non smette più, cioè se gli passo il 3 non bippa solo 3 volte ma all'infinito
  2. Tutti gli if con la funzione "substring()" non mi funzionano, perchè le funzioni non vengono proprio richiamate (avevo messo un else senza condizione e chiamava la funzione e funzionava con il parametro, quindi non credo sia un problema di parametro passato)

il codice è questo:

#include <Servo.h>
#include <BitVoicer11.h>
Servo Porta;
BitVoicerSerial input= BitVoicerSerial();
const int lamp= 8;
const int camera = 9;
const int bagno = 10;
const int cucina= 11;
const int speaker = 6;
byte tipo;
String comando;
int volte;
boolean intero= false, stringa= false;

void setup(){
 Serial.begin(9600);
 pinMode(camera, OUTPUT);
 pinMode(bagno, OUTPUT);
 pinMode(cucina, OUTPUT);
 pinMode(speaker, OUTPUT);
 pinMode(lamp, OUTPUT);
 Porta.attach(5);
}

void loop(){
  
  tipo=input.getData();
 
 if(tipo == BV_INT){
   intero= true;
   stringa= false;
   volte = input.intData;
 }
 else if(tipo == BV_STR){
   intero= false;
   stringa= true;
   comando = input.strData;
 }
  
  if(intero){
  suona(volte); 
 }
 else if (stringa){
   if(comando.substring(1,3) == "luc")
     luci(comando);
   else if(comando.substring(1,3) == "por")
     porta(comando);
   else if(comando.substring(1,3) == "lam")
     lampeggia(comando);

 }
 
}

void luci(String x){
 if(x.substring(9,10) == "on"){
  if(x.substring(5,7) == "cuc")
    digitalWrite(cucina, HIGH);
  else if(x.substring(5,7) == "bag")
    digitalWrite(bagno, HIGH);
  else
    digitalWrite(camera, HIGH);
  }
  else if(x.substring(10,12)=="off"){
    if(x.substring(5,7)=="cuc")
      digitalWrite(cucina, LOW);
    else if(x.substring(5,7)=="bag")
      digitalWrite(bagno, LOW);
    else
      digitalWrite(camera, LOW);
 } 
}

void porta(String x){
 if(x.substring(4,6)=="chi")
  Porta.write(0);
 else if(x.substring(4,6)=="apr")
  Porta.write(180);
}

void suona(int x){
  for(int i=0; i<=x; i++)
  {
    tone(speaker, 350, 200);
    delay(500);
    noTone(speaker);
  }
  
}

void lampeggia(String x){
 int pausa;
 if(x.substring(5,7)=="nor")
   pausa= 500;
 else if(x.substring(5,7)=="len")
   pausa= 800;
 else
   pausa= 200;
   
 while(x!="lam-sto"){
   if(x.substring(4)=="-")
     pausa -= 100;
   else
     pausa +=100;
     
  digitalWrite(lamp, HIGH);
  delay(pausa);
  digitalWrite(lamp, LOW);
  delay(pausa);
 }
}

I valori che invia bitvoicer tramite seriale sono:

  1. interi da 0 a 9
  2. stringhe: "lam-vel", "lam-nor", "lam-len", "lam-", "lam+", "lam-sto", "luc-cam-on", e così via, simili a queste, ovvero i primi 3 caratteri identificano la funzione mentre gli altri sono specifiche o valori.

Grazie, Salvatore

Forse è meglio se commento lo sketch per renderlo più chiaro?
Ve lo passo anche tramite Pastebin, così si legge meglio

#include <Servo.h>
 //Libreria per il collegamento a Bitvoicer
#include <BitVoicer11.h>

Servo Porta;
// Creo l'oggetto dove salverò e leggerò i parametri ricevuti
BitVoicerSerial input= BitVoicerSerial();
const int lamp= 8;
const int camera = 9;
const int bagno = 10;
const int cucina= 11;
const int speaker = 6;
byte tipo;
String comando;
int volte;
boolean intero= false, stringa= false;

void setup(){
 Serial.begin(9600);
 pinMode(camera, OUTPUT);
 pinMode(bagno, OUTPUT);
 pinMode(cucina, OUTPUT);
 pinMode(speaker, OUTPUT);
 pinMode(lamp, OUTPUT);
 Porta.attach(5);
}

void loop(){
  
  tipo=input.getData(); //Legge il contenuto dal flusso seriale
 // Controllo il tipo del parametro passato
 // BV_INT mi dice che il parametro è un intero
 if(tipo == BV_INT){
   intero= true;
   stringa= false;
   volte = input.intData; //intData serve a leggere l'intero passato
 }
 //BV_STR mi dice che il parametro è una stringa
 else if(tipo == BV_STR){
   intero= false;
   stringa= true;
   comando = input.strData; //strData serve a leggere la stringa passata
 }
  
  if(intero){
    // faccio bippare lo speaker
  suona(volte); 
 }
 else if (stringa){
  // controllo i primi 3 caratteri che mi dicono qual'è il comando
   if(comando.substring(1,3) == "luc")
   //Il comando si riferisce alle luci
     luci(comando);
   else if(comando.substring(1,3) == "por")
   //Il comando si riferisce alla porta
     porta(comando);
   else if(comando.substring(1,3) == "lam")
   //Il comando si riferisce al led da far lampeggiare
     lampeggia(comando);

 }
 
}

// Funzione per accendere le luci
void luci(String x){
  // se gli ultimi due caratteri sono "on" allora devo accendere
 if(x.substring(9,10) == "on"){
   // verifico cosa devo accendere
  if(x.substring(5,7) == "cuc")
    digitalWrite(cucina, HIGH);
  else if(x.substring(5,7) == "bag")
    digitalWrite(bagno, HIGH);
  else
    digitalWrite(camera, HIGH);
  }
  // se gli ultimi due caratteri sono "off" allora devo spegnere
  else if(x.substring(10,12)=="off"){
     // verifico cosa devo spegnere
    if(x.substring(5,7)=="cuc")
      digitalWrite(cucina, LOW);
    else if(x.substring(5,7)=="bag")
      digitalWrite(bagno, LOW);
    else
      digitalWrite(camera, LOW);
 } 
}

//Funzione per aprire o chiudere la porta
void porta(String x){
 if(x.substring(4,6)=="chi")
  Porta.write(0);
 else if(x.substring(4,6)=="apr")
  Porta.write(180);
}

//Funzione per far bippare lo speaker
void suona(int x){
  for(int i=0; i<=x; i++)
  {
    tone(speaker, 350, 200);
    delay(500);
    noTone(speaker);
  }
  
}

// Funzione per far lampeggiare il led
void lampeggia(String x){
 int pausa;
 if(x.substring(5,7)=="nor")
   pausa= 500;
 else if(x.substring(5,7)=="len")
   pausa= 800;
 else
   pausa= 200;
 
 //Lampeggia fin quando non dico stop
 while(x!="lam-sto"){
   if(x.substring(4)=="-")
     pausa -= 100;
   else
     pausa +=100;
     
  digitalWrite(lamp, HIGH);
  delay(pausa);
  digitalWrite(lamp, LOW);
  delay(pausa);
 }
}

Nella funzione substring(from, to) il from è un indice che parte da 0.

String A = "123456789";

A.substring(2, 3) restituisce "34"

Ho cambiato gli indici ma non funziona ancora, inoltre non capisco perchè lo speaker non bippa x volte :sweat_smile:

"Non funziona" è un po' generico, non trovi?

Perché non stampi il risultato di ogni sub string per verificare la cosa?

Hai ragione scusami :sweat_smile: , intendevo dire che le substring ancora non vanno.
Purtroppo se comunica con BitVoicer non posso vedere il monitor seriale.
Ora scrivo altri sketch con quegli If e controllo

Quando gli passo un intero, il buzzer inizia a suonare ad intermittenza ma non smette più, cioè se gli passo il 3 non bippa solo 3 volte ma all'infinito

Probabile che il valore che passi come parametro alla funzione che "fa i beep" non sia nel range che ti aspetti. Forse tutto deriva da un'errato parsing dei valori. Prova mettendo un if prima del for in cui controlli se "x" è maggiore ad esempio di 5 o di 10, nel caso esci dalla funzione senza eseguire il for.

[RISOLTO]
Ho risolto, in pratica ho dovuto fare:

String s="luc-cuc"
// per cercare luc
if(s.substring(0,3)=="luc)
   Serial.println("Entrato");

In pratica vuole la posizione dove ha inizio la stringa e la posizione dopo la fine della stringa.
In pratica con l'esempio di cyberhs
String A = "123456789";

A.substring(2, 3) restituisce "3"

Mentre per lo speaker ho inserito un if "if(x>=0 && x<=10)", entra nell'if ma il ciclo non si ferma

Grazie per l'aiuto

Ma non è che la Tone e la Servo si danno noia? Entrambe usano timer ed interrupt.

Ho eliminato il servo e lo speaker continua a bippare ::slight_smile:

Lo hai eliminato anche dal codice? Io parlavo della libreria Servo (nota la S maiuscola), non del servo(motore) in sé.