martedì 10 gennaio 2012

Parametri in MODBUS

Un giorno mi serviva inviare ad un dispositivo bluetooth delle stringhe in Modbus ASCII  Allora mi sono messo a scrivere un'interfaccia grafica che mi facilitasse il compito...
Il dispositivo che avevo costruito era un "semplice" termometro sonda con molte funzioni. Si interfacciava con alcune (mi sembra 4) termometri e con diversi relè che permettevano di controllare il sistema di riscaldamento/raffreddamento di qualsiasi cosa. A questo dispositivo avevo connesso un'interfaccia seriale Bluetooth. Tramite questa porta seriale era possibile configurare ed utilizzare questo dispositivo. Ad esempio inviando una certa stringa nella porta COM esatta era possibile ricevere come risposta la temperatura della prima sonda. Era anche possibile configurare il comportamento nel caso in cui la temperatura superasse certe soglie ad esempio accendendo una ventola.
Non tratterò la codifica dei messaggi perché è per voi totalmente inutile dato che codifica dei dati in input (decimali) e li formatta in esadecimale e calcola i relativi checksum per inviare al dispositivo una stringa corretta.
Più interessante è invece il sistema di invio/ricezione tramite una porta COM seriale. In questo caso si tratta di una Bluetooth ma il funzionamento è assolutamente identico ad una porta cablata (dato che il dispositivo bluetooth crea una connessione seriale standard).
Il primo passo necessario per fare tutto ciò è creare un oggetto di tipo SerialPort. Questa classe gestisce la comunicazione attraverso una porta seriale e tutte le funzioni che ne derivano.
Appena si ha creato una porta seriale è necessario configurare le impostazioni di base. Tali impostazioni sono :
- PortName (la porta COM)
- BaudRate (la velocità della porta in baud)
- DataBits (la lunghezza standard di bit in ogni byte di dati)
- StopBits (il numero di bit di stop per ogni byte)
- Parity (il protocollo di controllo della parità)
- ReadTimeout (il timeout in lettura)
- WriteTimeout (il timeout in scrittura)

Bene ora che la nostra porta è configurata bisogna aprirla. Basta chiamare
portaSeriale.Open(); 
Ok, la connessione è stata aperta, ora è possibile leggere e scrivere attraverso questa porta.
Per scrivere del testo basta eseguire un
 portaSeriale.Write(text);
text è la stringa di caratteri ASCII da inviare. E' bene ricordare che nella maggior parte dei casi per funzionare text deve terminare con CRLF (Carriage Return e Line Feed). Per inserire questi codici basta modificare text così:
text + "\r\n"

Il sistema di lettura è anch'esso molto semplice. Chiamando la funzione
msgTextRx = portaSeriale.ReadExisting();
Si assegna a msgTextRx il contenuto del buffer di lettura della porta seriale.
Basta per quanto riguarda l'apparato di invio/ricezione seriale è tutto.


Tutto ciò però è abbastanza scomodo da usare: bisognerebbe premere ogni volta "Calcola e invia" per leggere la temperatura. Allora ho pensato di aggiungere una funzione molto interessante: Esegue un loop e ogni n secondi esegue la lettura della temperatura e la scrive in un file Excel (o un altro formato). Il vantaggio di questo metodo è quello di avere un file Excel con i valori delle temperature, diventa quindi semplicissimo creare un grafico che rappresenta l'andamento termico delle sonde.
Per creare, modificare e salvare un file in formato Excel mi sono appoggiato alla libreria GemBoxSpreadsheet. Tramite questa libreria si può accedere ad una tabella tramite le coordinate delle celle, rendendo la modifica dei valori una vera sciocchezza. Il primo passo da compiere è dichiarare un'oggetto di tipo ExcelFile, il quale conterrà il nostro file. Poi bisogna creare un foglio di lavoro per farlo bisogna chiamare:
excelFile.Worksheets.Add("Data");
Verrà quindi creato un foglio di nome "Data". In questo foglio ho aggiunto la prima linea che contiene le intestazioni delle colonne:
excelFile.Worksheets.ActiveWorksheet.Cells["A1"].Value = "Ora";
excelFile.Worksheets.ActiveWorksheet.Cells["B1"].Value = "Indirizzo";
excelFile.Worksheets.ActiveWorksheet.Cells["C1"].Value = "Funzione";
excelFile.Worksheets.ActiveWorksheet.Cells["D1"].Value = "Valore";
excelFile.Worksheets.ActiveWorksheet.Cells["E1"].Value = "Data";
Sulle celle identificate da A1, B1, C1... sono stati scritti i valori corrispondenti. In ogni riga sotto verranno inserite le informazioni relative ai dati letti:
excelFile.Worksheets.ActiveWorksheet.Cells["A" + i.ToString()].Value = ora;
excelFile.Worksheets.ActiveWorksheet.Cells["B" + i.ToString()].Value = indirizzo;
excelFile.Worksheets.ActiveWorksheet.Cells["C" + i.ToString()].Value = funzione;
excelFile.Worksheets.ActiveWorksheet.Cells["D" + i.ToString()].Value = valore;
excelFile.Worksheets.ActiveWorksheet.Cells["E" + i.ToString()].Value = data;
Incrementando i  si andrà a scrivere una riga sotto.
Non resta altro che salvare il file. I formati supportati sono Csv, Html, Ods, Xls, Xlsx. Per salvare in un file Excel 2010 (o 2007) basta chiamare:
excelFile.SaveXlsx("file.xlsx");
Tutto qua, questa libreria è davvero utile e semplice da usare. Nel mio programma la ho usata per salvare il file in tutti i formati supportati, basta scegliere dal menu opzioni quello desiderato. Le opzioni vengono salvate in un file ini. Per leggere e scrivere in questo file mi sono basto sulla libreria kernel32 di windows. Il file di impostazioni è salvato in "D:/settings.ini".

DOWNLOAD:
Dropbox - Google Drive
SCREEN:

Nessun commento:

Posta un commento