lunedì 11 febbraio 2013

Capannina meteo economica

Cos'è una capannina meteo?  Una specie di bungalow dove si rifugia il meteorologo in vacanza? No, è una di quelle cose fondamentali usata per misurare correttamente la temperatura e l'umidità dell'aria. Infatti, se vogliamo che il nostro termometro o igrometro misurino la temperatura dell'aria e non la propria, bisogna schermarli dagli scambi radiativi con sorgenti esterne. Primo tra tutti il sole, che riscalda i corpi condensati ma non l'aria che è un gas. Secondo il cielo sereno di notte, che costituisce un pozzo freddo, capace di raffreddare i corpi condensati fino a temperature inferiori a quella dell'aria.
Una capannina meteorologica ha quindi il compito di schermare i nostri sensori dalla radiazione solare (visibile, onda corta) e notturne (infrarosso, onda lunga), ma nello stesso tempo deve permettere ai sensori di stare in equilibrio termico con l'aria. Quindi la capannina deve poter far passare più aria possibile al suo interno; certe volte addirittura è dotata di ventilatore.  In commercio ne esistono tante e di vario tipo, il costo è sicuramente superiore a quello degli stessi sensori e del sistema di acquisizione. Infatti oggi è possibile costruirsi da un sistema di misura meteorologico spendendo poco per la parte elettronica, mentre la parte più costosa è costituita da tutto ciò che è meccanico, vale a dire, l'anemometro, la capannina, il pluviometro a vaschetta basculante.
In questo post faccio vedere come, con il costo di una pizza+birra, è possibile costruirsi una capannina che soddisfa ai requisiti che ho spiegato su.
La parte meno costosa, ma anche più importante, è costituita da una confezione di piatti di plastica bianca, quelli un po' più robusti della media, spessore 0,5 mm. Io ho scelto un piatto quadrato, ma vanno bene anche quelli tondi, l'importante è che siano fondi.  I piatti di plastica hanno il vantaggio di essere leggeri e quindi reagiscono rapidamente ai cambiamenti di temperatura dell'aria. Lo svantaggio è ovviamente la fragilità, ma ho l'impressione che la capannina che ho costruito sia più robusta della apparenze, staremo a vedere!
Si incomincia con la foratura della "risma" di piatti, facendo 4 buchi da 5 mm per le viti di sostegno e un buco centrale da circa 30 mm che servirà a introdurre i sensori. Quest'ultimo può essere ottenuto usando una sega a tazza e un trapano a colonna. Attenzione alla velocità del trapano, perché la plastica può lacerarsi facilmente.  I piatti bucati appaiono come nella foto. Uno dei piatti, quello più in alto nella capannina, non avrà il buco centrale.
A questo punto si prendono 4 barre filettate di acciaio inox o ferro zincato (costa meno), 8 bulloni  con altrettante rondelle per ogni piatto. Si incomincia a fissare il piatto superiore, quello senza buco centrale, alle estremità delle barre. Gli altri piatti sono infilati successivamente e fissati con i bulloni ad una distanza di circa 3 cm l'uno dall'altro. Questa misura dipende essenzialmente da come sono fatti i bordi dei piatti. La distanza deve essere un buon compromesso tra una facile circolazione dell'aria e una buona barriera per i raggi solari.

Il numero di piatti da infilare è anche questo arbitrario. Solo quando avrò fatto alcune prove in pieno sole potrò dirvi cosa è meglio fare.
Finito di montare i piatti, ho preso un profilato di alluminio a sezione quadrata 2 x 2 cm e lungo un metro e l'ho fissato a due barre filettate sulla diagonale della capannina. Alle altre due barre ho fissato un pezzo di profilato più leggero che sarà a sua volta avvitato al profilato quadrato.


