Archivi tag: orologio

Realizziamo un orologio con l’RTC di Arduino UNO R4 WiFi

Arduino UNO R4 WiFi possiede un RTC interno facilmente programmabile che ci consentirà di mantenere costantemente traccia dell’ora e della data corrente.

Per chi ha iniziato da poco le sperimentazioni elettroniche ricordo che un Real-Time Clock (RTC), o Orologio in Tempo Reale, è un tipo di orologio costituito da un circuito elettronico utilizzato per tracciare il tempo in tempo reale. Questo significa che tiene traccia del giorno della settimana, della data e dell’ora corrente, dei minuti, dei secondi, proprio come un orologio normale, inoltre è possibile impostare un RTC per gestire l’ora legale e l’ora solare.

Nelle versione precedente di Arduino, UNO R3 non era presente un RTC pertanto bisognava utilizzare un apposito circuito elettronico esterno così come dettagliato nel post su questo sito: Utilizzare un orologio RTC con Arduino – Modulo Tiny RTC I2C, modulo RTC dotato di un integrato DS1307 cuore fondamentale della scheda.

L’utilizzo dell’RTC su Arduino UNO R4 WiFi avviene utilizzando la libreria RTC che consente di impostare oppure ottenere l’orario o ancora gestire allarmi per attivare interrupt.

Come accennato ad inizio post l’RTC integrato dispone di un pin VRTC, che viene utilizzato per mantenere in funzione l’RTC, anche quando l’alimentazione della scheda viene interrotta. Per utilizzare questa funzione è sufficiente fornire una tensione compresa tra 1,6 e 3,6 V al pin VRTC. In un post successivo mostrerò come utilizzare il pin VRTC.

Facendo riferimento agli esempi disponibili sul sito Arduino e nell’IDE analizziamo le fasi di configurazione dell’RTC.

Impostazione della data e dell’ora

RTCTime startTime(01, Month::AUGUST, 2023, 20, 49, 00, DayOfWeek::TUESDAY, SaveLight::SAVING_TIME_ACTIVE)

RTC.setTime(startTime)

Per impostare l’orario bisogna creare un oggetto RTCTime, in cui deve essere specificato il giorno, il mese, l’anno, l’ora, il minuto, il secondo, il giorno della settimana e l’attivazione dell’ora legale se prevista nella nazione in cui si sta utilizzando la scheda, quindi per impostare l’orario bisogna usare il metodo startTime.

Per chi incomincia con la programmazione il concetto di metodo appartiene alla programmazione ad orientata agli oggetti come ad esempio in C++, quando si programma in C è meglio parlare di funzione, ma spesso i due concetti vengono usati in modo alternativo.

Il primo sketch non fa altro che impostare l’ora corrente:

// inclusione della libreria RTC
#include "RTC.h"

void setup() {

  // impostazione della velocità della serial monitor
  Serial.begin(9600);

  // avvio dell'RTC
  RTC.begin();

  // creazione dell'oggetto RTCTime (possiamo assegnare un nome a piacimento)
  // data del giorno, mese, anno, ore, minuti, secondi, giorno della settimana, attivazione passaggio all'ora legale
  RTCTime startTime(2, Month::AUGUST, 2023, 9, 15, 00, DayOfWeek::WEDNESDAY, SaveLight::SAVING_TIME_ACTIVE);

  // impostazione dell'RTC con la data e lora configurate per RTCTime
  RTC.setTime(startTime);
}

// il loop non contiene nulla
void loop() {
}

Continua a leggere

Utilizzare un orologio RTC con Arduino – Modulo Tiny RTC I2C – Visualizzazione su display I2C

Continuo la serie di post dedicati all’uso dell’RTC con integrato DS1307, in questa lezione viene suggerito come visualizzare su un display 16×2 Hitachi HD44780 1602 con modulo I2C PCF8574T: giorno della settimana, data e ora.
L’obiettivo che si vorrà raggiungere nei prossimi tutorial sarà quello di realizzare un timer programmabile da utilizzare in diverse esercitazioni di automazione.

Lo Schema di collegamento è il seguente:

Allego lo Sketch generale in cui ho inserito commenti di spiegazione sulle varie parti del codice e sull’utilizzo di specifiche funzioni.

Per quanto riguarda la libreria LiquidCrystal_I2C vi rimando alla lezione:
Utilizzo dell’LCD 16×2 Hitachi HD44780 1602 con modulo I2C PCF8574T

/* Prof. Maffucci Michele
   15.01.2020
   Orologio - v01
*/

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

// La data e l'ora funzionano usando un RTC DS1307 collegato tramite I2C e Wire lib
#include "RTClib.h"

RTC_DS1307 rtc;

char stringa1[8]; // per memorizzare la stringa che include la data (dimensione massima data: 8 caratteri)
char stringa2[6]; // per memorizzare la stringa che include l'ora (dimensione massima ora: 6 caratteri)

