top of page

8×8 LED Matrix MAX7219 Tutorial with Scrolling Text & Android Control via Bluetooth

Students now you know everything about how a matrix works, let’s move to some advanced part of it.


8×8 LED Matrix Scrolling Arduino Code

Next let’s take a look at the scrolling text example and see what’s different. Below the code you will find its description.


#include <MaxMatrix.h> #include <avr/pgmspace.h>

PROGMEM const unsigned char CH[] = {

3, 8, B00000000, B00000000, B00000000, B00000000, B00000000, // space

1, 8, B01011111, B00000000, B00000000, B00000000, B00000000, // !

3, 8, B00000011, B00000000, B00000011, B00000000, B00000000, // "

5, 8, B00010100, B00111110, B00010100, B00111110, B00010100, // #

4, 8, B00100100, B01101010, B00101011, B00010010, B00000000, // $

5, 8, B01100011, B00010011, B00001000, B01100100, B01100011, // %

5, 8, B00110110, B01001001, B01010110, B00100000, B01010000, // &

1, 8, B00000011, B00000000, B00000000, B00000000, B00000000, // '

3, 8, B00011100, B00100010, B01000001, B00000000, B00000000, // (

3, 8, B01000001, B00100010, B00011100, B00000000, B00000000, // )

5, 8, B00101000, B00011000, B00001110, B00011000, B00101000, //*

5, 8, B00001000, B00001000, B00111110, B00001000, B00001000, // +

2, 8, B10110000, B01110000, B00000000, B00000000, B00000000, // ,

4, 8, B00001000, B00001000, B00001000, B00001000, B00000000, // -

2, 8, B01100000, B01100000, B00000000, B00000000, B00000000, // .

4, 8, B01100000, B00011000, B00000110, B00000001, B00000000, // /

4, 8, B00111110, B01000001, B01000001, B00111110, B00000000, // 0

3, 8, B01000010, B01111111, B01000000, B00000000, B00000000, // 1

4, 8, B01100010, B01010001, B01001001, B01000110, B00000000, // 2

4, 8, B00100010, B01000001, B01001001, B00110110, B00000000, // 3

4, 8, B00011000, B00010100, B00010010, B01111111, B00000000, // 4

4, 8, B00100111, B01000101, B01000101, B00111001, B00000000, // 5

4, 8, B00111110, B01001001, B01001001, B00110000, B00000000, // 6

4, 8, B01100001, B00010001, B00001001, B00000111, B00000000, // 7

4, 8, B00110110, B01001001, B01001001, B00110110, B00000000, // 8

4, 8, B00000110, B01001001, B01001001, B00111110, B00000000, // 9

2, 8, B01010000, B00000000, B00000000, B00000000, B00000000, // :

2, 8, B10000000, B01010000, B00000000, B00000000, B00000000, // ;

3, 8, B00010000, B00101000, B01000100, B00000000, B00000000, // <

3, 8, B00010100, B00010100, B00010100, B00000000, B00000000, // =

3, 8, B01000100, B00101000, B00010000, B00000000, B00000000, // >

4, 8, B00000010, B01011001, B00001001, B00000110, B00000000, // ?

5, 8, B00111110, B01001001, B01010101, B01011101, B00001110, // @

4, 8, B01111110, B00010001, B00010001, B01111110, B00000000, //A

4, 8, B01111111, B01001001, B01001001, B00110110, B00000000, // B

4, 8, B00111110, B01000001, B01000001, B00100010, B00000000, // C

4, 8, B01111111, B01000001, B01000001, B00111110, B00000000, // D

4, 8, B01111111, B01001001, B01001001, B01000001, B00000000, // E

4, 8, B01111111, B00001001, B00001001, B00000001, B00000000, // F

4, 8, B00111110, B01000001, B01001001, B01111010, B00000000, // G

4, 8, B01111111, B00001000, B00001000, B01111111, B00000000, // H

3, 8, B01000001, B01111111, B01000001, B00000000, B00000000, // I

4, 8, B00110000, B01000000, B01000001, B00111111, B00000000, // J

4, 8, B01111111, B00001000, B00010100, B01100011, B00000000, // K

4, 8, B01111111, B01000000, B01000000, B01000000, B00000000, // L

5, 8, B01111111, B00000010, B00001100, B00000010, B01111111, // M

5, 8, B01111111, B00000100, B00001000, B00010000, B01111111, // N

4, 8, B00111110, B01000001, B01000001, B00111110, B00000000, //O

4, 8, B01111111, B00001001, B00001001, B00000110, B00000000, // P

4, 8, B00111110, B01000001, B01000001, B10111110, B00000000, // Q

4, 8, B01111111, B00001001, B00001001, B01110110, B00000000, // R

4, 8, B01000110, B01001001, B01001001, B00110010, B00000000, // S

5, 8, B00000001, B00000001, B01111111, B00000001, B00000001, // T

4, 8, B00111111, B01000000, B01000000, B00111111, B00000000, // U

5, 8, B00001111, B00110000, B01000000, B00110000, B00001111, // V

5, 8, B00111111, B01000000, B00111000, B01000000, B00111111, // W

5, 8, B01100011, B00010100, B00001000, B00010100, B01100011, // X

5, 8, B00000111, B00001000, B01110000, B00001000, B00000111, // Y

4, 8, B01100001, B01010001, B01001001, B01000111, B00000000, // Z

2, 8, B01111111, B01000001, B00000000, B00000000, B00000000, // [

4, 8, B00000001, B00000110, B00011000, B01100000, B00000000, // \ backslash

2, 8, B01000001, B01111111, B00000000, B00000000, B00000000, // ]

3, 8, B00000010, B00000001, B00000010, B00000000, B00000000, // hat

4, 8, B01000000, B01000000, B01000000, B01000000, B00000000, // _

2, 8, B00000001, B00000010, B00000000, B00000000, B00000000, // `

4, 8, B00100000, B01010100, B01010100, B01111000, B00000000, // a

4, 8, B01111111, B01000100, B01000100, B00111000, B00000000, // b

4, 8, B00111000, B01000100, B01000100, B00101000, B00000000, // c

4, 8, B00111000, B01000100, B01000100, B01111111, B00000000, // d

4, 8, B00111000, B01010100, B01010100, B00011000, B00000000, // e

3, 8, B00000100, B01111110, B00000101, B00000000, B00000000, // f

4, 8, B10011000, B10100100, B10100100, B01111000, B00000000, // g

4, 8, B01111111, B00000100, B00000100, B01111000, B00000000, //h

3, 8, B01000100, B01111101, B01000000, B00000000, B00000000, // i

4, 8, B01000000, B10000000, B10000100, B01111101, B00000000, // j

4, 8, B01111111, B00010000, B00101000, B01000100, B00000000, // k

3, 8, B01000001, B01111111, B01000000, B00000000, B00000000, // l

5, 8, B01111100, B00000100, B01111100, B00000100, B01111000, // m

4, 8, B01111100, B00000100, B00000100, B01111000, B00000000, // n

4, 8, B00111000, B01000100, B01000100, B00111000, B00000000, // o

4, 8, B11111100, B00100100, B00100100, B00011000, B00000000, // p

4, 8, B00011000, B00100100, B00100100, B11111100, B00000000, // q

4, 8, B01111100, B00001000, B00000100, B00000100, B00000000, // r

4, 8, B01001000, B01010100, B01010100, B00100100, B00000000, // s

3, 8, B00000100, B00111111, B01000100, B00000000, B00000000, // t

4, 8, B00111100, B01000000, B01000000, B01111100, B00000000, // u

5, 8, B00011100, B00100000, B01000000, B00100000, B00011100, //v

5, 8, B00111100, B01000000, B00111100, B01000000, B00111100, // w

5, 8, B01000100, B00101000, B00010000, B00101000, B01000100, // x

4, 8, B10011100, B10100000, B10100000, B01111100, B00000000, // y

3, 8, B01100100, B01010100, B01001100, B00000000, B00000000, // z

3, 8, B00001000, B00110110, B01000001, B00000000, B00000000, // {

1, 8, B01111111, B00000000, B00000000, B00000000, B00000000, // |

3, 8, B01000001, B00110110, B00001000, B00000000, B00000000, // }

4, 8, B00001000, B00000100, B00001000, B00000100, B00000000, // ~

};

