Fra i tanti moduli che si possono trovare in giro per Arduino, uno dei più interessanti è il modulo SIM900. Con questo accessorio, potremo interfacciare i nostri progetti alla rete cellulare GSM.

Il modulo ci permette di avere tutte le funzionalità disponibili sulla rete cellulare: effettuare chiamate, inviare sms, e comunicare attraverso internet. Per poterlo utilizzare, ovviamente avremo bisogno di una SIM con un piano dati, sms e voce, a seconda delle nostre esigenze. Vediamo come sfruttare tutte le sue funzionalità.

Materiale hardware

Arduino Uno
Cavi Dupont
Breadboard
Modulo SIM900

Materiale Software

 

Procedura

Per prima cosa, assicuriamoci che la SIM scelta abbia il PIN disabilitato e mettiamola nell’apposito alloggio del modulo. Una volta fatto, abbiamo bisogno di alimentarlo, per farlo abbiamo 2 opzioni: collegare un alimentatore da 5V con il giusto connettore nell’apposita porta sulla scheda, oppure collegare le rispettive polarità sui pin 5V e GND del modulo. In entrambi i casi la sorgente di alimentazione deve fornire almeno 1A per garantire il corretto funzionamento.

ATTENZIONE! – In base alla modalità di alimentazione da noi scelta, sulla scheda è presente uno switch per selezionare la modalità di alimentazione. Posizionarlo nel modo in cui abbiamo scelto di alimentarlo.

Alimentato, il led PWR si accenderà indicando che il modulo è pronto ad essere acceso. Premiamo per qualche secondo il pulsante di accensione e il modulo si accenderà.

Per comunicare, viene effettuato un collegamento seriale, tra Arduino e il modulo GSM. È consigliato provare il modulo prima di iniziare a lavorare direttamente con uno sketch, per farlo possiamo collegarlo direttamente in seriale al computer effettuando un collegamento come in questa immagine, utilizzando un modulo Seriale->USB:

Collegato il modulo direttamente in seriale, possiamo utilizzare un programma chiamato AT Command Tester. Che permette di inviare vari comandi al modulo e di provare varie sue funzionalità.

Apriamo il programma (utilizzando run_64.bat o run_32.bat in base all’architettura del nostro sistema operativo), clicchiamo sul tasto “FIND PORTS” per cercare le porte seriali disponibili, selezioniamo quella corrispondente al modulo SIM900 e clicchiamo “connect”. Se tutto sarà andato a buon fine, sulla destra visualizzeremo le informazioni del modulo. Per essere certi che tutto funzioni, clicchiamo sulla “R” vicino a “get device info” e sulla destra vedremo comparire ulteriori info sul modulo.

Accertati che tutto funzioni, possiamo proseguire e vedere come sfruttare tutte le sue funzionalità.

Negli sketch che utilizzeremo verrà inizializzato un collegamento seriale software (tramite la libreria SoftwareSerial integrata nell’Arduino IDE) sui PIN 7 ed 8. Quindi colleghiamo rispettivamente i pin nel seguente modo:

  • il pin 8 di Arduino al pin 1 del modulo;
  • il pin 7 di Arduino al pin 2 del modulo.
  • Ricordiamoci inoltre di collegare la massa ai rispettivi pin GND del modulo e di Arduino.

 

Per le chiamate:

Per effettuare una chiamata, abbiamo bisogno di installare la libreria di Seeed Studio GPRS_SIM900, questa libreria ci permetterà di comunicare con il modulo in modo semplice senza dover utilizzare comandi “AT”. Per installarla, scarichiamo il file zip dal link di github, dall’IDE di Arduino andiamo su:

sketch > #include libreria > aggiungi libreria da file zip e selezioniamo il file zip appena scaricato.

Dopodiché creiamo un nuovo sketch e inseriamo il seguente codice:

#include <GPRS_Shield_Arduino.h>
#include <SoftwareSerial.h>
#include <Wire.h>