// Variabile per la verifica della cancellazione del display
int chiaveCancella = 0;

// Array multidimensionale costituito
// da 7 righe (giorni della settimana)
// 4 colonne (le lettere che compongono il giorno più il carattere null con cui deve terminare una stringa)

char giornoDellaSettimana[7][4] = {"Dom", "Lun", "Mar", "Mer", "Gio", "Ven", "Sab"};

// Inizializzazione della libreria in cui è descritta la modalità di utilizzo dei pin dell'LCD,
// impostazione dell'indirizzo dell'LCD 0x27 di 16 colonne e 2 linee

LiquidCrystal_I2C lcd(0x27, 16, 2);

void setup () {

  lcd.begin();      // inizializzazione dell'LCD
  lcd.backlight();  // attivazione della retroilluminazione

  if (!rtc.isrunning()) {
    lcd.setCursor(0, 0);
    lcd.print("RTC non funzionante!");
    // la riga che segue permette di impostare data e ora prendendo l'informazione
    // dal computer a cui è collegato Arduino
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // la riga che segue permette di impostare
    // esplicitamente da parte dell'utente data e ora
    // Gennaio 21, 2014 alle 3 del pomeriggio ybisognrà scrivere:
    // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
  }
}

void loop () {

/* Controllo del funzionamento dell'RTC all'interno del loop

   Il controllo della disconnessione dell'RTC viene effettuato anche all'interno del loop,
   se ciò non venisse effettuato, una disconnessione dell'RTC non permetterebbe la visualizzazione
   del messaggio "RTC non risponde", ma verrebbero visualizzati valori numerici errati.
   La successiva connessione dell'RTC farà riapparire data e ora, ma in una modalità non allineata,
   in cui saranno mostrati i valori numerici derivanti dalla precedente disconessione.
*/

  if (!rtc.isrunning()) {
    lcd.setCursor(0, 0);
    lcd.print("RTC non risponde");
    lcd.setCursor(0, 1);
    lcd.print("                ");
    chiaveCancella = 1;
  }

  else
  {
    if (chiaveCancella == 1) {
      
      /* La cancellazione del display avviene solamente una sola volta, solo se si è verificata
         una precedente disconnessione dell'RTC. L'azione è necessaria perché in fase
         di riconnessione dell'RTC appaiono sul display numeri non coerenti.
         La cancellazione potrebbe essere effettuata  direttamente nel corpo della prima if,
         ma ciò causerebbe un flikering del testo.
      */
      
      lcd.clear();
      chiaveCancella = 0;
    }

    DateTime now = rtc.now();

    lcd.setCursor(0, 0);

    // estrae dall'array giornoDellaSettimana il nome del giorno
    lcd.print(giornoDellaSettimana[now.dayOfTheWeek()]);
    lcd.setCursor(5, 0);

    /*
      int sprintf(char *str, const char *format, ...);
      ha lo stesso funzionamento della printf, con la differenza che
      l'output non sarà visualizzato sullo schermo (standard output), ma
      immagazzinato nel vettore str

      %d è uno dei possibili specificatori di formato che può essere usato nella sprintf
      ha il compito di indicare alla funzione (la sprintf) il tipo della variabile che deve essere
      visualizzata, in questo caso con d indichiamo decimale.
      Con %02d si specifica la stampa di solo due numeri decimali.
    */

    sprintf(stringa1, "%2d/%02d/%d", now.day(), now.month(), now.year());
    lcd.print(stringa1);
    lcd.setCursor(0, 1);
    sprintf(stringa2, "%02d:%02d:%02d", now.hour(), now.minute(), now.second());
    lcd.print(stringa2);
    delay(1000);
  }
}

Di seguito riprendo quanto già inserito nei commenti:

char giornoDellaSettimana[7][4] = {"Dom", "Lun", "Mar", "Mer", "Gio", "Ven", "Sab"};

Definisce un Array multidimensionale costituito da 7 righe, i giorni della settimana e 4 colonne, le lettere che compongono il giorno (3 lettere) più il carattere null con cui deve terminare una stringa.

...
 if (!rtc.isrunning()) {
    lcd.setCursor(0, 0);
    lcd.print("RTC non risponde");
    lcd.setCursor(0, 1);
    lcd.print("                ");
    chiaveCancella = 1;
  }
...

Il controllo della disconnessione dell’RTC viene effettuato anche all’interno del loop, se ciò non venisse eseguito, una disconnessione dell’RTC non permetterebbe la visualizzazione del messaggio “RTC non risponde”, ma verrebbero mostrati valori numerici errati. La successiva connessione dell’RTC farà riapparire data e ora, ma in una modalità non allineata, in cui saranno mostrati i valori numerici derivanti dalla precedente disconessione.