int DIN = 7; // DIN pin of MAX7219 module

int CLK = 6; // CLK pin of MAX7219 module

int CS = 5; // CS pin of MAX7219 module

int maxInUse = 2;

MaxMatrix m(DIN, CS, CLK, maxInUse);

byte buffer[10];

char text[]= "TechKnowSkola"; // Scrolling text


void setup() {

m.init(); // module initialize

m.setIntensity(15); // dot matix intensity 0-15

}

void loop() {

printStringWithShift(text, 100); // (text, scrolling speed)

}

// Display=the extracted characters with scrolling

void printCharWithShift(char c, int shift_speed) {

if (c < 32) return;

c -= 32;

memcpy_P(buffer, CH + 7 * c, 7);

m.writeSprite(32, 0, buffer);

m.setColumn(32 + buffer[0], 0);

for (int i = 0; i < buffer[0] + 1; i++)

{

delay(shift_speed);

m.shiftLeft(false, false);

}

}

// Extract the characters from the text string

void printStringWithShift(char* s, int shift_speed) {

while (*s != 0) {

printCharWithShift(*s, shift_speed);

s++;

}

}


Now let’s move to the functioning of Bluetooth HC-05


Description:


Here we have to include an additional library for the PROGMEN which is variable modifier and it’s used for storing data in the flash memory instead of SRAM. When we have a larger database of variables which are static, like in this case defining letters and characters, it’s better to store them in the flash memory because it’s much bigger, 32K bytes, compared to the 2K bytes of the SRAM.