//PIN RX DEL MODULO
#define PIN_TX    7
//PIN TX DEL MODULO
#define PIN_RX    8
#define BAUDRATE  9600
#define PHONE_NUMBER  "NUMERO DA CHIAMARE"

GPRS gprs(PIN_TX,PIN_RX,BAUDRATE);

void setup() {
  gprs.checkPowerUp();
  Serial.begin(9600);
  while(!gprs.init()) {
      delay(1000);
      Serial.println("Inizializzazione fallita!");
  }  

  while(!gprs.isNetworkRegistered())
  {
    delay(1000);
    Serial.println("Rete non ancora registrata!");
  }

  Serial.println("Inizializzazione completata.");
  Serial.println("Chiamo...");
  
  //Funzione da utilizzare per effettuare una chiamata.
  gprs.callUp(PHONE_NUMBER);
}

void loop() {

}

L’istruzione che permette di effettuare una chiamata è gprs.callUp(PHONE_NUMBER); e possiamo utilizzarla ogni volta che abbiamo bisogno di effettuare una chiamata nei nostri progetti.

Per inviare un SMS:

Per inviare un sms, possiamo utilizzare la stessa libreria delle chiamate, basta solo creare un nuovo sketch e incollare questo codice:

#include <GPRS_Shield_Arduino.h>
#include <SoftwareSerial.h>
#include <Wire.h>

//PIN RX DEL MODULO
#define PIN_TX    7
//PIN TX DEL MODULO
#define PIN_RX    8
#define BAUDRATE  9600
#define PHONE_NUMBER "NUMERO DA CHIAMARE"
#define MESSAGE  "MESSAGGIO DA INVIARE"

GPRS gprs(PIN_TX,PIN_RX,BAUDRATE);

void setup() {
  gprs.checkPowerUp();
  Serial.begin(9600);   
  
  while(!gprs.init()) {
      delay(1000);
      Serial.println("Inizializzazione fallita!");
  }  

  while(!gprs.isNetworkRegistered())
  {
    delay(1000);
    Serial.println("Rete non ancora registrata!");
  }

  Serial.println("Inizializzazione completata!");
  Serial.println("Provo ad inviare il messaggio.");
  
  if(gprs.sendSMS(PHONE_NUMBER,MESSAGE)) 
  {
    Serial.print("SMS inviato!\r\n");
  }
  else {
    Serial.print("Invio SMS fallito!\r\n");
  }
}

void loop() {

}

Qui invece, la funzione utilizzata per inviare l’SMS è gprs.sendSMS(PHONE_NUMBER,MESSAGE) da notare come la funzione si trovi all’interno di una IF, questo perché viene restituito un valore booleano. (TRUE quando è stato inviato con successo e FALSE quando non). In questo esempio viene mostrato un messaggio tramite seriale in caso di successo o fallimento.

Per effettuare una richiesta http POST:

Per inviare una richiesta di tipo POST ad un URL personalizzato, possiamo utilizzare il seguente sketch, che non ha bisogno di alcuna libreria, questo perché i comandi al modulo sono inviati singolarmente uno alla volta tramite seriale software. La lista completa dei comandi può essere trovata qui.

#include <SoftwareSerial.h>
int instruction=0;

//Variabili millis
long interval = 2000; //Tempo da aspettare fra ogni istruzione inviata al modulo GSM (2000ms)
long previousMillis = 0;  

//Link (URL) a cui inviare la richiesta
String link = "INSERIRE LINK";
//APN Sim inserita
String apn1 = "INSERIRE APN";
//Dati da inviare
String data = "INSERIRE DATI DA INVIARE";

//Crea seriale virtuale sui pin 8 e 7

SoftwareSerial SIM900(8, 7);
void setup() {
  //Inizializza seriale virtuale
  SIM900.begin(9600); 
  //Inizia seriale USB (Monitor Arduino)
  Serial.begin(9600); 
}

void loop() {

  //Utilizza la funzione per inviare la richiesta
  inviaPOST(link,data,apn1);

}

