Welcome to Hackster!
Hackster is a community dedicated to learning hardware, from beginner to pro. Join us, it's free!
glennedi
Published © GPL3+

Multi clock board

For: 1*Maxx7219 or 4*Maxx7219 or LCD via I2C connection

IntermediateFull instructions provided357
Multi clock board

Things used in this project

Hardware components

Ds3231 clock module
×1
MAXX7219 Display unit
Use a a single unit or multiple chained together as required
×1
4K7 Resistor
×2
0.1 inch 15 way socket
For the Arduino Nano
×2
0.1 inch 5 way socket
For Maxx7219
×1
0.1 inch 6 way socket
For Ds3231
×1
0.1 inch 4 way pin strip
For connecting the LCD via I2C
×1
Stripboard 37*24
×1
Arduino Nano R3
Arduino Nano R3
×1

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Schematics

Top view of clock board

Circuit diagram of clock board

Code

Binary clock

C/C++
/*
 * 
 * Read time from Ds3231 real time clock and display on 1*Maxx7219 display in binary
 * December 2021
 * 
 * 
*/

//for the clock
#include <DS3231.h>
#include <Wire.h>
DS3231 Clock;
bool h12;
bool PM;


// For the display
#include "LedControl.h"
/*
  ***** Pin numbers for LedControl *****
  pin 11 is connected to the DataIn
  pin 13 is connected to the CLK
  pin 10 is connected to LOAD / CS
  We have 4* MAX72XX.
*/
const int total_displays=4;
LedControl lc = LedControl(11, 13, 10, total_displays);



void setup()
{
  // Wakeup call for MAX72XX 
  lc.shutdown(0, false);

  // Set the brightness to a medium values 
  lc.setIntensity(0, 2);

  // Clear display
  lc.clearDisplay(0);

  // Start the I2C interface
  Wire.begin();

  Serial.begin(9600);
  
}

void loop()
{

int i=0;
int j=0;

const int blank_space=10;//position of blank space in my_array[][]

static int hours=0;
static int minutes=0;
static int hours_tens=0;
static int hours_units=0;
static int minutes_tens=0;
static int minutes_units=0;
static bool decimal_point_on =true;

minutes=Clock.getMinute();
hours=Clock.getHour(h12, PM);

hours_tens=(hours/10);
hours_units=(hours%10);
minutes_tens=(minutes/10);
minutes_units=(minutes%10);

Serial.println(hours_tens,BIN);
Serial.println(hours_units,BIN);
Serial.println(minutes_tens,BIN);
Serial.println(minutes_units,BIN);

//blank leading zero's
if (hours<10){hours_tens=0;}

lc.setColumn(0,6,hours_tens);//setColumn(address,column,value)
lc.setColumn(0,5,hours_units);//setColumn(address,column,value)
lc.setColumn(0,4,minutes_tens);//setColumn(address,column,value)
lc.setColumn(0,3,minutes_units);//setColumn(address,column,value)

delay(1000);
    
}



// End of program

LCD clock via I2C

C/C++
/*
 * 
 * Read time from Ds3231 real time clock and display on LCD in 12 hour format
 * December 2021
 * 
 * 
*/

#include <Wire.h>  // Comes with Arduino IDE
#include <LiquidCrystal_I2C.h>

//for the clock
#include <DS3231.h>
DS3231 Clock;
bool h12;
bool PM;

// set the LCD address to 0x27 for most displays
// A FEW use address 0x3F
LiquidCrystal_I2C lcd(0x3F,16,2);

void setup()
{

  lcd.init();
  lcd.init();
  lcd.backlight();

// NOTE: Cursor Position: (CHAR, LINE) start at 0  
  lcd.setCursor(0,0); 
  lcd.print("The time is:");
  
}

void loop()
{
  lcd.setCursor(0,1);
  
  // hour, minute, second
  lcd.print(Clock.getHour(h12, PM), DEC);
  lcd.print(':');
  lcd.print(Clock.getMinute(), DEC);
  lcd.print(':');
  lcd.print(Clock.getSecond(), DEC);

  // Add AM/PM indicator
  if (h12) {
    if (PM) {
      lcd.print(" PM ");
    } else {
      lcd.print(" AM ");
    }
  } else {
    lcd.print(" 24h ");
  }    

}// end of code

4*Maxx7219 clock

C/C++
/*
 * 
 * Read time from Ds3231 real time clock and display on 4*Maxx7219 display
 * December 2021
 * 
 * 
*/

//for the clock
#include <DS3231.h>
#include <Wire.h>
DS3231 Clock;
bool h12;
bool PM;


// For the display
#include "LedControl.h"
/*
  ***** Pin numbers for LedControl *****
  pin 11 is connected to the DataIn
  pin 13 is connected to the CLK
  pin 10 is connected to LOAD / CS
  We have 4* MAX72XX.
*/
const int total_displays=4;
LedControl lc = LedControl(11, 13, 10, total_displays);

