TiDiGino Contest, Display livello cisterna di Danilo Abbasciano

Presentiamo la candidatura del Sig. Danilo Abbasciano che si propone per la realizzazione del firmware del progetto TiDiGino e che ci presenta una sua recente applicazione con Arduino: Display per il livello di una cisterna.
Lasciamo la parola a Danilo:

Da febbraio 2009 ad oggi ho lavorato per una società come system administrator per GNU/Linux, occupandomi dell’installazione e della configurazione di software per la gestione della posta elettronica. Scripting in bash, Perl e PHP. Da settembre 2007 ad agosto 2008 e da novembre 2008 a dicembre 2008 ha lavorato presso una società che si occupa di sicurezza: inizialmente ha svolto mansioni di porting di applicazioni in linguaggio C su MySql e su sistemi x86-64 bit; successivamente mi sono dedicato allo sviluppo di servizi per compagnie telefoniche in Java.
Da settembre 2008 a novembre 2008 ho partecipato al Summer DistrICT Camp organizzato da Sardegna Ricerche in collaborazione con il CRS4 – Centro di Ricerca, Sviluppo e Studi Superiori in Sardegna. Ha lavorato, in Python, sullo studio e sulla manipolazione di stream audio.
Da giugno 2006 a settembre 2007 ho lavorato presso un’altra società come analista programmatore su piattaforma LAMP per l’implementazione e la gestione di vertical search engine, programmando principalmente nei linguaggi PHP, Bash–Script e SQL. Per hobby si occupa di elettronica, soprattutto nel ramo digitale realizzando semplici circuiti per piccole applicazioni domestiche.
Da novembre 2008 pubblico articoli sul mio blog trattando hac-king, sicurezza, open source, elettronica, programmazione, tutorial, netiquette, web e matematica. L’indirizzo è www.piumalab.org
Nel 2008 ho realizzato il portale per annunci di musicisti http://www.musici.ithttp://www.musici.it che tutt’ora gestisco in completa autonomia utilizzando le seguenti tecnologie: GNU/Linux, Apache, MySql e PHP; nel novembre 2005 ho ideato e implementato il progetto open source fick, un simulatore per la diffusione dei fluidi del quale tuttora sono il manteiner. Maggiori informazioni sono disponibili all’indirizzo web http://fick.sourceforge.net/ 

Ed ecco il progetto del Display per il livello di una cisterna:

Il progetto consiste in un dipositivo in grado di leggere e visualizzare in un display l’altezza del livello di acqua in un pozzo freatico o una cisterna.
Verrà utilizzato il dispositivo hardware Open Source Arduino, un sensore ad ultrasuoni della Parallax per misurare l’altezza dell’acqua, un display LCD compatibile con il driver Hitachi HD44780 di 16 caratteri su due linee e un sistema di allarme acustico (buzzer) che si attiva quando il livello supera la soglia prefissata.

Il progetto, come abbiamo già accennato, è composto da più parti. Un sensore sonar da posizionare nella parte alta del pozzo (a distanza di sicurezza dal livello dell’acqua) che punta verso il basso così da misurare la distanza tra il punto di posizionamento (nel nostro caso il punto più alto del pozzo) e la superficie dell’acqua. Facendo una semplice differenza tra grandezze note: la distanza tra il fondo e il sensore e la misura letta otteniamo l’altezza della superficie dell’acqua; inoltre conoscendo la superficie del pozzo risulta semplice calcolare anche il volume di acqua presente. Ad intervalli di tempo prestabiliti verranno lette le distanze e sarà visualizzato sul display l’altezza di acqua e il volume presente nel pozzo.

È prevista una barra orizzontale che riporta in termini relativi l’andamento del livello idrico all’interno del pozzo per una lettura semplice ed immediata.

 Se il livello supera una prima soglia di warning scatterà l’allarme che fa suonare il buzzer lentamente, se il livello supera la seconda soglia la frequenza della suoneria aumenta fino a quando il livello scenderà di nuovo sotto la soglia o quando si disattiva manualmente la suoneria attraverso un pulsante.

Arduino controlla la logica di funzionamento, tramite il seguente sketch:

/* -*- mode: c -*- */

/**

 * pozzo.pde 

 * version: 1.2

 */


