// Forum: https://forum.arduino.cc/t/time-almost-displaying-correctly-on-led-watch-matrix/1104816/2
// This Wokwi project: https://wokwi.com/projects/359845167514629121
#define NUM_COL 6 /// columns are anodes
#define NUM_ROW 6 /// rows are cathodes
#define COL_ON LOW /// the following four lines of code control switching the multiplexed LEDs on and off
#define COL_OFF HIGH
#define ROW_ON HIGH
#define ROW_OFF LOW
// pins for cathode (-) connections on ATmega328p, columns in LED matrix
const int colLED[NUM_COL] = { 2, 3, 4, 5, 6, 7 };
// pins for anode (+) connections on ATmega328p, rows in LED matrix
const int rowLED[NUM_ROW] = { 0, 1, A0, A1, A2, A3 };
int hour = 5; // 0...12 or 0...23
int minute = 35; // 0...59
int dayoftheweek = 2; // 1(sunday)...7
void setup() {
for (int i = 0; i < NUM_COL; i++) /// set all column pins to OUTPUT and OFF
{
pinMode(colLED[i], OUTPUT); /// set column LEDs to output
digitalWrite(colLED[i], COL_OFF); /// turn all columns off
}
for (int j = 0; j < NUM_ROW; j++) /// set all row pins to OUTPUT and OFF
{
pinMode(rowLED[j], OUTPUT); /// set row LEDs to output
digitalWrite(rowLED[j], ROW_OFF); /// turn all rows off
}
}
void loop() {
displayTime();
}
// displayTime is the led matrix multiplexing function.
void displayTime() {
// ----------------------------------------------------
// hour
// ----------------------------------------------------
int h = hour; // 0...11
if (h == 0)
h = 12; // 1...12
int hourRow = (h - 1) / 2;
int hourColumn = (h - 1) % 2;
ledOn( hourRow, hourColumn);
delayMicroseconds(150);
ledOff( hourRow, hourColumn);
// ----------------------------------------------------
// minute
// ----------------------------------------------------
int m = minute; // 0...59
int minuteRow;
if( m < 5) // zero minutes is located at the bottom
minuteRow = 5;
else
minuteRow = (m - 5) / 10; // start at 5 at the top
// A change of column for each 5 minutes: (m / 5)
// But the 10,20,30 are the right column: + 1
// There are two columns : %2
// The start column is : 2
int minuteColumn = 2 + ((m / 5) + 1) % 2;
ledOn( minuteRow, minuteColumn);
delayMicroseconds(150);
ledOff( minuteRow, minuteColumn);
// minute remainder 1...4
int r = m % 5;
if( r > 0) // leds off for seconds 0 and 5
{
r--; // row 0 for remainder 1
ledOn( r, 4);
delayMicroseconds(100);
ledOff( r, 4);
}
// ----------------------------------------------------
// day of the week
// ----------------------------------------------------
int w = dayoftheweek - 1; // 1(sunday)...7 -> 0...6
if( w > 0) // no led for sunday
{
w--; // monday is row 0
ledOn(w, 5);
delayMicroseconds(150);
ledOff(w, 5);
}
}
// turn on specific LED
void ledOn(int row, int col) {
digitalWrite(rowLED[row], HIGH); // row pin to +3V
digitalWrite(colLED[col], LOW); // column pin to 0V
}
// turn off specific LED
void ledOff(int row, int col) {
digitalWrite(rowLED[row], LOW); // row pin to 0V
digitalWrite(colLED[col], HIGH); // column pin to +3V
}