Il profilato da un metro serve a montare la capannina al palo verticale che normalmente sorregge tutti i sensori meteo, lo sbraccio di un metro è importante per non far interferire la capannina con il palo e gli altri sensori.
Il sensore di temperatura che ho usato (per ora manca quello di umidità) è costituito da un integrato DS18B20 collegato ad un cavetto due poli + schermo, sufficienti a fornire all'integrato GND, alimentazione +5 e linea dati I2C. Il sensore e il cavetto sono stati sigillati con un bagno di silicone liquido bianco.

Non mi resta ora che fare delle prove, misurando la temperatura in diverse condizioni di insolazione e vento. A presto conoscerete i risultati.

mercoledì 6 febbraio 2013

Misurare alte correnti con Arduino

Nel post precedente, parlando del metodo per controllare la corrente in un circuito, ho fatto vedere l'inserimento nel circuito di un sensore di corrente ad effetto Hall, il ACS715. Questo sensore restituisce una tensione di 133 mV per ogni Ampere che passa al suo interno. E' alimentato a 5 V e consente misure da 0 a 30 A.
Facilmente Arduino, utilizzando il suo input analogico, può misurare la tensione in uscita dal sensore e calcolare la corrente. Il problema sorge quando la corrente è pulsata, come quella usata nel circuito del mio precedente post. Il sensore è molto veloce, vale a dire che nel momento che Arduino lo interroga, potrebbe stare misurando la parte di onda quadra a 0 o quella a 5 V.  La risposta istantanea del sensore non è quindi adatta a misurare un valore medio della corrente, esattamente quello che invece darebbe un tester.
Ma questo inconveniente può essere superato con il software. Basta campionare la corrente qualche migliaio di volte al secondo e fare la media dei valori ottenuti.

Controllare carichi potenti!!

Mi sono posto il problema di usare Arduino per il controllo di dispositivi ad alto assorbimento di corrente, come ad esempio un ventilatore a 12 V o una lampada o una pompa.

Girando in rete ho visto diversi blog sull'uso dei MOSFET accoppiati ad Arduino. Il MOSFET, per chi non lo sapesse, è un componente elettronico attivo che funziona come un relè. Una piccola tensione in ingresso (piedino gate) riesce a chiudere un circuito (tra i due piedini Drain e Source) facendo passare correnti notevoli, anche di decine di Ampere.

Frugando nella scatola dei semiconduttori, ho trovato nel cassetto un MOSFET NDP405B della National, che può commutare una corrente fino a 12 A con una tensione di 12 V (144 W !!).  Va benissimo per il mio scopo che è quello di controllare dispositivi alimentati a 12 V, tipo quelli usati sulle autovetture.

Prima ho detto che il MOSFET funziona come un interruttore, quindi permette alla corrente di passare o non passare attraverso il dispositivo. Come puo' essere usato per farne passare una quantità voluta, tra 0 e il valore massimo?  Alcuni dispositivi come i motori o le lampade, hanno la prerogativa di reagire lentamente alla corrente pulsata (intermittente). Se per esempio alimentiamo un motore con una corrente che si interrompe ogni millisecondo, questo continuerà a girare, durante l'interruzione, come se fosse alimentato da una corrente continua, ma leggermente inferiore. Lo stesso dicasi per una lampada, anche quelle a LED, alimentate con corrente pulsata, ci appaiono emettere una luce continua a causa della reazione lenta della nostra retina (persistenza).  Quindi possiamo dire che alcuni dispositivi alimentati da corrente pulsata si comportano come se fossero alimentati da una corrente media, ricavata mediando i periodi di corrente "on" con quelli di corrente "off".  Variando quindi la lunghezza di questi periodi si possono ottenere tutti i valori di corrente media compresi tra 0 e il massimo.

In base a questa spiegazione, per raggiungere il nostro scopo di far passare una corrente media prefissata dentro al nostro carico, bisogna comandare il MOSFET con un treno di impulsi di durata voluta. In particolare, per il MOSFET NDP405B gli impulsi possono essere anche di 12 V di ampiezza. L'ideale è quindi inviare al Gate un'onda quadra  tra 0 e 12 V, con frequenza fissa, ma con la durata della semionda alta di lunghezza variabile a piacere.  La frazione di tempo in cui l'onda è alta rispetto al periodo è chiamata "Duty cycle". Arduino può produrre un'onda di questo genere, anche se fino a 5 V di ampiezza, usando l'uscita PWM e l'istruzione analogWrite(pin, value). L'onda quadra emessa, ha una frequenza di circa 490 Hz con un    duty cycle pari a value/255.  Value può andare da 0 (ampiezza media nulla) a 255 (ampiezza media 5V).

