Sesan george orientamento e scelta del progetto



Scaricare 199.06 Kb.
24.01.2018
Dimensione del file199.06 Kb.

ISTITUTO TECNICO INDUSTRIALE “G. MARCONI”

CLASSE 5a ET
INDIRIZZO

ELETTRONICA E TELECOMUNICAZIONI

ESAME DI STATO A.S. 2010/2011
BUILDING AUTOMATION
CIMMINO MATTEO
CRAVEDI SIMONE
FOGLIO FABIO
MULAZZI DAVIDE
NICOLLINI PAOLO

SESAN GEORGE

ORIENTAMENTO E SCELTA DEL PROGETTO

Il nostro gruppo, dopo aver discusso sul tipo di progetto da sviluppare in vista dell’esame di Stato, ha deciso di riprendere un progetto nel settore della building automation.

Questo settore si occupa dell’automatizzazione di ambienti e dispositivi in campo industriale ma anche domestico.

OBIETTIVO DEL PROGETTO

L’obiettivo del progetto è realizzare un sistema di controllo e di monitoraggio di ambienti che sfrutta una rete ethernet preesistente per gestire il flusso delle informazioni tra i vari apparati. Questa scelta è diversa dalla maggior parte delle soluzioni commerciali che prevedono l'uso di connessioni e standard di protocollo dedicate anziché la suite TCP/IP e le connessioni tipiche di una rete LAN.
BUILDING AUTOMATION

La building automation è qualcosa di più elevato rispetto la domotica. L’edificio intelligente, con il supporto delle nuove tecnologie permette la gestione coordinata, integrata e computerizzata degli impianti tecnologici (climatizzazione, distribuzione, acqua, gas,energia ed impianti di sicurezza) delle reti informatiche e delle reti di comunicazione, allo scopo di migliorare la flessibilità di gestione, il comfort, la sicurezza, il risparmio energetico degli immobili, la qualità dell’abitare e del lavorare all’interno degli edifici. A differenza della home automation, settore in fase di piena espansione, la building automation è già consolidata da diversi anni, per questo è opinione diffusa che i prodotti del medesimo settore, adattati su scala ridotta, possano essere applicati anche nella domotica. L’automazione degli edifici è giustamente considerata a un livello superiore rispetto alla domotica, anche se sotto alcuni punti di vista questi settori possono essere considerati in contrapposizione. Il punto di forza della Building Automation risiede nel fatto che in un edificio è necessario fornire tutta una serie di servizi (distribuzione, acqua, gas ed energia elettrica, impianti di sicurezza, segnale televisivo/satellitare, riscaldamento, ecc…) agli ambienti contenuti (appartamenti e uffici) così facendo questi impianti beneficiano, dal punto di vista del costo, del fatto di essere comunitari ovvero di ripartire su ogni utente un costo irrisorio se comparato al beneficio. Per questo,recentemente sono stati introdotti nei servizi offerti in comunione anche la refrigerazione (climatizzatore),il condizionamento dell’acqua potabile, la video sorveglianza, la connessione internet, ecc… Al livello inferiore la domotica deve ridistribuire i servizi distribuiti dal condomino nonché eventuali sottoservizi alle varie stanze dell’appartamento.


METODO DI LAVORO

Al fine di risparmiare tempo e di svolgere più progetti in parallelo, ci siamo divisi in più sottogruppi, ciascuno dei quali si è occupato di trattare aspetti specifici del progetto (ambienti di controllo, server, linguaggio perl, modulo gsm.) per approfondirli e realizzarli concretamente. Terminati i vari “sottoprogetti”, dopo aver condiviso nel gruppo i risultati, le problematiche e le nostre opinioni, abbiamo cercato di assemblarli tra di loro, in modo da realizzare il progetto finale.

Gli aspetti specifici trattati sono i seguenti:


  • applicativo per la gestione degli apparati ;

  • riproduzione ambienti di lavoro con relativi applicativi;

  • linguaggio PERL;

  • linguaggio HTML per lo sviluppo della pagina web;

  • siteplayer;

  • modulo GSM e relativi comandi AT;

  • cablaggio strutturale e circuitale;

Per lo sviluppo del progetto è stato fondamentale il supporto dei docenti e la consultazione di guide e manuali, online e non.


APPLICATIVO PER LA GESTIONE DEGLI APPARATI
Come abbiamo descritto precedentemente, il prototipo realizzato dal nostro gruppo è composto da un server centrale e da alcuni moduli periferici con connessione ethernet alla stessa LAN del server; a loro volta i moduli (client) dialogano con le schede a microcontrollore (i moduli di I/O) via interfaccia seriale (o USB con adattatore per seriale). In questo capitolo descriveremo brevemente i programmi sviluppati, la loro collocazione negli elaboratori e nelle schede micro e le modalità di comunicazione tra gli stessi. In parte abbiamo ripreso software sviluppato da alcuni allievi della precedente quinta.

(schema a blocchi sistema fisico manca modulo 4 che è virtuale e quindi è composto solo da un PC)



