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.

Ancora su ORTOLINO

In questi giorni sto provando ORTOLINO per lunghi periodi. L'obiettivo è quello di sperimentare la durata delle batterie (4 AAA) e l'attendibilità delle misure di resistenza del terreno con il sensore di umidità. Da una prima prova con una trasmissione dati ogni secondo e batterie IKEA, la durata è stata di 5 gg e 14 ore.  Ho quindi cambiato il programma, facendo trasmettere il Jeenode ogni 30 secondi. Adesso è in funzione dal 19/11. Intanto mi è sorto il dubbio che le misure di soil moisture siano influenzate dalla temperatura del terreno. Infatti questo è riscontrabile dalla letteratura, ma vorrei verificare sperimentalmente la differenza tra misure sulla stessa terra a due temperature diverse: quella del balcone, intorno a 10 °C, e quella dentro casa a circa 21°C.
Per chi fosse interessato a vedere il programma caricato su ORTOLINO, è qui sotto. Noterete alcuni commenti in inglese che derivano dal programma originale del Jeelabs, da cui sono partito.


/*   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
5 - 6  L  luminosità in unità digit
7 - 8    libero
9 - 10   Vcc  in mV

*/
#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 = 0;  // 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 la porta digitale 1 e 2
    an1.mode(OUTPUT);
    an2.mode(OUTPUT);
//  pull up resistors on analog ports

    an1.digiWrite2(0); //no pullup soil moisture
    an2.digiWrite2(0); // no pullup termometer TMP36GZ
    an3.digiWrite2(1);  // 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
//
     runningAvg2 = an2.anaRead();
     runningAvg3 = an3.anaRead();
     runningAvg4 = an4.anaRead();  
//       
     pluto[0] =  word(RH);
     temper = 10*(25 + (100*Vconv*runningAvg2-75));
     pluto[1] =  word(temper);  // gradi in decimi interi
     pluto[2] =  1023 - 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);
//   Backup  //////////////////////////////////
   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;
        }
    }
}

mercoledì 14 novembre 2012

Nuovo sensore termometrico con telelettura e zero consumo di energia

Ho risolto il problema della misura di temperatura esterna con consumo energetico nullo!!

Si può leggere a distanza, non richiede batterie e ha un range da -40 a +50 °C.  Provare per credere!

giovedì 8 novembre 2012

Taratura di Ortolino

La taratura di ortolino è stata fatta prendendo un campione di terriccio, essicato al forno, pesato e messo in un vaso dove è stato poi "piantato" ortolino. Alla terra si sono aggiunte quantità di acqua note e misurata la resistenza. Dopo varie misure si è ottenuta la seguente curva di taratura:

 La quantità di acqua in ascisse è espressa come percentuale della massa totale (acqua+terra).
Bisogna tener presente che questa curva può variare in funzione del tipo di terra nella quale si trova Ortolino. Pertanto vale la pena ripetere la procedura di taratura per terreni diversi.

Il sensore di temperatura, costituito da un integrato TMP36GZ non ha bisogno di taratura in quanto il livello di uscita è di 750 mV a 25°C e cambia di 10 mV / °C .

Il sensore di luce ha invece bisogno di taratura, ma può essere usato qualitativamente prendendo alcuni suoi valori in corrispondenza di varie condizioni di illuminazione (sole pieno, tramonto, notte...)

mercoledì 7 novembre 2012

Ortolino ?

Visto che ogni realizzazione con Arduino è chiamata con un nome che finisce in "ino", così ho chiamato la versione praticamente definitiva del soil moisture meter, descritto nei precedenti post, con il nome ORTOLINO. Se qualcuno ha in mente qualcosa di meglio, si faccia avanti!!

