You Jeen's Final Project
Contents
- 1 Project Proposal
- 2 Project Execution
- 3 Schematics
- 4 Code
- 5 References
Project Proposal
First submitted on Thursday, April 23, 2020.
Outline edited and updated on Saturday, May 3, 2020.
Introduction
By the end of CSC270: Digital Circuits & Computer Systems, we will have become acquainted with the ELEGOO Arduino Mega2560 Project Kit, which includes the Arduino Mega2560 Controller Board and other numerous parts that allow for various functionalities. This project aims to be cumulative by continuously adding to an initial configuration, namely connecting the Arduino Mega2560 to a 64-LED matrix. Ultimately, this project will culminate in an integration of 3 sensors with the Arduino Mega2560.
Outline
The objectives established in the Introduction will be achieved in 4 parts, as described below:
- Connecting the 64-LED matrix to an Arduino Mega2560 and programming it to display my name 'Y O U J E E N' while acting as a moving/scrolling LED display screen.
- Connecting a real-time clock to the Arduino Mega2560, already equipped with the 8x8 LED matrix, and making them correctly operate together. The LED matrix will show the time in format '00:00' in its entirety by acting as a moving/scrolling LED display screen, similar to Part 1.
- Connecting a sound sensor to the Arduino Mega2560, already equipped with the 8x8 LED matrix, and making them correctly operate together. The LED matrix will display a smiling face when the sound sensor detects a clap. Otherwise, the LED matrix will show nothing.
- Integrating all 3 of the sensors above with the Arduino Mega2560. A clap detected by the sound sensor will activate the connection between the real-time clock and the 8x8 LED matrix, which then acts a digital clock by displaying the time. Similar to the configurations in Parts 1 and 2, the time will move leftward in a scrolling display so that it is shown in its entirety.
Preparation
- Gather all necessary materials for this project from the ELEGOO Arduino Mega2560 Project Kit.
- Read through and watch all relevant resources (i.e., tutorials and videos).
- Proceed with Part 1 (see Outline).
- Proceed with Part 2 (see Outline).
- Proceed with Part 3 (see Outline).
- Proceed with Part 4 (see Outline).
- While tackling the 4 parts, report progress on this wiki page and start creating online presentation.
- Reports will include: relevant media (e.g., photos, videos), resources, sketches/code, and qualitative observations.
Project Execution
Materials & Setup
Materials below are gathered from the ELEGOO Arduino Mega2560 Project Kit:
- Arduino Mega2560 Controller Board
- 830 Tie-Points Breadboard
- MAX7219 Module (64-LED matrix)
- DS1307 RTC Module (Real-time clock)
-
Sound Sensor ModuleMembrane Switch Module (Keypad) - Breadboard Jumper Wires
- Female-to-Male Dupont Wires
Updated Outline
The objectives established originally in the outline above have been edited due to a malfunctioning sound sensor and discovery of new possible functionalities. Edits are included as bolded text.
- Connecting the 64-LED matrix to an Arduino Mega2560 and programming it to display my name 'Y O U J E E N' while acting as a moving/scrolling LED display screen.
- Connecting a real-time clock to the Arduino Mega2560, already equipped with the 8x8 LED matrix, and making them correctly operate together. The LED matrix will show the time in military-time format '00:00' to '24:00' in its entirety by acting as a moving/scrolling LED display screen, similar to Part 1.
- Connecting a keypad to the Arduino Mega2560, already equipped with the 8x8 LED matrix, and making them correctly operate together. The LED matrix will display a smiling face when the keypad receives the input from keys '2', '7', and '0', in that order. Otherwise, the LED matrix will show a sad face. When the user presses 'C' on the keypad, the user's previous input string is deleted so the user can start fresh in terms of entering input. When the user presses 'D' on the keypad, the LED matrix will restart from the beginning (i.e., not only is the user's previous input string deleted, but the LED display is also turned off).
- Integrating all 3 of the sensors above with the Arduino Mega2560. Only the correct input entered on the keypad will activate the connection between the real-time clock and the 8x8 LED matrix, which then acts a digital clock by displaying the time. Similar to the configurations in Parts 1 and 2, the time will move leftward in a scrolling display so that it is shown in its entirety. When the user presses 'C' on the keypad, the user's previous input string is deleted so the user can start fresh in terms of entering input. When the user presses 'D' on the keypad, the LED matrix will restart from the beginning (i.e., not only is the user's previous input string deleted, but the LED display is also turned off).
Parts 1 - 4
See below for a detailed execution of Parts 1-4 described in Outline above.
Part 1: Arduino Mega2560 + 64-LED Matrix
Tutorials
- How to Wire the Arduino with a 8x8 LED Dot Matrix
- Implementing a Scrolling Display on a 8x8 LED Dot Matrix with an Arduino
Progress
April 29, 2020: Successfully implemented scrolling display of my name 'YOU JEEN' on 8x8 LED matrix. See video below.
Part 2: Arduino Mega2560 + 64-LED Matrix + Real-time Clock
Resources/Tutorials
- How to Wire the Arduino with a RTC Module
- Default Code for integrating a RTC Module with an Arduino
- Understanding the Code for the RTC
- RTClib.h Library Documentation
Progress
April 29, 2020: Successfully implemented scrolling display of real-time date on 8x8 LED matrix. Now need to extract only the time from the full date displayed.
April 30, 2020: Successfully implemented scrolling display of real-time time in military time (while allowing possibility of 12-hour time mode in code) on 8x8 LED matrix by using the .toString()
method for the DateTime
class. See video below.
Part 3: Arduino Mega2560 + 64-LED Matrix + Keypad
Resources/Tutorials
- How to Wire the Arduino with a Membrane Switch Module (Keypad)
- Adafruit_Keypad.h Library Documentation
- Adafruit_Keypad.h Library Usage Example
- MaxMatrix.h Library Documentation
- How to Display Faces on a 8x8 LED Dot Matrix
- How to Software Reset the Arduino
Progress
May 1, 2020: EDIT - In the project proposal, I originally intended to use the sound sensor as my third sensor, but upon testing it, I found out that it did not work. So I changed my third sensor to the Membrane Switch Module (keypad). This sensor successfully worked with the 64 LED matrix. See video below.
Part 4: Arduino Mega2560 + 64-LED Matrix + Real-time Clock + Keypad
Resources
Progress
May 1, 2020: Successfully implemented integration of Arduino and 3 sensors altogether.
May 2, 2020: Attempted to add shutdown functionality to LED matrix once 'D' is pressed on keypad. This functionality works for Part 3, but strangely, not yet for Part 4.
May 2, 2020 (later in the day): Shutdown functionality for LED matrix once 'D' is pressed on keypad successfully works. See video below.
May 3, 2020: Final project completed!
Schematics
For each part, included on the left-hand side is the breadboard diagram for the relevant circuit and included on the right-hand side is the schematic for the circuit.
All figures were produced using the software Fritzing.
Part 1: Arduino + 64-LED Matrix ("Scrolling First Name"):
Part 2: Arduino + 64-LED Matrix + RTC ("Scrolling Time"):
Part 3: Arduino + 64-LED Matrix + Keypad ("Keycode-enabled Smiling Face"):
Part 4: Arduino + 64-LED Matrix + RTC + Keypad ("Keycode-enabled Scrolling Digital Clock"):
Code
For this project, the programming language used will be C. See Arduino sketches below.
Part 1: Arduino + 64-LED Matrix ("Scrolling First Name"):
/*
* pt1_ledmatrix_scrollingname.ino
*
* Moving/scrolling LED display, featuring first name 'YOU JEEN'.
* Uses 8x8 LED matrix (MAX7219 Module) and Arduino Mega2560
* Controller from ELEGOO Arduino Mega2560 Project Kit.
*
* Code here is modified from version found at
* https://www.instructables.com/id/Scrolling-Text-on-a-8x8-LED-Matrix-Using-an-Arduin/
*
*
* Name: You Jeen Ha
* Course: CSC270 Digital Circuits & Systems
* Professor: D. Thiebaut
* Final Project, Part 1
* Version: 02 May 2020
*/
#include <MaxMatrix.h>
#include <avr/pgmspace.h>
#define maxDisplays 1 // number of MAX7219's in use
const int data = 13; // DIN of LED matrix
const int load = 12; // CS of LED matrix
const int clock = 11; // CLK of LED matrix
byte Buf7219[7]; // "width,height,data[5]" single character buffer
char string[] = "YOU JEEN"; // text message to send to LED matrix
MaxMatrix matrix(data, load, clock, maxDisplays); // instantiate new LED matrix object
// Data array is stored in program memory (see memcpy_P for access).
// Parameters are width, height, and character data
PROGMEM const unsigned char CH[] = {
3, 8, B0000000, B0000000, B0000000, B0000000, B0000000, // space
1, 8, B1011111, B0000000, B0000000, B0000000, B0000000, // !
3, 8, B0000011, B0000000, B0000011, B0000000, B0000000, // "
5, 8, B0010100, B0111110, B0010100, B0111110, B0010100, // #
4, 8, B0100100, B1101010, B0101011, B0010010, B0000000, // $
5, 8, B1100011, B0010011, B0001000, B1100100, B1100011, // %
5, 8, B0110110, B1001001, B1010110, B0100000, B1010000, // &
1, 8, B0000011, B0000000, B0000000, B0000000, B0000000, // '
3, 8, B0011100, B0100010, B1000001, B0000000, B0000000, // (
3, 8, B1000001, B0100010, B0011100, B0000000, B0000000, // )
5, 8, B0101000, B0011000, B0001110, B0011000, B0101000, // *
5, 8, B0001000, B0001000, B0111110, B0001000, B0001000, // +
2, 8, B10110000, B1110000, B0000000, B0000000, B0000000, // ,
4, 8, B0001000, B0001000, B0001000, B0001000, B0000000, // -
2, 8, B1100000, B1100000, B0000000, B0000000, B0000000, // .
4, 8, B1100000, B0011000, B0000110, B0000001, B0000000, // /
4, 8, B0111110, B1000001, B1000001, B0111110, B0000000, // 0
3, 8, B1000010, B1111111, B1000000, B0000000, B0000000, // 1
4, 8, B1100010, B1010001, B1001001, B1000110, B0000000, // 2
4, 8, B0100010, B1000001, B1001001, B0110110, B0000000, // 3
4, 8, B0011000, B0010100, B0010010, B1111111, B0000000, // 4
4, 8, B0100111, B1000101, B1000101, B0111001, B0000000, // 5
4, 8, B0111110, B1001001, B1001001, B0110000, B0000000, // 6
4, 8, B1100001, B0010001, B0001001, B0000111, B0000000, // 7
4, 8, B0110110, B1001001, B1001001, B0110110, B0000000, // 8
4, 8, B0000110, B1001001, B1001001, B0111110, B0000000, // 9
2, 8, B01010000, B0000000, B0000000, B0000000, B0000000, // :
2, 8, B10000000, B01010000, B0000000, B0000000, B0000000, // ;
3, 8, B0010000, B0101000, B1000100, B0000000, B0000000, // <
3, 8, B0010100, B0010100, B0010100, B0000000, B0000000, // =
3, 8, B1000100, B0101000, B0010000, B0000000, B0000000, // >
4, 8, B0000010, B1011001, B0001001, B0000110, B0000000, // ?
5, 8, B0111110, B1001001, B1010101, B1011101, B0001110, // @
4, 8, B1111110, B0010001, B0010001, B1111110, B0000000, // A
4, 8, B1111111, B1001001, B1001001, B0110110, B0000000, // B
4, 8, B0111110, B1000001, B1000001, B0100010, B0000000, // C
4, 8, B1111111, B1000001, B1000001, B0111110, B0000000, // D
4, 8, B1111111, B1001001, B1001001, B1000001, B0000000, // E
4, 8, B1111111, B0001001, B0001001, B0000001, B0000000, // F
4, 8, B0111110, B1000001, B1001001, B1111010, B0000000, // G
4, 8, B1111111, B0001000, B0001000, B1111111, B0000000, // H
3, 8, B1000001, B1111111, B1000001, B0000000, B0000000, // I
4, 8, B0110000, B1000000, B1000001, B0111111, B0000000, // J
4, 8, B1111111, B0001000, B0010100, B1100011, B0000000, // K
4, 8, B1111111, B1000000, B1000000, B1000000, B0000000, // L
5, 8, B1111111, B0000010, B0001100, B0000010, B1111111, // M
5, 8, B1111111, B0000100, B0001000, B0010000, B1111111, // N
4, 8, B0111110, B1000001, B1000001, B0111110, B0000000, // O
4, 8, B1111111, B0001001, B0001001, B0000110, B0000000, // P
4, 8, B0111110, B1000001, B1000001, B10111110, B0000000, // Q
4, 8, B1111111, B0001001, B0001001, B1110110, B0000000, // R
4, 8, B1000110, B1001001, B1001001, B0110010, B0000000, // S
5, 8, B0000001, B0000001, B1111111, B0000001, B0000001, // T
4, 8, B0111111, B1000000, B1000000, B0111111, B0000000, // U
5, 8, B0001111, B0110000, B1000000, B0110000, B0001111, // V
5, 8, B0111111, B1000000, B0111000, B1000000, B0111111, // W
5, 8, B1100011, B0010100, B0001000, B0010100, B1100011, // X
5, 8, B0000111, B0001000, B1110000, B0001000, B0000111, // Y
4, 8, B1100001, B1010001, B1001001, B1000111, B0000000, // Z
2, 8, B1111111, B1000001, B0000000, B0000000, B0000000, // [
4, 8, B0000001, B0000110, B0011000, B1100000, B0000000, // backslash
2, 8, B1000001, B1111111, B0000000, B0000000, B0000000, // ]
3, 8, B0000010, B0000001, B0000010, B0000000, B0000000, // hat
4, 8, B1000000, B1000000, B1000000, B1000000, B0000000, // _
2, 8, B0000001, B0000010, B0000000, B0000000, B0000000, // `
4, 8, B0100000, B1010100, B1010100, B1111000, B0000000, // a
4, 8, B1111111, B1000100, B1000100, B0111000, B0000000, // b
4, 8, B0111000, B1000100, B1000100, B0000000, B0000000, // c // JFM MOD.
4, 8, B0111000, B1000100, B1000100, B1111111, B0000000, // d
4, 8, B0111000, B1010100, B1010100, B0011000, B0000000, // e
3, 8, B0000100, B1111110, B0000101, B0000000, B0000000, // f
4, 8, B10011000, B10100100, B10100100, B01111000, B0000000, // g
4, 8, B1111111, B0000100, B0000100, B1111000, B0000000, // h
3, 8, B1000100, B1111101, B1000000, B0000000, B0000000, // i
4, 8, B1000000, B10000000, B10000100, B1111101, B0000000, // j
4, 8, B1111111, B0010000, B0101000, B1000100, B0000000, // k
3, 8, B1000001, B1111111, B1000000, B0000000, B0000000, // l
5, 8, B1111100, B0000100, B1111100, B0000100, B1111000, // m
4, 8, B1111100, B0000100, B0000100, B1111000, B0000000, // n
4, 8, B0111000, B1000100, B1000100, B0111000, B0000000, // o
4, 8, B11111100, B0100100, B0100100, B0011000, B0000000, // p
4, 8, B0011000, B0100100, B0100100, B11111100, B0000000, // q
4, 8, B1111100, B0001000, B0000100, B0000100, B0000000, // r
4, 8, B1001000, B1010100, B1010100, B0100100, B0000000, // s
3, 8, B0000100, B0111111, B1000100, B0000000, B0000000, // t
4, 8, B0111100, B1000000, B1000000, B1111100, B0000000, // u
5, 8, B0011100, B0100000, B1000000, B0100000, B0011100, // v
5, 8, B0111100, B1000000, B0111100, B1000000, B0111100, // w
5, 8, B1000100, B0101000, B0010000, B0101000, B1000100, // x
4, 8, B10011100, B10100000, B10100000, B1111100, B0000000, // y
3, 8, B1100100, B1010100, B1001100, B0000000, B0000000, // z
3, 8, B0001000, B0110110, B1000001, B0000000, B0000000, // {
1, 8, B1111111, B0000000, B0000000, B0000000, B0000000, // |
3, 8, B1000001, B0110110, B0001000, B0000000, B0000000, // }
4, 8, B0001000, B0000100, B0001000, B0000100, B0000000, // ~
};
void setup() {
// initialize matrix
matrix.init();
// set brightness
matrix.setIntensity(4);
}
// Send text to matrix
void loop() {
// delay 3000 ms (3s) between messages
delay(3000);
// scroll message leftward
matrix.shiftLeft(false, true);
// number is message speed
// (the greater the number, the slower the message speed)
printStrWithShift(string,120);
}
// Put text on display by character
void printCharWithShift(char c, int shift_speed) {
if (c < 32) {
return;
}
c -= 32;
memcpy_P(Buf7219, CH + 7*c, 7);
matrix.writeSprite(maxDisplays*8, 0, Buf7219);
matrix.setColumn(maxDisplays*8 + Buf7219[0], 0);
for (int i=0; i<=Buf7219[0]; i++) {
delay(shift_speed);
matrix.shiftLeft(false, false);
}
}
// Put text on display by character according to string message
void printStrWithShift(char* s, int shift_speed) {
while (*s != 0) {
printCharWithShift(*s, shift_speed);
s++;
}
}
Part 2: Arduino + 64-LED Matrix + RTC ("Scrolling Time"):
/*
* pt2_ledmatrix_rtc.ino
*
* Moving/scrolling LED display, featuring current military time.
* Uses 8x8 LED matrix (MAX7219 Module), a DS1307 RTC Module
* (Real-Time Clock), and an Arduino Mega2560 Controller
* from the ELEGOO Arduino Mega2560 Project Kit.
*
* Code here adopts segments from the versions at
* https://www.instructables.com/id/Scrolling-Text-on-a-8x8-LED-Matrix-Using-an-Arduin/
* and
* https://learn.adafruit.com/ds1307-real-time-clock-breakout-board-kit/understanding-the-code
*
*
* Name: You Jeen Ha
* Course: CSC270 Digital Circuits & Systems
* Professor: D. Thiebaut
* Final Project, Part 2
* Version: 02 May 2020
*/
#include <stdio.h>
#include <string.h>
#include <MaxMatrix.h>
#include <avr/pgmspace.h>
#include <Wire.h>
#include <RTClib.h>
#include <time.h>
#define maxDisplays 1 // number of MAX7219's in use
RTC_DS1307 rtc;
const int data = 13; // DIN of LED matrix
const int load = 12; // CS of LED matrix
const int clk = 11; // CLK of LED matrix
byte Buf7219[7]; // "width,height,data[5]" single character buffer
MaxMatrix matrix(data, load, clk, maxDisplays); // instantiate new matrix object
// Data array is stored in program memory (see memcpy_P for access).
// Parameters are width, height, and character data
PROGMEM const unsigned char CH[] = {
3, 8, B0000000, B0000000, B0000000, B0000000, B0000000, // space
1, 8, B1011111, B0000000, B0000000, B0000000, B0000000, // !
3, 8, B0000011, B0000000, B0000011, B0000000, B0000000, // "
5, 8, B0010100, B0111110, B0010100, B0111110, B0010100, // #
4, 8, B0100100, B1101010, B0101011, B0010010, B0000000, // $
5, 8, B1100011, B0010011, B0001000, B1100100, B1100011, // %
5, 8, B0110110, B1001001, B1010110, B0100000, B1010000, // &
1, 8, B0000011, B0000000, B0000000, B0000000, B0000000, // '
3, 8, B0011100, B0100010, B1000001, B0000000, B0000000, // (
3, 8, B1000001, B0100010, B0011100, B0000000, B0000000, // )
5, 8, B0101000, B0011000, B0001110, B0011000, B0101000, // *
5, 8, B0001000, B0001000, B0111110, B0001000, B0001000, // +
2, 8, B10110000, B1110000, B0000000, B0000000, B0000000, // ,
4, 8, B0001000, B0001000, B0001000, B0001000, B0000000, // -
2, 8, B1100000, B1100000, B0000000, B0000000, B0000000, // .
4, 8, B1100000, B0011000, B0000110, B0000001, B0000000, // /
4, 8, B0111110, B1000001, B1000001, B0111110, B0000000, // 0
3, 8, B1000010, B1111111, B1000000, B0000000, B0000000, // 1
4, 8, B1100010, B1010001, B1001001, B1000110, B0000000, // 2
4, 8, B0100010, B1000001, B1001001, B0110110, B0000000, // 3
4, 8, B0011000, B0010100, B0010010, B1111111, B0000000, // 4
4, 8, B0100111, B1000101, B1000101, B0111001, B0000000, // 5
4, 8, B0111110, B1001001, B1001001, B0110000, B0000000, // 6
4, 8, B1100001, B0010001, B0001001, B0000111, B0000000, // 7
4, 8, B0110110, B1001001, B1001001, B0110110, B0000000, // 8
4, 8, B0000110, B1001001, B1001001, B0111110, B0000000, // 9
2, 8, B01010000, B0000000, B0000000, B0000000, B0000000, // :
2, 8, B10000000, B01010000, B0000000, B0000000, B0000000, // ;
3, 8, B0010000, B0101000, B1000100, B0000000, B0000000, // <
3, 8, B0010100, B0010100, B0010100, B0000000, B0000000, // =
3, 8, B1000100, B0101000, B0010000, B0000000, B0000000, // >
4, 8, B0000010, B1011001, B0001001, B0000110, B0000000, // ?
5, 8, B0111110, B1001001, B1010101, B1011101, B0001110, // @
4, 8, B1111110, B0010001, B0010001, B1111110, B0000000, // A
4, 8, B1111111, B1001001, B1001001, B0110110, B0000000, // B
4, 8, B0111110, B1000001, B1000001, B0100010, B0000000, // C
4, 8, B1111111, B1000001, B1000001, B0111110, B0000000, // D
4, 8, B1111111, B1001001, B1001001, B1000001, B0000000, // E
4, 8, B1111111, B0001001, B0001001, B0000001, B0000000, // F
4, 8, B0111110, B1000001, B1001001, B1111010, B0000000, // G
4, 8, B1111111, B0001000, B0001000, B1111111, B0000000, // H
3, 8, B1000001, B1111111, B1000001, B0000000, B0000000, // I
4, 8, B0110000, B1000000, B1000001, B0111111, B0000000, // J
4, 8, B1111111, B0001000, B0010100, B1100011, B0000000, // K
4, 8, B1111111, B1000000, B1000000, B1000000, B0000000, // L
5, 8, B1111111, B0000010, B0001100, B0000010, B1111111, // M
5, 8, B1111111, B0000100, B0001000, B0010000, B1111111, // N
4, 8, B0111110, B1000001, B1000001, B0111110, B0000000, // O
4, 8, B1111111, B0001001, B0001001, B0000110, B0000000, // P
4, 8, B0111110, B1000001, B1000001, B10111110, B0000000, // Q
4, 8, B1111111, B0001001, B0001001, B1110110, B0000000, // R
4, 8, B1000110, B1001001, B1001001, B0110010, B0000000, // S
5, 8, B0000001, B0000001, B1111111, B0000001, B0000001, // T
4, 8, B0111111, B1000000, B1000000, B0111111, B0000000, // U
5, 8, B0001111, B0110000, B1000000, B0110000, B0001111, // V
5, 8, B0111111, B1000000, B0111000, B1000000, B0111111, // W
5, 8, B1100011, B0010100, B0001000, B0010100, B1100011, // X
5, 8, B0000111, B0001000, B1110000, B0001000, B0000111, // Y
4, 8, B1100001, B1010001, B1001001, B1000111, B0000000, // Z
2, 8, B1111111, B1000001, B0000000, B0000000, B0000000, // [
4, 8, B0000001, B0000110, B0011000, B1100000, B0000000, // backslash
2, 8, B1000001, B1111111, B0000000, B0000000, B0000000, // ]
3, 8, B0000010, B0000001, B0000010, B0000000, B0000000, // hat
4, 8, B1000000, B1000000, B1000000, B1000000, B0000000, // _
2, 8, B0000001, B0000010, B0000000, B0000000, B0000000, // `
4, 8, B0100000, B1010100, B1010100, B1111000, B0000000, // a
4, 8, B1111111, B1000100, B1000100, B0111000, B0000000, // b
4, 8, B0111000, B1000100, B1000100, B0000000, B0000000, // c // JFM MOD.
4, 8, B0111000, B1000100, B1000100, B1111111, B0000000, // d
4, 8, B0111000, B1010100, B1010100, B0011000, B0000000, // e
3, 8, B0000100, B1111110, B0000101, B0000000, B0000000, // f
4, 8, B10011000, B10100100, B10100100, B01111000, B0000000, // g
4, 8, B1111111, B0000100, B0000100, B1111000, B0000000, // h
3, 8, B1000100, B1111101, B1000000, B0000000, B0000000, // i
4, 8, B1000000, B10000000, B10000100, B1111101, B0000000, // j
4, 8, B1111111, B0010000, B0101000, B1000100, B0000000, // k
3, 8, B1000001, B1111111, B1000000, B0000000, B0000000, // l
5, 8, B1111100, B0000100, B1111100, B0000100, B1111000, // m
4, 8, B1111100, B0000100, B0000100, B1111000, B0000000, // n
4, 8, B0111000, B1000100, B1000100, B0111000, B0000000, // o
4, 8, B11111100, B0100100, B0100100, B0011000, B0000000, // p
4, 8, B0011000, B0100100, B0100100, B11111100, B0000000, // q
4, 8, B1111100, B0001000, B0000100, B0000100, B0000000, // r
4, 8, B1001000, B1010100, B1010100, B0100100, B0000000, // s
3, 8, B0000100, B0111111, B1000100, B0000000, B0000000, // t
4, 8, B0111100, B1000000, B1000000, B1111100, B0000000, // u
5, 8, B0011100, B0100000, B1000000, B0100000, B0011100, // v
5, 8, B0111100, B1000000, B0111100, B1000000, B0111100, // w
5, 8, B1000100, B0101000, B0010000, B0101000, B1000100, // x
4, 8, B10011100, B10100000, B10100000, B1111100, B0000000, // y
3, 8, B1100100, B1010100, B1001100, B0000000, B0000000, // z
3, 8, B0001000, B0110110, B1000001, B0000000, B0000000, // {
1, 8, B1111111, B0000000, B0000000, B0000000, B0000000, // |
3, 8, B1000001, B0110110, B0001000, B0000000, B0000000, // }
4, 8, B0001000, B0000100, B0001000, B0000100, B0000000, // ~
};
void setup() {
#ifdef AVR
Wire.begin();
#else
Wire1.begin(); // Shield I2C pins connect to alt I2C bus on Arduino Due
#endif
rtc.begin();
if (! rtc.isrunning()) {
Serial.println("RTC is NOT running!");
}
// otherwise, set time acc to current time on compiler
rtc.adjust(DateTime(__DATE__, __TIME__));
// initialize matrix
matrix.init();
// set brightness
matrix.setIntensity(4);
}
// Send text to matrix
void loop() {
// get current date/time from RTC
DateTime now = rtc.now();
// make text message the time from RTC in 24-hr mode (military time)
char buf1[] = "hh:mm";
const char *string = now.toString(buf1);
// delay 3000 ms (3s) between messages
delay(3000);
// scroll message leftward
matrix.shiftLeft(false, true);
// number is message speed
// (the greater the number, the slower the message speed)
printStrWithShift(string,120);
}
// Put text on display by character
void printCharWithShift(char c, int shift_speed) {
if (c < 32) {
return;
}
c -= 32;
memcpy_P(Buf7219, CH + 7*c, 7);
matrix.writeSprite(maxDisplays*8, 0, Buf7219);
matrix.setColumn(maxDisplays*8 + Buf7219[0], 0);
for (int i=0; i<=Buf7219[0]; i++) {
delay(shift_speed);
matrix.shiftLeft(false, false);
}
}
// Put text on display by character according to string message
void printStrWithShift(char* s, int shift_speed) {
while (*s != 0) {
printCharWithShift(*s, shift_speed);
s++;
}
}
Part 3: Arduino + 64-LED Matrix + Keypad ("Keycode-enabled Smiling Face"):
/*
* pt3_ledmatrix_keypad.ino
*
* LED display shows smiling face if correct "keycode" is
* entered in. Otherwise, LED display shows sad face.
* Pressing the 'C' key will allow user to erase previous
* keypad input and reenter in a new string. Pressing
* the 'D' key will allow user to restart their LED matrix
* from the beginning (i.e., by erasing previous keypad
* input and turning the LED matrix off).
*
* Uses 8x8 LED matrix (MAX7219 Module), a Membrane Switch
* Module (keypad), and an Arduino Mega2560 Controller
* from the ELEGOO Arduino Mega2560 Project Kit.
*
* Code here adopts segments from the version at
* https://earthbondhon.com/smiley-faces-with-8x8-matrix-display/
*
*
* Name: You Jeen Ha
* Course: CSC270 Digital Circuits & Systems
* Professor: D. Thiebaut
* Final Project, Part 3
* Version: 02 May 2020
*/
#include "Adafruit_Keypad.h"
#include <LedControl.h>
#include <stdio.h>
#include <string.h>
const int data = 13; // DIN of LED matrix
const int load = 12; // CS of LED matrix
const int clk = 11; // CLK of LED matrix
const byte ROWS = 4; // num of keypad rows
const byte COLS = 4; // num of keypad columns
char keys[ROWS][COLS] = { // define the symbols on the buttons of the keypads
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
char *num_combo = "270\0"; // number combo for activating smile face on LED matrix
char *string = "\0"; // initialize keypad input string with empty str and null terminator
byte rowPins[ROWS] = {9, 8, 7, 6}; // connect to the row pinouts of the keypad
byte colPins[COLS] = {5, 4, 3, 2}; // connect to the column pinouts of the keypad
byte smile[8]= {0x3C,0x42,0xA5,0x81,0xA5,0x99,0x42,0x3C}; // array of smiling face for LED matrix
byte sad[8]= {0x3C,0x42,0xA5,0x81,0x99,0xA5,0x42,0x3C}; // array of sad face for LED matrix
// Initialize an instance of class NewKeypad
Adafruit_Keypad customKeypad = Adafruit_Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS);
// Initialize LedControl for LED matrix
LedControl matrix = LedControl(data, clk, load, 0);
// Declare reset function @ address 0
void(* resetFunc) (void) = 0;
void setup() {
// initialize keypad
customKeypad.begin();
// turn off power saving, enables display
matrix.shutdown(0, false);
// set brightness (0-15 possible values)
matrix.setIntensity(0, 8);
// clear display before start
matrix.clearDisplay(0);
// comment in to show output on Serial Monitor
// Serial.begin(9600);
}
void loop() {
// create row pulses
customKeypad.tick();
// if a new push button is detected
while(customKeypad.available()){
// read keypad button push as event
keypadEvent e = customKeypad.read();
// cast keypad button push as character
char ch_input = (char)e.bit.KEY;
if (e.bit.EVENT == KEY_JUST_RELEASED) {
// when user presses 'C' key (for Clear),
// reset input string
if (ch_input == 'C') {
// make string empty for new input
memset(string, 0, strlen(string));
}
// when user presses 'D' key (for Done),
// reset input string and software reset Arduino
else if (ch_input == 'D') {
// make string empty for new input
memset(string, 0, strlen(string));
// call reset
resetFunc();
}
// for other keys
else {
// concatenate input key chars into string
string = strncat(string, &ch_input, 1);
// comment in line to print string on Serial Monitor
// Serial.println(string);
}
} // end of if
// when keypad input matches "270"
// show smiling face on LED matrix
if (strcmp(string, num_combo) == 0) {
printByte(smile);
}
else {
// show sad face by default
printByte(sad);
}
} // end of while
} // end of loop()
void printByte(byte character [])
{
int i = 0;
for(i=0;i<10;i++)
{
matrix.setRow(0,i,character[i]);
}
}
Part 4: Arduino + 64-LED Matrix + RTC + Keypad ("Keycode-enabled Scrolling Digital Clock"):
/*
* pt4_ledmatrix_rtc_keypad.ino
*
* LED display shows current time from RTC if correct "keycode" is
* entered on the keypad. Otherwise, LED display will not show the
* time. Pressing the 'C' key will allow user to erase previous keypad
* input and reenter in a new string. Pressing the 'D' key will allow
* user to restart their LED matrix from the beginning (i.e., by erasing
* previous keypad input and turning the LED matrix off).
*
* Uses 8x8 LED matrix (MAX7219 Module), a DS1307 RTC module (Real-Time
* Clock), a Membrane Switch Module (keypad), and an Arduino Mega2560
* Controller from the ELEGOO Arduino Mega2560 Project Kit.
*
* Code here adopts segments from the version at
* https://www.instructables.com/id/Scrolling-Text-on-a-8x8-LED-Matrix-Using-an-Arduin/
*
* Name: You Jeen Ha
* Course: CSC270 Digital Circuits & Systems
* Professor: D. Thiebaut
* Final Project, Part 4
* Version: 02 May 2020
*/
#include <stdio.h>
#include <string.h>
#include "Adafruit_Keypad.h"
#include <MaxMatrix.h>
#include <avr/pgmspace.h>
#include <Wire.h>
#include <RTClib.h>
#include <time.h>
#define maxDisplays 1 // number of MAX7219's in use.
RTC_DS1307 rtc;
const int data = 13; // DIN of LED matrix
const int load = 12; // CS of LED matrix
const int clk = 11; // CLK of LED matrix
const byte ROWS = 4; // num of keypad rows
const byte COLS = 4; // num of keypad columns
char keys[ROWS][COLS] = { // define the symbols on the buttons of the keypads
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
char *num_combo = "270\0"; // number combo for activating smile face on LED matrix
char *input = "\0"; // initialize keypad input string
byte Buf7219[7]; // "width,height,data[5]" single character buffer
byte rowPins[ROWS] = {9, 8, 7, 6}; // connect to the row pinouts of the keypad
byte colPins[COLS] = {5, 4, 3, 2}; // connect to the column pinouts of the keypad
// Initialize an instance of class NewKeypad
Adafruit_Keypad customKeypad = Adafruit_Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS);
// Instantiate new LED matrix object
MaxMatrix matrix(data, load, clk, maxDisplays);
// Data array is stored in program memory (see memcpy_P for access).
// Parameters are width, height, and character data
PROGMEM const unsigned char CH[] = {
3, 8, B0000000, B0000000, B0000000, B0000000, B0000000, // space
1, 8, B1011111, B0000000, B0000000, B0000000, B0000000, // !
3, 8, B0000011, B0000000, B0000011, B0000000, B0000000, // "
5, 8, B0010100, B0111110, B0010100, B0111110, B0010100, // #
4, 8, B0100100, B1101010, B0101011, B0010010, B0000000, // $
5, 8, B1100011, B0010011, B0001000, B1100100, B1100011, // %
5, 8, B0110110, B1001001, B1010110, B0100000, B1010000, // &
1, 8, B0000011, B0000000, B0000000, B0000000, B0000000, // '
3, 8, B0011100, B0100010, B1000001, B0000000, B0000000, // (
3, 8, B1000001, B0100010, B0011100, B0000000, B0000000, // )
5, 8, B0101000, B0011000, B0001110, B0011000, B0101000, // *
5, 8, B0001000, B0001000, B0111110, B0001000, B0001000, // +
2, 8, B10110000, B1110000, B0000000, B0000000, B0000000, // ,
4, 8, B0001000, B0001000, B0001000, B0001000, B0000000, // -
2, 8, B1100000, B1100000, B0000000, B0000000, B0000000, // .
4, 8, B1100000, B0011000, B0000110, B0000001, B0000000, // /
4, 8, B0111110, B1000001, B1000001, B0111110, B0000000, // 0
3, 8, B1000010, B1111111, B1000000, B0000000, B0000000, // 1
4, 8, B1100010, B1010001, B1001001, B1000110, B0000000, // 2
4, 8, B0100010, B1000001, B1001001, B0110110, B0000000, // 3
4, 8, B0011000, B0010100, B0010010, B1111111, B0000000, // 4
4, 8, B0100111, B1000101, B1000101, B0111001, B0000000, // 5
4, 8, B0111110, B1001001, B1001001, B0110000, B0000000, // 6
4, 8, B1100001, B0010001, B0001001, B0000111, B0000000, // 7
4, 8, B0110110, B1001001, B1001001, B0110110, B0000000, // 8
4, 8, B0000110, B1001001, B1001001, B0111110, B0000000, // 9
2, 8, B01010000, B0000000, B0000000, B0000000, B0000000, // :
2, 8, B10000000, B01010000, B0000000, B0000000, B0000000, // ;
3, 8, B0010000, B0101000, B1000100, B0000000, B0000000, // <
3, 8, B0010100, B0010100, B0010100, B0000000, B0000000, // =
3, 8, B1000100, B0101000, B0010000, B0000000, B0000000, // >
4, 8, B0000010, B1011001, B0001001, B0000110, B0000000, // ?
5, 8, B0111110, B1001001, B1010101, B1011101, B0001110, // @
4, 8, B1111110, B0010001, B0010001, B1111110, B0000000, // A
4, 8, B1111111, B1001001, B1001001, B0110110, B0000000, // B
4, 8, B0111110, B1000001, B1000001, B0100010, B0000000, // C
4, 8, B1111111, B1000001, B1000001, B0111110, B0000000, // D
4, 8, B1111111, B1001001, B1001001, B1000001, B0000000, // E
4, 8, B1111111, B0001001, B0001001, B0000001, B0000000, // F
4, 8, B0111110, B1000001, B1001001, B1111010, B0000000, // G
4, 8, B1111111, B0001000, B0001000, B1111111, B0000000, // H
3, 8, B1000001, B1111111, B1000001, B0000000, B0000000, // I
4, 8, B0110000, B1000000, B1000001, B0111111, B0000000, // J
4, 8, B1111111, B0001000, B0010100, B1100011, B0000000, // K
4, 8, B1111111, B1000000, B1000000, B1000000, B0000000, // L
5, 8, B1111111, B0000010, B0001100, B0000010, B1111111, // M
5, 8, B1111111, B0000100, B0001000, B0010000, B1111111, // N
4, 8, B0111110, B1000001, B1000001, B0111110, B0000000, // O
4, 8, B1111111, B0001001, B0001001, B0000110, B0000000, // P
4, 8, B0111110, B1000001, B1000001, B10111110, B0000000, // Q
4, 8, B1111111, B0001001, B0001001, B1110110, B0000000, // R
4, 8, B1000110, B1001001, B1001001, B0110010, B0000000, // S
5, 8, B0000001, B0000001, B1111111, B0000001, B0000001, // T
4, 8, B0111111, B1000000, B1000000, B0111111, B0000000, // U
5, 8, B0001111, B0110000, B1000000, B0110000, B0001111, // V
5, 8, B0111111, B1000000, B0111000, B1000000, B0111111, // W
5, 8, B1100011, B0010100, B0001000, B0010100, B1100011, // X
5, 8, B0000111, B0001000, B1110000, B0001000, B0000111, // Y
4, 8, B1100001, B1010001, B1001001, B1000111, B0000000, // Z
2, 8, B1111111, B1000001, B0000000, B0000000, B0000000, // [
4, 8, B0000001, B0000110, B0011000, B1100000, B0000000, // backslash
2, 8, B1000001, B1111111, B0000000, B0000000, B0000000, // ]
3, 8, B0000010, B0000001, B0000010, B0000000, B0000000, // hat
4, 8, B1000000, B1000000, B1000000, B1000000, B0000000, // _
2, 8, B0000001, B0000010, B0000000, B0000000, B0000000, // `
4, 8, B0100000, B1010100, B1010100, B1111000, B0000000, // a
4, 8, B1111111, B1000100, B1000100, B0111000, B0000000, // b
4, 8, B0111000, B1000100, B1000100, B0000000, B0000000, // c // JFM MOD.
4, 8, B0111000, B1000100, B1000100, B1111111, B0000000, // d
4, 8, B0111000, B1010100, B1010100, B0011000, B0000000, // e
3, 8, B0000100, B1111110, B0000101, B0000000, B0000000, // f
4, 8, B10011000, B10100100, B10100100, B01111000, B0000000, // g
4, 8, B1111111, B0000100, B0000100, B1111000, B0000000, // h
3, 8, B1000100, B1111101, B1000000, B0000000, B0000000, // i
4, 8, B1000000, B10000000, B10000100, B1111101, B0000000, // j
4, 8, B1111111, B0010000, B0101000, B1000100, B0000000, // k
3, 8, B1000001, B1111111, B1000000, B0000000, B0000000, // l
5, 8, B1111100, B0000100, B1111100, B0000100, B1111000, // m
4, 8, B1111100, B0000100, B0000100, B1111000, B0000000, // n
4, 8, B0111000, B1000100, B1000100, B0111000, B0000000, // o
4, 8, B11111100, B0100100, B0100100, B0011000, B0000000, // p
4, 8, B0011000, B0100100, B0100100, B11111100, B0000000, // q
4, 8, B1111100, B0001000, B0000100, B0000100, B0000000, // r
4, 8, B1001000, B1010100, B1010100, B0100100, B0000000, // s
3, 8, B0000100, B0111111, B1000100, B0000000, B0000000, // t
4, 8, B0111100, B1000000, B1000000, B1111100, B0000000, // u
5, 8, B0011100, B0100000, B1000000, B0100000, B0011100, // v
5, 8, B0111100, B1000000, B0111100, B1000000, B0111100, // w
5, 8, B1000100, B0101000, B0010000, B0101000, B1000100, // x
4, 8, B10011100, B10100000, B10100000, B1111100, B0000000, // y
3, 8, B1100100, B1010100, B1001100, B0000000, B0000000, // z
3, 8, B0001000, B0110110, B1000001, B0000000, B0000000, // {
1, 8, B1111111, B0000000, B0000000, B0000000, B0000000, // |
3, 8, B1000001, B0110110, B0001000, B0000000, B0000000, // }
4, 8, B0001000, B0000100, B0001000, B0000100, B0000000, // ~
};
// Declare reset function @ address 0
void(* resetFunc) (void) = 0;
// Put text on display by character
void printCharWithShift(char c, int shift_speed) {
if (c < 32) {
return;
}
c -= 32;
memcpy_P(Buf7219, CH + 7*c, 7);
matrix.writeSprite(maxDisplays*8, 0, Buf7219);
matrix.setColumn(maxDisplays*8 + Buf7219[0], 0);
for (int i=0; i<=Buf7219[0]; i++) {
delay(shift_speed);
matrix.shiftLeft(false, false);
}
}
// Put text on display by character according to string message
void printStrWithShift(char* s, int shift_speed) {
while (*s != 0) {
printCharWithShift(*s, shift_speed);
s++;
}
}
void setup() {
// initialize keypad
customKeypad.begin();
#ifdef AVR
Wire.begin();
#else
Wire1.begin(); // Shield I2C pins connect to alt I2C bus on Arduino Due
#endif
rtc.begin();
if (! rtc.isrunning()) {
Serial.println("RTC is NOT running!");
// following line sets the RTC to the date & time this sketch was compiled
}
// otherwise, set time
rtc.adjust(DateTime(__DATE__, __TIME__));
// initialize matrix
matrix.init();
// set brightness of matrix
matrix.setIntensity(4);
// comment in to show output on Serial Monitor
// Serial.begin(9600);
}
// Send text to matrix
void loop() {
// get current date/time from RTC
DateTime now = rtc.now();
// make text message the time from RTC in 24-hr mode (military time)
char buf1[] = "hh:mm";
const char *string = now.toString(buf1);
// create row pulses
customKeypad.tick();
// if a new push button is detected
while (customKeypad.available()) {
// read keypad button push as event
keypadEvent e = customKeypad.read();
// cast keypad button push as character
char ch_input = (char)e.bit.KEY;
if (e.bit.EVENT == KEY_JUST_RELEASED) {
// when user presses 'C' key (for Clear),
// reset input string
if (ch_input == 'C') {
// make string empty for new input
memset(input, 0, strlen(input));
}
// when user presses 'D' key (for Done),
// reset input string and software reset Arduino
else if (ch_input == 'D') {
// make string empty for new input
memset(input, 0, strlen(input));
// clear LED display
matrix.clear();
// reset Arduino
resetFunc();
}
// for other keys
else {
// concatenate input key chars into string
input = strncat(input, &ch_input, 1);
// comment in line to print string on Serial Monitor
// Serial.println(input);
// when keypad input matches "270"
// show scrolling time on LED matrix
if (strcmp(input, num_combo) == 0) {
// delay 1.5s
delay(1500);
// scroll message leftward
matrix.shiftLeft(false, true);
// number is message speed
// (the greater the number, the slower the message speed)
printStrWithShift(string, 180);
}
// when input doesn't match "270",
// clear LED display
else {
matrix.clear();
}
} // end of else
} // end of if
} // end of while
} // end of loop()
References
How to Wire the Arduino with a 8x8 LED Dot Matrix
Implementing a Scrolling Display on a 8x8 LED Dot Matrix with an Arduino
How to Wire the Arduino with a RTC Module
Default Code for integrating a RTC Module with an Arduino
Understanding the Code for the RTC
RTClib.h Library Documentation
How to Wire the Arduino with a Membrane Switch Module (Keypad)
Adafruit_Keypad.h Library Documentation
Adafruit_Keypad.h Library Usage Example
MaxMatrix.h Library Documentation