#include <LiquidCrystal.h>


#define PING_PIN 13

#define BUZZER_PIN 8

#define SWITCH_INT 0 /* 0 => pin 2 */

#define PI 3.1415926535898

#define SUPERFICE_BASE (R_POZZO * R_POZZO * PI)

#define SIZE_BAR (16 * 5)

#define ALARM_ICON 0 /* code */

#define SOUND_ICON 6 /* code */

#define SOUND_ICON_ON 7 /* code */


#define R_POZZO 0.5 /* raggio pozzo (m) */

#define H_POZZO 146.0 /* cm */

#define SOGLIA_ALLARME_1 100 /* cm */

#define SOGLIA_ALLARME_2 120 /* cm */

#define DELAY_0 60000 /* ms; 1000 * 60 * 1 = 1 min */

#define DELAY_1 600 /* ms */

#define DELAY_2 200 /* ms */


/* initialize the library with the numbers of the interface pins */

LiquidCrystal lcd(12, 11, 5, 4, 3, 6);


int mute = 0;


byte *getChar(int n, byte newChar[]) {

  int i;

  byte code[5] = {

    B10000,

    B11000,

    B11100,

    B11110,

    B11111};


  for (i = 0; i < 8; i++)

    newChar[i] = code[n - 1];


  return newChar;

}


void setup() {

  int i;

  float h;

  byte newChar[8];


  /* set up the LCD's number of rows and columns: */

  lcd.begin(16, 2);


  for (i = 1; i < 6; i++)

    lcd.createChar(i, getChar(i, newChar));


  newChar = {

    B00000,

    B00100,

    B01010,

    B01010,

    B11111,

    B00100,

    B00000,

  };


  lcd.createChar(ALARM_ICON, newChar);


  newChar = {

    B00011,

    B00101,

    B11001,

    B11001,

    B11001,

    B00101,

    B00011,

  };


  lcd.createChar(SOUND_ICON, newChar);


  newChar = {

    B00100,

    B10010,

    B01001,

    B01001,

    B01001,

    B10010,

    B00100,

  };


  lcd.createChar(SOUND_ICON_ON, newChar);  


  pinMode(BUZZER_PIN, OUTPUT);


  /**

   * LOW to trigger the interrupt whenever the pin is low,

   * CHANGE to trigger the interrupt whenever the pin changes value

   * RISING to trigger when the pin goes from low to high,

   * FALLING for when the pin goes from high to low. 

   */

  attachInterrupt(SWITCH_INT, button, RISING);

  

  /* initialize serial communication */

  Serial.begin(9600);

}


void loop() {

  long hWatherCm;

  int litres;


  hWatherCm = read_height();

  if (check_alarm(hWatherCm) != 0) /* read again wather height */

    hWatherCm = read_height();


  lcd.clear();


  print_histogram(hWatherCm);

  

  lcd.setCursor(0, 1);


  lcd.print(hWatherCm);

  lcd.print(" cm - ");

  

  // litres = SUPERFICE_BASE * (hWather / 100.0) * 1000

  litres = floor(SUPERFICE_BASE * hWatherCm * 10);

  lcd.print(litres);

  lcd.print(" l ");

  

  lcd.setCursor(14, 1);

  lcd.write(SOUND_ICON);

  lcd.setCursor(15, 1);

  if (!mute)

    lcd.write(SOUND_ICON_ON);

  else

    lcd.write('X');


/*

  Serial.print("cm = ");

  Serial.println(hWatherCm);

*/


  switch (check_alarm(hWatherCm)) {

  case 1:

    lcd.setCursor(0, 0);

    lcd.write(ALARM_ICON);


    buzz(200);

    delay(DELAY_1);

    break;


  case 2:

    lcd.setCursor(0, 0);

    lcd.write(ALARM_ICON);


    buzz(200);

    delay(200);

    buzz(200);

    delay(DELAY_2);

    break;


  case 0: // no alarm

    delay(DELAY_0);

  }

}


void print_histogram(int hWatherCm) {

  int i;

  int bloks;

  float histogram;


  // hWatherCm : HPOZZO = histogram : SIZE_BAR

  histogram = (SIZE_BAR * hWatherCm) / H_POZZO;

  histogram = histogram + 0.5;


  bloks = (int)histogram / 5;


  for (i = 0; i < bloks; i++)

    lcd.write(5);

  

  if ((int)(histogram) % 5 > 0)

    lcd.write((int)(histogram) % 5);

}


