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.

0 votes, average: 0,00 out of 50 votes, average: 0,00 out of 50 votes, average: 0,00 out of 50 votes, average: 0,00 out of 50 votes, average: 0,00 out of 5 (0 voti, media: 0,00 su 5)
Per poter esprimere il tuo giudizio devi essere registrato. Accedi o registrati.
Loading...