Questo tutorial, diviso in due parti, servirà a realizzare un piccolo e semplice modulo ultra-low cost per il data logging ambientale.
In particolare andremo a campionare temperatura e quantità di luce, scrivendo i dati in un log file memorizzato su SD-Card.
Verrà utilizzata la piattaforma open hardware e software “Arduino”.
Info: arduino.cc
Hardware:
Per iniziare, avremo bisogno di una scheda Arduino Uno o Duemilanove (ma anche Mega, 2560, mini, nano etc etc).
Info: http://arduino.cc/it/main/boards
(Costo: ~25€ – Aiutiamo il progetto acquistando board 100% Made in Italy!)
Questa piccola schedina, è un piccolo computer in miniatura, dove già c’è tutto il necessario per programmarla senza troppi fronzoli software o hardware (come programmatori costosi).
Avremo bisogno, inoltre di qualche sensore:
Nel nostro caso andremo ad utilizzare un LM35 (questo potete comprarlo anche dai cinesi, costo: 1.50€) ed un LDR (light dependet resistor, costo0.30€)
L’LM35 si presenta in un package simil transistor (TO-92) a tre pin.
Il pinout (piedinatura), da sinistra verso destra con la parte piatta rivolta verso l’osservatore è: +5V, output, GND.
L’LDR è a tutti gli effetti un resistore variabile (tipo potenziometro), la sua resistenza cambia con la quantità di luce che si riflette su di esso.
Non ha polarità, può essere innestato a piacimento: la tensione entra da un capo ed esce alterata dall’altra. Da accoppiare con una resistenza da 500 Ohm (costo: gratis)
Per comodità ho usato un modulo (shield) aggiuntivo all’arduino che mi permette di avere:
1. Un RTC DS1307 (Real Time Clock), mantiene il tempo meglio del vostro orologio.
2. Un card reader, i nostri output li andremo a scrivere su file.
3. Led, non avendo monitor i led saranno le nostre spie.
4. Fori per saldare i sensori o per usare una breadboard
La shield vien venduta in kit di montaggio, significa che dovremo metter mano al saldatore (che male non fa).
Sul sito del produttore vi è un ampio tutorial fotografico su come assemblarla:
http://www.ladyada.net/make/logshield/solder.html
(opzionale, costo: 19.50$ http://www.ladyada.net/make/logshield/)
Wiring:
Entrambi i sensori lavorano su una tensione di 5v, l’output di ognuno ha una tensione di uscita linearmente proporzionale alla temperatura o alla quantità di luce percepita.
Arduino (il programmatore) ha il compito di leggere la tensione sui pin analogici, campionarla e renderla disponibile.
Per approfondimenti circa dettagli di funzionamento e parametri costruttivi dei sensori:
https://www.national.com/ds/LM/LM35.pdf
http://www.biltek.tubitak.gov.tr/gelisim/elektronik/dosyalar/40/LDR_NSL19_M51.pdf
Il wiring può esser fatto utilizzando una semplice breadboard oppure una millefori.
Il risultato finale deve essere più o meno così
Premesse:
Arduino, non è solo hardware ma anche: software, documentazione e community.
Sul sito ufficiale (arduino.cc) è possibile scaricare l’IDE che permette di programmare la propria Arduino via USB.
Il linguaggio di programmazione è (simil) C.
All’interno dell’ide, vi sono molti codici di prova già funzionanti, essa include gran parte delle librerie di cui avremo bisogno.
Altre sono presenti nei siti dei corrispettivi produttori hardware o dai siti personali di utenti che hanno condiviso le proprie.
Installare librerie di terze parti è molto semplice (un paio di copy&paste): google ci aiuterà non poco.
Nel nostro caso andremo ad utilizzare le librerie RTC ed SD suggerite sulla pagina di adafruit relative alla logger shield utilizzata: http://www.ladyada.net/make/logshield/download.html
E’ importante documentarsi sempre e approfonditamente sull’hardware su cui andremo a lavorare.
Datasheet, reference, librerie, documentazione varia e google vanno sempre consultati quando abbiamo hardware tra le mani.
Scrivere sulla riga di ricerca di Google: “PAROLA arduino”, risolverà gran parte dei nostri problemi.
Cercare: “lm35 arduino” o “ldr arduino” sia su google testo che immagini ci darà tantissima documentazione… per non parlare poi del forum ufficiale.
Se prendiamo in considerazione Arduino Uno/Duemilanove con controller Atmega328, avremo 32kb di memoria flash per il codice (parte statica) e 2kb per i dati (parte dinamica).
Seppur il compilatore (avr-gcc) ottimizza il codice, dobbiamo cercare di minimizzare al massimo l’uso della memoria.
Esempio: se dobbiamo contare da 1 a 50 usiamo uno short invece di un int, usiamo piccole matrici, facciamo tanto swapping su memorie esterne, dimentichiamo l’allocazione dinamica (esiste ma…).
Con l’esperienza capiremo che i codici scritti per arduino sono davvero molto leggeri: per muovere un braccio meccanico useremo al più 20righe di codice e un paio di variabili.
Il costo computazionale è tipicamente molto basso… sarebbe da pazzi pensare di usare un microcontroller a 16mhz per calcoli metereologici!
Il corpo dei codici da caricare (flashing) in Arduino è sempre formato da almeno due void function: setup e loop.
Setup: serve solo ad inizializzare alcuni valori, come ad esempio la modalità di funzione di alcuni pin, inizializzazione della seriale etc
Entra in esecuzione una sola volta: all’inizio, appena diamo alimentazione.
Loop: è un loop. Un ciclo infinito, il cuore del nostro codice.
La lettura analogica dell’lm35 verrà fatta sul pin 0 (zero) della nostra Arduino.
Senza troppo addentrarci in tecnicismi, diremo banalmente che la tensione di uscita del nostro transistor è la temperatura captata in quell’istante.
Info: http://www.ladyada.net/learn/sensors/tmp36.html
L’lm35 misura temperature in Celsius su un range di -55° +150° con un accuratezza di 0.5°.
Gli input analogici di arduino hanno una risoluzione di 10bit, ciò significa che avremo 2^10=1024 valori discreti.
Ci sono molte tecniche (hardware e software) per leggere la temperatura in modo accurato, ma il modo più semplice è convertire la tensione di uscita in gradi Celsius con questa formula:
temperaturaCelsius = (5.0 * sensor * 100.0)/1024.0;
(Tensione di alimentazione del lm35 * tensione in output dall’lm35 * offset 100) / su 1024 valori
Obiettivo finale:
L’idea è quella di realizzare un log file di testo con questa struttura:
LUCE – TEMPERATURA – ORARIO
• La campionatura, viene fatta ogni 3 secondi.
• Le letture dell’ldr e dell’lm35 vengono mediate su 20letture consecutive (senza delay).
• Stampa su porta seriale ad ogni scrittura per debugging.
Tentativo_1:
In questa primo sketch (sketch=programma=codice=algoritmo), leggeremo la temperatura dall’lm35 e andremo a scrivere sulla sd temperatura e orario.
L’orario verrà di volta in volta *chiesto* al nostro RTC.
#include <SD.h> #include <Wire.h> #include "RTClib.h" RTC_DS1307 RTC; const int chipSelect = 10; short i=0; void setup() { //seriale aperta a 9600 baud Serial.begin(9600); Serial.println("Initializing SD card..."); //inizializziamo i pin 3 e 4 per i led rosso-verde //pin 10 riservato al card reader pinMode(10, OUTPUT); pinMode(3, OUTPUT); pinMode(4, OUTPUT); //se il modulo sd non viene correttamente inizializzato if (!SD.begin(chipSelect)) { //messaggio di errore sul nostro monitor seriale Serial.println("Card failed, or not present"); for (i=0;i<10;i++) { //blinking del led rosso digitalWrite(3, HIGH); delay(100); digitalWrite(3, LOW); delay(100); } return; } //se correttamente inizializzata... Serial.println("card initialized."); //blinking led verde digitalWrite(4, HIGH); delay(500); digitalWrite(4, LOW); //inizializziamo l'RTC Wire.begin(); RTC.begin(); if (! RTC.isrunning()) { Serial.println("RTC is NOT running!"); RTC.adjust(DateTime(__DATE__, __TIME__)); } } void loop() { //chiediamo il tempo all'RTC DateTime now = RTC.now(); int analogPin=0; int sensor =0; //aspettiamo 3secondi delay(2900); //leggiamo e convertiamo la temperatura dal pin 0 di arduino sensor = analogRead(analogPin); sensor = (5.0 * sensor * 100.0)/1024.0; //stampa sulla seriale Serial.print("Temperatura: "); Serial.println(sensor); //apriamo in scrittura il file sulla sd File dataFile = SD.open("datalog.txt", FILE_WRITE); //Scriviamo: TEMPERATURA - ORA:MINUTI:SECONDI if (dataFile) { dataFile.print(sensor); dataFile.print(" - "); dataFile.print(now.hour(), DEC); dataFile.print(":"); dataFile.print(now.minute(), DEC); dataFile.print(":"); dataFile.println(now.second(), DEC); //chiudiamo il file dataFile.close(); //blinking led verde digitalWrite(4, HIGH); delay(100); digitalWrite(4, LOW); } else { //errore nell'apertura del file o card rimossa Serial.println("error opening datalog.txt"); for (i=0;i<10;i++) { //blinkig led rosso digitalWrite(3, HIGH); delay(100); digitalWrite(3, LOW); delay(100); } } }
Dopo il caricamento, apriamo il nostro monitor seriale (all’interno dell’ide c’è il proprio monitor seriale, ma possiamo utilizzare anche putty) a 9600baud sulla stessa porta USB su cui è attaccato il nostro arduino e avremo un output più o meno di questo tipo:
26 - 21:15:36
25 - 21:17:15
25 - 21:17:19
25 - 21:17:22
Ogni volta verrà scritto un nuovo record nel nostro file che può essere elaborato in qualsiasi modo.
In questo caso ho importato i dati su un foglio Excel:
Nel prossimo articolo uniremo alla temperatura anche la quantità di luce…
[Articolo comparso anche su: http://students.uniparthenope.it/]
Interessante poichè vorrei realizzare un data loggin per la registrazione di correnti elettriche in un sistema trifase.
Buona giornata.
P.S.
Qualcuno ha il mio stesso problema ?