La palletta da ping pong che si vede contiene una fotoresistenza, che diminuisce il suo valore all'aumentare della luce ambiente. L'intento è stato quello di completare la stazione per la misura del contenuto d'acqua nel terreno con un sensore di luce e con uno di temperatura: il filo che esce dal tubo.
Il jeenode contenuto all'interno del tubo, trasmette i valori della resistenza del terreno, della temperatura del terreno o dove si vuole posizionare la sonda, e un valore in mV inversamente proporzionale alla luce che batte sulla pallina.
Dopo varie prove con il soil moisture sensor (SMS) descrito nei miei precedenti post, quello che avevo chiamato carota bianca, ho deciso di sostituirlo con due più semplici bulloni in acciaio inox, come si vede nella foto successiva.  Infatti la carota rispondeva troppo lentamente alle variazioni di bagnatura. Il problema delle tensioni galvaniche ai capi degli elettrodi permane anche con i due bulloni, ma ho visto che il sistema di alimentazione che si inverte, riduce al minimo questo effetto.
Lo schema elettrico dei tre sensori è descritto nelle figure successive.
La prima mostra i circuiti equivalenti del SMS nelle due situazioni in cui si viene a trovare invertendo la sua alimentazione. Le due formule riguardano il calcolo della resistenza del sensore nelle due configurazioni. i due valori così trovati vengono poi mediati tra loro in modo da ridurre l'influenza delle tensioni galvaniche e dell'eventuale polarizzazione degli elettrodi. Il significato dei simboli è riportato sotto la figura.




Vs : è la d.d.p. galvanica prodotta dal Soil Moisture Sensor (SMS)
Vcc: è il valore “High” della d.d.p. sul piedino digitale P1D o P2D
P1A: è l’input analogico della porta P1
P1D: è l’input digitale della porta P1
P2D: è l’input digitale della porta P2
Rs : è la resistenza del SMS
R1: 56 Kohm
V1 : è la tensione misurata su P1A
V2: è la tensione misurata su P2A




Continua nel prossimo post.

sabato 20 ottobre 2012

E' nata la carota bianca

Cos'è la carota bianca? E' un'applicazione dei trasmettitori Jeenode dei quali ho parlato nei post precedenti.  Si tratta di un sensore di umidità del terreno (Soil Moisture), usato soprattutto per i sistemi automatici di irrigazione. Immaginate infatti di avere un orto o un giardino, piuttosto grande; avete bisogno di irrigare in modo diverso varie parti, perché magari consumano acqua non con la stessa velocità oppure vi sono piante che necessitano differenti quantità di acqua. Non possiamo però tirare fili per tutto il giardino per collegare i vari sensori alla centralina. L'idea è quindi quella di usare dei sensori che trasmettono il contenuto in acqua del terreno, con una precisione anche scarsa ma sufficiente a determinare quando quella parte di orto ha bisogno di essere irrigata.
 La carota bianca si presenta come un tubo di PVC con attaccato un cilindretto di gesso, questa parte è quella che va piantata nel terreno, con l'accortezza che sia ben a contatto con la terra. La parte in PVC che rimane fuori contiene il Jeenode con le batterie. All'interno del cilindretto di gesso vi sono due chiodi zincati, ma possono essere anche di acciaio inox, che fungono da elettrodi. Infatti quello che si misura è la resistenza elettrica tra i due chiodi, variabile in funzione della quantità di acqua presente nel terreno, che imbibisce il cilindro di gesso.
Ai due chiodi viene applicata una tensione di 5 V solo per il periodo della misura, quindi pochi secondi ogni tanto. Al fine di evitare polarizzazioni dei due elettrodi e eliminare per quanto possibile l'influenza di eventuali effetti galvanici, la tensione di 5 V tra i due chiodi  viene invertita ad ogni misura, grazie al fatto che il partitore resistivo è collegato a due uscite digitali del Jeenode. La resistenza, calcolata nelle due polarizzazioni, viene poi mediata.  La seconda foto mostra quello che c'è dentro il tubo di PVC. Il tubo è chiuso dalle due parti mediante due tappi assieme alle guarnizioni di gomma presenti all'interno del tubo.
Vorrei sottolineare il fatto che il tubo, le guarnizioni e i tappi sono materiali comunemente usati per gli impianti idraulici, si trovano quindi a bassissimo prezzo in qualsiasi negozio che fornisce questo tipo di materiali. Il compito del Jeenode è quello di trasmettere periodicamente il valore della resistenza tra i due chiodi alla centralina che acquisisce il  dato, lo memorizza ed in base a questo decide se azionare l'irrigatore relativo a quella zona dell'orto.
Il sensore necessita una taratura usando lo stesso terreno in cui dovrà funzionare. Un metodo di taratura generalmente usato consiste nell'essicare e pesare un campione di terreno, che sarà poi posto intorno al sensore, anch'esso secco. Poi si aggiungono quantità note di acqua e si misura la resistenza con lo stesso Jeenode.
Siccome il Jeenode dispone di 4 ingressi/uscite, alla misura di umidità può essere affiancata una misura di temperatura del terreno o qualche altro parametro utile.
 Chi ha voglia di costruire e provare questi sistemi può chiedermi dettagli e suggerimi la propria esperienza.  Naturalmente voglio ringraziare le persone che mi hanno ispirato attraverso i loro siti internet:
http://hackaday.com/2010/03/15/soil-moisture-sensing/
http://www.cheapvegetablegardener.com/2009/11/how-to-make-cheap-soil-moisture-sensor-2.html

domenica 14 ottobre 2012

Data-logger via radio pronto!

Progetto finito!  Adesso una scheda Arduino con shield data-logger di Adafruit e display LCD 16 x 1 è in grado di ricevere i dati da un Jeenode che funziona da ricevitore e un Jeenode da trasmettitore.
Il Jeenode trasmettitore invia lo stato dei 4 ingressi analogici ogni volta che uno qualsiasi di questi cambia valore o comunque ogni tempo prestabilito. I dati inviati al Jeenode ricevitore via radio sono subito passati all'Arduino logger via interfaccia seriale che provvede a mostrarli sul display e scriverli sulla SD card.

Il prossimo passo sarà quello di collegare al Jeenode trasmettitore, un sensore di umidità del terreno e uno di temperatura. Inserire il tutto in un contenitore stagno a basso costo e infilarlo nel terreno.  Con questa soluzione è possibile gestire l'irrigazione di un orto abbastanza grande, se si pensa che i Jeenode tirano fino a 250 metri e se ne possono usare un certo numero sparsi per l'orto.  Un centralina poi può gestire l'apertura di valvole per l'irrigazione di settori diversi.

venerdì 12 ottobre 2012

Trasferimento dati da Jeenode a Arduino

Oggi sono finalmente riuscito a far parlare Jeenode (vedi post precedente) con Arduino. Per chi non conosce questi interessanti tranceiver, che permettono di trasmettere dati via banda 868 MHz a circa 250 m, rammento che il software di gestione della trasmissione via radio utilizza l'interfaccia seriale hardware del ATMEGA, la stessa di Arduino. Quindi se si vuole mandare i dati ad una scheda Arduino, dopo averli ricevuti via radio da un Jeenode, bisogna usare un'altra interfaccia seriale, usando la libreria SerialSoftware, fornita con l'ambiente Arduino.  Una cosa interessante che ho scoperto è che se si usano due interfacce seriali nello stesso sketch, anche se fanno capo a pin diversi, bisogna usare la stessa baud rate. Con un po' di fatica quindi sono riuscito a realizzare la comunicazione tra Jeenode e Arduino.  In breve avviene così:

Jeenode 1 trasmette via radio a Jeenode 2 lo stato dei suoi 4 input analogici ( da 0 a 1023), usando lo sketch che minimizza il consumo di energia, fornito dalla stessa Jeelab.

Jeenode 2 appena riceve un pacchetto contenente i 4 dati + un'intestazione con lo ID del Jeenode 1, lo trasmette via seriale a Arduino.  Jeenode 2 usa lo sketch RF12demo fornito da Jeelab, dove ho aggiunto alcune istruzioni affinchè si possa usare l'interfaccia seriale software, attestata sui piedini 4 e 5 di Arduino, corrispondenti alle porte 1 e 2 di Jeenode.

Su Arduino ho messo un piccolo sketch che riceve i dati da Jeenode 2 via seriale, usando anche qui una seriale software attestata su 4 e 5. L'uso di una seriale software anche qui mi consente di utilizzare la seriale hardware per interagire con la IDE.

Prossima mossa sarà quella di usare uno shield data-logger di adafruit per memorizzare i dati ricevuti da Jeenode.


venerdì 5 ottobre 2012

Arduino e suono

Attivare musica, frasi e suoni con Arduino e poco altro.

Immaginate di aprire il frigorifero perché in preda ad una voglia sfrenata di uno spuntino fuori orario, appena aprite la porta una voce grida "CHIUDI QUELLA PORTA BRUTTO CICCIONE". Oppure un antifurto che anziché far partire la sirena, genera un forte latrato di cane o più latrati di cani diversi con una sequenza casuale.  Ancora, brani musicali scelti in base al cardiofrequenzimetro che indossiamo quando andiamo a correre.