Next with a character array we define the scrolling text and in the loop section the custom function printStringWithShift, prints the scrolling text on the LED matrix with a scrolling speed defined in milliseconds with the second argument. The first thing that this custom function do is that it extracts the characters from the text string and then display these scrolling characters on the led matrix.


The particular module that I have can be powered from 3.6 to 6 volts, because it comes on breakout board which contains a voltage regulator. However, the logic voltage level of the data pins is 3.3V. So, the line between the Arduino TX (Transmit Pin, which has 5V output) and the Bluetooth module RX (Receive Pin, which supports only 3.3V) needs to be connected through a voltage divider in order not to burn the module. On the other hand, the line between the Bluetooth module TX pin and the Arduino RX pin can be connected directly because the 3.3V signal from the Bluetooth module is enough to beaccepted as a high logic at the Arduino Board.


Circuit Schematics:

Here’s how we need to connect the module to the Arduino Board.



Connecting the Smartphone to the HC-05 Bluetooth Module and the Arduino

Now we are ready to connect the smartphone to the Bluetooth module and the Arduino. What we need to do here is to activate the Bluetooth and the smartphone will find the HC-05 Bluetooth module.


Then we need to pair the devices and the default password of the HC-05 module is 1234. After we have paired the devices we need an application for controlling the Arduino. There are many application in the Play Store for this purpose which will work with the Arduino code that we wrote. However, I made my own custom application for this tutorial using the MIT App Inventor online application. This is a great and easy to use application for building Android application and in my next tutorial you can find a detailed step by step guide how to build your own custom Android application for your Arduino Project.


Android App for Controlling 8×8 LED Matrix via Bluetooth Once we learned how the MAX7219 works, now we can make the third example which is a practical Arduino project where we will build a custom Android app to control the LED matrix via Bluetooth communication. Before we continue I would suggest you to check detailed tutorials on how to use the HC-05 Bluetooth module and how to build a custom Android app using the MIT App Inventor online application.