Per portare l'ampiezza dell'onda da 5 V a 12, come richiesto dal MOSFET, ho inserito nel circuito un transistor alimentato a 12 V, come nello schema qui sotto.


Nello schema si nota un altro componente, ACS715, inserito sulla linea di alimentazione del carico (Load). Questo componente serve a misurare la corrente. E' un dispositivo ad effetto Hall che consente ad Arduino di acquisire i dati di corrente. Ne parlerò in un prossimo post.

mercoledì 30 gennaio 2013

Monitoraggio ambientale: Radioattività all'aria aperta






Un contatore geiger autocostruito misura la radioattività di un minerale di Uranio a Novazza (BG).





Tempo fa, ho pubblicato, su questo blog, un Manifesto che propone la necessità che tutti partecipino al monitoraggio dell'ambiente.
A tal proposito, in questo post, parlo di una recente gita a Novazza, in provincia di Bergamo, sulle Alpi Orobie, dove in passato è stata scoperta, e si è tentato di sfruttare, una miniera di Uranio.
 In prossimità delle gallerie esplorative della miniera, sui sentieri aperti a tutti per magnifiche passeggiate in montagna, si trovano sassi con intrusioni di Uranite.  I contatori geiger, che ci siamo portati durante la gita, dimostrano in modo molto evidente livelli di radioattività elevati, dovuti essenzialmente alla radioattività naturale dell'Uranio.  I livelli, talvolta sopra le soglie di sicurezza, si riscontrano solo a pochi centimetri da alcune pietre, essenzialmente dovuti alla radioattività alfa e beta. E' pur vero però che questi sassi radioattivi sono abbandonati in giro e chiunque può prenderli e portarseli a casa con un certo rischio per la salute, specialmente se questi sono lasciati vicino alle persone, esempio su uno scaffale di libreria.

A fianco, uno scorcio primaverile del sentiero che corre vicino alla miniera di Novazza.

Sotto, il ghiaione sotto la miniera di Novazza dove è possibile trovare  molti frammenti con minerali di Uranio



Novazza in Val Seriana, Provincia di Bergamo


giovedì 13 dicembre 2012

Monitoraggio ambientale per tutti: il mio MANIFESTO




Quante volte sentiamo parlare di ambiente e delle azioni umane che lo violano in continuazione, sia su grande scala come ad esempio l’Ilva di Taranto, sia su piccola scala quando ci accorgiamo di discariche abusive sotto casa nostra, auto con motori inquinanti, scarichi indiscriminati nei corsi d’acqua e altro ancora.

Nonostante un apparato legislativo complesso ed enti pubblici preposti al controllo e al monitoraggio dell’ambiente, è opinione comune che l’ambiente non sia difeso abbastanza e come l’uomo ancora non sia sufficientemente sensibile, specialmente quando gli interessi personali prevalgono su quelli collettivi.

Credo allora che tutti i cittadini abbiano il diritto e il dovere di presidiare l’ambiente e denunciare quando questo sia violato in modo illegale o comunque lesivo dei nostri diritti a goderne i benefici.

Inoltre solo i cittadini possono giudicare l’operato di quegli organismi pubblici preposti al controllo e alla diffusione dei dati sull’ambiente, troppo spesso assoggettati a politiche che ne condizionano il funzionamento o per mancanza di risorse economiche o per voluta mancanza di trasparenza (ricordiamoci, a tal proposito, cosa è successo dopo il disastro di Fukuschima in merito alla diffusione di dati e notizie).

Si può presidiare l’ambiente con i nostri 5 sensi, e questo già lo facciamo tutti i giorni, ma anche con dispositivi di monitoraggio ormai alla portata di molti.