...
  else
  {
    if (chiaveCancella == 1) {
      
      /* La cancellazione del display avviene solamente una sola volta, solo se si è verificata
         una precedente disconnessione dell'RTC. L'azione è necessaria perché in fase
         di riconnessione dell'RTC appaiono sul display numeri non coerenti.
         La cancellazione potrebbe essere effettuata  direttamente nel corpo della prima if,
         ma ciò causerebbe un flikering del testo.
      */
      
      lcd.clear();
      chiaveCancella = 0;
    }
...

La cancellazione del display avviene una sola volta, solo se si è verificata una precedente disconnessione dell’RTC. L’azione è necessaria perché in fase di riconnessione dell’RTC appaiono sul display numeri non coerenti. La cancellazione potrebbe essere effettuata direttamente nel corpo della prima if, ma ciò causerebbe un flikering del testo così come appare nell’immagine che segue:

sprintf(stringa1, "%2d/%02d/%d", now.day(), now.month(), now.year());

int sprintf(char *str, const char *format, …); ha lo stesso funzionamento della printf, con la differenza che l’output non sarà visualizzato sullo schermo (standard output), ma immagazzinato nel vettore str.

%d è uno dei possibili specificatori di formato che può essere usato nella sprintf ha il compito di indicare alla funzione (la sprintf) il tipo della variabile che deve essere visualizzata, in questo caso con d indichiamo decimale. Con %02d si specifica la stampa di solo due numeri decimali.

Per i miei allievi:

Esercizio 1

Modificare lo sketch proposto in modo che la retroilluminazione dello schermo venga spenta dopo 15 secondi e la pressione di un pulsante la riattivi.

Esercizio 2

Modificare lo sketch realizzato al punto 2 inserendo anche un sensore DHT11 che mostra temperatura ed umidità dell’ambiente.

Appunti di programmazione su Arduino: orologio interno

delay(ms)

Mette in pausa un programma per la quantità di tempo specificata in millisecondi, un valore di 1000 millisecondi equivale a 1 secondo.

delay(1000);   // attende per 1 secondo

millis()

Restituisce il numero di millisecondi da quando la scheda Arduino ha incominciato l’esecuzione del programma corrente. Il tipo di dato è un unsigned long.

value = millis();   // imposta la variabile 'value'
                    // al valore restituito dalla funzione

Nota: questo valore va in overflow (supera il limite della memoria) per cui ricomincia da zero dopo circa 9 ore.

micros()

Restituisce il numero di microsecondi da quando la scheda Arduino ha incominciato l’esecuzione del programma corrente. Il tipo di dato è un unsigned long.

Nota: questo valore va in overflow (supera il limite della memoria) per cui ricomincia da zero dopo circa 70 minuti.

Sulle schede Arduino a 16MHz (ad es. Duemilanove e Nano), questa funzione ha una risoluzione di 4 microsecondi (il valore restituito è un multiplo di 4 secondi). Sulle schede Arduino a 8 MHz (ad es. LilyPad), questa funzione ha una risoluzione di 8 microsecondi.

Nota: ci sono 1.000 microsecondi in un millisecondo e 1.000.000 di microsecondi in un secondo.

delayMicroseconds(us)

Mette in pausa il programma per una quantità di tempo (in microsecondi) specificato dal parametro della funzione. Il tipo di dato è un unsigned long.

delayMicrosecons(1000);   // attende un millesimo di secondo

Per le lezioni precedenti consultare la sezione Appunti di programmazione che trovate nella pagina Arduino di questo sito.

Installare su Ubuntu il software dell’eZ430 Chronos

Procediamo nell’installazione di tutte le componenti necessarie per poter utilizzare il software di gestione dell’eZ430-Chronos su Ubuntu.

Il software eZ430-Chronos per Linux necessita delle TCL/Tk e se la vostra distribuzione Linux non la include installatela utilizzando i comandi apt-get:

sudo apt-get install tcl8.5
sudo apt-get install tk8.5

[wpspoiler name=”Fasi di installazione tcl8.5 e tk8.5″]

[/wpspoiler]

Per generare gli eventi della tastiera e i click del mouse tramite i pulsanti dell’orologio è richiesta l’installazione di xdotool. Installate con il comando apt-get:

sudo apt-get install xdotool

[wpspoiler name=”Fasi di installazione di xdotool”]

[/wpspoiler]

Ora sul vostro computer avete creato l’infrastruttura necessaria per per poter procedere con l’installazione eZ430-Chronos Setup.

Inseriamo il CD-ROM e andate nella cartella:

software -> linux -> ez430-chronos installer

doppio click su chronos-setup:

[wpspoiler name=”Dove si trova chronos-setup?”]

[/wpspoiler]

[wpspoiler name=”Fasi di installazione di eZ430-Chronos”]

[/wpspoiler]

Conclusa l’installazione troverete nella vostra home directory la cartella: Texas Instruments dove sono allocati i file necessari per la gestione del vostro microcontrollore

[wpspoiler name=”Dove si trova il software installato?”]

[/wpspoiler]

Continuiamo con l’installazione…

inserite su una presa USB del PC l’access point RF dell’orologio:

Verificate nella directory /dev la presenza di /dev/ttyACMx, dove x specifica il numero della porta.

Se l’access point RF non viene montato in /dev/ttyACMx, impostate la variabile COM nel file eZ430-Chronos_CC_1_1.tcl e eZ430-Chronos_Datalogger_1_1.tcl in /dev/ttyACM0

Rendere eseguibili i due script: eZ430-Chronos_CC_1_1.tcl e eZ430-Chronos_Datalogger_1_1.tcl mediante il comando da terminale:

chmod u+x ./eZ430-Chronos_CC_1_1.tcl
chmod u+x ./eZ430-Chronos_Datalogger_1_1.tcl

a questo punto potete avviare i due script da terminale:

./eZ430-Chronos_CC_1_1.tcl

e

./eZ430-Chronos_Datalogger_1_1.tcl

oppure facendo doppio click sul file e poi premendo su esegui.

Nel Control Center attivate la comunicazione tra computer e orologio facendo click su “Start Access Point” e sull’orologio selezionate con il pulsante # la funzionalità ACC o PPT e avviate la trasmissione premendo sul pulsante “freccia in basso”.

Il filmato che segue mostra il funzionamento dell’accellerometro a 3 assi, i grafici X, Y, Z in funzione del tempo mostrano i movimenti dell’orologio lungo i tre assi:

Con l’eZ430-Chronos potete pilotare il puntatore del mouse, ad esempio per il controllo di una presentazione PowerPoint su computer, dal Control Center attivate l’access point, selezionate la funzionalità ACC o PPT sull’orologio (pulsante #) e attivate la comunicazione con il pulsante “freccia in basso”, poi fate click sul pulsante “Mouse On (M)” (oppure premete il tasto M della tastiera) a questo punto potete pilotare il puntatore.

Di seguito il filmato che mostra il controllo del mouse:

eZ430-Chronos ambiente di sviluppo per orologi della Texas Instruments

La settimana scorsa ho acquistato un kit di sviluppo ez430 chronos basato sul microcontrollore 16 bit della Texas Instruments CC430F6137, dispositivo a bassissimo consumo destinato alla realizzazione di dispositivi portatili.

Il kit di sviluppo è un orologio sportivo water resistant fino a 30 metri con software e hardware open e quindi potete variarne ogni cosa, sul CD-ROM in dotazione trovate anche i PCB!
ez430 chronos è fornito con una chiavetta usb che permette di collegare direttamente al computer il microcontrollore ed una chiavetta RF.
Il display LCD a 96 segmenti è retroilluminato, è dotato di un accelerometro a 3 assi, termometro, altimetro e barometro, sensore voltaggio batteria, rilevatore di battito cardiaco che può ricevere da diversi sensori in commercio, pedometro, velocità bici e possibilità di controllare il PC mediante l’orologio come se fosse un mouse.

Potete programmare e aggiornare il software direttamente anche via radio.

Il costo del kit di sviluppo è di $49.00 (a cui andranno successivamente aggiunti 15 Euro di Dogana) dal sito della Texas Instruments ed è composto da:

  • Orologio wireless eZ430-Chronos con software già installato
  • chiavetta USB per programmazione e debugging
  • CC1111 USB RF access point
  • Cacciavite Phillips
  • viti di ricambio
  • CD contenente la documentazione e il software di sviluppo

Esistono 3 versioni che differiscono per la frequenza di funzionamento:

  • eZ430-Chronos-433 – 433 MHz
  • eZ430-Chronos-868 – 868 MHz
  • eZ430-Chronos-915 – 915 MHz

Io ho acquistato la versione a 915 MHz è mi è stata consegnata in 48 ore! Inoltre l’assistenza clienti di TI è ottima.

L’orologio viene fornito già programmato e lo potete usare subito come orologio sportivo, sul CD-ROM disponete del software necessario per usarlo anche come datalogger.

Si programma in C e sul CD-ROM avete alcuni esempi, in questi giorni di vacanza sto facendo alcuni esperimenti e se riuscirò realizzerò alcuni tutorial.
Gli ambienti di sviluppo funzionano su Windows e Linux, io per ora sto programmando su Ubuntu.

In ogni caso se volete approfondire l’argomento questi i due link di partenza:

Di seguito un video interessante in cui l’orologio viene usato come chiave elettronica per l’apertura di una porta di un’abitazione.

Spero di poterne trarre spunti didattici interessanti da sperimentare con i miei allievi.