You Jeen's Final Project

From CSclasswiki
Jump to: navigation, search

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:

  1. 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.
  2. 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.
  3. 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.
  4. 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

  1. Gather all necessary materials for this project from the ELEGOO Arduino Mega2560 Project Kit.
  2. Read through and watch all relevant resources (i.e., tutorials and videos).
  3. Proceed with Part 1 (see Outline).
  4. Proceed with Part 2 (see Outline).
  5. Proceed with Part 3 (see Outline).
  6. Proceed with Part 4 (see Outline).
  7. While tackling the 4 parts, report progress on this wiki page and start creating online presentation.
    1. 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 Module Membrane 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.

  1. 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.
  2. 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.
  3. 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).
  4. 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

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

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

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"):

Breadboard diagram for part 1 (Arduino Mega2560, LED Matrix) Schematic for part 1 (Arduino Mega2560, LED Matrix)

Part 2: Arduino + 64-LED Matrix + RTC ("Scrolling Time"):

Breadboard diagram for part 2 (Arduino Mega2560, LED Matrix, and RTC) Schematic for part 2 (Arduino Mega2560, LED Matrix, and RTC)

Part 3: Arduino + 64-LED Matrix + Keypad ("Keycode-enabled Smiling Face"):

Breadboard diagram for part 3 (Arduino Mega2560, LED Matrix, and Keypad) Schematic for part 3 (Arduino Mega2560, LED Matrix, and Keypad

Part 4: Arduino + 64-LED Matrix + RTC + Keypad ("Keycode-enabled Scrolling Digital Clock"):

Breadboard diagram for part 4 (Arduino Mega2560, LED Matrix, RTC, and Keypad) Schematic for part 4 (Arduino Mega2560, LED Matrix, RTC, and Keypad)

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

ELEGGO Tutorial for Mega2560

Fritzing Software

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

How to Display Faces on a 8x8 LED Dot Matrix

How to Software Reset the Arduino