GPS/GSM

Valuta questo articolo 0 Voti

Autori: Lorenzo Maiorfi e Gianluca Ruta

Una delle funzionalità sicuramente più interessanti nell'ambito dello sviluppo di soluzione embedded riguarda la possibilità da parte di un dispositivo di utilizzare un modulo GPS per conoscere la propria posizione geografica, particolarmente utile in applicazioni fruibili "in mobilità". Tale famiglia di applicazioni beneficia spesso della possibilità di effettuare comunicazioni remote tramite la rete GSM/GPRS/UMTS, finalizzate alla fruizione di servizi di rete che richiedono un collegamento ad Internet.

Sul mercato è possibile reperire molti tipi di ricevitori GPS, quasi sempre basati su chipset SiRF, così come molto varia è anche l'offerta di moduli GSM/GPRS. Una buona soluzione è rappresentata da moduli che integrano entrambe le funzionalità, come ad esempio il modulo Telit GM862-GPS, utilizzato in numerosi progetti per la sua grande programmabilità. Il modulo in questione incorpora infatti al proprio interno un microcontrollore che implementa funzionalità complesse quali l'esecuzione di applicazioni scritte in Phyton, un linguaggio di alto livello molto utilizzato nelle comunità degli sviluppatori di tutto il mondo, e la gestione di un vero e proprio stack di rete TCP/IP, con il quale il modulo permette al proprio host di essere collegato ad Internet via GPRS.

L'interfaccia di comunicazione tra scheda a microcontrollore host e modulo GSM/GPS è seriale ed in particolare basata su comandi "AT", secondo quanto previsto dallo standard Hayes del 1977.

Per utilizzare tale interfaccia all'interno di un'applicazione sviluppata con il .NET Micro Framework è pertanto sufficiente allestire una comunicazione seriale asincrona ed utilizzare il set dei comandi riconosciuti dal modulo.

Per i nostri esempi abbiamo utilizzato il modulo in questione in una configurazione hardware che prevede una daughter board, prodotta da Sparkfun, che, oltre ad esporre sotto forma di pin con passo 0.1" la piedinatura del connettore del modulo, si occupa della sua alimentazione e della gestione di due led diagnostici (si veda la figura seguente). Il dispositivo prevede inoltre due connettori coassiali MMCX per l'utilizzo di due antenne esterne distinte per i due sotto-moduli GPS e GSM/GPRS. Da un punto di vista software, lo sviluppo viene enormemente semplificato dalla disponibilità di una libreria open-source denominata "MicroGM862", inclusa recentemente, come per la libreria per la gestione dei moduli Xbee, all'interno del progetto MFToolkit, disponibile come già detto su Codeplex all'indirizzo http://mftoolkit.codeplex.com.

La libreria mette a disposizione una classe denominata GM862GPS che espone tutte le funzionalità relative alla registrazione all'interno della rete GSM e GPRS, alla gestione degli SMS, alla gestione del GPS, fino alla gestione dello stack di rete, con il quale è ad esempio possibile effettuare richieste HTTP via GPRS.

L'inizializzazione dell'oggetto GM862GPS avviene tramite un costruttore che prevede il passaggio di un'istanza della classe  AT_Interface, anch'essa definita all'interno della libreria, responsabile della gestione della comunicazione seriale con l'host, come illustrato nel frammento di codice seguente:

 

GM862GPS GM862 = new GM862GPS(new AT_Interface("COM1", 115200));

Una volta creato l'oggetto "driver", è possibile effettuare le operazioni di registrazione all'interno della rete GSM e GPRS come illustrato nel frammento di codice seguente:


1: // Selezione banda GSM-DCS
2: if (!GM862.GSM.SelectNetworkBand(GSM.NetworkBands.GSM900_DCS1800))
3:     throw new Exception("Selezione banda fallita!");
4:  
5: // Sottoscrizione evento OnPinRequest
6: GM862.GSM.OnPinRequest = new GSM.PinRequestHandler(delegate(String PINType)
7: {
8:     if (PINType == "SIM PIN")
9:       return "0000";
10:     
11:     if (PINType == "SIM PUK")
12:       return "05969374, 0000";
13:  
14:   throw new Exception("Richiesta PIN sconosciuta");
15: });
16:  
17: // Sottoscrizione evento ricezione chiamata
18: GM862.GSM.OnRecievingCall = new GSM.RecievingCallHandler(delegate()
19: {
20:     Debug.Print("Driiiin!");
21:     Thread.Sleep(500);
22: });
23:  
24: // Roaming GSM
25: GM862.GSM.AllowRoaming = true;
26:  
27: // Inizializzaizone GSM
28: GM862.GSM.Initialize();
29:  
30: // Roaming GPRS
31: GM862.GPRS.AllowRoaming = true;
32:  
33: // Inizializzazione GPRS
34: GM862.GPRS.Initialize();

Analogamente, è possibile inizializzare il modulo per la gestione dei sotto-sistemi relativi rispettivamente a SMS e GPS mediante il frammento di codice seguente.

1: // Inizializzazione text messaging 

2: GM862.TextMessaging.Initialize(); 

3:  

4: // Inizializzazione GPS 

