Go Down

Topic: [risolto] Caratteri nascosti in una stringa? (Read 990 times) previous topic - next topic

hermit274

Apr 21, 2013, 01:15 am Last Edit: Apr 22, 2013, 12:59 pm by hermit274 Reason: 1
Ciao Ragazzi, mi trovo alle prese con un nuovo progetto con una GSM shield.
Vorrei leggere gli eventi che la shield invia ad Arduino, in particolare vorrei sapere quando viene ricevuto un sms in modo tale da poter accendere un led. Sono riuscito a scrivere il codice, ma mi sono bloccato.
Praticamente non viene eseguito il giusto confronto tra stringhe e il programma non va avanti.
Vi posto il codice:
Code: [Select]
#define led 13

#include <SoftwareSerial.h>
#include <string.h>

SoftwareSerial sim900(7, 8);

String istruzione = "";
int numero_ultimo_sms = 0;
char carattere;
int i = 0;
int inizio_sms = 0;


void setup(){
 sim900.begin(19200);
 Serial.begin(19200);
 delay(500);
}


void loop(){
leggi();
}
 
void leggi(){
 if( sim900.available() >0){
   carattere = sim900.read();
   if(carattere != '\r'){
    istruzione += carattere;
   }
   delay(5);
   Serial.print(istruzione);
 }
 
 if(istruzione.startsWith("+CMTI: \"SM\",")){
   Serial.print("Ricevuto un SMS, contenuto");
   delay(5);
   numero_ultimo_sms = carattere - '0';     //posso fare questa cosa perchè uscito dal ciclo while ho ancora in memoria l'ultima informazione che è un numero
   sim900.print("AT+CMGR=");
   sim900.println(numero_ultimo_sms);
   istruzione = "";

   while(sim900.available() >0){      //leggo l'sms
     carattere = sim900.read();
     istruzione += carattere;    //adesso in istruzione c'è il contenuto dell'sms!
     delay(5);
     Serial.print(carattere);
     i = i+1;
     if(carattere == '\"\"'){
       inizio_sms = i;
     }
    }

     istruzione.toLowerCase();

   if(istruzione.substring(inizio_sms,(istruzione.length()-2)) == "accendi"){
     digitalWrite(led, HIGH);
     i=0;
     inizio_sms = 0;
     istruzione = "";
   }
   else if(istruzione.substring(inizio_sms,(istruzione.length()-2)) == "spegni"){
     digitalWrite(led,LOW);
     i=0;
     inizio_sms = 0;
     istruzione = "";
   }
 }
}


il programma si pianta qui
Code: [Select]
if( sim900.available() >0){
   carattere = sim900.read();
   if(carattere != '\r'){
    istruzione += carattere;
   }
   delay(5);
   Serial.print(istruzione);
 }

questa parte di programma viene eseguita, ma tutto il resto non va avanti. Come mai? Non riesco a capire, deve esserci qualche carattere nascosto nella stringa che non riesco a capire...
Vi posto anche quello che viene prodotto dal mio Serial Monitor
Code: [Select]


+
+C
+CM
+CMT
+CMTI
+CMTI:
+CMTI:
+CMTI: "
+CMTI: "S
+CMTI: "SM
+CMTI: "SM"
+CMTI: "SM",
+CMTI: "SM",6
+CMTI: "SM",6
+CMTI: "SM",6

Qualche suggerimento?

nid69ita

Quindi non ti da mai la frase "Ricevuto un sms...."   ?