L’elettronica industriale mette oggi a disposizione la componentistica più avanzata a prezzi bassissimi; dispositivi open hardware e software, come Arduino con tutte le sue applicazioni, sono fruibili da chiunque, anche con minima formazione di base.

Allora perché non mettere al servizio dell’ambiente questo patrimonio di opportunità, creando dispositivi a basso costo, anche a scapito della loro precisione, per osservare e misurare quei numerosi parametri che caratterizzano l’ambiente che ci circonda?

Sarebbe anche un’occasione per imparare tutti qualcosa di più e quindi capire meglio i dati ufficiali che vengono diffusi.

Campi elettromagnetici, radiazioni ionizzanti, discariche abusive, immissioni inquinanti in aria o in acqua, sono tutte situazioni in cui sicuramente l'elettronica amatoriale può dare un contributo con sistemi di allerta e misura.

Credo che l’osservazione continua e diffusa sia la chiave del successo di un valido controllo ambientale operato dai cittadini. Troppo spesso gli enti preposti intervengono solo dopo i grandi disastri o solo “a spot”, permettendo a chi inquina deliberatamente di operare con metodi difficilmente individuabili e punibili.

Le discariche abusive come i veicoli che vi trasportano i rifiuti possono essere fotografati e denunciati. Alcuni parametri significativi della qualità dell’acqua nei fiumi, nei navigli, in mare, possono essere misurati facilmente e far scattare allarmi.

Chi si ricorda delle lenzuola appese fuori dalle finestre per dimostrare in modo visivo l’inquinamento dell’aria? Si può fare qualcosa di meglio e di un pochino più scientifico?

Io credo di sì, dobbiamo affiancare alle comunicazioni ufficiali sull’ambiente, quelle di una rete di cittadini osservatori e misuratori con la competenza sufficiente a valutare i dati propri e quelli che vengono diffusi dalle istituzioni.

mercoledì 12 dicembre 2012