Here’s the Arduino code and now let’s see the modifications compared to the previous example. /* 8x8 LED Matrix MAX7219 Scrolling Text Android Control via Bluetooth by Dejan Nedelkovski, www.HowToMechatronics.com Based on the following library: GitHub | riyas-org/max7219 https://github.com/riyas-org/max7219 */ #include <MaxMatrix.h> #include <SoftwareSerial.h> #include <avr/pgmspace.h> PROGMEM const unsigned char CH[] = { 3, 8, B00000000, B00000000, B00000000, B00000000, B00000000, // space 1, 8, B01011111, B00000000, B00000000, B00000000, B00000000, // ! 3, 8, B00000011, B00000000, B00000011, B00000000, B00000000, // " 5, 8, B00010100, B00111110, B00010100, B00111110, B00010100, //# 4, 8, B00100100, B01101010, B00101011, B00010010, B00000000, // $


5, 8, B01100011, B00010011, B00001000, B01100100, B01100011, // % 5, 8, B00110110, B01001001, B01010110, B00100000, B01010000, // & 1, 8, B00000011, B00000000, B00000000, B00000000, B00000000, // ' 3, 8, B00011100, B00100010, B01000001, B00000000, B00000000, // ( 3, 8, B01000001, B00100010, B00011100, B00000000, B00000000, // ) 5, 8, B00101000, B00011000, B00001110, B00011000, B00101000, // * 5, 8, B00001000, B00001000, B00111110, B00001000, B00001000, // + 2, 8, B10110000, B01110000, B00000000, B00000000, B00000000, // , 4, 8, B00001000, B00001000, B00001000, B00001000, B00000000, //- 2, 8, B01100000, B01100000, B00000000, B00000000, B00000000, // . 4, 8, B01100000, B00011000, B00000110, B00000001, B00000000, // / 4, 8, B00111110, B01000001, B01000001, B00111110, B00000000, // 0 3, 8, B01000010, B01111111, B01000000, B00000000, B00000000, // 1 4, 8, B01100010, B01010001, B01001001, B01000110, B00000000, // 2 4, 8, B00100010, B01000001, B01001001, B00110110, B00000000, // 3 4, 8, B00011000, B00010100, B00010010, B01111111, B00000000, // 4 4, 8, B00100111, B01000101, B01000101, B00111001, B00000000, // 5 4, 8, B00111110, B01001001, B01001001, B00110000, B00000000, // 6 4, 8, B01100001, B00010001, B00001001, B00000111, B00000000, // 7 4, 8, B00110110, B01001001, B01001001, B00110110, B00000000, // 8 4, 8, B00000110, B01001001, B01001001, B00111110, B00000000, // 9 2, 8, B01010000, B00000000, B00000000, B00000000, B00000000, // : 2, 8, B10000000, B01010000, B00000000, B00000000, B00000000, //; 3, 8, B00010000, B00101000, B01000100, B00000000, B00000000, // < 3, 8, B00010100, B00010100, B00010100, B00000000, B00000000, // = 3, 8, B01000100, B00101000, B00010000, B00000000, B00000000, // > 4, 8, B00000010, B01011001, B00001001, B00000110, B00000000, // ? 5, 8, B00111110, B01001001, B01010101, B01011101, B00001110, // @ 4, 8, B01111110, B00010001, B00010001, B01111110, B00000000, // A 4, 8, B01111111, B01001001, B01001001, B00110110, B00000000, // B 4, 8, B00111110, B01000001, B01000001, B00100010, B00000000, // C 4, 8, B01111111, B01000001, B01000001, B00111110, B00000000, // D 4, 8, B01111111, B01001001, B01001001, B01000001, B00000000, // E 4, 8, B01111111, B00001001, B00001001, B00000001, B00000000, // F 4, 8, B00111110, B01000001, B01001001, B01111010, B00000000, // G 4, 8, B01111111, B00001000, B00001000, B01111111, B00000000, // H 3, 8, B01000001, B01111111, B01000001, B00000000, B00000000, // I 4, 8, B00110000, B01000000, B01000001, B00111111, B00000000, // J 4, 8, B01111111, B00001000, B00010100, B01100011, B00000000, // K


