// 4-Bit LED Digital Module with 2x 74HC595D-chip, there are 5 pins from top to bottom:
// VCC : pin 5V;
// SCLK : pin A0;
// SRLK : pin A1;
// DIO : pin A3
// GND : pin GND
#define PIN_SCLK A0 // serial clock, set LOW & HIGH after set PIN_DIO
#define PIN_RCLK A1 // register clock, set LOW & HIGH after write digit
#define PIN_DIO A2 // set PIN_DIO set index bit from 0,1,2,3,4,5,6,7 = A,B,C,D,E,F,G,DP
const byte TOTAL_DIGITS = 4; // default is 4, you may need to change this value depends on amounts of digits on your module, i'm not sure will it work if changed, good luck ;))
const byte BYTES_0_TO_9[] = { // list of bytes to display from top to bottom, 1 byte = 8 bits, bit starts from right to left, from left to right are DotPoint,G,F,E,D,C,B,A
B00111111, // 0
B00000110, // 1
B01011011, // 2
B01001111, // 3
B01100110, // 4
B01101101, // 5
B01111101, // 6
B00000111, // 7
B01111111, // 8
B01101111, // 9
};
constunsignedint POW_10[] = { // cache value for saving performance, https://www.arduino.cc/reference/en/language/functions/math/pow/
for(byte indexDigit = 0; indexDigit < TOTAL_DIGITS; indexDigit++) { // write each digits from most right to most left
digitalWrite(PIN_RCLK, LOW);
shiftOut(PIN_DIO, PIN_SCLK, MSBFIRST, ~dataPGFEDCBA[indexDigit]); // shift out byte display 8 bit display PGFEDCBA, because of we are using 4-digit common anode, need inverse bit by using "~"
shiftOut(PIN_DIO, PIN_SCLK, MSBFIRST, 1 << indexDigit); // shift out byte display 8 bit display digits
// there is another way to set 16 bits, instead of shiftOut
// is make 3 line of code for 16 times, just change isOn variable for each bit of bytePGFEDCBA & byteDigit from most left to most right ;))
} while(duration-- > 0); // avoid case duration = 0--
}
voidwriteInt(unsignedshortduration, intnumber) { // 4 digit display from -999 to 9999, short is enough for 4 digit, but i wanted to support up to 8 digits, then i use int
byte dataPGFEDCBA[TOTAL_DIGITS];
byte totalDigit;
if(number >= 0) { // zero and positive numbers
totalDigit = TOTAL_DIGITS; // show full digits
} else { // negative numbers
totalDigit = TOTAL_DIGITS - 1; // can not show full digits because of most left digit display negative symbol
dataPGFEDCBA[totalDigit] = BYTE_NEGATIVE; // show negative symbol "-";
voidwriteIntUnit(unsignedshortduration, intnumber, bytebyteUnit) { // 4 digit display from -99 to 999, short is enough for 4 digit, but i wanted to support up to 8 digits, then i use int
byte dataPGFEDCBA[TOTAL_DIGITS];
dataPGFEDCBA[0] = byteUnit; // write unit
byte totalDigit;
if(number >= 0) { // zero and positive numbers
totalDigit = TOTAL_DIGITS; // show full digits
} else { // negative numbers
totalDigit = TOTAL_DIGITS - 1; // can not show full digits because of most left digit display negative symbol
dataPGFEDCBA[totalDigit] = BYTE_NEGATIVE; // show negative symbol "-";
1. Code test all LEDs from top to bottom, from left to right:
const byte BIT_ORDER = MSBFIRST; // Most Significant Bit First = 1
const byte PIN_LATCH_ST_CP = 8; // Pin connected to ST_CP of 74HC595
const byte PIN_DATA_DS = 11; // Pin connected to DS of 74HC595. The pin on which to output each bit. Allowed data types: int. Should be ~ pin.
const byte PIN_CLOCK_SHCP = 12; // Pin connected to SH_CP of 74HC595. The pin to toggle once the PIN_DATA_DS has been set to the correct value. Allowed data types: int.
const byte BIT_ROWS[] = {8, 13, 7, 11, 0, 6, 1, 4}; // index row bit: R1/Q0, R2, R3, R4, R5, R6, R7, R8; index value start from 0, -1 each pin
const byte TOTAL_ROWS = sizeof(BIT_ROWS); // total row pins
const byte BIT_COLUMNS[] = {12, 2, 3, 9, 5, 10, 14, 15}; // index column bits: C1/Q3, Q1/C2, C3, C4, C5, C6, C7, C8; index value start from 0, -1 each pin
const byte TOTAL_COLUMNS = sizeof(BIT_COLUMNS); // total column pins
voidsetup() {
pinMode(PIN_LATCH_ST_CP, OUTPUT);
pinMode(PIN_DATA_DS, OUTPUT);
pinMode(PIN_CLOCK_SHCP, OUTPUT);
}
unsignedshortmarkColumn(byteindexColumnOn) { // column is cathod, set indexColumnOn value to 0 to LED on, other columns value to 1 to LED off
const byte BIT_ORDER = MSBFIRST; // Most Significant Bit First = 1
const byte PIN_LATCH_ST_CP = 8; // Pin connected to ST_CP of 74HC595
const byte PIN_DATA_DS = 11; // Pin connected to DS of 74HC595. The pin on which to output each bit. Allowed data types: int. Should be ~ pin.
const byte PIN_CLOCK_SHCP = 12; // Pin connected to SH_CP of 74HC595. The pin to toggle once the PIN_DATA_DS has been set to the correct value. Allowed data types: int.
const byte BIT_ROWS[] = {8, 13, 7, 11, 0, 6, 1, 4}; // index row bit: R1/Q0, R2, R3, R4, R5, R6, R7, R8; index value start from 0, -1 each pin
const byte TOTAL_ROWS = sizeof(BIT_ROWS); // total row pins
const byte BIT_COLUMNS[] = {12, 2, 3, 9, 5, 10, 14, 15}; // index column bits: C1/Q3, Q1/C2, C3, C4, C5, C6, C7, C8; index value start from 0, -1 each pin
const byte TOTAL_COLUMNS = sizeof(BIT_COLUMNS); // total column pins
voidsetup() {
pinMode(PIN_LATCH_ST_CP, OUTPUT);
pinMode(PIN_DATA_DS, OUTPUT);
pinMode(PIN_CLOCK_SHCP, OUTPUT);
}
voidloop() {
for(byte indexRow = 0; indexRow < TOTAL_ROWS; indexRow++) { // each row from top to bottom
// there are 16 bits, turn on current row by set row value to 1, all columns values to 0
const byte BIT_ORDER = MSBFIRST; // Most Significant Bit First = 1
const byte PIN_LATCH_ST_CP = 8; // Pin connected to ST_CP of 74HC595
const byte PIN_DATA_DS = 11; // Pin connected to DS of 74HC595. The pin on which to output each bit. Allowed data types: int. Should be ~ pin.
const byte PIN_CLOCK_SHCP = 12; // Pin connected to SH_CP of 74HC595. The pin to toggle once the PIN_DATA_DS has been set to the correct value. Allowed data types: int.
const byte BIT_ROWS[] = {8, 13, 7, 11, 0, 6, 1, 4}; // index row bit: R1/Q0, R2, R3, R4, R5, R6, R7, R8; index value start from 0, -1 each pin
const byte TOTAL_ROWS = sizeof(BIT_ROWS); // total row pins
const byte BIT_COLUMNS[] = {12, 2, 3, 9, 5, 10, 14, 15}; // index column bits: C1/Q3, Q1/C2, C3, C4, C5, C6, C7, C8; index value start from 0, -1 each pin
const byte TOTAL_COLUMNS = sizeof(BIT_COLUMNS); // total column pins
voidsetup() {
pinMode(PIN_LATCH_ST_CP, OUTPUT);
pinMode(PIN_DATA_DS, OUTPUT);
pinMode(PIN_CLOCK_SHCP, OUTPUT);
}
voidloop() {
for(byte indexColumn = 0; indexColumn < TOTAL_COLUMNS; indexColumn++) { // each row from top to bottom
// there are 16 bits used for 16 pins.
// all index bit of rows are on = 8 bits (row anode value = 1)
// 1 index bit of column are on (column anode value = 0), 7 other columns are off (value = 1)
// so there is 1 bit value = 0, all bits are 16 = decimal: 65535, xor current index column let it's value to 0;
const byte BIT_ORDER = MSBFIRST; // Most Significant Bit First = 1
const byte PIN_LATCH_ST_CP = 8; // Pin connected to ST_CP of 74HC595
const byte PIN_DATA_DS = 11; // Pin connected to DS of 74HC595. The pin on which to output each bit. Allowed data types: int. Should be ~ pin.
const byte PIN_CLOCK_SHCP = 12; // Pin connected to SH_CP of 74HC595. The pin to toggle once the PIN_DATA_DS has been set to the correct value. Allowed data types: int.
const byte BIT_ROWS[] = {8, 13, 7, 11, 0, 6, 1, 4}; // index row bit: R1/Q0, R2, R3, R4, R5, R6, R7, R8; index value start from 0, -1 each pin
const byte BIT_COLUMNS[] = {12, 2, 3, 9, 5, 10, 14, 15}; // index column bits: C1/Q3, Q1/C2, C3, C4, C5, C6, C7, C8; index value start from 0, -1 each pin
unsignedshort DURATION_COLUMN = 2; // value too high make you see LED blink, should <=3 is OK
const byte BIT_ORDER = MSBFIRST; // Most Significant Bit First = 1
const byte PIN_LATCH_ST_CP = 8; // Pin connected to ST_CP of 74HC595
const byte PIN_DATA_DS = 11; // Pin connected to DS of 74HC595. The pin on which to output each bit. Allowed data types: int. Should be ~ pin.
const byte PIN_CLOCK_SHCP = 12; // Pin connected to SH_CP of 74HC595. The pin to toggle once the PIN_DATA_DS has been set to the correct value. Allowed data types: int.
const byte BIT_ROWS[] = {8, 13, 7, 11, 0, 6, 1, 4}; // index row bit: R1/Q0, R2, R3, R4, R5, R6, R7, R8; index value start from 0, -1 each pin
const byte BIT_COLUMNS[] = {12, 2, 3, 9, 5, 10, 14, 15}; // index column bits: C1/Q3, Q1/C2, C3, C4, C5, C6, C7, C8; index value start from 0, -1 each pin
unsignedshort DURATION_COLUMN = 2; // value too high make you see LED blink, should <=3 is OK
const byte BIT_ORDER = MSBFIRST; // Most Significant Bit First = 1
const byte PIN_LATCH_ST_CP = 8; // Pin connected to ST_CP of 74HC595
const byte PIN_DATA_DS = 11; // Pin connected to DS of 74HC595. The pin on which to output each bit. Allowed data types: int. Should be ~ pin.
const byte PIN_CLOCK_SHCP = 12; // Pin connected to SH_CP of 74HC595. The pin to toggle once the PIN_DATA_DS has been set to the correct value. Allowed data types: int.
const byte BIT_ROWS[] = {8, 13, 7, 11, 0, 6, 1, 4}; // index row bit: R1/Q0, R2, R3, R4, R5, R6, R7, R8; index value start from 0, -1 each pin
const byte BIT_COLUMNS[] = {12, 2, 3, 9, 5, 10, 14, 15}; // index column bits: C1/Q3, Q1/C2, C3, C4, C5, C6, C7, C8; index value start from 0, -1 each pin
unsignedshort DURATION_COLUMN = 2; // value too high make you see LED blink, should <=3 is OK
const byte BIT_ORDER = MSBFIRST; // Most Significant Bit First = 1
const byte PIN_LATCH_ST_CP = 8; // Pin connected to ST_CP of 74HC595
const byte PIN_DATA_DS = 11; // Pin connected to DS of 74HC595. The pin on which to output each bit. Allowed data types: int. Should be ~ pin.
const byte PIN_CLOCK_SHCP = 12; // Pin connected to SH_CP of 74HC595. The pin to toggle once the PIN_DATA_DS has been set to the correct value. Allowed data types: int.
const byte BIT_ROWS[] = { 8, 13, 7, 11, 0, 6, 1, 4 }; // index row bit: R1/Q0, R2, R3, R4, R5, R6, R7, R8; index value start from 0, -1 each pin
const byte BIT_COLUMNS[] = { 12, 2, 3, 9, 5, 10, 14, 15 }; // index column bits: C1/Q3, Q1/C2, C3, C4, C5, C6, C7, C8; index value start from 0, -1 each pin
constunsignedshort DURATION_COLUMN = 2; // value too high make you see LED blink, should <=3 is OK
constunsignedshort DURATION_MINUTE = 50; // default is 1000ms * 60s = 60 000ms, value current testing
constunsignedshort TOTAL_MINUTES = 12 * 60; // total minutes in
constunsignedshort START_MINUTES = 0; // value of minutes when start project, range from 0 to TOTAL_MINUTES
byte HOURS[12][8] = {
{0, 0, 0, 0, 12, 0, 0, 0},
{0, 0, 0, 0, 8, 4, 0, 0},
{0, 0, 0, 0, 8, 8, 0, 0},
{0, 0, 0, 0, 16, 16, 0, 0},
{0, 0, 0, 0, 16, 32, 0, 0},
{0, 0, 0, 0, 48, 0, 0, 0},
{0, 0, 0, 48, 0, 0, 0, 0},
{0, 0, 32, 16, 0, 0, 0, 0},
{0, 0, 16, 16, 0, 0, 0, 0},
{0, 0, 8, 8, 0, 0, 0, 0},
{0, 0, 4, 8, 0, 0, 0, 0},
{0, 0, 0, 12, 0, 0, 0, 0}
};
byte MINUTES[60][8] = {
{0, 0, 0, 0, 15, 0, 0, 0},
{0, 0, 0, 0, 14, 1, 0, 0},
{0, 0, 0, 0, 12, 3, 0, 0},
{0, 0, 0, 0, 8, 7, 0, 0},
{0, 0, 0, 0, 8, 6, 1, 0},
{0, 0, 0, 0, 8, 4, 3, 0},
{0, 0, 0, 0, 8, 4, 2, 1},
{0, 0, 0, 0, 8, 4, 2, 2},
{0, 0, 0, 0, 8, 4, 4, 2},
{0, 0, 0, 0, 8, 4, 4, 4},
{0, 0, 0, 0, 8, 8, 4, 4},
{0, 0, 0, 0, 8, 8, 8, 4},
{0, 0, 0, 0, 8, 8, 8, 8},
{0, 0, 0, 0, 16, 16, 8, 8},
{0, 0, 0, 0, 16, 16, 16, 8},
{0, 0, 0, 0, 16, 16, 16, 16},
{0, 0, 0, 0, 16, 16, 16, 32},
{0, 0, 0, 0, 16, 16, 32, 32},
{0, 0, 0, 0, 16, 32, 32, 32},
{0, 0, 0, 0, 16, 32, 32, 64},
{0, 0, 0, 0, 16, 32, 64, 64},
{0, 0, 0, 0, 16, 32, 64, 128},
{0, 0, 0, 0, 16, 32, 192, 0},
{0, 0, 0, 0, 16, 96, 128, 0},
{0, 0, 0, 0, 16, 224, 0, 0},
{0, 0, 0, 0, 48, 192, 0, 0},
{0, 0, 0, 0, 112, 128, 0, 0},
{0, 0, 0, 0, 240, 0, 0, 0},
{0, 0, 0, 48, 192, 0, 0, 0},
{0, 0, 0, 112, 128, 0, 0, 0},
{0, 0, 0, 240, 0, 0, 0, 0},
{0, 0, 128, 112, 0, 0, 0, 0},
{0, 0, 192, 48, 0, 0, 0, 0},
{0, 0, 224, 16, 0, 0, 0, 0},
{0, 128, 96, 16, 0, 0, 0, 0},
{0, 192, 32, 16, 0, 0, 0, 0},
{128, 64, 32, 16, 0, 0, 0, 0},
{64, 64, 32, 16, 0, 0, 0, 0},
{64, 32, 32, 16, 0, 0, 0, 0},
{32, 32, 32, 16, 0, 0, 0, 0},
{32, 32, 16, 16, 0, 0, 0, 0},
{32, 16, 16, 16, 0, 0, 0, 0},
{16, 16, 16, 16, 0, 0, 0, 0},
{16, 16, 8, 8, 0, 0, 0, 0},
{16, 8, 8, 8, 0, 0, 0, 0},
{8, 8, 8, 8, 0, 0, 0, 0},
{4, 8, 8, 8, 0, 0, 0, 0},
{4, 4, 8, 8, 0, 0, 0, 0},
{4, 4, 4, 8, 0, 0, 0, 0},
{2, 4, 4, 8, 0, 0, 0, 0},
{2, 2, 4, 8, 0, 0, 0, 0},
{1, 2, 4, 8, 0, 0, 0, 0},
{0, 3, 4, 8, 0, 0, 0, 0},
{0, 1, 6, 8, 0, 0, 0, 0},
{0, 0, 7, 8, 0, 0, 0, 0},
{0, 0, 3, 12, 0, 0, 0, 0},
{0, 0, 1, 14, 0, 0, 0, 0},
{0, 0, 0, 15, 0, 0, 0, 0},
{0, 0, 0, 3, 12, 0, 0, 0},
{0, 0, 0, 1, 14, 0, 0, 0}
};
byte indexColumnDisplaying = 0; // store current index column for avoid column on the right display less than column on the left
const byte BIT_ORDER = MSBFIRST; // Most Significant Bit First = 1
const byte PIN_LATCH_ST_CP = 8; // Pin connected to ST_CP of 74HC595
const byte PIN_DATA_DS = 11; // Pin connected to DS of 74HC595. The pin on which to output each bit. Allowed data types: int. Should be ~ pin.
const byte PIN_CLOCK_SHCP = 12; // Pin connected to SH_CP of 74HC595. The pin to toggle once the PIN_DATA_DS has been set to the correct value. Allowed data types: int.
const byte BIT_ROWS[] = {8, 13, 7, 11, 0, 6, 1, 4}; // index row bit: R1/Q0, R2, R3, R4, R5, R6, R7, R8; index value start from 0, -1 each pin
const byte BIT_COLUMNS[] = {12, 2, 3, 9, 5, 10, 14, 15}; // index column bits: C1/Q3, Q1/C2, C3, C4, C5, C6, C7, C8; index value start from 0, -1 each pin
unsignedshort DURATION_COLUMN = 2; // value too high make you see LED blink, should <=3 is OK