In allegato un semplice sketch che visualizza su un display Oled I2C 128x64 px, controller SSD1306, ora e data con i nomi in esteso dei giorni e dei mesi prelevando i dati da un modulo RTC DS3231.
Il tutto è da intendersi ad uso didattico come esempio su come vanno utilizzato i display Oled e gli RTC DS3231, le librerie utilizzate sono specificate, con relativi link, nella descrizione dello sketch, in particolare viene usata la libreria Oled_I2C di Rinky Dink, in pratica un porting della UTFT per gli Oled, e la DS3231 di Korneliusz Jarzebski, a mio avviso la migliore tra quelle che ho provato.
Per inizializzare l’RTC nel codice c’è questa riga “clock.setDateTime(DATE, TIME);” che fa caricare data e ora del pc al momento della compilazione sul DS3231, va usata solo la prima volta che si carica lo sketch, poi deve essere commentata lo sketch va ricompilato e ricaricato, altrimenti ad ogni reset l’RTC viene riportato alla data e ora di compilazione.
Le dimensioni dello sketch dopo la compilazione sono rilevanti, flash ~10178 byte, per via del font caratteri, ram 1324 byte, per via del buffer da 1k che viene creato dalla libreria per gestire il display.
/*
Oled RTC v1.0 build 07/08/2017
Orologio con datario e temperatura.
display oled 128x64, RTC DS3231
La temperatura è quella del sensore interno al RTC,
può risultare sensibilmente diversa da quella ambiente reale.
Librerie:
oled - Oled_I2C di Rinky Dink (UTFT x Oled), http://www.rinkydinkelectronics.com/library.php?id=79
rtc - DS3231 di Korneliusz Jarzebski, https://github.com/jarzebski/Arduino-DS3231
todo:
Nella prossima versione verrà aggiunto il supporto
ad un sensore DHT22 per umidità e temperatura e un
sensore BMP180 per la pressione atmosferica.
*/
/*
struct RTCDateTime
{
uint16_t year;
uint8_t month;
uint8_t day;
uint8_t hour;
uint8_t minute;
uint8_t second;
uint8_t dayOfWeek;
uint32_t unixtime;
};
*/
#include <avr/pgmspace.h>
#include <OLED_I2C.h>
#include <Wire.h>
#include <DS3231.h>
DS3231 clock;
OLED myOLED(SDA, SCL, 8);
RTCDateTime dt;
// font utilizzati
extern uint8_t SmallFont[];
// extern uint8_t MediumNumbers[];
extern uint8_t BigNumbers[];
char stringa[20];
// array per nome giorni e mesi
const char mesi[13][10] = {
{" "}, {"Gennaio"}, { "Febbraio"}, { "Marzo"}, {"Aprile"}, {"Maggio"},
{ "Giugno"}, {"Luglio"}, {"Agosto"}, { "Settembre"}, {"Ottobre"}, {"Novembre"}, {"Dicembre"}
};
const char giorni[8][10] = {
{" "}, {"Lun."}, { "Mar."}, {"Mer."}, {"Gio."}, {"Ven."}, {"Sab."}, {"Dom."}
};
void setup()
{
clock.begin(); // avvia RTC
myOLED.begin(); // avvia oled
myOLED.clrScr(); // cancella screen buffer oled
myOLED.setBrightness(255); // setta luminosità oled
/*
decommentare questa linea solo per inizializzare
il RTC con la data e ora di compilazione del codice
*/
// clock.setDateTime(__DATE__, __TIME__);
}
void loop()
{
float tempr;
char temprS[6];
uint8_t old_sec;
dt = clock.getDateTime(); // acquisce dati dal RTC
if (old_sec != dt.second) // verifica cambio orario
{
old_sec = dt.second;
myOLED.setFont(BigNumbers);
// scrive ora su oled
sprintf(stringa, "%i-%i-%i", dt.hour, dt.minute, dt.second);
myOLED.print(stringa, CENTER, 0);
myOLED.setFont(SmallFont);
// scrive data su oled
//sprintf(stringa, "%s %i %s %i", giorni[dt.dayOfWeek], dt.day, mesi[dt.month], dt.year);
myOLED.print(stringa, CENTER, 35);
// legge temperatura
tempr = clock.readTemperature();
// converte float in stringa, 2 cifre intere, 1 decimale
dtostrf(tempr, 4, 1, temprS);
// scrive temperatura su oled
sprintf(stringa, "Temperatura: %s", temprS);
myOLED.print(stringa, CENTER, 55);
// copia screen buffer sullo schermo
myOLED.update();
// cancella screen buffer
myOLED.clrScr();
}
}
foto del prototipo realizzato con un Arduino UNO, si può usare qualunque modello di Arduino dotato di I2C, e una breadboard per collegare display e RTC, alimentazione sia del display che del modulo RTC a 5V.
Attenzione che non tutti i modelli di display Oled 128x64 includono un regolatore di tensione a 3.3V, fate molta attenzione a questo “dettaglio” prima di collegare l’alimentazione.