Sunday, February 16, 2020

MAX7219 DotMatrix library

Years ago I was given an assignment of creating a test instrument that had a dot matrix display and charged with the task of devising a menu system to be used by the operators to program the machine. To solve the problem I created firmware that shifted the display at a rate the operator could read comfortably but quick enough to be able to program the machine in a timely manner. It turned out to be a big success so when years later I spotted a dot matrix display on ebay I thought it would be fun to see if I could create a C++ library for the device.

Figure 1: The DotMatrix unit in it's case.

The display featured in this article is an 8X8 Dot Marix display with a MAX7219 driver that are packaged four displays to a unit. The units are programmed via a 3-wire serial interface, SPI without MISO and may be daisy chained together. Figure 1 shows the display with 2 units that have been chained together and emclosed in a case I 3D printed.

Key Features of the MAX7219, Serially Interfaced, 8-Digit, LED Display Drivers

  • 10MHz Serial Interface
  • Individual LED Segment Control
  • Decode/No-Decode Digit Selection
  • 150µA Low-Power Shutdown (Data Retained)
  • Digital and Analog Brightness Control
  • Display Blanked on Power-Up
  • Drive Common-Cathode LED Display
  • Slew-Rate Limited Segment Drivers for Lower EMI (MAX7221)
  • SPI, QSPI, MICROWIRE Serial Interface (MAX7221)
  • 24-Pin DIP and SO Packages
The CDotMatrix library code has been modified from the LEDMartixDriver code created by Bartosz Bielawski at

Data is read from EEPROM and a Commands structure (see Listing 1) created that is used when stepping through the data. A 3 pass parse is performed on the data; the first pass removes all spaces from the command statements, the second pass determines the command types and any associated parameters and the third pass adds the address and length of data. The commands structure is added to an command array which the CDotMatrixManager uses during processing.

typedef struct Commands
    unsigned char	cmd;	// The command character
    unsigned char*	caddr;	// Address of the command
    unsigned char	scmd;	// Sub-command for D,L,S and E commands
    int				param;	// Parameter, numeric value
    unsigned char*	daddr;	// Address of data
    int				dlen;	// Length of data
    // Used by the manager to keep track of loops
    uint16_t		IteractionCursor;
    uint8_t			rowCursor;

Listing 1. Commands structure

As can be seen in listing 2, data is interspersed with commands that are enclosed withing curly brackets that contain parameters that vary according to the type of command.

  \file eeprom.c
  \author Mike Hankey
  \date 2/12/2020
  Command Description
  Command	    Param1	Param2	Example	Description
      P		n				{P:n}	Pause (n = mS)
      D		#				{D:#}	Direction (# = [U]p, [D]own, [R]ight, [L]eft)
      I		n				{I:n}	Intensity (n = 0 to 10 => 0 light - 10 bright)
      S		#		n		{S:#,n}	Output a series of Spaces per columns (# = direction, n = columns)
      B				n		{B:n}	Blink display (n = number of times to blink / 2)
      C						{C}		Clears display
      L		n		n		{L:#,n}	Loop (# = loop identifier, n = repeat count {0 = continuous)
      E		#				{E:#}	End of Loop {# = loop identifier)
  Example string;
      {D:L}Hello {P:500}{D:U}{L:2,0}{D:L}Dot Matrix demo{E:A}
      ^	 ^     ^	  ^	   ^      ^    ^              ^
      |	 |	   |	  |	   |	  |	   |			  End of Loop 'A'	
      |	 |	   |	  |	   | 	  |	   String to output
      |	 |	   |	  |	   |	  Direction Left-to-Right
      |	 |	   |	  |	   Loop 'A', repeat continuously
      |	 |	   |	  Direction Up, repeats until changed or until characters are no longer visible   
      |	 |	   Pause for 500 mS
      |	 String to output
      Direction Left-t- Right	 
  This is the default string!	    
  #include <avr/eeprom.h>
  struct DefaultInfo
  uint16_t length;
  unsigned char str[200];
  const struct DefaultInfo Info[] EEMEM = {
  /*       |--------1---------2---------3---------4---------5---------6---------|---------|---------|--------*/
  { 147, {"{I:2}{D:R}DotMatrix{S:R,5}{P:80}{D:D}"
          "{D:R}C++ library{P:10}{D:U}"
          "{L:A,2}{D:R}Feature rich{S:R,4}{S:L,4}{S:R,35}"

Listing 2. eeprom.c listing

The example application provided;

  • {I:2} Set Intensity to 2
  • {D:R} Display data "DotMatrix" from Right to Left
  • {S:R,5} Inset 5 spaces on the right
  • {P:80} Pause for 80 units
  • {D:D} Shift display down until not visible
  • {D:R} Display data "C++ library" from right to left
  • {P:10} Pause 10 units
  • {D:U} Shift display up until not visible
  • {L:A} Start Loop A, to be repeated 2 times
  • {D:R} Display data "Feature Rich" from Right to left
  • {S:R,4} Insert 4 spaces on right
  • {S:L,4} Insert 4 spaces on left
  • {S:R,35} Insert 35 spaces on right
  • {D:R} Display data "Flashy" from right to left
  • {S:R,10} Insert 10 spaces on right
  • {B:20} Blink display 10 times on anmd 10 off
  • {D:U} Shift display up until not visible
  • {E:A} End loop A, when repeat count reached goes back to beginning

The main module uses Timer1 interrupt, fired approximately each 1mS to call the CDotMatrixManagers Process method which processes the current command. When data is output each column is output to the display each time the Process method is called. When the entire string of data is displayed the next command becomes active and the process repeats.


Top ^