Archivio mensile:giugno 2012

Tutorial: data logging con Arduino – Parte 1

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!)

ArduinoUno_R3_Front

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)

LDR1

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

4589675367_2192d37442

(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.

wiringok

Il risultato finale deve essere più o meno così

dscn6890
Coding:

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:

capturesg

Nel prossimo articolo uniremo alla temperatura anche la quantità di luce…

[Articolo comparso anche su: http://students.uniparthenope.it/]

Indicatore livello GPL a valori continui

Ciao a tutti i miei fans (4 gatti)!

Oggi vorrei proporvi una mod per le vostre vetture molto cool: un indicatore del livello del GPL a valori continui.

Cosa significa?
Scommetto che molti di voi, per colpa di questa crisi, hanno acquistato un auto a gpl/metano o hanno installato un impianto sulle vostre auto a benzina.

La cosa che mi rende un pò sconcertato è il modo con cui viene indicata la quantità di gpl nei nostri toroidi.
Tutto viene affidato ad un pic che, tra le tante cose, pilota 5 led: riserva 1/4, 2/4, 3/4 e 4/4.
Dunque, rappresentano la quantità in modo discreto e non continuo: non avete modo di capire quanto gpl avete effettivamente!

19052012015

Facciamo un paio di conti:
Ipotizziamo un toroide di 45litri.
Ogni led rappresenta circa 45/4 del totale, ovvero 11.25 litri.
Se abbiamo 11.3 litri, quasi certamente, il vostro pic accenderà il 2° led che vi trarrà in inganno perchè penserete di avere 22.5 litri!
Per non parlare poi di quando camminate a riserva pensando di avere un bel pò di gas quando poi….

Come risolvere, dunque, questo problemino fastidioso?
Prima però, dovremmo rispondere ad un’altra domanda…. Come funziona esattamente il meccanismo che accende i led?

Proverò a spiegarvelo a parole mie…
Su di ogni toroide c’è un sensore resistivo che varia a secondo del livello di liquido all’interno del toroide.
Questo grazie ad un meccanismo a me ignoto, ma che ipotizzio sia realizzabile con qualche galleggiante a calamita.
Il sensore indica il livello in modo analogico (con una lancetta) e lo trasforma sotto forma di tensione che andrà direttamente al commutatore, che spalmerà la suddetta tensione, su 4 led:

dscn0733l

Nel mio caso ho un sensore resistivo aeb1050 ed un commutatore aeb722a:

19052012012 19052012013 19052012014

Aprendo il commutatore ho notato che:

1. E’ fatto davvero bene. Una bella pcb, ottime saldature, ottimi componenti, ottima elettronica: ho notato un pò di diodi di protezione.

2. La tensione del sensore va quasi direttamente all’entrata RC5 di un pic della famiglia 16F-qualcosa-

3. Ogni led corrisponde ad una porta del pic

4. Altra elettronica che penso servi a commutare l’impianto da gas a benzina e viceversa… tipo dei piccoli relè

Dunque, se i calcoli non mi ingannano, la tensione doveva variare tra 0~5v.
Studiando bene lo schema di montaggio ed altre caratteristiche dell’impianto, consultabile nel pdf al link: http://www.aeb.it/prodotti/commutatori/722
…si capisce in un batter d’occhio che il cavetto bianco (se correttamente installato dal vostro meccanico) porta direttamente al sensore.

captureuxg

Ho così splittato il cavetto e l’ho chiuso con un pò di guaina termorestringente:

dscn0737hc dscn0738g

Ho collegato il tester in questo modo: il positivo al cavo bianco appena splittato e il negativo ad un qualsiasi negativo… io ho usato quello del posacenere.

capturetx

…e bingo!

dscn0740v dscn0741n

La mia bellissima tensione!
Come si può evincere è molto vicina a 0v… 1.6v, quasi un pieno!
Più precisamente:
5v : 45litri = 1.67v : x
x = (45*1.67)/5 = 15.03 litri al pieno
y = 45 – x
y = 29.97 ~ 30litri effettivi!

(però non credo che il mio toroide sia da 45litri… dovrebbe essere tipo 42litri)

Ho avuto modo di camminare col tester attaccato e ho fatto anche un pò di gas.
Proprio come in una vera lancetta a benzina, il valore varia con la quantità di gpl.
Non solo… ad ogni buca, salita/discesa il valore cambiava proporzionalmente: in salita diminuiva e in discesa aumentava.

Ora viene il bello, come inscatolare il tutto rendendo più elegante questa lettura?
A mio avviso il modo più semplice è acquistare un piccolo voltimetro a pannello a 7 segmenti (o lcd) che si accende all’accensione dell’auto (o con uno switch in serie) che indica il voltaggio sul cavo bianco: 0v pieno, 5v serbatoio vuoto.
Tipo questo:

captureuud

E’ la soluzione più economica (meno di 3euro dalla cina), facile e pulita.
Ma se volete una cosa più elaborata, precisa e figa… beh… arduino!
Collegate la tensione all’input analogico, fate un piccolo sketch di conversione, mediate i vostri valori e rappresentateli su un bel display luminoso.

A voi la scelta!!

19052012005

PS
Ovviamente, non mi assumo nessuna responsabilità circa quello che andrete a fare sul vostro impianto!

PPSS
Ovviamente, il tutto varia da impianto a impianto… bisognerebbe riapplicare un pò di teoria e modificare leggermente (spero per voi) questa mod.

Nota_1:
Cosa abbastanza strana è che si può regolare anche i litri di gpl che indicano la riserva, cito il manuale: È possibile effettuare una piccola rettifica del numero di chilometri che possono essere percorsi in riserva; ruotando il sensore nella sede della multivalvola in senso antiorario, i chilometri che si possono percorrere in riserva diminuiscono mentre ruotandolo in senso orario i chilometri che si possono percorrere aumentano.