Ciao a tutti, ho acquistato un modulo gsm sim900l, sono riuscito a telefonare senza particolari problemi, per esigenze di abbonamento sulla sim, invio comandi ad arduino solo tramite chiamate telefoniche, (uno squillo fai questo, due squilli fai quello).
Per fare questo prima vorrei capire come faccio a conteggiarli, ad esempio quando arduino chiama il mio cellulare. Al momento do un delay(15000) come timeout alla chiamata, ma cosi facendo la chiamata per problemi sulla rete potrebbe anche non partire.
Per maggiore comprensione vi posto il codice:
void CHIAMATA() {
if (numero_tentativi_di_chiamata < 1){
Serial.println("Imposto la chiamata");
mySerial.available()!=0; delay(10);
mySerial.println("ATD+393244445d44;");
delay(100);
Serial.print("Chiamata in corso...");
delay(15000);
}
numero_tentativi_di_chiamata++;
}
Il risultato finale che vorrei ottenere è che dopo aver effettuato due squilli, arduino chiuda la chiamata.
Altra cosa che non mi è molto chiara è come ricevere il responso sui comandi AT ad esempio: mySerial.println("ATD+393244445d44;"); come so che è andato a buon fine? Dai pdf dei comandi che ho trovato in rete dovrei ricevere OK come risposta, ma non capisco come, non trovo nessun esempio a riguardo.
NON devi usare la delay() che è una funzione bloccante, ma devi studiarti come si usa la millis(), prima QUI, poi QUI ed infine leggi anche QUI e QUI ... e ti dovrebbe essere più chiaro come "fare altre cose" durante quei 15 sec.
Dopo la Serial.print() devi leggere la seriale e ricevere le risposte ...
... cerca sia qui che su Google "Arduino seriale" per vedere come fare dato che devi leggere una "serie" di caratteri ...
conosco già la funzione millis, non ho bisogno che il software vada avanti comunque.
Puoi farmi un esempio su come leggere? il massimo che sono riuscito ad ottenere è una serie di numeri che si aggiornano mano mano che il loop va avanti
MrBrownIT:
Puoi farmi un esempio su come leggere? il massimo che sono riuscito ad ottenere è una serie di numeri che si aggiornano mano mano che il loop va avanti
Ti do delle indicazioni, ma il codice lo scrivi tu ...
sempre verificare che ci sia qualche cosa da leggere (metodo available())
se c'è qualche cosa da leggere, leggere il carattere (metodo read()) e metterlo in un array di caratteri
continuare sino al "terminatore" del messaggio (se ben ricordo ogni messaggio/risposta termina con CR ovvero 0x0D)
quando si riceve il carattere terminatore mettere nell'array suddetto il carattere 0x00 per indicare che la stringa è terminata
elaborare la stringa ricevuta (che è nell'array) alla ricerca di ciò che serve.
In tuo aiuto, specie per il punto 5, ci sono le funzioni che si trovano in <string.h> che fa parte di AVR libc (libreria sempre automaticamente inclusa dall'IDE).
Guglielmo
P.S.: Ripeto, se cerchi con Google "Arduino serial read" trovi solo ... 3'670'000 risultati
Ho cercato ma non riesco a farlo funzionare, altrimenti non avrei scritto qui...
comunque sono riuscito a fare qualcosa, ricevo dei valori casuali:
I received: -1
I received: -1
I received: -1
I received: -1
I received: -1
I received: -1
I received: -1
I received: -1
I received: 10
I received: 67
I received: 69
I received: 58
I received: 34
I received: 79
I received: 78
I received: 69
I received: 34
I received: 48
I received: 10
I received: -1
I received: -1
I received: -1
I received: -1
I received: -1
I received:
cose così, ho pensato fossero stringhe in esadecimale ma non hanno senso. Da manuale pdf della modulo GSM A6 al comando ATD dovrei ricevere OK come risultato oppure ERROR... niente del genere
#include <SoftwareSerial.h>
#include <String.h>
SoftwareSerial mySerial(3, 2); //definisco le porte per la comunicazione seriale GSM
int chiamataincorso=0;
int numero_tentativi_di_chiamata=0;
void setup() {
Serial.begin(19200); //velocità seriale del programma
mySerial.begin(19200); //velocità seriale del modulo GSM
}
void loop() {
Serial.print("I received: ");
Serial.println(mySerial.read(), DEC);
chiamataincorso= mySerial.read();
CHIAMATA();}
void CHIAMATA() {
if (numero_tentativi_di_chiamata < 1){
Serial.println("Imposto la chiamata");
mySerial.available()!=0; delay(10);
mySerial.println("ATD+3932xxxxxxx;"); //compongo il numero
delay(100);
Serial.print(chiamataincorso);
//if (numero_tentativi_di_chiamata > -1){ mySerial.println("ATH"); }
}
numero_tentativi_di_chiamata++;
}
hai ignorato il punto 1. che è fondamentale (... per questo hai tutti quei -1)
stai stampando il valore decimale di ogni singolo carattere invece del carattere, se guardi ... altro non è che il codice ASCII di alcuni caratteri:
10=; 67='C',; 69='E'; 58=':'; 34='"'; 79='O'; 78='N'; 69='E'; 34='"'; 48='0'; 10= --> CE:"ONE"0
sta per Line Feed ed è uno dei terminatori assieme al Carriage return che vale 13.
hai impostato il "formato" delle "risposte"? ... perché mi sembra di ricordare ch ci siano più "formati"
Quando il metodo read() restituisce -1 significa che il buffer dati è vuoto, pertanto serve controllare se nel buffer seriale ci siano dati con if (mySerial.available()!=0) e poi usare mySerial.read().
cose così, ho pensato fossero stringhe in esadecimale ma non hanno senso.
Infatti non ha senso perché gli stai chiedendo di stampare in decimale usando DEC. I dati transitano sempre in forma binaria poi sei libero di stamparli come di pare, infatti se al posto di DEC usi HEX li stampa in esadecimale.
Maurotec:
Quando il metodo read() restituisce -1 significa che il buffer dati è vuoto, pertanto serve controllare se nel buffer seriale ci siano dati con if (mySerial.available()!=0) e poi usare mySerial.read().
Infatti non ha senso perché gli stai chiedendo di stampare in decimale usando DEC. I dati transitano sempre in forma binaria poi sei libero di stamparli come di pare, infatti se al posto di DEC usi HEX li stampa in esadecimale.
https://www.arduino.cc/en/Serial/Println
Ciao.
Ciao avevo già provato ad impostare in esadecimale, stesso risultato, stringhe diverse:
I received: FFFFFFFF
I received: FFFFFFFF
I received: FFFFFFFF
I received: FFFFFFFF
I received: FFFFFFFF
I received: 41
I received: 58
I received: D
I received: D
I received: 4F
I received: D
#include <SoftwareSerial.h>
#include <String.h>
SoftwareSerial mySerial(3, 2); //definisco le porte per la comunicazione seriale GSM
int chiamataincorso=0;
int numero_tentativi_di_chiamata=0;
void setup() {
Serial.begin(19200); //velocità seriale del programma
mySerial.begin(19200); //velocità seriale del modulo GSM
}
void loop() {
if (mySerial.available() != 0) {
Serial.print("I received: ");
Serial.println(mySerial.read(), HEX);
}
chiamataincorso= mySerial.read(), HEX;
CHIAMATA();}
void CHIAMATA() {
if (numero_tentativi_di_chiamata < 1){
Serial.println("Imposto la chiamata");
mySerial.available()!=0; delay(10);
mySerial.println("ATD+39320fgdfg64;"); //compongo il numero
delay(10);
mySerial.println("ATX0");
//if (numero_tentativi_di_chiamata > -1){ mySerial.println("ATH"); }
}
numero_tentativi_di_chiamata++;
}
Così è come ho corretto il programma, stesso risultato; potreste farmi un'esempio pratico, altrimenti non riesco a capire
Così è come ho corretto il programma, stesso risultato; potreste farmi un'esempio pratico, altrimenti non riesco a capire
Purtroppo non mai usato alcun modulo GSM (ovviamente so cosa sono i comando AT).
Io credo che prima si debba inviare il comando AT e poi leggere la risposta e non viceversa, quindi:
mySerial.println("ATX0");
equivale ad inviare il comando ATX0, dopo devi leggere sempre da mySerial.
Si dovrebbe sempre leggere e controllare la risposta dopo avere inviato un comando AT, questo perché ad esempio la risposta potrebbe indicare un errore.
In realtà Mauro, il problema principale è che MrBrownIT non si è messo li a capire cosa è e come funziona una trasmissione seriale e quindi, come si ricevono dati da una porta seriale, tutte cose che NON si fanno con un complesso programma che colloquia con un GSM, ma con un semplice programmino che parla con il monitor seriale, ma si è messo subito a scrivere il suo programma !
Solo dopo aver capito bene il meccanismo utilizzato uno dovrebbe mettersi a fare cose più complesse ... :
Comuque, c'è sempre la "scorciatoia" ("... pappa pronta", altamente "diseducativa" perché NON insegna nulla sulla seriale) ... per cui gli basta il metodo readStringUntil() per ricevere quello che gli serve, impostando come terminatore il carattere 0x0A.
gpb01:
In realtà Mauro, il problema principale è che MrBrownIT non si è messo li a capire cosa è e come funziona una trasmissione seriale e quindi, come si ricevono dati da una porta seriale, tutte cose che NON si fanno con un complesso programma che colloquia con un GSM, ma con un semplice programmino che parla con il monitor seriale, ma si è messo subito a scrivere il suo programma !
Solo dopo aver capito bene il meccanismo utilizzato uno dovrebbe mettersi a fare cose più complesse ... :
Comuque, c'è sempre la "scorciatoia" ("... pappa pronta", altamente "diseducativa" perché NON insegna nulla sulla seriale) ... per cui gli basta il metodo readStringUntil() per ricevere quello che gli serve, impostando come terminatore il carattere 0x0A.
Guglielmo
Guglielmo racchiudi nel tuo modo di fare superiore ed arrogante il motivo percui cerco di evitare i forum, mod come te non fanno che male alla community, se qualcuno cerca aiuto è chiaro che lo fa perchè non ha trovato esaustive le info reperite, mandarlo su google non serve a niente, la pappa pronta come la chiami tu, quando si parla di codice, credo sia molto più educativa di mille parole al vento...
Detto questo per chi in futuro ne avesse bisogno ecco la pappa pronta forse un pò grezza e mal fatta ma funzionante:
#include <SoftwareSerial.h>
const byte rxPin = 3; // Tx
const byte txPin = 2; // rx
SoftwareSerial A6GSM (rxPin, txPin);
void setup() {
Serial.begin(19200);
A6GSM.begin(19200); //è diverso da scheda a scheda
delay(1000);
A6GSM.println("ATD+tuonumero");
for (int timer=0; timer < 20; timer++){ //definisco il numero di righe da mostrare
String inData = A6GSM.readStringUntil('\n'); //leggo la risposta
Serial.println("Got response from AT: " + inData); //mostro la discussione tra arduino e il modulo gsm
//ripulisco la stringa
String mystr = (inData.substring(8,15) + inData.substring(17,18));
String stato = mystr;
stato.trim();
Serial.println(stato);
}
A6GSM.println("ATH"); //termino la chiamata
//Non occorre mostrare il risultato perchè restituira solo ATH
}
void loop() {
}
MrBrownIT:
... la pappa pronta come la chiami tu, quando si parla di codice, credo sia molto più educativa di mille parole al vento...
... invece è totalmente diseducativa, difatti tu NON hai imparato un bel nulla su come veramente funziona una seriale e, peggio, ti sei messo ad usare la classe "Serial" che, su piccole MCU come quella di Arduino, è da evitare come la peste !
La prossima volta che dovrai leggere dei dati da una porta seriale (da un diverso sensore) e NON avrai la bella libreriola che qualcun'altro, studiando, ha fatto per te, sarai, purtroppo, da capo a dodici. :
Comunque, contento tu ...
Guglielmo
P.S.: ... la mia NON è affatto arroganza ... è che tu, evidentemente, non sei abituato a chi ti dice in chiaramete come stanno le cose, senza peli sulla lingua e senza tanti inutili giri di belle parole (solo per una forma di "cortesia" e "falsità" che è sempre piuttosto dannosa). P.P.S.: ... e NON vedo cosa c'entri il fatto che io sia anche "moderatore" ... chi ti ha risposto è l'UTENTE gpb01 (... che risponde sempre allo stesso modo), NON certo il "moderatore" gpb01 che interveniene per tutt'altre cose relative al rispetto del regolamento.
Vedila come vuoi, fatto sta che ora sono in grado di usare il modulo gsm come voglio, se mi fossi fermato a quello che dicevi, starei ancora alla prima pagina del manuale e sicuramente a breve avrei abbandonato il progetto.
Comunque, contento tu ... meno contento chi ha bisogno di aiuto