Hardware components | ||||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
Software apps and online services | ||||||
|
This is my upgraded version of a Digital & Binary Clock using an 8 Digit x 7 Segment LED Display.
I like to give new features for usual devices, specially clocks, and in this case the use of 7 Seg display for Binary Clock is unconventional and it is an interesting and a different way of applying it.
My choice in this project was to use a display powered by the MAX72xx wich is really useful because it uses only three digital Arduino ports. I also used an inexpensive DS1307 RTC module to store the time mode of clock on its internal memory: standard 24HS or AM-PM.
Every time you reset or restart the Arduino, the time mode will change.
The first four digits at left of display show the hours and minutes in decimal numbers. The next three digits show the hours, minutes and seconds in binary notation and the last digit at right inform the weekday.
About the code, I had to develop a way to use the "LedControl" library to turn conventional 7-Seg decimal display into a Binary display. The solution is to use "setRow" function that is usually applied for dot matrix display. With this function, you can control individually the display LEDs to create any chars pattern.
Hope you like!
/*
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