Io proverei a capire se eventualmente la funzione StartWith non possa avere dei problemi "nascosti".
Prova a fare il test su meno caratteri
esempio:
     if(istruzione.startsWith("+CMTI")){

L'importante è vedere se così "entra" nell'if. Se entra, prova ad aumentare i caratteri di uno alla volta fino a quello che non piace alla classe String. E' solo un tentativo e logicamente il resto del programma non funzionerebbe.
my name is IGOR, not AIGOR

hermit274

No purtroppo non mi visualizza mai "ricevuto sms" :-( il problema è proprio quello!
Adesso sono in giro e sto scrivendo con il telefono, appena arrivo a casa provo a inserire meno caratteri e vediamo come si comporta :-)

hermit274

Adesso mi e sorto un dubbio...ma il risultato che ho postato del serial monitor e esatto? C'e un ritorno a capo che io non ho messo! Infatti ho utilizzato la funzione

Code: [Select]
Serial.print e non
Code: [Select]
serial.println

???

hermit274

ciao ragazzi. Ho cercato di rivedere il codice ma a me sembra tutto ok, ho scoperto che nel serial monitor, ogni volta che Arduino stampava i risultati ci sono due spazi vuoti (due ritorni a capo). Ho scartato queste due letture, è ho ottenuto la stringa che volevo. Vi posto il codice
Code: [Select]
#define led 13

#include <SoftwareSerial.h>
#include <string.h>

SoftwareSerial sim900(7, 8);

String istruzione = "";
int numero_ultimo_sms = 0;
char carattere;
int i = 0;
int inizio_sms = 0;
int counter = 0;

void setup(){
  sim900.begin(19200);
  Serial.begin(19200);
  delay(500);
}


void loop(){
leggi();
}
 
void leggi(){
  if( sim900.available() >0){
    carattere = sim900.read();
    if(counter > 1){
     istruzione += carattere;
    }
    delay(5);
    counter ++;
  }
 
  if(istruzione.startsWith("+CMTI: \"SM\",")){
    Serial.print("Ricevuto un SMS, contenuto");
    delay(5);
    numero_ultimo_sms = istruzione.charAt(istruzione.indexOf(',')+1);     //posso fare questa cosa perchè uscito dal ciclo while ho ancora in memoria l'ultima informazione che è un numero
    sim900.print("AT+CMGR=");
    sim900.println(numero_ultimo_sms);
    istruzione = "";

    while(sim900.available() >0){      //leggo1 l'sms
      carattere = sim900.read();
      istruzione += carattere;    //adesso in istruzione c'è il contenuto dell'sms!
      delay(5);
      Serial.print(carattere);
      i = i+1;
      if(carattere == '\"\"'){
        inizio_sms = i;
      }
     }

      istruzione.toLowerCase();

    if(istruzione.substring(inizio_sms,(istruzione.length()-2)) == "accendi"){
      digitalWrite(led, HIGH);
      i=0;
      inizio_sms = 0;
      istruzione = "";
    }
    else if(istruzione.substring(inizio_sms,(istruzione.length()-2)) == "spegni"){
      digitalWrite(led,LOW);
      i=0;
      inizio_sms = 0;
      istruzione = "";
    }
  }
}

A questo punto mi chiedo, che razza di ritorni a capo sono?Io nel codice precedente avevo messo un if che controllava questo carattere
Code: [Select]
if(carattere != '\r'){
     istruzione += carattere;
    }

ma a quanto pare lo considera lo stesso...

gpb01

#5
Apr 21, 2013, 05:18 pm Last Edit: Apr 21, 2013, 05:20 pm by gpb01 Reason: 1

...
A questo punto mi chiedo, che razza di ritorni a capo sono? .....


1. potevi fare un Serial.print del loro valore in HEX così si capiva

2. A naso ... potrebbero essere dei '\n' ('\r' = CR, '\n' = LF ... spesso trovi i ritorni a capo come '\r\n')

Guglielmo
Search is Your friend ... or I am Your enemy !

leo72

Il ritorno a capo varia da SO a SO.
Solo Windows usa 2 ritorni a capo, la sequenza di caratteri ASCII 10 e 13, cioè \n e \r.
\n è new line e \r è return

Linux usa \n mentre mi pare che MacOS usi \r.

gpb01

@Leo : Si, ma ieri, per pochi minuti, hermit274 aveva postato una risposta (che poi deve aver cancellato perché non ve ne è più traccia), in cui diceva che il problema era esattamente quello, ovvero che il modulo ritornava '\r\n' e che, risolto questo gli si era posto un altro problema.

Ma poi, mentre gli stavo rispondendo al secondo problema, ... ha cancellato il tutto  :smiley-eek:

Guglielmo
Search is Your friend ... or I am Your enemy !

hermit274

Sì scusate ragazzi, avevo tolto quello che avevo scritto perché mi ero reso conto che nel codice che avevo scritto c'era un errore logico e quindi il problema era inconsistente :-). Cmqe si avevate proprio ragione, il problema erano gli \n\r. Ho seguito il consiglio di stampare il tutto in hex e in effetti i primi due caratteri erano DA :-)

Go Up