4, 8, B01111111, B01000000, B01000000, B01000000, B00000000, // L 5, 8, B01111111, B00000010, B00001100, B00000010, B01111111, // M 5, 8, B01111111, B00000100, B00001000, B00010000, B01111111, // N 4, 8, B00111110, B01000001, B01000001, B00111110, B00000000, // O 4, 8, B01111111, B00001001, B00001001, B00000110, B00000000, // P 4, 8, B00111110, B01000001, B01000001, B10111110, B00000000, // Q 4, 8, B01111111, B00001001, B00001001, B01110110, B00000000, // R 4, 8, B01000110, B01001001, B01001001, B00110010, B00000000, // S 5, 8, B00000001, B00000001, B01111111, B00000001, B00000001, //T 4, 8, B00111111, B01000000, B01000000, B00111111, B00000000, // U 5, 8, B00001111, B00110000, B01000000, B00110000, B00001111, // V 5, 8, B00111111, B01000000, B00111000, B01000000, B00111111, // W 5, 8, B01100011, B00010100, B00001000, B00010100, B01100011, // X 5, 8, B00000111, B00001000, B01110000, B00001000, B00000111, // Y 4, 8, B01100001, B01010001, B01001001, B01000111, B00000000, // Z 2, 8, B01111111, B01000001, B00000000, B00000000, B00000000, // [ 4, 8, B00000001, B00000110, B00011000, B01100000, B00000000, // \ backslash 2, 8, B01000001, B01111111, B00000000, B00000000, B00000000, // ] 3, 8, B00000010, B00000001, B00000010, B00000000, B00000000, // hat 4, 8, B01000000, B01000000, B01000000, B01000000, B00000000, // _ 2, 8, B00000001, B00000010, B00000000, B00000000, B00000000, // ` 4, 8, B00100000, B01010100, B01010100, B01111000, B00000000, // a 4, 8, B01111111, B01000100, B01000100, B00111000, B00000000, //b 4, 8, B00111000, B01000100, B01000100, B00101000, B00000000, // c 4, 8, B00111000, B01000100, B01000100, B01111111, B00000000, // d 4, 8, B00111000, B01010100, B01010100, B00011000, B00000000, // e 3, 8, B00000100, B01111110, B00000101, B00000000, B00000000, // f 4, 8, B10011000, B10100100, B10100100, B01111000, B00000000, // g 4, 8, B01111111, B00000100, B00000100, B01111000, B00000000, // h 3, 8, B01000100, B01111101, B01000000, B00000000, B00000000, // i 4, 8, B01000000, B10000000, B10000100, B01111101, B00000000, // j 4, 8, B01111111, B00010000, B00101000, B01000100, B00000000, // k 3, 8, B01000001, B01111111, B01000000, B00000000, B00000000, // l 5, 8, B01111100, B00000100, B01111100, B00000100, B01111000, // m 4, 8, B01111100, B00000100, B00000100, B01111000, B00000000, // n 4, 8, B00111000, B01000100, B01000100, B00111000, B00000000, // o 4, 8, B11111100, B00100100, B00100100, B00011000, B00000000, // p 4, 8, B00011000, B00100100, B00100100, B11111100, B00000000, // q 4, 8, B01111100, B00001000, B00000100, B00000100, B00000000, // r


