CORSO SERALE (Classe V/STE) Area di progetto anno scolastico 2006/2007 Allievo: Lazzari Matteo Tutor: Prof. Zaniol Italo Termostato controllato tramite modulo GSM IL PROGETTO REALIZZATO 1 Indice Introduzione Schema a blocchi del sistema Descrizione schema a blocchi Schema elettrico Descrizione schema elettrico Circuito di alimentazione Circuito di programmazione Modulo GSM Descrizione della piedinatura Perché utilizzare un modulo GSM? Caratteristiche principali Funzioni principali Programmare il modulo GSM Il Pic16F877 La porta seriale nel pic Il sensore di temperatura DS18B20 Analisi del software Programma del modulo GSM Analisi di alcune routine del pic Istruzioni d’uso Pag 3 Pag 3 Pag 4 Pag 5 Pag 6 Pag 6 Pag 7 Pag 8 Pag 9 Pag 9 Pag 10 Pag 11 Pag 12 Pag 13 Pag 14 Pag 21 Pag 28 Pag 29 2 Introduzione Come conclusione di una serie di progetti sviluppati durante l’anno scolastico inerenti l’acquisizione ed il controllo di grandezze fisiche, si è deciso di realizzare un controllo di temperatura che, utilizzando un modulo GSM prodotto dalla SonyEricsson, consente anche un controllo a distanza di tale grandezza fisica. Con il sistema realizzato è possibile infatti interagire sia localmente che a distanza mediante un telefono cellulare. Localmente è possibile: • Leggere la temperatura ambiente su un display LCD • Attivare \ disattivare un generatore di calore • Impostare il Set Point di intervento del generatore di calore • controllare la temperatura nell’ambiente in cui è situato il termostato in modo ON/OFF A distanza, mediante trasmissione/ricezione di SMS, è possibile: • conoscere la temperatura dell’ambiente controllato • conoscere lo stato del generatore di calore • Attivare \ disattivare il generatore di calore • Impostare il Set Point • ricevere una segnalazione di allarme (ad esempio da un antifurto) Schema a blocchi del sistema 3 Descrizione dello schema a blocchi Lo schema a blocchi evidenzia come il pic 16f877 sia il cuore del sistema. Esso controlla: Il sensore di temperatura I pulsanti di set point Il pulsante ON/OFF Un ingresso di allarme La comunicazione con il modulo GSM Il display LCD Il Modulo GSM, invece, svolge le seguenti funzioni: Interfaccia con la rete GSM Invio e ricezione di messaggi SMS comunicazione con il PIC Una porta seriale viene utilizzata per programmare il modulo GSM on board tramite un personal computer in cui è installato un opportuno software di programmazione fornito gratuitamente dalla casa costruttrice e scaricabile dal sito della multinazionale. Grazie a questa porta si risparmia tempo in fase di programmazione e messa a punto oltre a ridurre le possibili rotture del modulo dovute al continuo “leva e metti” su un connettore a 60 pin di tipo SMD. Schema elettrico Trattandosi di un prototipo, ed essendo poco il tempo a disposizione per la realizzazione del progetto, è stata utilizzata, come base di partenza, una demoboard che prevede: • • • • • • • Un connettore per la programmazione in-circuit ( il programmatore usato è il PICkit 2 della Microchip che viene collegato al PC tramite porta USB ) Uno strip femmina a 14 pin per controllare un display LCD Uno strip femmina a 8 pin per collegare un tastierino esadecimale o simile 6 led che possono essere scollegati dalle relative uscite che li comandano mediante dei jumper. Due pulsanti Due strip femmina a 20 pin che riflettono la piedinatura del PIC e possono essere utilizzati per alloggiare schede di espansione Un regolatore di tensione che fornisce i 5 volt alla scheda a partire da un alimentatore esterno ( ad esempio 12V ) che si collega alla demoboard tramite plug di alimentazione. La demoboard è di seguito mostrata. Ulteriori notizie si possono trovare nel sito della scuola ( vedi materiale didattico ). 4 Sui due strip femmina è stata collocata la scheda che riguarda in modo particolare il progetto realizzato. Lo schema elettrico di questa scheda è quello di seguito riportato. Da una prima analisi si può notare: • una porta seriale che utilizza due MAX 232 per l’interfacciamento con il PC • un circuito di alimentazione del modulo GSM • il connettore per l’interfacciamento di questa scheda con la demoboard • il circuito di interfaccia tra microcontrollore e modulo GSM 5 • il sensore di temperatura Descrizione schema elettrico Circuito di alimentazione Poiché il modulo GSM e i due MAX232 devono essere alimentati a 3.6V, si utilizza questo semplice circuito per convertire i 12V di alimentazione nei 3.6V richiesti. Il componente principale è un LM317; la tensione voluta si ottiene regolando opportunamente il trimmer di 3,6Volt. Il led segnala la presenza della tensione. Per quanto concerne i criteri di progetto ci si è attenuti a quelli forniti dal costruttore ( si vedano i data sheet ). Porta seriale Visto che il modulo GSM comunica con il PC tramite protocollo asincrono RS232 su sette linee ( il MAX 232 dispone di 2 ingressi e due uscite ) è necessario utilizzare due MAX232. I segnali della porta sono: DCD = Data Carrier Detect RD = Received Data TD = Trasmitted Data DTR = Data Terminal Ready RI = Ring Indicator CTS = Clear To Send RTS =Request To Send La programmazione avviene configurando la porta seriale del PC alla velocità di 9600 Bit/Sec 6 Modulo GSM Il modulo GSM è montato su un circuito stampato di cui si riporta il layout. Esso è stato realizzato per poter utilizzare il modulo in diversi progetti senza la necessità di saldare ogni volta il connettore smd a 60 pin che tra l’altro ha un costo di circa sette euro. PAKAGE SCHEDA GSM Tale schedina implementa: • il connettore a 60 pin per alloggiare il modulo GSM • il dispositivo per alloggiare la SIM card • due connettori strip maschio per poter alloggiare la scheda su un circuito applicativo • alcuni componenti di supporto Nella foto si può vedere tale schedina 7 Per interfacciare la scheda al circuito che la ospiterà, mediante programma EAGLE, è stato realizzato il simbolo di figura a cui è associato il pakage precedentemente visto. SIMBOLO SCHEDA GSM Tale simbolo riporta i pin del modulo GSM. Oltre alla citata porta seriale usata per la programmazione, il modulo controlla due diodi led: • LD2 per segnalare ricezione SMS • LD3 segnala la connessione alla rete GSM ( lampeggia quando ha trovato la rete ) Tramite il transistore Q1, che fa da adattatore di tensione ( si ricorda che il PIC lavora con 5V mentre il modulo con 3.6V ), il modulo comunica al PIC lo stato della rete che viene proposto sul display LCD. Tramite Q4 il GSM invia dati al PIC utilizzando la porta seriale; il transistore viene utilizzato ancora come adattatore di tensione . Il diodo shottky D2 serve ad adattare il livello di tensione proveniente dalla seriale del PIC ( che è a 5V ), con le esigenze del modulo il cui livello riconosciuto come alto non deve essere superiore a 3.6V. Tale diodo presenta il catodo collegato all’uscita della seriale e l’anodo connesso al pin Vio che fornisce 3.6V. Quando il PIC invia un livello alto, il diodo è interdetto e quindi sull’ingresso abbiamo 3.6V. Quando invece il livello è basso, il diodo è in conduzione e sull’ingresso del modulo abbiamo la tensione tra anodo e catodo del diodo che essendo di tipo shottky è di circa 0.1V e quindi tale valore viene riconosciuto come basso dal modulo GSM. Abbiamo infine un pulsante che consente di attivare/disattivare il modulo. 8 INTERFACCIAMENTO TRA MODULO GSM ED IL RESTO DEL CIRCUITO Analisi del modulo GSM Piedinatura del modulo GSM 9 Perché utilizzare un modulo GSM Il modulo GM47 prodotto dalla Sony Ericsson appartiene ad una nuova generazione di dispositivi GSM destinata ad essere integrata all’interno di applicazioni che richiedono una comunicazione macchina/macchina o uomo/macchina di tipo wireless. Il GR47 può essere utilizzato in tutte quelle situazioni che richiedono l’invio e la ricezione di dati (attraverso gli SMS ) oppure che richiedono la realizzazione di chiamate vocali attraverso la rete GSM. Sebbene il modulo sia dotato di porte di ingresso e uscita, è possibile interfacciarlo, come nel nostro caso, con sistemi basati su microprocessore. Il microcontrollore interagisce col GR47 attraverso una connessione seriale. Caratteristiche principali Il dispositivo ha dimensioni e peso estremamente ridotti. E’ di tipo dual band (lavora infatti alle frequenze di 900 e 1800MHz); è in grado di trasmettere dati mediante SMS, oppure mediante modem alla velocità di 9,6Kbps ( GSM ) o tramite protocollo GPRS fino a 86,6 Kbps. Permette inoltre di effettuare chiamate vocali e gestire gli SMS e la rubrica sia all’interno del modulo che all’interno di una SIMCard. 10 La programmazione del modulo si effettua in un ambiente di sviluppo che utilizza un linguaggio di programmazione simile all’ANSI C. Analisi delle funzioni principali Servizio SMS: Il modulo supporta l’invio e la ricezione di SMS, sia attraverso il protocollo PDU che text mode. La massima lunghezza di un SMS è di 160 caratteri utilizzando una codifica a 7bit e di 140 caratteri con codifica a 8bit. Servizio Dati: Il modulo supporta l’invio e la ricezione di dati secondo il protocollo GSM e GPRS. Servizio Chiamata vocale: Il GR47 presenta la capacità di generare, ricevere e terminare chiamate vocali. Sono inoltre disponibili i servizi di multichiamate, attesa di chiamata e deviazione di chiamata (dipendenti dal gestore di rete GSM). SIM Card: 11 Il dispositivo supporta il collegamento a una SIMCard esterna che rispetti la tecnologia 3 o 5V. Alimentazione: Il modulo richiede una tensione nominale di 3,6V, ma è in grado di funzionare correttamente anche all’interno del range 3,4V÷4V; l’assorbimento di corrente dipende dal tipo di applicazione e se è in corso una trasmissione. Il GR47 non dispone di capacità interne per supportare i picchi di corrente richiesti dalla trasmissione; per questo motivo sull’alimentazione viene richiesta l’aggiunta di condensatori elettrolitici di adeguata capacità. La porta seriale: Il modulo dispone di tre porte seriali UART, utilizzabili per realizzare comunicazioni asincrone verso dispositivi esterni. La UART1 è conforme allo standard RS232 a 9 pin; UART2 e UART3 realizzano invece collegamenti dati seriali full duplex di utilizzo generale. A causa dei livelli di tensione, per l’interfacciamento verso l’esterno delle UART, è necessario utilizzare degli integrati MAX232. I dati vengono trasmessi secondo il seguente standard: 1 bit di start, 8 bit di dati, nessuna parità e 1 bit di stop. Il baud rate di default della UART1 è di 9,6Kbit/s, anche se tramite comandi AT è possibile arrivare fino a 460Kbit/s. Programmazione del modulo GSM Per la programmazione del modulo, la Sony Ericsson fornisce il pacchetto M2mpower che realizza un completo ambiente di sviluppo IDE . La figura mostra una schermata di tale ambiente. 12 Ambiente di sviluppo M2mpower La scheda di espansione realizzata 13 Il Pic16f877 Come già detto il Pic16f877 è il cuore del progetto. Oltre alle periferiche gestite dalla demoboard ( tastierino, display LCD, led di segnalazione, pulsanti ), esso gestisce, tramite la scheda di espansione, il sensore digitale di temperatura, il pulsante di allarme, un led di segnalazione per simulare l’allarme, e, tramite i piedini RC6 e RC7, la comunicazione seriale con il modulo GSM. Ci soffermeremo ora sulle caratteristiche essenziali della porta seriale presente nel PIC e sulla gestione del sensore di temperatura. 14 La porta seriale nel pic Il PIC 16F877 dispone di una porta seriale che consente il dialogo tra microcontrollore e altri dispositivi pure dotati di porta seriale ( ad esempio un PC ). I pin dedicati sono sono RC7 che viene utilizzato come ingresso seriale e RC6 come uscita seriale. Il tipo di comunicazione può essere sincrona o asincrona. In questa analisi ci occupiamo della sola modalità asincrona. I registri dedicati ( ad esclusione di quelli di interrupt ), sono: PIR1, RCSTA, TXREG, TXSTA, SPBRG. - SPBRG ( banco1): il valore caricato in questo registro consente di stabilire la velocità di trasmissione. Riferirsi alle tabelle 10.4 e 10.5 ( pag. 108 e 109 del manuale ) per determinare il valore da caricare nel registro in base alla velocità di trasmissione desiderata. Il valore si può anche calcolare con la formula Vt = Fosc/ ( 64 ( X + 1 )) dove X è il valore da caricare in SPBRG e Fosc è la frequenza del clock del processore. Questa formula è valida quando il bit 2 del registro TXSTA è 0 ovvero è selezionato un Baud rate a bassa velocità. Se questo bit è 1, ovvero è selezionato un Baud rate ad alta velocità, la formula da usare è Vt = Fosc/ ( 16 ( X + 1 )). Esempio: sia Fosc = 4 MHz , Vt = 9600 bit/sec, Baud rate a bassa velocità. Dalla formula si ottiene X = Fosc/ (64 * Vt ) –1 = 5.51 Stabilito un valore 6 si ottiene Vt = 10.416.6 con un errore dato da (10417 – 9600)/9600 = 8.5% che è un errore non accettabile (NA) . Utilizzando un Baud rate ad alta velocità si ottiene: X = Fosc/ (16 * Vt ) –1 = 25.04. Stabilito un valore 25 si ottiene Vt = 9615.38 con un errore dato da (9615 – 9600)/9600 = 0.16 % che è un errore accettabile. - TXSTA (banco1): questo registro consente di configurare i parametri della porta di trasmissione e cioè: - comunicazione sincrona/asincrona - abilitare/disabilitare il bit di parità - abilitare/disabilitare trasmissione - RCSTA ( banco0 ): questo registro consente di configurare i parametri della porta di ricezione e cioè: - abilitare/disabilitare porta seriale - abilitare/disabilitare ricezione del nono bit ( bit di parità) - riconoscere errori di framing e di overrun - TXREG (banco 0): in questo registro si carica il valore a 8 bit da inviare - RCREG (banco 0): in questo registro si legge il valore ricevuto a 8 bit - PIR1 (banco 0 ): il bit 5 di questo registro si porta a 1 quando il registro RCREG contiene un dato pronto. 15 Il sensore di temperatura DS18B20 ed il protocollo di comunicazione con il processore Il trasduttore, in grado di misurare temperature tra -55°C e +125°C con una precisione di 0.5°C nel range compreso tra -10°C e +85°C, è di tipo digitale e quindi è capace di fornisce in codice binario il valore di temperatura misurato. I trasduttori digitali, rispetto a quelli analogici come LM35 o l’AD590 ecc., presentano il grande vantaggio di semplificare notevolmente l’hardware in quanto non sono necessari il circuito di condizionamento e il convertitore analogico/digitale. Tutto ciò, naturalmente, in presenza di un circuito di elaborazione di tipo digitale; tenuto conto che l’elettronica digitale ha soppiantato le tecniche analogiche, la soluzione di trasduttori che forniscono l’informazione sulla misura di una grandezza fisica in formato numerico, è sicuramente vantaggiosa sia in termini di costi che di affidabilità e precisione. Naturalmente è necessario un certo impegno per scrivere il software adeguato a gestire la comunicazione tra circuito di elaborazione e trasduttore. Di seguito sono riassunte le prestazioni del componete che sono state ricavate dai datasheet forniti dal costruttore. 16 Caratteristiche del trasduttore di temperatura DS18B20 Come si può notare dai dati di presentazione del componente, esso dispone di una unica linea per comunicare col circuito programmabile. Tale linea ( si veda lo schema elettrico ) è collegata alla tensione di alimentazione tramite una resistenza di pullup di 4.7Kohm come consigliato dal costruttore e ad un pin del PIC. Senza analizzare tutte le caratteristiche del trasduttore, ci occuperemo del protocollo di comunicazione e di parte del software che consente di leggere la temperatura; il protocollo si deduce dai datasheet forniti dal costruttore. Il software è di uso generale ( è stato utilizzato anche in altri progetti ) ed è suddiviso in tanti sottoprogrammi che saranno richiamati in genere dal programma principale o da un sottoprogramma che gestisce tutte le routine. L’operazione di lettura della temperatura consiste nei seguenti passi: 1) PROCEDURA DI RESET la comunicazione deve iniziare con la procedura di reset indicata in figura. a) La linea di comunicazione tenuta alta dalla resistenza di pullup ( il pin del controllore è configurato come ingresso ) deve essere portata bassa per almeno 480 microsecondi. Ciò si ottiene configurando il pin del PIC collegato alla linea del trasduttore come uscita a livello basso. b) successivamente la linea va rilasciata ( si configura il pin del PIC come ingresso ) e questa viene portata alta dalla resistenza di pullup per un tempo compreso tra 15 e 60 microsecondi. c) il trasduttore porta la linea a livello basso per un tempo compreso tra 60 e 240 microsecondi per poi rilasciarla. La seguente routine, chiamata R_ESET, esegue la procedura di reset. Si noti che l’interrupt viene disabilitato in modo che eventuali chiamate non possano disturbare le temporizzazioni richieste dalla procedura di reset. L’interrupt viene riabilitato al termine della routine. 17 ;********** ROUTINE RESET SENSORE R_ESET BCF INTCON,7 ;DISABILITA INTERRUPT BSF STATUS,5 ;BANCO 1 BCF TRISB,0 ;LINEA COME USCITA BCF STATUS,5 ;BANCO 0 BCF PORTB,0 ;LINEA BASSA CALL RIT_500 ;RITARDO 500 MICROSECONDI BSF STATUS,5 ;BANCO 1 BSF TRISB,0 ;LINEA COME INGRESSO BCF STATUS,5 ;BANCO 0 NOP NOP LP BTFSS PORTB,0 ;CONTROLLA SE LINEA ALTA GOTO LP NOP NOP LP1 BTFSC PORTB,0 ;CONTROLLA SE BASSA GOTO LP1 NOP NOP LP11 BTFSS PORTB,0 ;CONTROLLA SE LINEA ALTA GOTO LP11 CALL RIT_500 ;RITARDO 500 MICROSECONDI BSF INTCON,7 ;ABILITA INTERRUPT RETURN 2) INVIO COMANDO SKIP ROM Se non si desidera modificare i parametri nella EEPROM del trasduttore, si deve inviare un comando di SKIP ROM ( codice CCH ) . 3) INVIO COMANDO CONVERSIONE Si può ora inviare un comando di Start conversione ( codice 44 H ); il tempo di conversione dipende dalla risoluzione desiderata che va da 9 a 12 bit. Per default la risoluzione è di 12 bit. Se si desidera modificarla bisogna caricare il registro di configurazione della memoria EEPROM con adeguati valori. Con la massima risoluzione il tempo di conversione è di 750 millesimi di secondo al massimo. Durante la conversione la linea di comunicazione è tenuta bassa dal trasduttore; al termine della conversione la linea viene portata alta. Il PIC è quindi in grado di sapere quando la conversione è terminata interrogando tale linea. 4) SI RIPETONO LE PRODEDURE 1) E 2) DI RESET E SKIP ROM 5) INVIO COMANDO LETTURA MAPPA DI MEMORIA ( SCRATCHPAD ) Mediante il codice BEH si comanda di leggere la mappa di memoria del trasduttore; questa memoria è costituita da 9 byte come mostrato in figura. 18 I primi 2 byte contengono le informazioni riguardanti la temperatura acquisita. Non è necessario leggere tutti i byte; la procedura di lettura può essere bloccata inviando un comando di reset. Per i nostri scopi il comando di reset viene dato dopo la lettura dei primi due byte. Il contenuto dei primi due registri presenta l’informazione secondo il formato indicato in figura. I bit 15, 14, 13, 12, 11 contengono l’informazione riguardante il segno positivo ( tutti i bit sono a 0 ) o negativo ( tutti i bit sono a 1 ) della temperatura. I bit da 0 a 10 contengono il peso degli undici bit che forniscono il valore di temperatura. Ad esempio il bit 26, se a 1, significa che nel calcolo della temperatura in decimale si dovrà sommare un contributo pari a 64. Le potenze con esponente negativo indicano valori decimali cioè 0.5, 0.25, 0.125 e 0.0625. Per quanto riguarda la lettura/scrittura di un bit bisogna rispettare le temporizzazioni indicate in figura che cercheremo di analizzare in sintesi. Scrittura di un bit 0 1) Il pin del PIC è configurato come ingresso e la linea di comunicazione è tenuta alta dalla resistenza di pullup 2) Il pin del PIC viene configurato come uscita a livello basso. Essa viene tenuta bassa per un tempo compreso tra 60 e 120 microsecondi. 19 3) Il pin viene configurato come ingresso. La linea si porta a livello alto grazie alla resistenza di pullup. Prima di inviare un nuovo bit deve trascorrere almeno 1 microsecondo. Scrittura di un bit 1 1) Il pin del PIC è configurato come ingresso e la linea di comunicazione è tenuta alta dalla resistenza di pullup 2) Il pin del PIC viene configurato come uscita a livello basso. Essa viene tenuta bassa per un tempo compreso tra 1 e 15 microsecondi. 3) Il pin viene configurato come ingresso. La linea si porta a livello alto grazie alla resistenza di pullup e tale deve rimanere per almeno 60 microsecondi. Lettura di un bit 1) Il pin del PIC è configurato come ingresso e la linea di comunicazione è tenuta alta dalla resistenza di pullup 2) Il pin del PIC viene configurato come uscita a livello basso. Essa viene tenuta bassa per un tempo massimo di 15 microsecondi. 3) Il pin viene configurato come ingresso. Nei successivi 45 microsecondi è possibile leggere lo stato della linea. Riportiamo di seguito alcune routine che realizzano alcuni dei passi analizzati. I commenti chiariscono il senso delle varie istruzioni. 20 ;********** ROUTINE START CONVERSIONE (0X44=01000100)*************************** CONVERTI CALL ZERO ;SCRIVI UNO ZERO CALL ZERO CALL UNO ;SCRIVI UN UNO CALL ZERO CALL ZERO CALL ZERO CALL UNO CALL ZERO BSF STATUS,5 ;BANCO 1 BSF TRISB,0 ;LINEA COME INGRESSO BCF STATUS,5 ;BANCO 0 LPTC BTFSS PORTB,0 ;CONTROLLA SE FINITA CONVERSIONE GOTO LPTC RETURN ;********** ROUTINE CHE SCRIVE UN0 ZERO ************************************* ZERO BCF INTCON,7 ;DISABILITA INTERRUPT BSF STATUS,5 ;BANCO 1 BCF TRISB,0 ;LINEA COME USCITA ( RB4 ERA GIA’ BASSO ) BCF STATUS,5 ;BANCO 0 CALL RIT_100 ;ATTESA DI CIRCA 100 MICROSECONDI (LIVELLO BASSO IN ;USCITA) BSF STATUS,5 ;BANCO 1 BSF TRISB,0 ;LINEA COME INGRESSO BCF STATUS,5 ;BANCO 0 NOP ;RITARDO 5 MICROSECONDI NOP NOP NOP NOP BSF INTCON,7 ;ABILITA INTERRUPT RETURN ;********** ROUTINE SKIP COMAND (0XCC=11001100) COMANDO CALL ZERO ;CHIAMA ROUTINE CHE SCRIVE 0 CALL ZERO CALL UNO ;CHIAMA ROUTINE CHE SCRIVE 1 CALL UNO CALL ZERO CALL ZERO CALL UNO CALL UNO RETURN 21 Analisi del software Programmazione del modulo GSM Da una prima analisi del software, si deduce che il linguaggio di programmazione del modulo, nella sintassi, è molto simile al linguaggio C. La differenza sostanziale consiste nel fatto che esso è di tipo interpretato, cioè la traduzione in codice oggetto viene effettuata al momento dell’esecuzione, mentre il C è un linguaggio compilato. Questa differenza causa non pochi problemi di collaudo del software in quanto, a seconda delle diverse condizioni che lanciano o meno una routine o impongono l’esecuzione di un ciclo invece di un altro, l’intercettazione degli errori risulta piuttosto laboriosa. Un certo sforzo richiede anche la ricerca, mediante l’help in linea, delle funzioni che svolgono una certa funzione. Ad esempio la funzione SMSRM consente di trasferire il contenuto di un SMS in un array di testo. smsrm Read Short Message Service (SMS) Message Data int smsrm ( char *msgData, int msgDataSize, int msgSlotNumber ); Return Value 0 Failure to read SMS message >0 Successfull read of SMS message (size of SMS message) Parameters msgData Read SMS message data msgDataSize Number of bytes of SMS message data to read msgSlotNumber Slot number to read SMS message data from La funzione MCMP consente di confrontare due buffer che contengono rispettivamente, ad esempio, il messaggio SMS ricevuto e un codice sotto forma di testo ( all’atto della ricezione di un SMS, per comprendere il comando da eseguire, tale testo viene confrontato con tutti quelli programmati) . Mcmp Memcmp - compares two buffers of a specified length for equality char *mcmp(char *Buf1,char *Buf2,int count); Return Value Returns >0 if Buf1 > Buf2 <0 if Buf1 < Buf2 0 if Buf1 == Buf2 Numerose sono le funzioni utilizzate nel programma: per una analisi più approfondita si rimanda all’help in linea dell’ambiente di sviluppo. Si riporta il codice sorgente completo caricato nel processore del modulo che ha il compito di interagire con l’interfaccia radio. 22 /* SISTEMA DI CONTROLLO GSM /* AREA DI PROGETTO /* LAZZARI MATTEO /* TUTOR PROF. ZANIOL ITALO char testo[160]; char number_sms[160]; */ */ */ */ /* variabili globali */ main () { int chiamata=0,conf,pos; /* variabili locali */ int nuovosms=29; int STATO_RETE=10; int i,val; char zero[160]="0"; /* Configura variabili*/ char uno[160]="1"; char due[160]="2"; char tre[160]="3"; char quattro[160]="4"; char ricall[2]; char parole1[150]; char parole[150]; char numero[16]; char sms_num[16]; char trasm0[2]="0"; char trasm1[2]="1"; char trasm2[2]="2"; char trasm3[2]="3"; char trasm4[2]="4"; char trasm5[2]="5"; char trasm6[2]="6"; char trasm7[2]="7"; char trasm8[2]="8"; char trasm9[2]="9"; char cinque[160]="5"; char sei[160]="6"; char sette[160]="7"; char otto[160]="8"; char nove[160]="9"; prs(0); utc(1,3,0); /*apri porta seriale a 9600bit/sec)*/ io(2,2,1); /*accendi diodo segnalazione funzione per 5 secondi*/ io(1,2,1); dlys(5); io(1,2,0); for(i=0;i<20;i++) { val=gtb(STATO_RETE); /*controlla connessione alla rete*/ if(val==1) { break; /*esci dal ciclo*/ } dlys(2); /*attesa 2 secondi*/ } for(;;) { /*ciclo infinito*/ if(gtf(nuovosms)) { chiamata=1; } if(chiamata==1) { chiamata=0; /*controlla se c’è chiamata */ /*segnala ricevuto sms*/ /*se ricevuto sms*/ /*azzera chiamate*/ 23 atcrt(); /*apri canale AT*/ pos=smsrs(); /*rileva posizione sms*/ smsrm(testo,160,pos); /*copia sms in array testo*/ sms_num = smsra (number_sms, 160, pos); conf=mcmp(testo,zero,1); /*ricevuto 0? */ if(conf==0) { io(1,2,1); /*se si accendi ld1*/ temperatura(); /*chiama routine che invia temperatura*/ smsd(pos); /*cancella sms*/ io(1,2,0); /*spegni led*/ } conf=mcmp(testo,uno,1); if(conf==0) { io(1,2,1); /*se si accendi ld1*/ richiesta(); /*chiama routine che richiede stato*/ smsd(pos); /*cancella sms*/ io(1,2,0); /*spegni led*/ } conf=mcmp(testo,due,1); if(conf==0) { io(1,2,1); /*se si accendi ld1*/ attiva(); /*chiama routine che attiva periferica*/ smsd(pos); /*cancella sms*/ io(1,2,0); /*spegni led*/ } conf=mcmp(testo,tre,1); if(conf==0) { io(1,2,1); /*se si accendi ld1*/ disattiva(); /*disattiva periferica*/ smsd(pos); /*cancella sms*/ io(1,2,0); /*spegni led*/ } conf=mcmp(testo,quattro,1); if(conf==0) { uts (trasm4,1); dlys(1); /*trasmetti codice quattro al PIC*/ /*ritardo*/ io(1,2,1); dlys(1); io(1,2,0); io(1,2,1); dlys(1); io(1,2,0); io(1,2,1); dlys(1); io(1,2,0); conf=mcmp(testo+2,zero,1); if(conf==0) { uts (trasm0,1); } conf=mcmp(testo+2,uno,1); if(conf==0) { uts (trasm1,1); /*confronta testo ricevuto*/ /*invia decine*/ /*trasmetti al PIC*/ /*confronta testo ricevuto*/ /*invia decine*/ /*trasmetti al PIC*/ 24 } conf=mcmp(testo+2,due,1); if(conf==0) { uts (trasm2,1); } conf=mcmp(testo+2,tre,1); if(conf==0) { uts (trasm3,1); } conf=mcmp(testo+2,quattro,1); if(conf==0) { uts (trasm4,1); } conf=mcmp(testo+2,cinque,1); if(conf==0) { uts (trasm5,1); } conf=mcmp(testo+2,sei,1); if(conf==0) { uts (trasm6,1); } conf=mcmp(testo+2,sette,1); if(conf==0) { uts (trasm7,1); } conf=mcmp(testo+2,otto,1); if(conf==0) { uts (trasm8,1); } conf=mcmp(testo+2,nove,1); if(conf==0) { uts (trasm9,1); } /*confronta testo ricevuto*/ /*invia decine*/ /*trasmetti al PIC*/ /*confronta testo ricevuto*/ /*invia decine*/ /*trasmetti al PIC*/ /*confronta testo ricevuto*/ /*invia decine*/ /*trasmetti al PIC*/ /*confronta testo ricevuto*/ /*invia decine*/ /*trasmetti al PIC*/ /*confronta testo ricevuto*/ /*invia decine*/ /*trasmetti al PIC*/ /*confronta testo ricevuto*/ /*invia decine*/ /*trasmetti al PIC*/ /*confronta testo ricevuto*/ /*invia decine*/ /*trasmetti al PIC*/ /*confronta testo ricevuto*/ /*invia decine*/ /*trasmetti al PIC*/ dlys(1); /*ritardo*/ io(1,2,1); dlys(1); io(1,2,0); io(1,2,1); dlys(1); io(1,2,0); io(1,2,1); dlys(1); io(1,2,0); conf=mcmp(testo+3,zero,1); /*confronta testo ricevuto*/ if(conf==0) /*invia unità*/ { uts (trasm0,1); /*trasmetti al PIC*/ } conf=mcmp(testo+3,uno,1); /*confronta testo ricevuto*/ if(conf==0) /*invia unità*/ { uts (trasm1,1); /*trasmetti al PIC*/ } conf=mcmp(testo+3,due,1); /*confronta testo ricevuto*/ if(conf==0) /*invia unità*/ { uts (trasm2,1); /*trasmetti al PIC*/ 25 } conf=mcmp(testo+3,tre,1); if(conf==0) { uts (trasm3,1); } conf=mcmp(testo+3,quattro,1); if(conf==0) { uts (trasm4,1); } conf=mcmp(testo+3,cinque,1); if(conf==0) { uts (trasm5,1); } conf=mcmp(testo+3,sei,1); if(conf==0) { uts (trasm6,1); } conf=mcmp(testo+3,sette,1); if(conf==0) { uts (trasm7,1); } conf=mcmp(testo+3,otto,1); if(conf==0) { uts (trasm8,1); } conf=mcmp(testo+3,nove,1); if(conf==0) { uts (trasm9,1); } io(1,2,1); dlys(1); io(1,2,0); io(1,2,1); dlys(1); io(1,2,0); io(1,2,1); dlys(1); io(1,2,0); io(1,2,1); dlys(1); io(1,2,0); io(1,2,1); dlys(1); io(1,2,0); io(1,2,1); dlys(1); io(1,2,0); smsd(pos); /*confronta testo ricevuto*/ /*invia unità*/ /*trasmetti al PIC*/ /*confronta testo ricevuto*/ /*invia unità*/ /*trasmetti al PIC*/ /*confronta testo ricevuto*/ /*invia unità*/ /*trasmetti al PIC*/ /*confronta testo ricevuto*/ /*invia unità*/ /*trasmetti al PIC*/ /*confronta testo ricevuto*/ /*invia unità*/ /*trasmetti al PIC*/ /*confronta testo ricevuto*/ /*invia unità*/ /*trasmetti al PIC*/ /*confronta testo ricevuto*/ /*invia unità*/ /*trasmetti al PIC*/ } prs(1); atdst(); } } } /*----------------------------------------------*/ /* routine che invia al PIC uno 0 attende */ /* di ricevere la temperatura e invia sms */ 26 /*----------------------------------------------*/ temperatura() { int i,val=0; char trasm[2]="0"; char btemp [160]="TEMPERATURA = GRADI CENTIGRADI"; char ricevuto[2]; uts (trasm,1); /*trasmetti zero al PIC*/ for(i=0;i<20;i++) /*attendi risposta dal pic*/ { val=utr(ricevuto,2); /*controlla se ricevuto 2 byte*/ if(val) /*se ricwvuto dato invia sms*/ { if(ricevuto[0]==0) { sncpy (btemp + 14, "0", 1); } if(ricevuto[0]==1) { sncpy (btemp + 14, "1", 1); } if(ricevuto[0]==2) { sncpy (btemp + 14, "2", 1); } if(ricevuto[0]==3) { sncpy (btemp + 14, "3", 1); } if(ricevuto[0]==4) { sncpy (btemp + 14, "4", 1); } if(ricevuto[0]==5) { sncpy (btemp + 14, "5", 1); } if(ricevuto[0]==6) { sncpy (btemp + 14, "6", 1); } if(ricevuto[0]==7) { sncpy (btemp + 14, "7", 1); } if(ricevuto[0]==8) { sncpy (btemp + 14, "8", 1); } if(ricevuto[0]==9) { sncpy (btemp + 14, "9", 1); } if(ricevuto[1]==0) { sncpy (btemp + 15, "0", 1); } if(ricevuto[1]==1) { sncpy (btemp + 15, "1", 1); } if(ricevuto[1]==2) { sncpy (btemp + 15, "2", 1); } 27 if(ricevuto[1]==3) { sncpy (btemp + 15, "3", 1); } if(ricevuto[1]==4) { sncpy (btemp + 15, "4", 1); } if(ricevuto[1]==5) { sncpy (btemp + 15, "5", 1); } if(ricevuto[1]==6) { sncpy (btemp + 15, "6", 1); } if(ricevuto[1]==7) { sncpy (btemp + 15, "7", 1); } if(ricevuto[1]==8) { sncpy (btemp + 15, "8", 1); } if(ricevuto[1]==9) { sncpy (btemp + 15, "9", 1); } smss(number_sms,btemp,145,slen(number_sms),slen(btemp)); val=0; io(1,1,1); /*accendi led1 per 2 secondi*/ dlys(2); io(1,1,0); break; } dlys(1); } /*attesa 1 secondi*/ } /*----------------------------------------------*/ /* routine che invia al PIC un 1 attende */ /* di ricevere informazione e invia sms */ /*----------------------------------------------*/ richiesta() { int ii,val1=0; char trasm1[2]="1"; char risp1 [160]="Periferica off"; char risp2 [160]="Periferica on"; char ricevuto1[2]; atcrt(); /*apri canale AT*/ uts (trasm1,1); /*trasmetti uno al PIC*/ for(ii=0;ii<20;ii++) /*attendi risposta dal pic*/ { val1=utr(ricevuto1,1); /*controlla se ricevuto 1 byte*/ if(val1) /*se ricwvuto dato invia sms*/ { if(ricevuto1[0]==0) { smss(number_sms,risp1,145,slen(number_sms),slen(risp1)); } if(ricevuto1[0]==1) { smss(number_sms,risp2,145,slen(number_sms),slen(risp2)); } val1=0; io(1,1,1); /*accendi led1 per 2 secondi*/ 28 dlys(2); io(1,1,0); break; } dlys(1); } /*attesa 1 secondi*/ } /*----------------------------------------------*/ /* routine che invia al PIC un 2 */ /* attiva periferica */ /*----------------------------------------------*/ attiva() { char trasm2[2]="2"; uts (trasm2,1); /*trasmetti due al PIC*/ io(1,1,1); /*accendi led1 per 2 secondi*/ dlys(2); io(1,1,0); } /*----------------------------------------------*/ /* routine che invia al PIC un 3 */ /* disattiva periferica */ /*----------------------------------------------*/ disattiva() { char trasm3[2]="3"; uts (trasm3,1); /*trasmetti due al PIC*/ io(1,1,1); /*accendi led1 per 2 secondi*/ dlys(2); io(1,1,0); } /* ***** FINE ****** */ Alcune routine del Pic ;***********ROUTINE INVIA TEMPERATURA AL MODULO GSM******************* INV_TEMP MOVF MOVWF CALL MOVF MOVWF CALL CLRF RETURN TEL_H,0 DATO SER_TX TEL_L,0 DATO SER_TX DATO ;sposta il valore di tel_h in dato;decine ;invia il valore di dato tramite seriale ;sposta il valore di tel_l in dato;unità Con la seguente routine il Pic invia, tramite seriale, al modulo GSM i valori di temperatura letti dal sensore di temperatura e convertiti in codice BCD. Al modulo prima arrivano le decine e poi le unità ;**************ROUTINE INPOSTA TEMPERATURA SU RICHIESTA GSM******************* PLUTO BTFSS GOTO MOVF MOVWF BCF MOVF ANDLW MOVWF PLUTO2 BTFSS PIR1,5 PIR1,5 PLUTO RCREG,0 DATO PIR1,5 DATO,0 0X0F DECINE2 ;CONTROLLA SE ARRIVATO DATO SU PORTA SERIALE ;SE SI, SALVA IN DATO ;MASHERA BIT NON VALIDI ;CONVERTE DA ASCII A DECIMALE ;PRONTO PER ESSERE VISALIZZATO ;RICEZIONE UNITà 29 GOTO MOVF MOVWF BCF MOVF ANDLW MOVWF MOVF MOVWF BCF RLF RLF RLF MOVF MOVWF BCF RLF MOVF ADDWF MOVF ADDWF MOVLW MOVWF RETURN PLUTO2 RCREG,0 DATO PIR1,5 DATO,0 0X0F UNITA2 DECINE2,W CONFRONT STATUS,0 CONFRONT,F CONFRONT,F CONFRONT,F DECINE2,W DECINE4 STATUS,0 DECINE4,F DECINE4,W CONFRONT,F UNITA2,W CONFRONT,F D'1' ONOFF2 ;CONVERTI DATO IN BINARIO PER CONTROLLO ;TEMPERATURA ;PREDISPONI PER ATTIVARE IMPIANTO In questa routine il pic controlla continuamente se gli arriva un dato da porta seriale per poi trasferire ciò che ha ricevuto in due registri: Decine2,Unita2 utilizzati per la gestione del display. ;************ROUTINE VERIFICA SE RICEVUTO DATO DA PORTA SERIALE SER_RX BTFSS PIR1,5 ;RICEVUTO DATO? RETURN ;SE NO, ESCI MOVF RCREG,0 ;ALTRIMENTI SALVA SU MEMORIA MOVWF DATO BCF PIR1,5 ;AZZERA FLAG RETURN ;*************ROUTINE TRASMISSIONE DI UN BYTE CONTENUTO IN DATO************ SER_TX MOVF DATO,0 MOVWF TXREG ;INVIA DATO RETURN CONTROLTEMP MOVF PROVA,0 SUBWF CONFRONT,0 BTFSS STATUS,0 GOTO BOO1 BSF PORTE,0 GOTO BOO BOO1 BCF PORTE,0 BOO BTFSC STATUS,2 BCF PORTE,0 RETURN Semplicissima routine ma fondamentale. Il registro ‘prova’ contenente la temperatura reale presente nell’ambiente, viene confrontato con il set point che si trova in ‘confront’; se quest’ultima risulta superiore si diattiva il carico altrimenti lo dattiva. 30 Istruzioni d’uso Di seguito si riportano i codici da inviare tramite SMS per la gestione del sistema: • • • • • Richiesta temperatura Richiesta stato periferica Attivazione periferica Disattiva periferica Imposta temperatura di riferimento 0 1 2 3 4 xx dove xx è il valore che si vuole impostare N.B. Per le funzioni 0 e 1il modulo risponde a qualsiasi cellulare chiamante e non a quelli con numero preimpostato. Esso è in grado di estrapolare, dal messaggio ricevuto, il numero del cellulare chiamante. Nella pagina seguente vengono riportate le schermate di alcuni messaggi ricevuti Il display del telefono dopo aver ricevuto la temperatura dal modulo 31 Il display dopo aver ricevuto lo stato della periferica Gestione del sistema localmente Quando si alimenta il termostato, il controllo è impostato off. Sul display appare la temperatura dell’ambiente e il valore preimpostato di set-point (20 ˚C) ( valore di default ). La temperatura di set-point si può regolare localmente tramite i due pulsanti presenti sulla demoboard oppure tramite cellulare; in quest’ultimo 32 caso, una volta ricevuta la temperatura di nuovo set point, il controllo automatico di temperatura è avviato. Localmente l’attivazione viene effettuata tramite pulsante ON/OFF. Una volta attivato il controllo, il microcontrollore confronta la temperatura dell’ambiente con quella di set-point; se la temperatura ambientale è inferiore viene attivato un sistema di riscaldamento che si disattiva un volta raggiunta la temperatura predefinita. Per controllare il generatore non è stato previsto un relè; un led simula lo stato di questo attuatore. Inoltre è presente un ingresso di allarme, anche in questo caso simulato da un pulsante, e un segnalatore ottico a led. Tuttavia nulla toglie di inserire al posto del pulsante un sensore e al posto del led una sirena. Quando si attiva l’allarme, il sistema invia un messaggio al numero di telefono preimpostato che, tramite SMS, segnala una situazione di allarme. Approfondimenti teorici Telefonia mobile Introduzione: La telefonia mobile e in particolar modo il sistema radiomobile, ha avuto, dagli anni novanta a oggi, una enorme evoluzione tanto che al giorno d’oggi gli utenti di telefonia mobile superano quelli di telefonia fissa. Struttura di un sistema cellulare: Un sistema radiomobile terrestre deve contemporaneamente soddisfare 2 esigenze: • Garantire una adeguata copertura radio sul territorio di competenza • Servire un gran numero di utenti in relazione alla richiesta effettiva del servizio Per soddisfare queste esigenze si utilizza il concetto di riutilizzo delle frequenze. Il riutilizzo delle frequenze consiste nel riutilizzare le stesse frequenze a patto che la distanza tra le due antenne sia tale da non creare interferenze fra loro. Per far questo il sistema radiomobile utilizza un sistema a celle dove ciascuna cella utilizza frequenze diverse da quelle contingue e celle non contigue possono riutilizzare la stessa frequenza. In realtà le celle non sono mai tutte uguali tra loro ma dipendono dalla conformazione del suolo e dal livello di utenze che si vuole assegnare a ciascuna cella. Per irradiare il segnale all’interno di una cella si utilizzano due metodi: 33 • Center excited: essa consiste nel porre un’antenna omnidirezionale al centro di una cella. • Cornerexcited: essa consiste nel porre una serie di antenne all’incrocio di tre celle svasando la direzione dei vari segnali di 120°. FDMA-TDMA Per servire all’interno di ogni cella un numero elevato di utenti in presenza di un numero contenuto di canali radio, viene utilizzata la tecnica FDMA-TDMA. Con tale tecnica (tecnica di accesso multiplo a divisione di frequenza e a divisione di tempo) la banda radio a disposizione, ad esempio 890÷915 MHz, viene suddivisa in n canali e ogni canale viene suddiviso in m slot utilizzando una multiplazione TDM. In pratica ogni telefono utilizza,durante la comunicazione, un canale solo per la durata di uno slot. Ogni canale ha a disposizione otto slot. 34 Come evidenziato in figura, in analogia al sistema TDM telefonico, le trame sono poi organizzate in multitrame, supertrame e ipertrame per far viaggiare le informazioni all’interno della rete mobile e per l’interfacciamento con la rete fissa. GSM900 Il sistema GSM utilizza la banda 890÷915 MHz per l’uplink e la banda 935÷960 MHz per il downlink; quindi ogni banda radio dispone di 45 MHz. Questa banda viene suddivisa in 124 canali di 200 KHz, ciascuno dei quali è in grado di portare fino a otto segnali numerici multiplati con tecnica TDM GSM1800 Analogo al GSM900 con l’unica differenza che la banda utilizzata si trova a 1800 MHz con il vantaggio di utilizzare una banda più ampia rispetto al fratello minore e quindi disporre di un maggior numero di canali radio. La modulazione utilizzata è una variante della modulazione a spostamento di frequenza ( FSK ). Rispetto a questa, filtri formatori limitano la larghezza di banda del segnale modulato in modo da evitare interferenze tra canali radio adiacenti ed aumentare l’efficienza spettrale vale a dire il numero di bit trasmessi per ogni Hz di banda. 35