5: GM862.GPS.Initialize(); 

  Una volta completata la procedura di inizializzazione, eventualmente preceduta da un reset hardware del modulo attivabile mediante l'utilizzo di un'apposita OutputPort collegata al pin "RESET" del modulo, è possibile accedere alle funzionalità di alto livello relative ai vari sotto-sistemi, il più semplice dei quali è senza dubbio quello relativo al GPS, utilizzabile mediante frammento di codice seguente, che illustra come estrarre il dato relativo rispettivamente a qualità del rilevamento GPS, numero di satelliti visibili, latitudine, longitudine, velocità e data/ora del rilevamento (in formato UTC):

  1: // Parameti GPS 

2: byte gpsFix; 

3: byte gpsNoSat; 

4: double gpsLat; 

5: double gpsLon; 

6: double gpsSpeed; 

7: DateTime gpsDateTime; 

8:  

9: GM862.GPS.ReadGPSData(out gpsFix, out gpsNoSat, out gpsLat, out gpsLon, out gpsSpeed, out gpsDateTime); 

10: Debug.Print((gpsFix > 0) ? "GPS FIX OK" : "NO GPS FIX"); 

Un po' più complessa, ma non di molto, è la gestione degli SMS. Le funzionalità principali esposte dalla libreria consentono di enumerare i messaggi contenuti nella SIM o nella memoria del modulo, leggere il contenuto di un messaggio, eliminare un messaggio, inviare un nuovo messaggio e ricevere una notifica a seguito della ricezione di un nuovo messaggio.

Nel frammento di codice che segue, ad esempio, viene registrato un gestore di evento relativo alla ricezione di un nuovo SMS; tale gestore si occupa dapprima della lettura del messaggio (righe 9-12) e successivamente elimina il messaggio ricevuto (se presente nella memoria di tipo "SM", ossia nella SIM, unica possibilità prevista nell'attuale versione del firmware). Una volta eliminato il messaggio viene poi composto ed inviato (a riga 19) un nuovo messaggio di risposta al mittente.

1: GM862.TextMessaging.OnRecievedTextMessage = 

2:     new TextMessaging.RecievedTextMessageHandler(delegate(String Memory, int Location) 

3: { 

4:    TextMessaging.TextMessage TextMessage; 

5:  

6:    Debug.Print("SMS ricevuto!"); 

7:  

8:    // Lettura contenuto messaggio 

9:    if (GM862.TextMessaging.ReadTextMessage(Memory, Location, out TextMessage)) 

10:    { 

11:        Debug.Print("Da: " + TextMessage.Orginator); 

12:        Debug.Print("Messaggio: " + TextMessage.Message); 

13:  

14:        if (Memory.IndexOf("SM") != -1) 

15:            Debug.Print("Eliminazione messaggio: " + 

16:                 (GM862.TextMessaging.DeleteMessage("SM", TextMessage.Location) ? "OK" : "ERROR")); 

17:  

18:        Debug.Print("Rispondo..."); 

19:        GM862.TextMessaging.SendTextMessage(TextMessage.Orginator, "Roger"); 

20:               

21:    } 

22:    

23: }); 

L'ultimo esempio che prendiamo in esame si riferisce invece all'esplorazione delle possibilità relative al networking, ed in particolare del supporto al protocollo HTTP che consente ad un'applicazione host di utilizzare il modulo GM862GPS per effettuare una richiesta web via Internet. Nel caso illustrato di seguito, una volta verificata l'avvenuta registrazione alla rete GSM e GPRS (righe 4-5) e impostati i parametri di configurazione relativi all'accesso GPRS (riga 12) e allo stack di rete (righe 20-24), l'applicazione effettua una chiamata HTTP di tipo GET verso il servizio API del noto portale di social networking Twitter, in particolare finalizzata a rilevare le "tendenze" della settimana, riportando all'interno della finestra di debug dell'ambiente di sviluppo la risposta ottenuta.

Le istruzioni relative a quest'ultimo esempio sono riportate nel frammento di codice seguente.

 

 

1: // Rimaniamo in attesa della disponibilità della rete GSM/GPRS 

2: while (true) 

3: { 

4:    if (!GM862.GSM.RegistratedOnGSMNetwork()) continue; 

5:    if (!GM862.GPRS.RegistratedOnGPRSNetwork()) continue; 

6:    break; 

7: } 

8:  

9: Debug.Print("GSM/GPRS pronti"); 

10:  

11: // Configurazione parametri accesso GPRS 

12: if (!GM862.GPRS.SetContextConfiguration(1, "web.omnitel.it", "", "", "0.0.0.0")) 

13:     throw new Exception("Configurazione GPRS fallita"); 

14:  

15: // Attivazione del ptimo contesto GPRS 

16: if (!GM862.GPRS.ActivateContext(1)) 

17:     throw new Exception("Attivazione GPRS fallita"); 

18:  

19: // Configurazione socket 

20: if (!GM862.GPRS.SetSocketConfig(1, 1, 0, 90, 600, 50)) 

21:     throw new Exception("Configurazione socket fallita (1/2)"); 

22:  

23: if (!GM862.GPRS.SetSocketExtendedConfig(1, 0, 0, 0)) 

24:     throw new Exception("Configurazione socket fallita (2/2)"); 

25:  

26: if (GM862.Networking.WebRequest(1, "http://search.twitter.com/trends/weekly.json", 

27:                String.Empty, out response, "GET", String.Empty, String.Empty)) 

28: { 

29:     Debug.Print(new string(System.Text.Encoding.UTF8.GetChars(response))); 

30: } 

31: else 

32: { 

33:     Debug.Print("Chiamata HTTP fallita"); 

34: }