ORTOLINO V.2.0 (Spero l'ultima)

Dunque ORTOLINO sta funzionando imperturbato da circa 1 mese, con sempre le stesse batterie. Però ho scoperto che si potevano introdurre alcune migliorie. Innanzitutto quando le temperature sono scese sotto lo zero mi sono accorto che le variabili di tipo "word" non hanno il segno, pertanto un numero negativo viene trasformato nel massimo valore permesso. Per ora ho risolto la cosa passando dai gradi centigradi ai gradi Kelvin, così sono sempre positivi. Poi ho scoperto che per valori alti di radiazione solare, la fotoresistenza ha dei valori così bassi che l'uscita digitale del partitore diventa trascurabile. In parole povere il valore trasmesso  è sempre lo stesso e non evidenzia variazioni di radiazione. Ho risolto il problema collegando la fotoresistenza in un altro modo e alimentandola con la tensione di 3.3 V fornita da un piedino di uscita digitale, solo al momento della misura, per non consumare energia inutilmente. Il nuovo schema è il seguente:

PxD vuol dire il piedino digitale della porta x del Jeenode.
PxA vuol dire il piedino analogico della porta x del Jeenode.

Come si può notare, anche l'alimentazione del sensore di temperatura TMP36 è presa dal piedino digitale, questo sempre per risparmiare energia. Il piedino infatti viene portato a +3.3 V solo poco prima della misura.




Il programma caricato sul Jeenode è qui sotto:


/*   Trasmette le variabili misurate da Ortolino
struttura del pacchetto di 10 byte trasmesso
1 - 2  RH  resistenza del soil moisture in centinaia di ohm
3 - 4  T  temperatura del suolo in decimi di grado Kelvin
5 - 6  L  luminosità in unità digit da 0 a 1023
7 - 8    libero
9 - 10   Vcc  in mV

Corretto per temperature negative, le temperature sono trasmesse
in °K, perchè una variabile word e' solo positiva

*/

#include <JeeLib.h>
#include <avr/sleep.h>
ISR(WDT_vect) { Sleepy::watchdogEvent(); }
Port an1 (1);
Port an2 (2);
Port an3 (3);
Port an4 (4);
MilliTimer readoutTimer, aliveTimer;
//word runningAvg1;
word runningAvg2;
word runningAvg3;
word runningAvg4;
byte radioIsOn;
word pluto[5];
int  nodeID;
int ECHO = 1;  // Print debug
float R1 = 55.3;  // Kohm
float VCC = 3.3;
float Vconv = VCC/1023;
float V1=0;
float V2=0;
float RH1=0;
float RH2=0;
float RH=0;
float diff = 0;
float temper= 0;

//////////function for reading power supply/////////////////

long readVcc() { // SecretVoltmeter from TinkerIt
long result;
  // Read 1.1V reference against AVcc
  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
  delay(2); // Wait for Vref to settle
  ADCSRA |= _BV(ADSC); // Convert
  while (bit_is_set(ADCSRA,ADSC));
  result = ADCL;
  result |= ADCH<<8;
  result = 1126400L / result; // Back-calculate AVcc in mV
  return result;
 }
///////////////////////////////////////////////////////

void setup () {
    // initialize the serial port and the RF12 driver
    Serial.begin(57600);
    Serial.print("\n[pof66]");
    nodeID = rf12_config();
    if(ECHO == 1){
      delay(1000);
    Serial.println(nodeID);
    }
    // set up easy transmissions at 30 sec rate
    rf12_easyInit(30);  
//  setta come INPUT le 4 porte analogiche
    an1.mode2(INPUT);
    an2.mode2(INPUT);
    an3.mode2(INPUT);
    an4.mode2(INPUT);
//  setta come output le 4 porta digitale
    an1.mode(OUTPUT);
    an2.mode(OUTPUT);
    an3.mode(OUTPUT);
    an4.mode(OUTPUT);

//  no pull up resistors on the 3 analog ports

    an1.digiWrite2(0); //no pullup soil moisture
    an2.digiWrite2(0); // no pullup termometer TMP36GZ
    an3.digiWrite2(0);  // no pullup photoresistor
    an4.digiWrite2(1);
    
// prime the running average
 //   runningAvg1 = an1.anaRead();
    runningAvg2 = 0;
    runningAvg3 = 0;
    runningAvg4 = 0;
// start with the radio on
    radioIsOn = 1;
}

////////////////////////////////////////////////

static void lowPower (byte mode) {
    // disable the ADC
    byte prrSave = PRR, adcsraSave = ADCSRA;
    ADCSRA &= ~ bit(ADEN);
    PRR &= ~ bit(PRADC);
    // go into power down mode
    set_sleep_mode(mode);
    sleep_mode();
    // re-enable the ADC
    PRR = prrSave;
    ADCSRA = adcsraSave;
}
////////////////////////////////////////////////////

static void loseSomeTime (word ms) {
    // only slow down for longer periods of time, as this is a bit inaccurate
    if (ms > 100) {
        word ticks = ms / 32 - 1;
        if (ticks > 127)    // careful about not overflowing as a signed byte
            ticks = 127;
        rf12_sleep(ticks);  // use the radio watchdog to bring us back to life
        lowPower(SLEEP_MODE_PWR_DOWN); // now we'll completely power down
        rf12_sleep(0);      // stop the radio watchdog again
        // adjust the milli ticks, since we've just missed lots of them
        extern volatile unsigned long timer0_millis;
        timer0_millis += 32U * ticks;
    }
}
//////////////////////////////////////////////////////////

void loop () {
    // switch to idle mode while waiting for the next event
    lowPower(SLEEP_MODE_IDLE);
    // keep the easy tranmission mechanism going
    if (radioIsOn && rf12_easyPoll() == 0) {
        rf12_sleep(0); // turn the radio off
        radioIsOn = 0;
    }
    // if we will wait for quite some time, go into total power down mode
    if (!radioIsOn)
        loseSomeTime(readoutTimer.remaining());
    // only take  sensors reading once a second
    // fa una lettura dei sensori ogni 30 secondi
    if (readoutTimer.poll(30000)) {
      
 // sensor power supply for measuring V1, i.e. P1-D on and P2-D off
      
        an1.digiWrite(1);
        an2.digiWrite(0);
        Sleepy::loseSomeTime(1000);
//        delay(1000);
        V1 =  Vconv*an1.anaRead();
        
 // sensor power supply for measuring V2, i.e. P1-D off and P2-D on
    
        an1.digiWrite(0);
        an2.digiWrite(1);
        Sleepy::loseSomeTime(1000);
//        delay(1000);
        V2 =  Vconv*an1.anaRead();

 //  compute RH

    diff = abs(3.3 - V2);
    if(diff < 0.001){
      RH2 = 5000.0;
    }
    else{
     RH2 = R1*V2/(3.3 - V2);
    }
    if(V1 < 0.001){
      RH1 = 5000.0;
    }
    else{
     RH1 = R1*(3.3 - V1)/V1;
    }
     RH = 5*(RH1+RH2);  // 0.1 kohm
//  read temperature
        an4.digiWrite(1);
        Sleepy::loseSomeTime(1000);
        runningAvg2 = an2.anaRead();
        an4.digiWrite(0);
//  read light
        an3.digiWrite(1);
        Sleepy::loseSomeTime(1000);
        runningAvg3 = an3.anaRead();
        an3.digiWrite(0);
//  read port 4  with anything
     runningAvg4 = an4.anaRead();  
//       
     pluto[0] =  word(RH);
     temper = 10*(273.2 + 25 + (100*Vconv*runningAvg2-75)); // in °K
     pluto[1] =  word(temper);  // gradi in decimi interi
     pluto[2] =  runningAvg3;  // unità digit per la luminosità
     pluto[3] =  runningAvg4;  
     pluto[4] =  word(readVcc()); // read power supply in mV 
// send measurement data, but only when it changes
      char sending = rf12_easySend(&pluto, sizeof pluto);

//   Print something //////////////////////////////////

   if(ECHO == 1){
       Serial.print(" Node ID: ");
       Serial.print(nodeID);
       Serial.print(" n.byte payload: ");
       Serial.println(sizeof pluto);
       Serial.print(" P1: ");
       Serial.print(pluto[0]);
       Serial.print(" P2: ");
       Serial.print(pluto[1]);
       Serial.print(" P3: ");
       Serial.print(pluto[2]);
       Serial.print(" P4: ");
       Serial.print(pluto[3]);
       Serial.print(" Vcc: ");
       Serial.println(pluto[4]);
   }
///////////////////////////////////////////////
   
        // force a "sign of life" packet out every 60 seconds
        if (aliveTimer.poll(60000))
            sending = rf12_easySend(0, 0); // always returns 1
        if (sending) {
            // make sure the radio is on again
            if (!radioIsOn)
                rf12_sleep(-1); // turn the radio back on
            radioIsOn = 1;
        }
    }
}



giovedì 22 novembre 2012

ORTOLINO: influenza della temperatura

Dopo alcune prove, che consistevano nello spostare ORTOLINO con tutto il vaso di terra dal balcone a 12 °C all'inteno della casa a 21°C, ho constatato che la resistenza del suolo non cambia. Poi ho messo acqua nel vaso fino a veder comparire un filo d'acqua nel piattello sotto. Questo credo sia un segnale che la terra nel vaso è satura d'acqua, la resistenza è scesa fino a 10 kohm. Dalla taratura fatta in precedenza a questa resistenza corrisponde un contenuto di acqua pari al 15% circa.  Bisogna tener presente che la percentuale si riferisce al peso totale di terra+acqua.
Bene adesso credo che sia arrivato il momento di provare ORTOLINO sul campo, registrare i dati e magari osservare a vista quando il terreno avrebbe bisogno di essere irrigato, in modo da individuare i valori di resistenza limite, che servono a far scattare l'irrigazione automatica.