Analizziamo il sorgente del programma:
Nel costruttore della Form1 vengono istanziati ed inizializzati gli oggetti principali; in particolare viene configurata la chartArea dell’oggetto chart1, modificando le proprietà degli assi (intervalli, valori minimo/massimo, colori).
L’asse X viene configurato per visualizzare un orizzonte temporale di 300 secondi (costante CHART_SECONDS):
void setup() { Serial.begin(9600); randomSeed(analogRead(0)); } void loop() { int randomValue = random(0, 1023); Serial.println(randomValue, DEC); delay(5000); } |
Sempre nel costruttore viene creata la serie dati che conterrà i dati ricevuti e vengono impostati alcuni parametri (nome, tipo di grafico, spessore e colore della linea, tipo di dati per l’asse X):
mySerie = new Series("AnalogInput"); mySerie.ChartType = SeriesChartType.FastLine; mySerie.BorderWidth = 1; mySerie.Color = Color.Red; mySerie.XValueType = ChartValueType.DateTime; chart1.Series.Add(mySerie); |
Nei metodi legati agli eventi di load della form e di click del pulsante Connect viene gestita la comunicazione con la porta seriale, in maniera simile a quanto già visto nei tutorials presenti in questo sito:
- elenco delle porte seriali disponibili e loro aggiunta ad una combobox
- creazione di un oggetto SerialPort e apertura della connessione (9600 baud 8N1)
- aggiunta di un handler per l’evento DataReceived
Il metodo serialPort_DataReceived, handler di DataReceived, chiama – tramite metodo delegate – AddData() che si occupa effettivamente di aggiornare grafico e datastream.
Tale metodo riceve il dato dalla porta seriale e lo aggiunge al grafico, impostando come valore sull’asse X il timestamp attuale:
DateTime timeStamp = DateTime.Now; string stringValue = serialPort.ReadLine(); chart1.Series[0].Points.AddXY(timeStamp, Double.Parse(stringValue)); |
Quindi calcola il primo dato da visualizzare, togliendo dal timestamp attuale 300 secondi e rimuove i dati più vecchi di tale timestamp. Infine sposta l’asse X in modo da centrarlo sui dati rimasti (impostando come origine il primo di essi) e invalida il grafico in modo che venga ridisegnato:
double removeBefore = timeStamp.AddSeconds(-CHART_SECONDS).ToOADate(); while (mySerie.Points[0].XValue < removeBefore) { mySerie.Points.RemoveAt(0); } chart1.ChartAreas[0].AxisX.Minimum = mySerie.Points[0].XValue; chart1.ChartAreas[0].AxisX.Maximum = DateTime.FromOADate(mySerie.Points[0].XValue).AddSeconds(CHART_SECONDS).ToOADate(); chart1.Invalidate(); |
Se è richiesto l’aggiornamento di Pachube, verifica che tutte le informazioni siano corrette e utilizza l’oggetto WebClient per chiamare con il metodo PUT l’indirizzo di aggiornamento del datastream:
string updatePath = "http://api.pachube.com/v2/feeds/" + tbFeedId.Text + "/datastreams/" + tbDatastreamId.Text + ".csv"; |
inserendo negli headers della chiamata HTTP la API Key specificata e gestendo eventuali errori di connessione:
webClient.Headers.Set("X-PachubeApiKey", tbAPIKey.Text); try { webClient.UploadString(updatePath, "PUT", stringValue); } |
Per semplicità ho deciso di utilizzare la modalità di aggiornamento in formato csv come indicato nella documentazione.
Nel concludere, vi ricordo che tutto il materiale (programma già compilato e sorgenti) è disponibile nel mio repository su GitHub e che nel forum di questo sito sono disponibile per domande/richieste.
Ciao Luca, progettino interessante, ho trovato in giro questa utility per Excel, solo fino al 2003, per rappresentazione grafica di dati da seriale.
http://www.parallax.com/ProductInfo/Microcontrollers/PLXDAQDataAcquisitiontool/tabid/393/Default.aspx
molto interessante se non l’hai già vista.
Ci si vede
Ciao