// Character table for clock numbers
/*
int Matrix[][X] = { {1,2,3,4,...,X},//  initializers for row indexed by 0
                    {3,4,5,6,...,X},//  initializers for row indexed by 1
                    {1,9,2,8,...,X},//  initializers for row indexed by 2
                    {9,8,7,6,...,X} };
*/
                   
 byte my_array [11][8]={
    {B01110000,  //0
    B10001000,
    B10011000,
    B10101000,
    B11001000,
    B10001000,
    B01110000,B00000000},
    //6,
 
    {B01000000,  //1
    B11000000,
    B01000000,
    B01000000,
    B01000000,
    B01000000,
    B11100000,B00000000},
    //4,
 
    {B01110000,  //2
    B10001000,
    B00001000,
    B00010000,
    B00100000,
    B01000000,
    B11111000,B00000000},
    //6,
 
    {B11111000,  //3
    B00010000,
    B00100000,
    B00010000,
    B00001000,
    B10001000,
    B01110000,B00000000},
    //6,
 
    {B00010000,  //4
    B00110000,
    B01010000,
    B10010000,
    B11111000,
    B00010000,
    B00010000,B00000000},
    //6,
 
    {B11111000,  //5
    B10000000,
    B11110000,
    B00001000,
    B00001000,
    B10001000,
    B01110000,B00000000},
    //6,
 
    {B00110000,  //6
    B01000000,
    B10000000,
    B11110000,
    B10001000,
    B10001000,
    B01110000,B00000000},
    //6,
 
    {B11111000,  //7
    B10001000,
    B00001000,
    B00010000,
    B00100000,
    B00100000,
    B00100000,B00000000},
    //6,
 
    {B01110000,  //8
    B10001000,
    B10001000,
    B01110000,
    B10001000,
    B10001000,
    B01110000,B00000000},
    //6,
 
    {B01110000,  //9
    B10001000,
    B10001000,
    B01111000,
    B00001000,
    B00010000,
    B01100000,B00000000},
    //6,

    {B00000000,  //blank 
    B00000000,
    B00000000,
    B00000000,
    B00000000,
    B00000000,
    B0000000,B00000000}    
};

void setup()
{
  // Wakeup call for MAX72XX 
  lc.shutdown(0, false);
  lc.shutdown(1, false);
  lc.shutdown(2, false);
  lc.shutdown(3, false);

  // Set the brightness to a medium values 
  lc.setIntensity(0, 2);
  lc.setIntensity(1, 2);
  lc.setIntensity(2, 2);
  lc.setIntensity(3, 2);

  // Clear display
  lc.clearDisplay(0);
  lc.clearDisplay(1);
  lc.clearDisplay(2);
  lc.clearDisplay(3);

  // Start the I2C interface
  Wire.begin();
  
}

void loop()
{

int i=0;
int j=0;

const int blank_space=10;//position of blank space in my_array[][]

static int hours=0;
static int minutes=0;
static int hours_tens=0;
static int hours_units=0;
static int minutes_tens=0;
static int minutes_units=0;
static bool decimal_point_on =true;

minutes=Clock.getMinute();
hours=Clock.getHour(h12, PM);

hours_tens=(hours/10);
hours_units=(hours%10);
minutes_tens=(minutes/10);
minutes_units=(minutes%10);

//blank leading zero's
if (hours<10){hours_tens=blank_space;}

//Function format:display_write(row,data,display_number,total_displays)
//row = an individual line on an individual display (1=top line 8=bottom line)
//data = 8 bits - bit=1 led on, bit=0 led off
//display_number = rightmost display is 0 count upwards to the display you wish to address 
//total_displays = the total number of displays you have chained together

//write data to displays
for (i=0;i<10;i++){
for(j=0;j<8;j++){display_write(j+1,my_array[minutes_units][j],0,total_displays);}

for(j=0;j<8;j++){display_write(j+1,my_array[minutes_tens][j],1,total_displays);}


for(j=0;j<8;j++){switch(j){case 3:display_write(j+1,decimal_point(my_array[hours_units][j],decimal_point_on),2,total_displays);break;
                            case 4:display_write(j+1,decimal_point(my_array[hours_units][j],decimal_point_on),2,total_displays);break;
                            default:display_write(j+1,my_array[hours_units][j],2,total_displays);break;} }

for(j=0;j<8;j++){display_write(j+1,my_array[hours_tens][j],3,total_displays);}

}     



delay(200);

decimal_point_on=!decimal_point_on;
    
}

// My_functions

//function to add or remove decimal point for particular display segment
byte decimal_point(byte x,bool y){if (y){x|=0b00000010;}else{x&=0b11111101;}return x;}


// Function to transfer a row of data to specific display
void display_write(int row, int value, int display_number, int total_displays) {

int i=0;
 
//transfer data to display_number only 
for (i=total_displays;i>=0;i--){if (i==display_number){lc.setRow(i,row,value);} } //void setRow(int addr, int row, byte value);
                                   
}

// End of program

Credits

glennedi
5 projects • 23 followers
Contact

Comments

Please log in or sign up to comment.