Tutto questo è fattibile usando un accessorio di Arduino (shield) ideato da www.adafruit.com, il WaveShield, che permette di caricare, su una SD card da 1 Gb, brani in formato .WAV e poi eseguirli tramite comandi impartiti dal programma caricato su Arduino.  Le possibilità sono infinite. Lo shield ha un'uscita audio che può essere collegata ad un piccolo altoparlante oppure all'ingresso di un normale amplificatore.

Le 2 board, assieme alla batteria e all'altoparlante possono essere alloggiate in una economica scatola per collegamenti elettrici, vedi foto. Dalla scatola escono i collegamenti per gli input analogici di Arduino, in modo che sia possibile collegare sensori esterni di vario tipo. Ad esempio per l'applicazione del frigorifero ho usato un fotoresistore che modifica la sua resistenza a seconda della luce esterna. Se il tutto viene sistemato sul coperchio della scatola, è più facile poi caricare nuovi programmi su Arduino con il cavo USB.
 



mercoledì 3 ottobre 2012

Bastone Radar per non vedenti

Questo bastone "vede" gli ostacoli distanti fino a 6 metri.

Un'altra applicazione di Arduino, assieme ad un sensore di distanza ad ultrasuoni e ad un micro-vibratore simile a quelli usati nei cellulari.
Il sensore ad ultrasuoni rileva un ostacolo compreso tra 6 e 1 metro. La distanza è "tradotta" da Arduino in una vibrazione con frequenza diversa che viene trasmessa al manico del bastone.

Un guanto che "sente" la flessione delle dita e la trasmette a distanza.

Un'applicazione wireless per trasmettere a distanza la posizione delle dita di una mano

Questo dispositivo permette di trasmettere a distanza la posizione delle dita di una mano. Ogni dito del guanto ha un sensore di flessione autocostruito. Questi sensori molto facili da realizzare sono fatti di Velostat, un foglio sottile di materiale plastico conduttore, che ha la caratteristica di variare la propria resistenza se compresso o piegato. I sensori sono realizzati con tre striscioline di Velostat sovrapposte e due sottili fili di rame sulle facce esterne. La flessione del dito provoca una variazione di resistenza molto ampia. Come costruire questi sensori e molto altro, potete trovarlo su www.kobakant.at.



L'acquisizione e la trasmissione dello stato dei sensori, l'ho realizzata con una coppia di Jeenode www.jeelabs.org. Questi utilissimi oggetti sono costituiti da un ATmega328p che in pratica è lo stesso integrato usato da Arduino accoppiato ad un tranceiver RFM12B che trasmette sulla banda degli 868 MHz. 

Si programma con la stessa interfaccia IDE di Arduino ed è dotato di librerie che permettono la facile trasmissione di dati da un nodo all'altro. I due nodi da me usati, uno per la trasmissione dei sensori di flessione, l'altro per la ricezione, "tirano" fino a circa 250 m in linea d'aria, mentre in casa riescono tranquillamente a superare anche due pareti. L'assorbimento di corrente da parte dei Jeenode è molto limitato, usando opportuni accorgimenti nel software.  Questi Jeenode rappresentano un'interessante soluzione a tutti i problemi di domotica, smart metering e inoltre sono a basso costo.


Nella foto qui sopra si puo' vedere l'accensione di un led sul nodo ricevitore, dovuto alla flessione del dito medio.


Nella foto a sinistra si vedono i due moduli Jeenode usati per questo progetto.
Si può notare l'antenna (filo rosso) e i cavetti di alimentazione. Il nodo ricevente è quello a sinistra con i 4 led che si accendono in corrispondenza dei piegamenti delle 4 dita. Il noto trasmittente, a destra, è stato scollegato dal guanto. Il chip che si vede è l'ATmega, mentre quello in alto con il pallino giallo è il tranceiver. I due nodi si programmano con un cavo USB-TTL da connettere ai 6 pin in basso.
E' una grande emozione vedere che dei numeri generati da un nodo vengono trasmessi all'altro anche a distanza di 200 metri. E' forse la stessa cosa che ha provato Marconi??