ultimo aggiornamento 3 maggio 2015


JLCPCB - 10 PCB per $ 2 (100 * 100 mm, 2-layer)
Il più grande produttore di PCB in Cina, oltre 600.000 clienti e oltre 10.000 ordini online al giorno
Produzione veloce in sole 24 ore e preventivo online gratuito: https://jlcpcb.com/quote


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