/*
Project: Digital & Binary Clock
Author: LAGSILVA
Hardware: Arduino UNO R3 - MAX72XX LED Matrix - RTC DS1307
Revision: 2.0
Date: 29.Dec.2017
License: CC BY-NC-ND 4.0
(Attribution-NonCommercial-NoDerivatives 4.0 International)
-----------------------------------------------------------------------
Note: This version is for RTC DS1307 without Temperature (C) feature.
-----------------------------------------------------------------------
*/
#include <LedControl.h> // Library for LED Matrix - MAX72XX
#include <Wire.h> // Library for DS1307RTC - Pins of Arduino UNO: A4 (SDA), A5 (SCL)
#include <DS1307RTC.h> // Library for Real Time Clock
#include <Time.h> // Library for Time
#include <TimeLib.h>
#define DS1307_I2C_ADDRESS 0x68 // This is the I2C address (RTC)
// Global Variables
byte hora, minuto, segundo, dia, mes, diaSemana, k;
byte timeMode, font, pos, pmStatus, clockType;
byte unidadeHora, unidadeMinuto, unidadeSegundo, dezenaHora, dezenaMinuto, dezenaSegundo, tempDez, tempUni;
byte unidadeDia, unidadeMes, dezenaDia, dezenaMes;
unsigned long tempo;
/*
Pin numbers do Arduino para conexao com o MAX72XX (matriz de LED com controlador MAX72XX)
pin 2 is connected to the DataIn (DIN)
pin 3 is connected to LOAD (CS)
pin 4 is connected to the CLK (CLK)
*/
LedControl lc = LedControl(2, 4, 3, 2); // LedControl(int dataPin, int clkPin, int csPin, int numDevices)
// Array of Digits - 0 a 9 - Size 5x3 (02 sets of fonts)
byte num[2][10][3] = {
// Stylish Font type
{
{0x70, 0x88, 0x70}, // 0
{0x00, 0xF8, 0x40}, // 1
{0x48, 0xA8, 0x98}, // 2
{0xF8, 0xA8, 0x88}, // 3
{0x78, 0x20, 0xE0}, // 4
{0xB8, 0xA8, 0xE8}, // 5
{0x38, 0x28, 0xF8}, // 6
{0xC0, 0xB8, 0x80}, // 7
{0xF8, 0xA8, 0xF8}, // 8
{0xF8, 0xA0, 0xE0}, // 9
},
// Conventional Font type
{
{0xF8, 0x88, 0xF8}, // 0
{0x00, 0xF8, 0x40}, // 1
{0xE8, 0xA8, 0xB8}, // 2
{0xF8, 0xA8, 0xA8}, // 3
{0xF8, 0x20, 0xE0}, // 4
{0xB8, 0xA8, 0xE8}, // 5
{0xB8, 0xA8, 0xF8}, // 6
{0xF8, 0x80, 0x80}, // 7
{0xF8, 0xA8, 0xF8}, // 8
{0xF8, 0xA0, 0xE0}, // 9
},
};
void setup() {
Wire.begin();
// Read datum of Time Mode (24hs or AM-PM)stored in RTC
Wire.beginTransmission(DS1307_I2C_ADDRESS); // Open I2C line in write mode
Wire.write((byte)0x08); // Set the register pointer to (0x08)
Wire.endTransmission(); // End Write Transmission
Wire.requestFrom(DS1307_I2C_ADDRESS, 1); // In this case read only 1 byte
pos = Wire.read(); // Read the Time Mode and Font Type stored at RTC memory
timeMode = pos & 1; // Time Mode (24hs = 0 / AM-PM = 1)
font = pos >> 1; // Font Type (Stylish = 0 / Conventional = 1)
clockType = pos >> 2; // Clock Type (Digital = 0 / Binary =1)
pos = (pos + 1) % 6; // Change the Time Mode and Font Type when Arduino is restarted
// Write data of Clock Mode (Decimal or Binary) in RTC
Wire.beginTransmission(DS1307_I2C_ADDRESS); // Open I2C line in write mode
Wire.write((byte)0x08); // Set the register pointer to (0x08)
Wire.write(pos); // Record at RTC memory the Mode of Time
Wire.endTransmission(); // End Write Transmission
// Setup of Display "0"
lc.shutdown(0, false); // Wakeup Display "0"
lc.setIntensity(0, 4); // Set the Brightness of Display ( 0 to 15)
lc.clearDisplay(0); // Clear Display "0"
// Setup of Display "1"
lc.shutdown(1, false); // Wakeup Display "1"
lc.setIntensity(1, 4); // Set the Brightness of Display ( 0 to 15)
lc.clearDisplay(1); // Clear Display "1"
setSyncProvider(RTC.get); // Function to read RTC (Real Time Clock)
setSyncInterval(60); // Set the number of seconds between re-sync
//setTime(14, 05, 0, 10, 12, 2017); // Set the Time and Date
//RTC.set(now()); // Set the RTC time
}
void loop() {
switch (clockType) {
// Digital Clock
case 0:
dia = day();
mes = month();
diaSemana = weekday();
tempo = millis();
while (millis() - tempo <= 6000) { // 06 seconds to plot Time
hora = hour();
minuto = minute();
if (timeMode == 1) {
if (hora > 11) {
lc.setLed(0, 0, 0, true); // Set PM status
}
hora = hora % 12;
if (hora == 0) {
hora = 12;
}
}
unidadeHora = hora % 10;
dezenaHora = hora / 10;
unidadeMinuto = minuto % 10;
dezenaMinuto = minuto / 10;
// Plot Time
for (k = 0; k < 3; k++) {
tempDez = num[font][dezenaHora][k] >> 2;
tempUni = num[font][unidadeHora][k] >> 2;
lc.setRow(0, k + 5 , tempDez);
lc.setRow(0, k + 1 , tempUni);
tempDez = num[font][dezenaMinuto][k] >> 2;
tempUni = num[font][unidadeMinuto][k] >> 2;
lc.setRow(1, k + 4 , tempDez);
lc.setRow(1, k , tempUni);
}
// Blink Seconds
lc.setLed(1, 7, 7, true);
delay(500);
lc.setLed(1, 7, 7, false);
delay(500);
}
lc.clearDisplay(0);
lc.clearDisplay(1);
unidadeDia = dia % 10;
dezenaDia = dia / 10;
unidadeMes = mes % 10;
dezenaMes = mes / 10;
// Plot Date
for (k = 0; k < 3; k++) {
tempDez = num[font][dezenaDia][k] >> 2;
tempUni = num[font][unidadeDia][k] >> 2;
lc.setRow(timeMode, k + 5 - timeMode, tempDez);
lc.setRow(timeMode, k + 1 - timeMode, tempUni);
tempDez = num[font][dezenaMes][k] >> 2;
tempUni = num[font][unidadeMes][k] >> 2;
lc.setRow((1 + timeMode) % 2, k + 4 + timeMode, tempDez);
lc.setRow((1 + timeMode) % 2, k + timeMode, tempUni);
}
lc.setLed((1 + timeMode) % 2, 7 * ( (1 + timeMode) % 2), 7, true); // Plot dot for month - 24h & AM/PM
lc.setLed(timeMode, 8 - diaSemana, 0, true); // Plot Weekday
delay(4000); // 04 seconds to plot Date
lc.clearDisplay(0);
lc.clearDisplay(1);
break;
// Binary Clock
case 1:
dia = day();
mes = month();
diaSemana = weekday();
hora = hour();
minuto = minute();
segundo = second();
lc.setLed(timeMode, 8 - diaSemana, 0, true); // Plot Weekday - Show
delay(1000); // 01 second to refresh Time & Date in Binary
pmStatus = 0;
if (timeMode == 1) {
if (hora > 11) {
pmStatus = 1;
}
hora = hora % 12;
if (hora == 0) {
hora = 12;
}
}
unidadeHora = hora % 10;
dezenaHora = hora / 10;
unidadeMinuto = minuto % 10;
dezenaMinuto = minuto / 10;
unidadeSegundo = segundo % 10;
dezenaSegundo = segundo / 10;
// Plot Time Hour-Minute-Second and PM status
lc.setRow((1 + timeMode) % 2, 7, (dezenaHora << 1) + 1);
lc.setRow((1 + timeMode) % 2, 6, (unidadeHora << 1) + 1);
lc.setRow((1 + timeMode) % 2, 4, (dezenaMinuto << 1) + 1);
lc.setRow((1 + timeMode) % 2, 3, (unidadeMinuto << 1) + 1);
lc.setRow((1 + timeMode) % 2, 1, (dezenaSegundo << 1) + 1);
lc.setRow((1 + timeMode) % 2, 0, (unidadeSegundo << 1) + 1 + (pmStatus << 7));
unidadeDia = dia % 10;
dezenaDia = dia / 10;
unidadeMes = mes % 10;
dezenaMes = mes / 10;
// Plot Date: Day-Month or Month-Day
lc.setRow(timeMode, 6 - 4 * timeMode, (dezenaDia << 1) + 1);
lc.setRow(timeMode, 5 - 4 * timeMode, (unidadeDia << 1) + 1);
lc.setRow(timeMode, 3 + 2 * timeMode, (dezenaMes << 1) + 1);
lc.setRow(timeMode, 2 + 2 * timeMode, (unidadeMes << 1) + 1);
lc.setLed(timeMode, 8 - diaSemana, 0, false); // Plot Weekday - Clear
break;
}
}
Comments