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:
#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 = "";
}
}
}
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
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.
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
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
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
#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
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
@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
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