4, 8, B01001000, B01010100, B01010100, B00100100, B00000000, // s 3, 8, B00000100, B00111111, B01000100, B00000000, B00000000, // t 4, 8, B00111100, B01000000, B01000000, B01111100, B00000000, // u 5, 8, B00011100, B00100000, B01000000, B00100000, B00011100, // v 5, 8, B00111100, B01000000, B00111100, B01000000, B00111100, // w 5, 8, B01000100, B00101000, B00010000, B00101000, B01000100, // x 4, 8, B10011100, B10100000, B10100000, B01111100, B00000000, // y 3, 8, B01100100, B01010100, B01001100, B00000000, B00000000, // z 3, 8, B00001000, B00110110, B01000001, B00000000, B00000000, //{ 1, 8, B01111111, B00000000, B00000000, B00000000, B00000000, // | 3, 8, B01000001, B00110110, B00001000, B00000000, B00000000, // } 4, 8, B00001000, B00000100, B00001000, B00000100, B00000000, // ~ }; int dIn = 7; // DIN pin of MAX7219 module int clk = 6; // CLK pin of MAX7219 module int cs = 5; // CS pin of MAX7219 module int maxInUse = 2; // Number of MAX7219's connected MaxMatrix m(dIn, cs, clk, maxInUse); SoftwareSerial Bluetooth(8, 7); // Bluetooth byte buffer[10]; char incomebyte; int scrollSpeed = 100; char text[100] = "TechKnowSkola "; // Initial text message int brightness = 15; int count = 0; char indicator; void setup() { m.init(); // MAX7219 initialization m.setIntensity(brightness); // initial led matrix intensity, 0-15 Bluetooth.begin(38400); // Default communication rate of the Bluetooth module } void loop() { // Printing the text printStringWithShift(text, scrollSpeed); if (Bluetooth.available()) { // Checks whether data is comming from the serial port indicator = Bluetooth.read(); // Starts reading the serial port, the first byte from the incoming data // If we have pressed the "Send" button from the Android App, clear the previous text


if (indicator == '1') { for (int i = 0; i < 100; i++) { text[i] = 0; m.clear(); } // Read the whole data/string comming from the phone and put it into text[] array. while (Bluetooth.available()) { incomebyte = Bluetooth.read(); text[count] = incomebyte; count++; } count = 0; } // Adjusting the Scrolling Speed else if (indicator == '2') { String sS = Bluetooth.readString(); scrollSpeed = 150 - sS.toInt(); // Milliseconds, subtraction because lower value means higher scrolling speed } // Adjusting the brightness else if (indicator == '3') { String sB = Bluetooth.readString(); brightness = sB.toInt(); m.setIntensity(brightness); } } } void printCharWithShift(char c, int shift_speed) { if (c < 32) return; c -= 32; memcpy_P(buffer, CH + 7 * c, 7); m.writeSprite(32, 0, buffer); m.setColumn(32 + buffer[0], 0); for (int i = 0; i < buffer[0] + 1; i++) { delay(shift_speed); m.shiftLeft(false, false); } }



void printStringWithShift(char* s, int shift_speed) { while (*s != 0) {

printCharWithShift(*s, shift_speed); s++;

}

}

void printString(char* s)

{

int col = 0; while (*s != 0)

{

if (*s < 32) continue; char c = *s - 32;

memcpy_P(buffer, CH + 7 * c, 7); m.writeSprite(col, 0, buffer); m.setColumn(col + buffer[0], 0); col += buffer[0] + 1;

s++;

}

}


Description:

First we need to include the SoftwareSerial.h library which will enable the Bluetooth communication and define some variables needed for the program. In the setup section we need to initialize the Bluetooth at its default baud rate of 38400 bits per second. I set the initial text

message to be “TechKnowSkola” with 100 milliseconds delay scrolling speed.


Next, in the loop section, using the Bluetooth.available() function we check whether there is

incoming data from the serial port and if that’s true using the Bluetooth.read function we start reading the serial port, one byte each iteration. So the first incoming byte will be always stored into the “indicator” variable and according to it choose whether we will change the text message, the scrolling speed or the brightness of the LED matrix.



If we take a look at the Android app code blocks we can notice that when the “Send” button is clicked, first we send the indication byte, in this case “1”, which means we want the change the text message. In order to do that, at the Arduino side, we will clear the whole character array and also clear the LED matrix display. Then in the “while” loop we will read the rest of the data in the serial port, and that’s the messaged typed in the text box of the Android app.

In case the indication variable is “2”, that means we have changed the position of the scrolling speed slider, so we will read its new value using the Bluetooth.readString() function and adjust the scrolling speed. In the same way we adjust the brightness of the LEDs.


You can download the app from the following link:

https://drive.google.com/open?id=1xvR_tyTF-zzdrqc6RrdHlcD5FRICIbs5

GET IN TOUCH

We'd love to hear from you

bottom of page