ultimo aggiornamento 3 maggio 2015 |
|
Il progetto realizzato da Antonio Valenti di Roma denominato theArd "Tempus fugit" è un orologio basato sulla piattaforma Arduino con la riproduzione dei suoni di un antico orologio a pendolo ed in particolare con:
< una melodia ad ogni cambio di ora; |
< Rintocchi alle ore 9, 12, 15, 18, 21, 24; |
< Segnale di “gong” al cambio del quarto, della mezzora e dei tre quarti. |
Ulteriore caratteristica del progetto è quella di “accompagnare” i
rintocchi sonori della giornata (cambio di ora, del “quarto”, della
“mezzora” e dei “tre-quarti”) con la visualizzazione di frasi
personalizzabili e la dicitura delle fasi salienti della giornata
secondo la rappresentazione “latina” in uso nell'antica Roma.
Inoltre viene visualizzato:
< il tempo corrente in ore, minuti e secondi; |
< la data (giorno, mese ed anno); |
< la temperatura (in gradi centigradi); |
< l'umidità relativa. |
|
|
Il sistema prevedere, anche, un pulsante di “mute” per silenziare temporaneamente i suoni. Per il progetto sono stati utilizzati i seguenti macro-componenti:
< Scheda Arduino Uno; |
< Modulo LPM11162; |
< Voice Shield by Adrirobot; |
< Modulo RTC connesso in I2C; |
< Sensore di temperatura ed umidità DHT11; |
< LCD 20x4 BLU compatibile HD44780 e con la libreria LiquidCrystal I2C; |
< Convertitore seriale I2C LCD HD44780 – Arduino; |
< Contenitore per progetti elettronici “hobby_parts_and_supplies”(GB); |
< Alimentatore stabilizzato switching da 9V/1A. |
All'interno del programma sono utilizzate le seguenti librerie:
< SoftwareSerial; |
< LPM11162; |
< dht11; |
< Wire; |
< LiquidCrystal_I2C. |
Vengono, infine, utilizzati i seguenti pin:
Pin +5V |
Alimentazione |
Pin GND |
Alimentazione |
Pin Digital 2 |
Pin 2 RESET modulo LPM11162 |
Pin Digital 3 |
Pin 3 TX modulo LPM11162 |
Pin Digital 4 |
Pin 4 RX modulo LPM11162 |
Pin Digital 5 |
Pin 5 BUSY modulo LPM11162; |
Pin Digital 14 (A3) |
Sensore DHT11; |
Pin Analogico A4 ed A5 |
moduli I2C (LCD e RTC) |
La corrente assorbita in esercizio è 110-125 mA. Il progetto, ovviamente, è totalmente personalizzabile in termini di:
< Scelta della melodia; |
< Suoni dei rintocchi; |
< Tipologia di visualizzazione delle ore; |
< Frasi che scorrono nelle varie fasi salienti della giornata. |
Programma
the_Ard__Tempus_fugit.ino
/* Sketch relativo all'implementazione di un orologio con la riproduzione dei suoni di un antico orologio a pendolo con una melodia ad ogni cambio di ora, rintocchi alle ore 9, 12, 15, 18, 21, 24 e segnale di “Gong” al cambio del quarto, della mezzora e dei tre quarti accompagnate dalla visualizzazione di frasi personalizzabili. Visualizzazione della fase oraria secondo la rappresentazione “latina” in uso nell'antica Roma. Aprile 2015 - ing.Antonio Valenti <http://www.progettotema.it> This example code is in the public domain. */ #include <SoftwareSerial.h> #include <LPM11162.h> #include <dht11.h> #include <Wire.h> #include <LiquidCrystal_I2C.h> #define DHT11PIN 14 // dht11 signal pin D17 (A3) #define LPM11162_RX 3 //Arduino TX (out) #define LPM11162_TX 4 //Arduino RX (in) #define LPM11162_RESET 2 //(out) #define LPM11162_BUSY 5 //(in) #define USA_TOOLKIT 0 #define DEBUG 0 LPM11162 audio(LPM11162_RX, LPM11162_TX, LPM11162_RESET, LPM11162_BUSY); int OldMinute = 0; int OldSecond = 0; int OldHour = 0; //******** #define Mute 7 // pin di input dove è collegato il pulsante di Mute int valMute = 0; // si userà val per conservare lo stato del pin di input int statoMute = 0; // ricorda lo stato in cui si trova il Mute, stato = 0 Mute Off, stato = 1 Mute On //********** const char* Mesi[] = {"Dic", "Gen", "Feb", "Mar", "Apr", "Mag", "Giu", "Lug", "Ago", "Set", "Ott", "Nov" }; byte termometro[8] = //icona della temperatura { B00100, B01010, B01010, B01110, B01110, B11111, B11111, B01110 }; byte umidita[8] = //icona dell'umidità { B00100, B00100, B01010, B01010, B10001, B10001, B10001, B01110, }; byte altop[8] = //icona dell'altoparlante { B00011, B00011, B11111, B11111, B11111, B11111, B00011, B00011, }; byte mute[8] = //icona del Mute { B00000, B10001, B01010, B00100, B01010, B10001, B00000, B00000, }; LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // const byte DS1307_CTRL_ID = 0x68; // indirizzo del DS1307 real-time clock const byte NumberOfFields = 7; // numero dei campi (bytes) richiesti dallo RTC const int numCols = 20; int Second ; int Minute; int Hour; int Day; int Wday; int Month; int Year; dht11 DHT11; void setup() { Serial.begin(9600); lcd.begin(20, 4); lcd.backlight(); Wire.begin(); lcd.clear(); lcd.createChar(1, termometro); lcd.createChar(2, umidita); lcd.createChar(3, altop); lcd.createChar(4, mute); #if USA_TOOLKIT if ( audio.synch() ) { audio.bridge(); } #endif audio.begin(9600); Wire.beginTransmission(DS1307_CTRL_ID); Wire.write((byte)0x00); Wire.endTransmission(); Wire.requestFrom(DS1307_CTRL_ID, NumberOfFields); Second = bcd2dec(Wire.read() & 0x7f); Minute = bcd2dec(Wire.read() ); Hour = bcd2dec(Wire.read() & 0x3f); // 24hr clock OldHour = Hour; OldMinute = Minute; } void loop() { //***********MUTE********* valMute = digitalRead(Mute); // legge il valore del Mute e lo conserva // controlla che l'input sia HIGH (pulsante premuto) // e cambia lo stato del Mute if (valMute == HIGH) { statoMute = 1 - statoMute; } if (statoMute == 1) { audio.volume(0); lcd.setCursor(18, 2); lcd.write(3); // simbolo indicatore dell'altoparlante lcd.setCursor(19, 2); lcd.write(4); // simbolo indicatore del Mute } else { audio.volume(50); lcd.setCursor(18, 2); lcd.print(" "); // Elimina simbolo Mute } //*************End of MUTE*********** Wire.beginTransmission(DS1307_CTRL_ID); Wire.write((byte)0x00); Wire.endTransmission(); Wire.requestFrom(DS1307_CTRL_ID, NumberOfFields); Second = bcd2dec(Wire.read() & 0x7f); Minute = bcd2dec(Wire.read() ); Hour = bcd2dec(Wire.read() & 0x3f); Wday = bcd2dec(Wire.read() ); Day = bcd2dec(Wire.read() ); Month = bcd2dec(Wire.read() ); Year = bcd2dec(Wire.read() ); Year = Year + 2000; dispaly_temperatura(); //visualizza temperatura digitalClockDisplay(); // visualizza il tempo delay(1000); if (Minute != OldMinute) { OldMinute = Minute; switch (Minute) { case 15: Quarto(); lcd.clear(); lcd.setCursor(0, 0); lcd.print(" XV minuties "); marquee(" frase "); //****frase personalizzata**** lcd.clear(); break; case 30: Quarto(); lcd.clear(); lcd.setCursor(0, 0); lcd.print(" XXX minuties "); marquee(" frase "); //****frase personalizzata**** lcd.clear(); break; case 45: Quarto(); lcd.clear(); lcd.setCursor(0, 0); lcd.print(" XLV minuties "); marquee(" frase "); //****frase personalizzata**** lcd.clear(); break; default : #if DEBUG Serial.println(Minute); #endif break; } } if (Hour != OldHour) { OldHour = Hour; switch (Hour) { case 9: Ora(); Nove(); lcd.clear(); lcd.setCursor(0, 0); lcd.print(" hora tertia "); marquee(" frase "); //****frase personalizzata**** lcd.clear(); break; case 12: //Ora(); //Dodici(); lcd.clear(); lcd.setCursor(0, 0); lcd.print(" hora sexta "); marquee(" frase "); //****frase personalizzata**** lcd.clear(); break; case 15: Ora(); Tre(); lcd.clear(); lcd.setCursor(0, 0); lcd.print(" hora nona "); marquee(" frase "); //****frase personalizzata**** lcd.clear(); break; case 18: Ora(); Sei(); lcd.clear(); lcd.setCursor(0, 0); lcd.print(" hora duodecima "); marquee(" frase "); //****frase personalizzata**** lcd.clear(); break; case 21: Ora(); Nove(); lcd.clear(); lcd.setCursor(0, 0); lcd.print(" hora tertia "); lcd.setCursor(0, 1); lcd.print(" prima vigilia "); marquee(" frase "); //****frase personalizzata**** lcd.clear(); break; case 00: Ora(); Dodici(); lcd.clear(); lcd.setCursor(0, 0); lcd.print(" hora tertia "); lcd.setCursor(0, 1); lcd.print(" secunda vigilia "); marquee(" frase "); //****frase personalizzata**** lcd.clear(); break; default : Serial.print(Hour); Ora(); lcd.clear(); lcd.setCursor(1, 0); lcd.print(" Tempus fugit "); marquee(" frase "); //****frase personalizzata**** lcd.clear(); break; } } } // Converte BCD a Decimale byte bcd2dec(byte num) { return ((num / 16 * 10) + (num % 16)); } void digitalClockDisplay() { Serial.print(Hour); lcd.setCursor(6, 1); lcd.print(Hour); printDigits(Minute); printDigits(Second); Serial.print(" "); lcd.print(" "); lcd.setCursor(4, 0); Serial.print(Day); lcd.print(Day); Serial.print(" "); lcd.print(" "); Serial.print(Month[Mesi]); lcd.print(Month[Mesi]); Serial.print(" "); lcd.print(" "); Serial.print(Year); lcd.print(Year); Serial.println(); } // utility per la visualizzazione dell'orologio void printDigits(int digits) { Serial.print(":"); lcd.print(":"); if (digits < 10) { Serial.print('0'); lcd.print("0"); } Serial.print(digits); lcd.print(digits); } // seguono le utility per la dicitura dell'ora void Ora() { audio.play("suoneria.Wav"); while ( audio.isBusy() ); delay (1000); } void Nove() { audio.play("9.Wav"); while ( audio.isBusy() ); delay (1000); } void Dodici() { audio.play("12.Wav"); while ( audio.isBusy() ); delay (1000); } void Tre() { audio.play("3.Wav"); while ( audio.isBusy() ); delay (1000); } void Sei() { audio.play("6.Wav"); while ( audio.isBusy() ); delay (1000); } void Quarto() { audio.play("15.Wav"); while ( audio.isBusy() ); delay (1000); } // utility per il marquee delle frasi void marquee( char *text) { int length = strlen(text); if (length < numCols) lcd.print(text); else { int pos; for ( pos = 0; pos < numCols; pos++) lcd.print(text[pos]); delay(1000); pos = 1; while (pos <= length - numCols) { lcd.setCursor(0, 2); for ( int i = 0; i < numCols; i++) lcd.print(text[pos + i]); delay(300); pos = pos + 1; } } } // utility per la visualizzazione della temperatura ed della umidità relativa void dispaly_temperatura() { int chk = DHT11.read(DHT11PIN); lcd.setCursor(3, 3); lcd.write(1); // simbolo indicatore della temperatura lcd.setCursor(5, 3); lcd.print((float)DHT11.temperature, 0); lcd.setCursor(7, 3); lcd.print((char)223); // simbolo dei gradi Celsius lcd.print("C"); lcd.setCursor(12, 3); lcd.write(2); // simbolo indicatore dell'umidità lcd.setCursor(14, 3); lcd.print((float)DHT11.humidity, 0); lcd.print("%"); Serial.print((float)DHT11.temperature); Serial.print(" "); Serial.print((float)DHT11.humidity ); Serial.println(); } |
Elenco revisioni | |
27/07/2014 | Corretto refuso sul valore di C8 |
29/10/2012 | Emissione preliminare |