long read_height() {

  /**

   * establish variables for duration of the ping, 

   * and the distance result in centimeters:

   */

  long duration, hWatherCm;


  /**

   * The PING))) is triggered by a HIGH pulse of 2 or more microseconds.

   * Give a short LOW pulse beforehand to ensure a clean HIGH pulse:

   */

  pinMode(PING_PIN, OUTPUT);

  digitalWrite(PING_PIN, LOW);

  delayMicroseconds(2);

  digitalWrite(PING_PIN, HIGH);

  delayMicroseconds(5);

  digitalWrite(PING_PIN, LOW);


  /**

   * The same pin is used to read the signal from the PING))): a HIGH

   * pulse whose duration is the time (in microseconds) from the sending

   * of the ping to the reception of its echo off of an object.

   */

  pinMode(PING_PIN, INPUT);

  duration = pulseIn(PING_PIN, HIGH);


  /* convert the time into a distance */

  hWatherCm = H_POZZO - microseconds_to_centimeters(duration);


  if (hWatherCm < 0)

    return 0;


  if (hWatherCm > H_POZZO)

    return H_POZZO;


  return hWatherCm;

}


void buzz(int msec) {

  if (!mute)

    digitalWrite(BUZZER_PIN, HIGH);

  delay(msec);

  digitalWrite(BUZZER_PIN, LOW);

}


int check_alarm(int hWatherCm) {

  if (hWatherCm > SOGLIA_ALLARME_1) {

     if (hWatherCm < SOGLIA_ALLARME_2)

       return 1;

     else

       return 2;

  }

  return 0;

}


long microseconds_to_centimeters(long microseconds) {

  /**

   * The speed of sound is 340.29 m/s or 29.4 microseconds per centimeter.

   * The ping travels out and back, so to find the distance of the

   * object we take half of the distance travelled.

   */

  return microseconds / 29.387 / 2;

}


void button() {

  //  Serial.println("Pulsante premuto");

  mute = !mute;

  

  lcd.setCursor(15, 1);

  if (!mute)

    lcd.write(SOUND_ICON_ON);

  else

    lcd.write('X');

}


Il programma può esser scaricato qui: sketchbook_pozzo.pde
È anche disponibile il PCB del progetto.

VOTA PER IL SIG. DANILO! GUARDA I PROGETTI DI TUTTI GLI ALTRI CANDIDATI.

[ratings]