Server centrale
E' l'elemento centrale del progetto; i compiti che assolve sono:

  • Interrogare periodicamente e ciclicamente gli host per richiedere il valore delle grandezze controllate. Dal modulo 1 viene rilevata la temperatura reale dell'ambiente controllato (una scatola contenente un riscaldatore elettrico ed un ventilatore); dal modulo 2 viene rilevata la temperatura dell'aula server d'istituto da tenere sotto controllo; i moduli 3 e 4 sono solo di uscita (il 4 è simulato). L'operazione è schedulata ogni cinque minuti e le grandezze rilevate vengono mostrate in immagini aggiornate con la stessa cadenza temporale nella home page del sito web dedicato. Il programma che realizza questa funzione, scritto in linguaggio Perl, è “datain_module.cgi” (più avanti descritto con maggior dettaglio).

  • Permettere la gestione dell'intero sistema da una pagina web del sito dedicato. La pagina di amministrazione a regime dovrebbe essere accessibile solo da personale autorizzato. Attualmente, per ragioni di tempo, questa funzione non è stata attivata. I comandi ai moduli che si possono modificare sono:

  1. Modulo 1: il Set Point dell'anello di regolazione di temperatura della scatola

  2. Modulo 2: la scelta indipendente del livello logico di otto uscite digitali verificabili mediante l'accensione di altrettanti LED

  3. Modulo 3: Siteplayer con controllo ad anello aperto della velocità di un ventilatore.

  4. Modulo 4: simulato (per ragioni di tempo). Il segnale inviato dal server viene restituito identico (connessione diretta TX-RX della seriale. E' implementato su un computer con S:O. Windows per mostrare la portabilità del Perl.

E' stato necessario pertanto installare sul server un applicativo che può ospitare pagine web (un web server, nel ns. caso Apache) e realizzare due pagine web, la principale (home) index.html e quella di amministrazione manual_new.cgi che descriveremo più avanti. Il programma che si occupa della trasmissione dei comandi ai quattro moduli è dataout_module.cgi è scritto in Perl ed è eseguito quando l'amministratore preme il pulsante “Update” nella pagina di amministrazione

  • Testare la connessione con i vari moduli

  • Accettare e decodificare i messaggi sms da cellulare per amministrazione remota. Dalla pagina web di amministrazione è possibile disabilitare questa funzione. In verità ora il web server è con Ip pubblico e la gestione da remoto può avvenire anche via internet dalla pagina descritta nel punto precedente. La gestione degli sms è svolta utilizzando un modulo gsm dati collegato ad una porta seriale del server. Dato che è necessario interrogare il modem per sapere se sono arrivati nuovi messaggi, abbiamo realizzato il programma Perl rx_tx_gsm.pl che è schedulato ogni minuto e una volta ricevuto il messaggio lo decodifica per riconoscerne la validità; in caso affermativo vengono inviati i comandi ai moduli via rete.

I programmi datain_module_new.cgi, dataout_module_new.cgi e rx_tx_gsm.pl sono concorrenti nel senso che possono interagire tra loro, in quanto dialogano con gli stessi moduli, perciò è stata messa a punto una strategia di “interblocco” senza livelli di priorità. Ogni programma prima di comunicare controlla in una tabella di un database mysql il campo block: se il valore è uguale a 1 un altro processo sta comunicando con i moduli e perciò il programma “si mette in coda” testando il campo finchè viene riportato a zero. Se non ci sono immissioni di nuovi comandi via web o via sms l'unico programma eseguito è datain_module.cgi che interroga come già detto ogni cinque minuti i moduli periferici.

MODULO GSM E COMANDI AT
Per la gestione a distanza del nostro ambiente abbiamo utilizzato un telecontrollo con un modulo tc35i ideato dal sottogruppo della Siemens Cinterion che permette di interagire con tutti i sistemi presenti come, ad esempio, gli impianti di riscaldamento (due termo resistenze), di climatizzazione (una ventola) consentendone il comando diretto e lo scambio delle relative informazioni. Tramite semplici sms potremo essere in grado di controllare le molteplici funzionalità del nostro sistema (presenza malfunzionamenti, temperature, livello di umidità ecc…). Il modulo che è sostanzialmente un completo cellulare in versione open manca solo di tastiera e display.

Per far funzionare il modem occorre dunque un software/firmware che, attraverso opportuni comandi, provvede all'accensione del modem, oltre che la verifica del PIN e la registrazione della carta SIM sulla rete GSM. Le operazioni appena accennate dette anche di inizializzazione vengono effettuate attraverso opportuni comandi inviati attraverso la porta seriale del modem. Per il funzionamento è inoltre necessario un'antenna GSM ed una carta SIM.

Prima di iniziare ad usare concretamente il terminale sono stati consultati manuali della Siemens in modo da comprenderne il corretto utilizzo.

Il modem risponde a opportuni comandi Heyes, tutti i parametri di configurazione e di esecuzione vengono settati direttamente del calcolatore con semplici caratteri AT.

Dopo aver settato le impostazioni iniziali del modulo, quali la registrazione alla rete, il livello del segnale e il gestore della SIM, si possono usare comandi opportuni per l’invio e la ricezione di sms.

Comandi utilizzati per la configurazione:


AT+F:

porta tutti i parametri al valore di fabbrica,

risposta del modem: OK.
AT+CREG?:

verifica registrazione alla rete GSM,

risposta: +CREG ; 0,1 (il modem è registrato).
AT+COPS?:

verifica gestore.

risposta: +COPS (codice gestore).

AT+CSQ:

verifica livello segnale,

risposta: +CSQ.
AT+SMSO:

spegne il modulo da computer.


AT&V:

indica la configurazione attuale,

risposta: configurazione attuale modem.
ATEF:

ristabilisce le caratteristiche di fabbrica.


AT+CMGD=1:

cancella il primo messaggio in memoria.


Ricezione e trasmissione sms:

Per ricevere ed inviare gli SMS il modulo deve essere posto in modalità TEXT con i relativi comandi

in ricezione ed in trasmissione.

In ricezione di SMS il modulo si comporta come un normale telefono cellulare.

I messaggi ricevuti vengono memorizzati nella memoria della SIM.

Sequenza comandi utilizzati per ricevere SMS:


AT+CMGF=1: modalità trasmissione TEXT.

AT+CMGF=ALL: scegli tutti gli sms in memoria.

AT+CMGR=: scelta sms specifico.
Sequenza comandi utilizzati per trasmettere SMS:
AT+CMGF=1: modalità trasmissione TEXT.

AT+CMGS=: invia il messaggio al numero desiderato.
“Hardware” del server
Il server è stato realizzato con una macchina “virtuale” ospitata dall'Hypervisor ESXi di Vmware e risiede nell'aula server dell'istituto. ESXi 4.1 è la versione free del software di virtualizzazione Vmware di tipo server. L'hypervisor, che viene installato per primo sul computer, è una sorta di s. o. “contenitore” di macchine virtuali accessibili solo da remoto via rete (anche con strumenti grafici come Vmware Sphere client). Il sistema operativo del nostro server virtuale è una distribuzione GNU/Linux Debian stable (Squeeze). I programmi necessari al funzionamento del server e quelli realizzati da noi sono stati caricati dai repository Debian e/o modificati quasi sempre da riga di comando via ssh (secure shell).

Hardware e software “periferico”


Sui pc connessi in rete collegati ai moduli 1, 2 e 4 viene eseguito continuamente il programma perl server_modn.pl il cui scopo principale è quello di attendere connessioni via rete da uno dei tre programmi citati prima e di “trasferire” i comandi al modulo n. Il protocollo implementato prevede l'invio del carattere T per chiedere al modulo l'invio di una serie di caratteri che contengono la codifica della temperatura attuale o del carattere C per avvisare il modulo dell'invio successivo del nuovo Set Point (modulo 1) o della combinazione delle uscite digitali (modulo 2). Alla fine, in entrambi i casi, la connessione con il client (uno dei tre programmi che girano sul server) viene chiusa lato client, ma il server rimane attivo per attendere nuove connessioni. Anche se è la funzione meno visibile, questa connessione a livello 4 (TCP) del modello ISO/OSI è la base fondamentale dello sviluppo del ns. progetto. Il modulo 3 è realizzato con un Siteplayer (vedi avanti).
Pc 1 e Modulo 1
Sul pc che realizza l'interfaccia tra Il sistema è un semplice controllo di temperatura a catena chiusa basato su microcontrollore con gestione remota. Il programma C scritto per il PIC 16F876A è ciclico e controlla continuamente se sono arrivati caratteri da seriale. Se è arrivato un carattere controlla che sia T o C. Nel primo caso trasmette su seriale la temperatura rilevata dalla sonda analogica LM 35, amplificata dall'op amp LF 351 e convertita dal A/D interno al PIC; nel secondo, memorizza i tre caratteri del nuovo Set Point della regolazione, compresa teoricamente tra 0°C e 50°C. Se non arrivano comandi o arriva un carattere diverso da T e C il programma lo scarta ed esegue solo il confronto tra Set Point e temperatura attuale per determinare se attivare il riscaldamento o la ventilazione. I tre caratteri inviati non sono strettamente necessari dato che abbiamo scelto la risoluzione ad otto bit. Nelle prove effettuate con l'Hyperterminal però è stato molto comodo rendere tutti i numeri visibili perché codificati in ASCII. Così ad esempio invece di inviare il byte 11111111 (FF in esadecimale e 255 in decimale) non visibile, vengono trasmessi tre caratteri ASCII 32 35 35 che risultano visualizzati a monitor come 255. Se il Set Point vale 000 (ASCII 30 30 30) vengono spenti sia il riscaldatore che il ventilatore.
Scelta del linguaggio di programmazione e moduli PIC utilizzati:

Il C è tecnicamente un linguaggio di programmazione ad alto livello. Tuttavia, risulta molto meno astratto di linguaggi anche affini (appartenenti allo stesso livello), come per esempio il Pascal. Per questo motivo, talvolta viene anche identificato con la definizione di linguaggio di medio livello. Il C è rinomato per la sua efficienza, e si è imposto come linguaggio di riferimento per la realizzazione di software di sistema su gran parte delle piattaforme hardware moderne.

- A/D Converter:
Tale modulo ha la funzione di acquisire un segnale analogico dall’esterno e convertirlo in una parola digitale per poterlo quindi processare.

Le applicazioni sono infinite e l’interfacciamento con un segnale analogico è sicuramente più rapido e semplice da effettuare rispetto a quello di un segnale digitale, sebbene per sua natura sia più soggetto ai disturbi. Essendo i PIC dispositivi TTL, possono ricevere sugli ingressi del convertitore A/D segnali con tensioni variabili da 0 a 5 volt, non possono quindi accettare tensioni negative e, per tensioni superiori a 5 volt è necessario adottare dei partitori di tensione (realizzati semplicemente con resistenze) in maniera tale da non ricevere mai in ingresso tensioni superiori a 5 volt.

Il 16F876 ha un convertitore A/D a 10bit. Ovvero è capace di convertire un valore di tensione, variabile da 0 a 5 volt, in una parola da 10bit, con valori digitali variabili da zero fino al valore 1023 (1024 valori possibili) . Quindi il minimo valore di tensione acquisibile (la sensibilità):
5/1024 = 0.00488V, ovvero circa 5mV.
Il convertitore A/D all’interno è uno solo. Gli ingressi, invece, sono più di uno: il nostro PIC ha 5 ingressi analogici. I pin capaci di acquisire un segnale analogico sono quelli contrassegnati sui data sheet con la sigla AN. Di conseguenza ogni volta andrà specificato da quale ingresso analogico prelevare il segnale.

Per realizzare questo modulo occorre settare determinati registri:


-ADCON0 :


E’ il registro che si occupa di controllare le operazioni del modulo convertitore, ovvero: l’accensione/spegnimento, la selezione dell’ingresso dal quale prelevare il segnale, l’avvio delle operazioni di conversione.

-ADCON1 :


E’ il registro che si occupa del settaggio delle porte analogiche. Tramite questo registro, difatti, possiamo dire al PIC quali pin devono comportarsi come ingressi analogici.

Infine ADRESH e ADRESL sono i due registri nei quali è riportato il risultato della conversione appena effettuata.

Per effettuare quindi una corretta acquisizione e conversione del segnale bisogna rispettare alcune tempistiche ben precise: abbiamo un tempo di acquisizione, che è necessario per poter caricare a piena capacità il condensatore di campionamento, ed un tempo di conversione, che inizia quando settiamo ADGO e termina quando viene settato ADIF, e rappresenta il tempo necessario al modulo A/D per poter effettuare l’operazione di conversione. La somma dei due tempi prende il nome di tempo di campionamento.

-USART:


Il protocollo di comunicazione RS232 sui PIC si implementa normalmente facendo uso della periferica chiamata USART (Universal Synchronous Asynchronous Receiver Transmitter), opportunamente interfacciata dal MAX232 per traslare i livelli di tensione. La periferica USART può essere impostata per lavorare in modalità asincrona full duplex oppure per lavorare in modalità sincrona half duplex (come master o come slave). Il modulo USART del PIC16F877A permette di eseguire trasmissioni/ricezioni sincrone e asincrone; i due moduli funzionano in modo indipendente.

Per la gestione dell'usarti vengono utilizzati i seguenti registri:

-RCSTA:registro di controllo e di stato della sezione ricevente

-TXSTA:registro di stato e di controllo della sezione trasmittente

-RCREG:buffer di ricezione

-TXREG:buffer di trasmissione

-SPBRG:generatore del baud rate

La UART viene configurata agendo via software sui registri TXSTA in trasmissione e RXSTA in ricezione.

I dati prima di essere trasmessi dal uC devono essere caricati nel registro TXREG, in ricezione vengono salvati nel registro RXREG.

Il baud-rate della comunicazione si imposta agendo sul registro SPGREG.

Dispositivi e integrati utilizzati (escluso PIC16F876):


-Max rs-232:
è un classico circuito di interfaccia RS232/TTL. Con soli 4 condensatori esterni e alimentato a 5V è in grado di generare le tensioni di ±10V (infatti è in grado di erogare una tensione d'uscita superiore a quella di alimentazione sfruttando circuiti di pompa di carica) compatibili con lo standard RS232 e di convertire i dati con livelli TTL in dati RS232 e viceversa.
Ideale per interfacciare qualunque microcontrollore con un PC .


Livello logico

Livelli TTL/CMOS

Livelli RS-232

0

0V

12V

1

5V

-12V


(case max 232)

-Sonda analogica di temperatura LM35 (national semiconductors):
Questa sonda di temperatura è un circuito integrato utilizzato per chiudere l’anello di retroazione del modulo 1 infatti la sua uscita analogica dopo un’opportuna amplificazione (per adattare l’uscita alla dinamica d’ingresso dell’ADC) viene convertita in digitale, fornendo così al sistema il valore della temperatura presente nell’ambiente controllato. La sonda opera tra -50 e +150 °C ed ha un legame ingresso uscita espresso dalla relazione:

V0 = 10 [mv/°C] x °C



(connection diarams LM35)



(lm 35)
Amplificatore operazionale RS351:

Utilizzato in configurazione non invertente (guadagno=10) per condizionare l’uscita della sonda di temperatura lm35 e adattarla alla dinamica d’ingresso dell’ADC implementato nel PIC (0 - 5v)

Schema elettrico modulo 1:


(A destra scheda micro modulo 1, a sinistra simulazione fisica ambiente controllato)


(interno ambiente controllato modulo1)

Pc 2 e Modulo 2
Il pc a cui è collegato implementa lo stesso programma server_modn.pl del server virtuale. Il suo indirizzo IP però è chiaramente diverso. A tal proposito ricordiamo che per instaurare una connessione TCP (connection-like) tra un server ed un client i due processi/programmi che vogliono comunicare possono utilizzare i socket che sono caratterizzati dall'indirizzo IP e da un numero di porta. Nel ns. caso questo host ha indirizzo pubblico 212.189.172.166 e abbiamo scelto come porta la 9002. I numeri di porta sopra i primi 1023 sono utilizzabili perché non impiegati da servizi importanti (80 http, 443 https, 25 smtp ecc...).

Anche i caratteri ASCII di comando sono gli stessi dell'altro host.

Questa scheda a microprocessore gestisce una sonda digitale 18B20 e accetta il comando di cambiamento di livello di otto uscite digitali. Lo scambio di informazioni avviene in ASCII. In questo caso non ci sono anelli di regolazione, quindi il programma su microcontrollore attende T o C; se arriva T interroga la sonda con un protocollo proprietario ed invia la stringa al programma Perl sul server centrale che estrae la temperatura in gradi Celsius. Se arriva C attende i tre caratteri ASCII e li decodifica per estrarre le otto uscite digitali.

Il programma di questo modulo è stato scritto con linguaggio assembly, che è molto più vicino al linguaggio macchina rispetto al C. Attraverso questo modulo abbiamo voluto far comprendere che attraverso una postazione remota (pc o gsm) è possibile inviare controlli a qualsiasi dispositivo ( si consideri le uscite di questo modulo dei segnali di controllo che piloteranno eventualmente circuiti di potenza).





(schema a blocchi modulo 2)


(scheda micro e interfaccia a LED modulo 2)


Modulo 3 Siteplayer
E' un dispositivo dotato direttamente di interfaccia Ethernet perciò può essere collegato direttamente alla rete nella quale si fanno circolare i dati scambiati tra il server centrale e i moduli. SP utilizza il protocollo UDP per collegare la sua interfaccia seriale con la rete. E' conveniente utilizzarlo nelle aree in cui non ci sono pc che possono fungere da interfaccia tra moduli di I/O e server centrale. Nel ns. caso è stato collegato ad una scheda prototipo realizzata con un microcontrollore PIC che regola mediante PWM la velocità di un ventilatore (Att 1) .

(schema elettrico modulo 3)



(Siteplayer con interfacce Ethernet e Seriale RS232)

Breve descrizione dei programmi scritti in linguaggio Perl



Premessa

Questo progetto è stata l'occasione per utilizzare computer basati su un sistema operativo libero open source come GNU/Linux. In particolare il server centrale è dotato di una distribuzione Debian Squeeze. Nel mondo Linux le distribuzioni (Red Hat, Fedora, Slackware, Ubuntu ecc...) sono i sistemi operativi basati su kernel Linux (l'unità più interna del s.o.) più vari tipi di applicativi, tutti rigorosamente liberi, che l'utente può installare per agevolare il proprio lavoro. Come già detto il sistema operativo è stato installato come macchina virtuale su un hypervisor ESXi. . Molti dei programmi di servizio per l'amministrazione di un server GNU/Linux sono scritti in un linguaggio interpretato, il Perl appunto, relativamente facile da apprendere. La sintassi è simile al C anche se non è così performante e soprattutto per noi, che non abbiamo solide basi di programmazione, è stato conveniente trovare già pronti diversi pacchetti software detti module, che hanno permesso di ottenere la comunicazione via rete e seriale in maniera relativamente semplice. Altre parti di codice sono stati sviluppate da allievi della precedente 5 ET1. Un altro grosso vantaggio del Perl è che praticamente indipendente dalla piattaforma; infatti a casa abbiamo lavorato su script (si chiamano così i programmi Perl) che girano anche sotto Windows senza modifiche. Naturalmente ci sono anche degli svantaggi: è un linguaggio interpretato quindi in contesti in cui la velocità di esecuzione è critica è inadeguato. In più è possibile una scrittura di codice un po' disinvolta con difficoltà perciò di riutilizzo e/o di comprensione nel caso di file estesi. Molti programmatori professionisti lo utilizzano in fase di prototipazione per poi usare altri linguaggi (C, C++...) nella versione definitiva.


datain_module_new.cgi
Il programma schedulato per essere eseguito ogni cinque minuti esegue questi passi fondamentali:


  1. Controlla nel database che sia possibile la connessione via rete con i moduli.

  2. Nel caso negativo (campo block uguale a 1) il programma attende che “qualcuno” (gli altri due programmi concorrenti) ne cambino il valore. Al momento non è previsto timeout

  3. Se block vale 0 lo riporta a 1 bloccando così l'esecuzione contemporanea degli altri due files di comando e apre una connessione TCP con i server_modn.pl in sequenza. Viene usato il module IO::Socket per stabilire la connessione.

  4. Invia ad ogni server tcp il carattere T e attende la risposta che arriva dopo che il server ha interrogato via seriale il modulo a microcontrollore. Per il modulo 3 invia un datagramma UDP sempre con il carattere T.

  5. I dati di risposta dei vari moduli vengono analizzati togliendo i caratteri di controllo e viene estratta la temperatura in gradi Celsius e scritta nella tabella log del database. Il dato viene anche scritto in un altro database round robin per ottenere l'andamento temporale grafico della temperatura (vedi avanti rrdtool)

  6. Alla fine la connessione di rete viene chiusa e riportato a zero il campo block nel database.


dataout_module_new.cgi
Questo programma è eseguito sul server centrale ed è lanciato alla pressione del pulsante Update nella pagina web di amministrazione manual_new.cgi da cui riceve i parametri da un form contenente diversi checkbox e caselle di testo.


  1. Ogni sezione per default ha attivato il checkbox “Mantieni”. Significa che se viene solo premuto Update vengono mantenuti i controlli precedenti, quindi nessun comando è inviato ai moduli

  2. Tolta la spunta al checkbox Mantieni della sezione interessata, è possibile modificare: l'abilitazione dei moduli, l'abilitazione al controllo remoto via SMS, il Setpoint di temperatura del modulo 1, l'attivazione o meno delle otto uscite digitali del modulo 2 e il riferimento di velocità del modulo 3. Il modulo 4 non è stato attivato per ragioni di tempo

  3. L'interazione con gli altri due programmi avviene con la stessa modalità indicata prima. Solo i comandi cambiati vengono inviati ai rispettivi moduli e riportati nel database mysql.

  4. Vengono aggiornati i led della pagina web e il comando redirect apre nel browser la home page del sito web


rx_tx_gsm.pl
Questo script usa diverse subroutine la prima delle quali Serial_sms_read() utilizzando gli AT command del modem legge l'eventuale presenza di un nuovo messaggio nella memoria del modem gsm.

  1. Se la risposta è negativa lo script termina senza effettuare nessuna operazione

  2. Se c'è un nuovo sms viene letto e salvato nel database mysql. Se la ricezione da sms è bloccata viene cancellato dalla memoria tramite un comando AT il messaggio e lo script termina

  3. Se la ricezione è abilitata comincia il controllo del corpo del messaggio che deve contenere una stringa di password seguita da quattro campi delimitati da punti; ad esempio la stringa: jwqd.1234.3789.210011111. Ha questo significato: jwqd stringa password; 1234 invio 234 al modulo 1; 3789 invio 789 al modulo 3; 210011111 attivazione uscite d7, d4, d3, d2, d1 e d0 del modulo 2. Un altro campo con 4 seguito da un numero di cellulare è stato previsto ma non ancora testato per inviare al numero indicato un sms con le informazioni principali gestite dal sistema.

  4. La stringa inviata deve contenere all'inizio la password, ma l'ordine d'inserimento dei campi successivi è arbitrario; l'unico vincolo è il numero massimo dei campi presi in considerazione (quattro) sempre delimitati dal punto. In caso di campo errato (ad es. contiene caratteri non numerici, non ha la lunghezza corretta) il comando viene scartato.

  5. I nuovi comandi sono memorizzati nel database e vengono inviati solo ai moduli abilitati e con comando diverso da quello attuale; la procedura di interblocco è la stessa già vista.

  6. Alla fine viene inviato un comando di cancellazione sms alla memoria del modem gsm che pertanto al più contiene un solo sms alla volta. Il colloquio con il modem avviene con la porta seriale del server centrale utilizzando il module Perl Device::Serial Port

Linguaggio html e pagine web index.html e manual_new.cgi


Abbiamo dovuto imparare qualche rudimento anche di linguaggio html per poter pubblicare le pagine che riportano lo stato dei moduli controllati e la loro amministrazione. La home page index.html è molto semplice e contiene due immagini, aggiornate ogni cinque minuti dallo script schedulato datain_module.cgi e lo stato delle otto uscite del modulo 2. La generazione delle immagini è effettuata da rrdtool (vedi avanti). Per il poco tempo a disposizione non abbiamo potuto utilizzare tecniche di impaginazioni più moderne (ad es. con fogli di stile) ma ci interessava completare il tutto in tempo utile. La pagina di amministrazione manual_new.cgi è un poco più complessa perché contiene un form per inviare parametri con il metodo GET allo script dataout_module.cgi che crea la pagina in esecuzione.

Immagini dinamiche con rrdtool


Questo applicativo permette di ottenere i diagrammi temporali, sotto forma di immagini .png di una o più grandezze memorizzate in un database round robin, da cui il nome, (sono database che contengono un numero limitato di valori e poi vengono sovrascritti ad es. se scegliamo la scadenza giornaliera e l'intervallo di cinque minuti per ogni campione, in tutto vengono memorizzati 288 valori e poi i successivi man mano sovrascrivono i più vecchi). L'aggiornamento ciclico del database e la creazione delle immagini associate permettono di ottenere l'andamento temporale delle grandezze osservate con la risoluzione desiderata.

Script server TCP


Questi programmi girano continuamente sugli host virtuale e remoto e forniscono la possibilità di comunicazione bidirezionale tra server centrale e moduli periferici. Ne è stato utilizzato uno server_modn.pl partendo da un altro realizzato da allievi della precedente quinta. Come già detto per il modulo 3 la connessione avviene con protocollo UDP.

Classe 5et1 Building Automation


Dispensa Listati Programmi:
Listato C modulo 1:
#include

#include


#include

#include

#include

#include "usart.c"

#include


//#include "putchar.c"

//#include "putch.c"


#define _XTAL_FREQ 4000000

__CONFIG (XT & WDTDIS & PWRTEN & BORDIS & LVPDIS & DUNPROT & WRTEN & DEBUGDIS & UNPROTECT);


//dichiarazioni
unsigned int temperatura = 0b10000000; //riservo cella temperatura (iniziale 128 ASCII)

unsigned int temperatura1; //riservo cella temperatura1 (prima acquis)

unsigned int temperatura2; //riservo cella temperatura2 (seconda acquis)

unsigned int temperatura3; //riservo cella temperatura3 (terza acquis)

unsigned int setpoint = 0; //setpoint iniziale = 0b00000000

unsigned char temp_ascii[6]; //riservo array 3 caratteri

unsigned char new_set; //riservo cella per nuovo setpoint

unsigned char dato_ok = 0x4F; //dato_ok = 0x4F

unsigned char x; //riservo cella x

unsigned char y; //riservo cella y

unsigned char input = 'A'; //riservo cella input

unsigned char dato_rx[3]; //riservo array 3 caratteri

unsigned int errore; //errore = fattore duty cycle

unsigned int duty_cycle; //riservo cella registro regloatore d.c

unsigned int amplif = 100; //riservo cella guadagno per pwm (iniziale 100 ascii)

unsigned int temp_fin; //riservo cella per valora finale conversione temperatura (media 3 conversioni)

unsigned char amplif_arr[6]; //riservo array per ricezione guadagno

//inizializzazione PORT e abilitazione UART


void init (void)

{

TRISA = 0b11111111; //PORTA intput



TRISB = 0b00000000; //PORTB output

TRISC = 0b10000000; //PORTC all output: RC1 (PWM Ventola), RC2 (PWM Resistori), RC7 in

init_comms(); //setup usart definito in usart.h

}
void conf_uart (void)

{

TXSTA = 0b00000110; /*settaggio registro uart ''TRANSMIT STATUS AND CONTROL REGISTER''



bit7->CSRC: Clock Source Select bit (per modalità asincrona non importa) --> 0

bit6->TX9: 9-bit Transmit Enable bit (trasmetto a soli 8 bit) --> 0

bit5->TXEN: Transmit Enable bit (trasmissione momentaneamente spenta) --> 0

bit4->SYNC: USART Mode Select bit (modalità asincrona) --> 0 bit3->Unimplemented (non usato) --> 0

bit2->BRGH: High Baud Rate Select bit (alta velocità) --> 1

bit1->TRMT: Transmit Shift Register Status bit (flag) --> 1

bit0->TX9D: 9th bit of Transmit Data, can be Parity bit (no 9 bit) --> 0

*/

RCSTA = 0X80; /*settaggio registro uart ''RECEIVE STATUS AND CONTROL REGISTER''



bit7->SPEN: Serial Port Enable bit (abilito configurazione porte seriali) --> 1

bit6->RX9: 9-bit Receive Enable bit (lavoro con 8 bit) --> 0

bit5->SREN: Single Receive Enable bit (per asincrono non importa) --> 0

bit4->CREN: Continuous Receive Enable bit (ricezione al momento spenta) --> 0

bit3->ADDEN: Address Detect Enable bit --> 0

bit2->FERR: Framing Error bit --> 0

bit1->OERR: Overrun Error bit --> 0

bit0->RX9D: 9th bit of Received Data (uso 8 bit) --> 0

*/
SPBRG = 0x19; //baud rates for asynchronous mode (boud rate = 9600) 19(esadecimale) 25(decimale)

}
void conversione (void)

{

ADCON0 = 0b01000011; //settaggio convertitore per linea RA0 stato ->on



//bit 7 e 6 -> ADCS1 ADCS0 ,scelta frequenza di conversione (fosc/8)

//bit 5,4,3 -> CHS2:CHS0 ,scelta linea da convertire (RA0)

//bit 2 ->ADG0 , avvia conversione

//bit 1 ->non utilizzato

//bit 0 ->ADCON ,accende il modulo
ADCON1 = 0b01111001; //settaggio convertitore per linea RA0 stato ->on

//bit 7 -> ADFM ,risultato giustificato a sx

//bit 6 ->ADCS2 , scelta frequenza

//bit 5,4 -> non utilizzato

//bit 3,2,1,0 -> PCFG3:PCFG0 ,scelta dinamica dei pin (AN7,6 digitali;AN5:AN0 analogici)
ADGO = 1; //bit 2 di ADCON0 = 1 -> avvia conversione

while (ADGO==1) {}; //attende che ADGO = 0 basso (fine conversione)


temperatura = ADRESH; //valore conversione in temperatura
itoa(temp_ascii, temp_fin, 10); //conversione temperatura in ascii
ADCON0 = 0b01000010; //disabilito ADC

}
void abilitazione_int (void)

{

TXSTA = 0b00000110; /*settaggio registro uart ''TRANSMIT STATUS AND CONTROL REGISTER''



bit7->CSRC:Clock Source Select bit(per modalità asincrona non importa) --> 0

bit6->TX9: 9-bit Transmit Enable bit (trasmetto a soli 8 bit) --> 0

bit5->TXEN: Transmit Enable bit (trasmissione momentaneamente spenta) --> 0

bit4->SYNC: USART Mode Select bit (modalità asincrona) --> 0

bit3->Unimplemented (non usato) --> 0

bit2->BRGH: High Baud Rate Select bit (alta velocità) --> 1

bit1->TRMT: Transmit Shift Register Status bit (flag) --> 1

bit0->TX9D: 9th bit of Transmit Data, can be Parity bit (no 9 bit) --> 0

*/
RCSTA = 0X80; /*settaggio registro uart ''RECEIVE STATUS AND CONTROL REGISTER''

bit7->SPEN: Serial Port Enable bit (abilito configurazione porte seriali) --> 1

bit6->RX9: 9-bit Receive Enable bit (lavoro con 8 bit) --> 0

bit5->SREN: Single Receive Enable bit (per asincrono non importa) --> 0

bit4->CREN: Continuous Receive Enable bit(ricezione al momento spenta) --> 0

bit3->ADDEN: Address Detect Enable bit --> 0

bit2->FERR: Framing Error bit --> 0

bit1->OERR: Overrun Error bit --> 0

bit0->RX9D: 9th bit of Received Data (uso 8 bit) --> 0

SPBRG = 0x19; //baud rates for asynchronous mode (boud rate = 9600) 19(esadecimale) 25(decimale)


TXEN = 1; //abilita tx

CREN = 1; //abilita rx

GIE = 1; //interrupt enable

PEIE = 1; //enable interrupt da periferiche

RCIE = 1; //enable interrupt usart

}

void trasmissione (void)



{

input = getch(); //leggi risposta utente

if (input == 'T')

{

for(x=0;x<=2;x++) //3 cicli for per x=0, x=1, x=2



{

putchar(temp_ascii[x]); //invio temp_ascii

__delay_ms(100);

}

}


else if (input == 'C') //NUOVO SETPOINT

{
CREN = 1; //abilita rx

TXEN = 0; //disabilita tx
for(x=0;x<=2;x++) //3 cicli for per x=0, x=1, x=2

{

dato_rx[x] = getch(); //acquisisco dat rx



new_set = atoi(dato_rx); //converto in binario

setpoint = new_set; //setto new setpoint

}
CREN = 0; //disabilita rx

TXEN = 1; //abilita tx

for(x=0;x<=2;x++) //3 cicli for per x=0, x=1, x=2

{

putchar(dato_rx[x]); //echo dato rx



__delay_ms(100);

}

}


else if (input == 'E') //rx valore guadagno (da eliminare quando finito)

{

CREN = 1; //abilita rx



TXEN = 0; //disabilita tx
for(x=0;x<=2;x++) //3 cicli for per x=0, x=1, x=2

{

amplif_arr[x] = getch(); //acquisisco dat rx



amplif = atoi(amplif_arr); //converto in binario

}
CREN = 0; //disabilita rx

TXEN = 1; //abilita tx

for(x=0;x<=2;x++) //3 cicli for per x=0, x=1, x=2

{

putchar(amplif_arr[x]); //echo dato rx



__delay_ms(100);

}

}


else

{

}



}
void pwm (void)

{

errore = abs( setpoint - temp_fin ); //errore --> differenza tra temperatura acquisita (temp_fin) e quella prefissata (setpoint)



duty_cycle = errore * amplif;

duty_cycle = duty_cycle/256;


if (setpoint < temp_fin) //ventola on, rpower off

{


// configurazione Timer2 e CCP2 per PWM su RC1

CCP1CON = 0;

PR2 = 0xBB; // periodo pwm

CCPR2L = duty_cycle; // duty cycle

CCP2X = 0; CCP2Y = 0;

TOUTPS3 = 0; TOUTPS2 = 0; TOUTPS1= 0; TOUTPS0 = 0; // postscaler 1:1

T2CKPS1 = 1; T2CKPS0 = 1; // prescaler 1:16

TMR2IE = 0;

TMR2ON = 1; // abilitazione timer2

CCP2M3 = 1; CCP2M2 = 1; // ccp2 in modo pwm

}
else //ventola off, rpower on

{

// configurazione Timer2 e CCP1 per PWM su RC2



CCP2CON = 0;

PR2 = 0xBB; // periodo pwm

CCPR1L = duty_cycle; // duty cycle

CCP1X = 0; CCP1Y = 0;

TOUTPS3 = 0; TOUTPS2 = 0; TOUTPS1= 0; TOUTPS0 = 0; // postscaler 1:1

T2CKPS1 = 1; T2CKPS0 = 1; // prescaler 1:16

TMR2IE = 0;

TMR2ON = 1; // abilitazione timer2

CCP1M3 = 1; CCP1M2 = 1; // ccp2 in modo pwm

}

}


void main (void)

{

init(); //definizioni e variabili



conf_uart(); //abilitazione rx

pwm();


__delay_ms(1000); //controllo della ventola o rpower

CCP1CON = 0; //disabilita pwm 1

CCP2CON = 0; //disabilita pwm 2

conversione(); //1^a conversione

temperatura1=temperatura; //1° valore

conversione(); //2^a lettura

temperatura2=temperatura; //2° valore

conversione(); //3^a conversione

temperatura3=temperatura; //3° valore

temp_fin = (temperatura1 + temperatura2 + temperatura3)/3;


//media (media fatta per evitare eventuali errori nella conversioni dovuti a disturbi istantanei)

abilitazione_int(); //spezzo sequenza per non perdere eventuali interrupt

RCIF = 0; //disabilitazione interrupt

__delay_ms(100); //controllo della ventola o rpower

pwm(); //controllo della ventola o rpower

CREN = 1; //riabilito rx


while(1)

{

pwm();



__delay_ms(1000); //controllo della ventola o rpower

CCP1CON = 0; //disabilita pwm 1

CCP2CON = 0; //disabilita pwm 2

conversione(); //1^a conversione

temperatura1=temperatura; //1° valore

conversione(); //2^a lettura

temperatura2=temperatura; //2° valore

conversione(); //3^a conversione

temperatura3=temperatura; //3° valore

temp_fin = (temperatura1 + temperatura2 + temperatura3)/3;

//media (media fatta per evitare eventuali errori nella conversioni dovuti a disturbi istantanei)

conf_uart(); //abilitazione rx

__delay_ms(100); //controllo della ventola o rpower

pwm(); //controllo della ventola o rpower

abilitazione_int(); //abilitazione interrupt

__delay_ms(50); //ritardo 50 ms

RCIF = 0; //disabilitazione interrupt

}

}


static void interrupt isr (void)

{

if (RCIF) //quando arriva interrupt eseguo tx



{

trasmissione(); //avvia trasmissione

}

RCIF = 0; //disabilito bit interrupt



}
Listato assembly modulo 2:

RADIX DEC

INCLUDE "p16f876.INC"

ERRORLEVEL -302

__CONFIG 3F71H

ORG 0x20


;-------------------------------------------------------------------------------------
ds1820 RES 1

errore RES 1

d1 RES 1

d2 RES 1


d3 RES 1

KEY RES 1

temp1 RES 1 ;temperatura msb

temp2 RES 1 ;temperatura lsb

CL RES 1

huns RES 1

tens RES 1

ones RES 1

temp_h RES 3

temp_l RES 3

TEMP RES 1

count RES 1

control RES 1

cen RES 1

dec RES 1

uni RES 1

binario RES 1

;--------------------------------------------------------------------------------------

;Uso delle porte I/O

;PORTA: RA4 - RA3 out-input da 18b20

;PORTB: uscite verso il campo

;PORTC: RC0 - errore sonda led rosso on pin 11; RC6 TX UART pin 17; RC7 RX UART pin 18


ORG H'00'

start bsf STATUS,RP0

bcf STATUS,RP1

movlw H'06' ; Configure all pins digital

movwf ADCON1

movlw b'001101111' ;RA4 output, RA3 input

movwf TRISA

movlw H'0'

movwf TRISB ;portb all output

MOVLW B'10000100' ;imposta RC7 RX e RC2 come input gli altri tutti out

MOVWF TRISC

MOVLW H'67' ;carica il fattore di baud rate per 2400bit/s

MOVWF SPBRG

BSF TXSTA,BRGH ;alta velocità di trasmissione

BCF TXSTA,SYNC ;modalità asincrona

BCF TXSTA,TX9 ;disabilità nono bit

BCF TXSTA,TXEN ;disabilita trasmissione

BCF STATUS,RP0 ;banco 0

BSF RCSTA,SPEN ;abilita USART

MOVLW B'10101010'

MOVWF PORTB ;

;main program

inizio call RX_dato ;attendi l'invio di un carattere di controllo

movwf control

movlw H'54'

XORWF control,0

BTFSS STATUS,Z ;è arrivato T?

goto riprova

goto arrivatoT

riprova movlw H'43'

XORWF control,0 ;è arrivato C?

BTFSC STATUS,Z

goto dato ;si attendi dato da host

goto inizio ;carattere errato, aspetta ancora

arrivatoT call sub_temp ;acquisisci e invia la temperatura a host

goto inizio

dato call RX_dato

movwf cen

call RX_dato

movwf dec

call RX_dato

movwf uni

call dec_binario

movwf PORTB ;aggiorna le uscite su portb

call ok_dato ;invia conferma ricezione dato ad host

goto inizio

;subroutine di dialogo con 18b20, conversione dei due byte ricevuti in ascii e invio ad host

sub_temp

call leggi_sensore

movf temp1,0 ;in w temp high

call BIN_ASCII ;converti in ascii

movf huns,0

;MOVLW D'80'

movwf temp_h

movf tens,0

;MOVLW D'82'

movwf temp_h+1 ;in temp_h valore ascii byte alto

movf ones,0

;MOVLW D'84'

movwf temp_h+2

movf temp2,0

call BIN_ASCII ;converti in ascii

movf huns,0

movwf temp_l

movf tens,0

movwf temp_l+1 ;in temp_l valore ascii byte basso

movf ones,0

movwf temp_l+2

call invio_temp

return
;subroutine conferma dato

ok_dato movlw H'42' ;invio del carattere di conferma B (OK)

call TX


return

;subroutine invio temperatura


invio_temp movlw H'4F' ;invio del carattere di conferma O (OK)

call TX


movf temp_h,0

call TX


movf temp_h+1,0

call TX


movf temp_h+2,0

call TX


movf temp_l,0

call TX


movf temp_l+1,0

call TX


movf temp_l+2,0

call TX


return

;subroutine lettura 18b20

leggi_sensore

call inizializza_ds1820 ; inizializzazione e riconoscimento del DS1820

call delay_600us

movlw H'CC'

movwf ds1820

call scrivi_ds1820 ; salta la ROM

call delay_600us

movlw H'44'

movwf ds1820

call scrivi_ds1820 ; comando 0x44: converti temperatura

call delay_1s ;tempo necessario per la conversione 750ms -> attesa 1s

call inizializza_ds1820

call delay_600us

movlw H'CC'

movwf ds1820

call scrivi_ds1820 ; salta la ROM

movlw H'BE'

movwf ds1820

call scrivi_ds1820 ; comando 0xBE: leggi la Scratchpad

call leggi_ds1820

movf ds1820,0

movwf temp2 ; Temperatura LSB

call leggi_ds1820

movf ds1820,0

movwf temp1 ; Temperatura MSB

return
inizializza_ds1820

bcf PORTA,4 ;usa RA4 (pin 6)

call delay_600us ; 600 us se e' zero -> resetta

bsf PORTA,4

call delay_80us ; Aspetta 80 us

bcf errore,0

btfsc PORTA,3

bsf errore,0 ;La sonda non ha risposto -> errore

return
scrivi_ds1820

movlw H'08'

movwf KEY


scrivi_ds1820_loop

rrf ds1820,1 ; sposta verso destra

nop

btfss STATUS, C



goto $+3

call scrivi_uno

goto $+2

call scrivi_zero

decfsz KEY,1

goto scrivi_ds1820_loop ; continua fino a che sono stati inviati 8 bit nviati 8 bit

return

scrivi_uno



bcf PORTA,4

call delay_7us ; Aspetta 7 us

bsf PORTA,4

call delay_80us ; Aspetta 80 us

return

scrivi_zero



bcf PORTA,4

call delay_80us ; Aspetta 80 us

bsf PORTA,4

return


leggi_ds1820

clrf ds1820

bcf STATUS, C

movlw H'08'

movwf KEY

leggi_ds1820_loop

bcf PORTA,4 ; basso -> 0

nop


nop

bsf PORTA,4 ; se e' alto non sara'_ trasmesso

nop

nop


nop

nop


nop

nop


nop

nop


bsf STATUS,C

btfss PORTA,3 ; campionamento del bus

bcf STATUS,C

rrf ds1820,1 ; sposta verso destra

call delay_80us ; Aspetta 80 us

decfsz KEY,1

goto leggi_ds1820_loop ; Aspetta fino a che sono stati inviati 8 bit

return
;--------routines di ritardo per il dialogo con DS18B20------------------

delay_600us movlw H'C6' ; Aspetta 600 us

movwf d1


delay_600us_loop

decfsz d1,1

goto delay_600us_loop

nop


return
delay_50us movlw H'0F' ; Aspetta 50 us

movwf d1


delay_50us_loop

decfsz d1,1

goto delay_50us_loop

return
delay_30us movlw 30 ; Aspetta 30 us

movwf d1

delay_30us_loop

decfsz d1,1

goto delay_30us_loop

return
delay_15ms movlw 182 ; Aspetta 15 ms

movwf d1


movlw 12

movwf d2


delay_15ms_loop

decfsz d1,1

goto $+2

decfsz d2,1

goto delay_15ms_loop

goto $+1


nop

return
delay_7us goto $+1 ; Aspetta 7 us

nop

nop


return
delay_80us movlw H'19' ; Aspetta 80 us

movwf d1


delay_80us_loop

decfsz d1,1

goto delay_80us_loop

return
delay_1s movlw 0x07 ; Aspetta 1 s

movwf d1

movlw 0x2F

movwf d2

movlw 0x03

movwf d3

delay_1s_loop decfsz d1, f

goto $+2

decfsz d2, f

goto $+2

decfsz d3, f

goto delay_1s_loop

goto $+1


goto $+1

goto $+1


return

;Subroutine ricezione dato

RX_dato BCF STATUS,RP0 ; SELEZ. BANCO 0

BSF RCSTA,SPEN ; ABILITA PORTA SERIALE (RC7=RX E RC6=TX)

BSF RCSTA,CREN ; ABILITA LA RICEZIONE DATI

TEST_dato BTFSS PIR1,RCIF ; TESTO SE IL DATO è STATO RICEVUTO

GOTO TEST_dato

MOVF RCREG,0 ; SPOSTA IL DATO RICEVUTO IN W

BCF RCSTA,CREN ; DISABILITA LA RICEZIONE DATI

RETURN
;Subroutine invio carattere

TX BSF STATUS,RP0 ;SELEZ. BANCO 1

BSF TXSTA,TXEN ;INIZIA LA TRASMISSIONE SERIALE SUL PIN RC6

BCF STATUS,RP0 ;SELEZ. BANCO 0

MOVWF TXREG ;SPOSTA IN TXREG IL DATO DA INVIARE AL PC

BSF STATUS,RP0 ;SELEZ. BANCO 1

GIRO3 BTFSS TXSTA,TRMT ;CONTROLLO SE IL DATO è STATO TRASMESSO

GOTO GIRO3 ;SE IL BIT TRMT è 1 SVOLGE LA CONVERSIONE

BCF TXSTA,TXEN

BCF STATUS,RP0 ;SELEZ. BANCO 0

CALL MS1


RETURN
;subroutine ritardo 1 ms

MS1 MOVLW 142

MOVWF CL

MSR1 GOTO $+1

GOTO $+1

DECFSZ CL,F

GOTO MSR1

NOP


RETURN
;subroutine conversione binario->ascii------------------------------------------------
BIN_ASCII

bcf STATUS,RP0 ;bank 0

movwf TEMP

movlw 8


movwf count

clrf huns

clrf tens

clrf ones


BCDADD3
movlw 5

subwf huns, 0

btfsc STATUS, C

CALL ADD3HUNS


movlw 5

subwf tens, 0

btfsc STATUS, C

CALL ADD3TENS


movlw 5

subwf ones, 0

btfsc STATUS, C

CALL ADD3ONES


decf count, 1

bcf STATUS, C

rlf TEMP, 1

rlf ones, 1

btfsc ones,4 ;

CALL CARRYONES

rlf tens, 1
btfsc tens,4 ;

CALL CARRYTENS

rlf huns,1

bcf STATUS, C


movf count, 0

btfss STATUS, Z

GOTO BCDADD3

movf huns, 0 ; add ASCII Offset

addlw h'30'

movwf huns


movf tens, 0 ; add ASCII Offset

addlw h'30'

movwf tens
movf ones, 0 ; add ASCII Offset

addlw h'30'

movwf ones

RETURN
ADD3HUNS


movlw 3

addwf huns,1

RETURN
ADD3TENS
movlw 3

addwf tens,1

RETURN
ADD3ONES
movlw 3

addwf ones,1

RETURN
CARRYONES

bcf ones, 4

bsf STATUS, C

RETURN
CARRYTENS

bcf tens, 4

bsf STATUS, C

RETURN
; subroutine di conversione decimale - binario

dec_binario

movlw h'0'

movwf binario

movlw h'30'

subwf cen,1

subwf dec,1

subwf uni,1

movf cen,0

btfss STATUS,Z ;cen è 0?

goto ce1

movwf binario

goto de0

ce1 movlw h'1'

subwf cen,1

btfss STATUS,Z ;cen è 1?

goto ce2

movlw d'100'

movwf binario

goto de0


ce2 movlw d'200' ;cen è 2

movwf binario

de0 movf dec,0

btfss STATUS,Z ;dec è 0?

goto de1

goto un0


de1 movlw h'1'

subwf dec,1

btfss STATUS,Z ;dec è 1?

goto de2

movlw d'10'

addwf binario,1

goto un0

de2 movlw h'1'

subwf dec,1

btfss STATUS,Z ;dec è 2?

goto de3

movlw d'20'

addwf binario,1

goto un0


de3 movlw h'1'

subwf dec,1

btfss STATUS,Z ;dec è 3?

goto de4

movlw d'30'

addwf binario,1

goto un0

de4 movlw h'1'

subwf dec,1

btfss STATUS,Z ;dec è 4?

goto de5

movlw d'40'

addwf binario,1

goto un0

de5 movlw h'1'

subwf dec,1

btfss STATUS,Z ;dec è 5?

goto de6

movlw d'50'

addwf binario,1

goto un0

de6 movlw h'1'

subwf dec,1

btfss STATUS,Z ;dec è 6?

goto de7

movlw d'60'

addwf binario,1

goto un0

de7 movlw h'1'

subwf dec,1

btfss STATUS,Z ;dec è 7?

goto de8

movlw d'70'

addwf binario,1

goto un0

de8 movlw h'1'

subwf dec,1

btfss STATUS,Z ;dec è 8?

goto de9

movlw d'80'

addwf binario,1

goto un0

de9 movlw d'90'

addwf binario,1

un0 movf uni,0

addwf binario

movf binario,0

return


END






©astratto.info 2017
invia messaggio

    Pagina principale