void ShowSerialData()
{
  //Attendi scrittura su seriale virtuale
  while(SIM900.available()!=0)
  Serial.write(char (SIM900.read())); //Leggi i dati ricevuti
}

void inviaPOST(String URL, String dati, String APN){

    //Utilizza millis per temporizzare le istruzioni.

    unsigned long currentMillis = millis();

  if(currentMillis - previousMillis > interval) {
    previousMillis = currentMillis;   
    
    ShowSerialData();

    if(instruction==0){
        Serial.println("Test comunicazione 1:");
        SIM900.println("AT");
        instruction++;      
    }
    else if(instruction==1){
        Serial.println("Test comunicazione 2:");
        SIM900.println("AT");
        instruction++;
    }
    else if(instruction==2){
        Serial.println("Attivo beacon GPRS");
        SIM900.println("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\""); 
        instruction++;
    }
    else if(instruction==3){
        Serial.println("Imposto APN");
        SIM900.println("AT+SAPBR=3,1,\"APN\",\"" + APN  + "\"");
        instruction++;
    }
    else if(instruction==4){
        Serial.println("AT+SAPBR=1,1\\r\\n");
        SIM900.println("AT+SAPBR=1,1");
        instruction++;
    }
    else if(instruction==5){
        Serial.print("AT+SAPBR=2,1\\r\\n");
        SIM900.println("AT+SAPBR=2,1");
        instruction++;
    }
    else if(instruction==6){
        Serial.println("Inizializza HTTP");
        SIM900.println("AT+HTTPINIT");
        instruction++;
    }
    else if(instruction==7){
        SIM900.println("AT+HTTPPARA=\"CID\",1");
        instruction++;
    }
    else if(instruction==8){
        Serial.println("Invio url...");
        SIM900.println("AT+HTTPPARA=\"URL\",\""+ URL +"\"");
        instruction++;
    }
    else if(instruction==9){
        Serial.println("Imposto dimensione dati...");
        //Inserire dimensioni in byte dati, al posto di 33
        SIM900.println("AT+HTTPDATA=33,10000"); 
        instruction++;
    }
    else if(instruction==10){
        Serial.println("Invio dati...");  
        SIM900.println(dati);
        instruction++;
    }
    else if(instruction==11){
        Serial.println("AT+HTTPACTION=1\\r\\n");
        SIM900.println("AT+HTTPACTION=1");
        instruction++;
    }
    else if(instruction==12){
        Serial.println("Termina sessione HTTP");  
        SIM900.println("AT+HTTPTERM");
        instruction++;
    }
    else if(instruction==13){
        Serial.println("Invio completato! Risultato request:");
        SIM900.println("AT+SAPBR=0,1");
        instruction++;
    }
    
  }
  
}

In questo sketch ho realizzato una funzione chiamata inviaPOST che riceve come parametri: URL a cui inviare i dati, DATI variabile da inviare e APN l’apn utilizzato dall’operatore della sim inserita nel modulo. All’interno della funzione i comandi vengono inviati con un intervallo impostato nella variabile interval inizializzata ad inizio sketch. (2 secondi è l’intervallo minimo che è possibile raggiungere per avere una comunicazione stabile)

NB: Per l’invio di richieste POST, al modulo viene inviato il comando AT+HTTPDATA=(dimensione dati in byte, tempo di attesa), all’interno dello sketch impostare la dimensione in byte della stringa da inviare, per farlo calcolare le dimensioni della stringa utilizzando questo strumento. E sostituire le dimensioni nella riga in cui viene inviato il comando.

Per effettuare un test possiamo utilizzare il sito webhook.site che ci permette di visualizzare le richieste inviate al nostro url univoco. Basta inserirlo nella stringa link, caricare lo sketch e attendere che la nostra richiesta venga inviata.

Conclusione

Questo modulo, anche se più costoso rispetto ad altri moduli per Arduino, è uno dei più utili in progetti che hanno bisogno di poter comunicare in qualsiasi situazione. Ad esempio nella realizzazione di una stazione meteo o in un allarme.