19 Commenti

  1. Avrei proprio bisogno del progetto di Danilo! Semplice e grandioso! Infatti è utile perchè raccolgo l'acqua piovana che finisce in cisterne interrate e quando arriva la siccità non è facile gestirle. Con queso dispositivo possiamo avere solo l'imbarazzo della scelta. Come potrei fare per conoscere eventualmente il costo e poter riceverne almeno uno per poterlo testare? Ringrazio e saluto
  2. Bello anche questo progetto. Eccellenti gli spunti offerti da un programma sorprendentemente semplice. Decisamente oscura (non l'ho trovata io?) la realizzazione e gli schemi.
  3. meraviglioso, sono d'accordo con stefano... peccato che la clientela, secondo me, non la vedo pronta a recepire... didatticamente perfetto! commercialmente penso perchè noh!?
  4. Si, un grande ! Anch'io vorrei sapere se è possibile acquistare il tutto direttamente da Danilo, senza dover smanettare per trovare i due pezzi hardware.
  5. La redazione può metterci in contatto con Danilo affinchè possa rispondere ai nostri post? Vorrei porgli un'ulteriore domanda ovvero se possibile interfacciarlo con una centralina per l'irrigazione, di quelle agiscono sulle elettrovalvole e in questo caso considerano il budget idrico a disposizione dato dalla scheda realizzata da Danilo.
  6. Fantastico! Anche io credo che poterlo interfacciare a delle pompe/elettrovalvole lo renda utile a mille scopi. Come si fa a votare il proprio progetto preferito?
  7. Salve a tutti, Grazie per gli apprezzamenti, fa sempre piacere sapere che il proprio lavoro e` apprezzato e potrebbe essere utile ad altri appassionati di elettronica. L'idea di fagli comandare delle pompe o elettrovalvole e` molto buona, ed anche semplice da integrare nel dispositivo. Per disegnare il pcb ho usato questo programma http://www.expresspcb.com/ potete scaricarlo e aprire il file in fondo all'articolo. Il programma non e` niente di eccezionale ma e` semplice da usare. Ho costruito questo circuito per hobbies, chi vuole puo` realizzarlo e/o modificarlo per conto proprio. Ovviamente sono disponibile per consigli e adattamenti per diverse applicazioni.
  8. Ciao Danilo, ho notato che il tuo sensore ad ultrasuoni ha 3 pin invece che 4 (VDD GND Trigg e Echo) mi sapresti dire che differenza c'è ? Grazie mille
  9. L'unica differenza e` che con 3 pin viene utilizzato un solo pin per il segnale in output e in input. Per prima cosa si invia il Pulse per far in modo che il sensore inva un ultrasuono e poi si usa lo stesso pin in ingresso per aspettare l'Echo. Con 4 pin ce ne e` uno dedicato all'invio ed uno alla ricezione.
  10. Salve, ho appena acquistato un tidigino per poterlo utilizzare con linux e mac osx ma, con mia suprema sorpresa, non riesco a programmarlo. Il tidigino in mio possesso infatti e' utilizzabile solo con sistemi windows. Sotto linux ed osx viene riconosciuta la porta seriale, ma dall'idea di arduino non si riesce a caricare nulla, il tidigino va in timeout, mentre sotto windows tutto fila liscio. Vi risulta la cosa? Ho contattato i produttori, ma nemmeno loro mi hanno saputo dare una risposta avendo a disposizione solamente sistemi windows. Grazie R
  11. Ciao, ho provato ad creare questo progetto, ma ho trovato diversi problemi. 1) Nel display appaiono simboli strani e non mi da neanche dei valori numerici di misura. 2) Nessuna distanza viene rilevata dal sensore 3) Il buzzer continua a suonare continuamente a intermittenza. La sorgente e il progetto è stato copiato da questo link http://www.piumalab.org/display-per-livello-acqua/ Avrei bisogno di risolvere il problema perché il progetto da te creato per me è molto importante. Grazie in anticipo
  12. Ciao Volevo realizzare il tuo progetto, il quale è molto completo ed è tra i migliori che ho trovato in giro. Premetto che non ho le sufficienti conoscenze di programmazione. Ho il seguente problema: Andando a compilare - verificare lo sketch, mi compaiono molti errori di sintassi, tipo i seguenti: sketchbook_pozzo.pde: In function 'void setup()': sketchbook_pozzo:58: error: expected primary-expression before '{' token sketchbook_pozzo:58: error: expected `;' before '{' token sketchbook_pozzo:70: error: expected primary-expression before '{' token sketchbook_pozzo:70: error: expected `;' before '{' token sketchbook_pozzo:82: error: expected primary-expression before '{' token sketchbook_pozzo:82: error: expected `;' before '{' token sketchbook_pozzo.pde: In function 'void loop()': sketchbook_pozzo:146: error: call of overloaded 'write(int)' is ambiguous C:\Program Files (x86)\Arduino\libraries\LiquidCrystal/LiquidCrystal.h:82: note: candidates are: virtual size_t LiquidCrystal::write(uint8_t) C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino/Print.h:49: note: size_t Print::write(const char*) sketchbook_pozzo:154: error: call of overloaded 'write(int)' is ambiguous C:\Program Files (x86)\Arduino\libraries\LiquidCrystal/LiquidCrystal.h:82: note: candidates are: virtual size_t LiquidCrystal::write(uint8_t) C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino/Print.h:49: note: size_t Print::write(const char*) Può darsi che non abbia le corrette librerie inserite? Grazie Cordiali Saluti Fabio
  13. Ciao e complimenti per il tuo progetto. Volevo replicare il progetto per casa mia ma il listato da l'errore "assigning to an array from an initializer list" fermandosi sulla linea "newChar = {". Non riesco a sistemare la cosa. Per favore potresti aiutarmi? Ti ringrazio.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.

Main Menu