- Notifications
You must be signed in to change notification settings - Fork5
Flexible and powerful an Arduino library to control LED matrixes on chips MAX7219 and MAX7221
License
valmat/LedMatrix
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
LedMatrix is a flexible and powerfulArduino C++11 library to control LED matrixes on chips MAX7219 and MAX7221.
With theLedMatrix library, you can flexibly control LED matrixes are connected via chipsMAX7219 andMAX7221. As well as cascades of such matrices. And whole groups of cascades.It can work via software SPI, using any three free pins or through hardware SPI.Hardware SPI of course is faster.
First of all, you need to connect the header file:#include <LedMatrix.h>
.Further, as is customary in the Arduino sketches, you need to create a global object:
#include"LedMatrix.h"// pin 11 is connected to the DataIn// pin 13 is connected to the CLK// pin 10 is connected to LOAD (cs)// Software-SPILedMatrixmatrix(11,13,10);
or so:
#include"LedMatrix.h"//Hardware-SPILedMatrixmatrix(10);
Now the matrix is ready to use.
The library provides two constructors.
One constructor creates a matrix that operates through software SPI:
// Software-SPI Constructor// @param dataPin pin on the Arduino where data gets shifted out (DIN)// @param clockPin pin for the clock (CLK)// @param csPin pin for selecting the device (CS - chip select pin)LedMatrix(uint8_tdata,uint8_tclk,uint8_tcs);
The other creates by using hardware SPI:
// HardWare-SPI Constructor// @param csPin pin for selecting the device (CS -- chip select pin)LedMatrix(uint8_tcs);
The choice of the using SPI depends on the invoked constructor.
Below are the main methods:
// Set the shutdown (power saving) mode for the devicevoidshutdown()const;
The methodshutdown()
turns off the power of the matrix, in order to save energy. By default, at startup, the matrix power is turned on.
// Set the wakeup mode for the devicevoidwakeup()const;
The methodwakeup()
turns on the power of the matrix if it was previously turned off.
// Set the brightness of the display.// @param intensity the brightness of the display. (0..15)voidsetIntensity(uint8_tintensity)const;
The methodsetIntensity()
sets the brightness of the LEDs. Possible values are from 0 to 15.
// Switch all LEDs on the display to off.voidclear();
The methodclear()
"cleans" the screen by turning off all points on the matrix.
// Switch all LEDs on the display to on.voidfill();
The methodfill()
"fills" the screen by turning on all points on the matrix.
As I said before, the matrix may be combined in a cascade. I believe that when they are combined in a cascade is necessary to proceed first and foremost from the ease of installation. In this case, some matrices may be rotated. For this, I added the ability to programmatically rotation matrices.
The following methods implement this feature:
// Set how many times to rotate the matrix clockwise// @param From 0 to 3voidsetRotation(uint8_ttimes=1);// Reset rotation flag to defaultvoidresetRotation();// Get how many times the matrix was rotated clockwiseuint8_tgetRotation()const;
To know which index has the matrix in the cascade will help the following method:
// get device index in cascadeuint16_tindex()const;
Now let's talk about how to "fill" matrixes.
To fill a matrix, use the following methods:
// Set the status of a single LED.// @param Row row the row of the Led (0..7)// @param Col col the column of the Led (0..7)// @param state If true the led is switched on, if false it is switched offvoidset(constRow&row,constCol&col,boolstate);// Turn on LED at a point// @param Row row the row of the Led (0..7)// @param Col col the column of the Led (0..7)voidon(constRow&row,constCol&col);// Turn off LED at a point// @param Row row the row of the Led (0..7)// @param Col col the column of the Led (0..7)voidoff(constRow&row,constCol&col);// Set all LEDs in a row to a new state// @param row which is to be set (0..7)// @param value each bit set to 1 will light up the corresponding LED.voidset(constRow&row,buint8_tvalue);// Set all LEDs in a column to a new state// @param col -- column which is to be set (0..7)// @param value -- each bit set to 1 will light up the corresponding LED.voidset(constCol&col,buint8_tvalue);// Set all LEDs in a row to a new state// @param row which is to be set (0..7)// @param value each bit set to 1 will light up the corresponding LED.voidsetRow(constRow&row,buint8_tvalue);// Set all LEDs in a column to a new state// @param col -- column which is to be set (0..7)// @param value -- each bit set to 1 will light up the corresponding LED.voidsetCol(constCol&col,buint8_tvalue);// Allows to initialize the values of all points of the matrix// @param initializer_list instancetemplate<typenameT>voidset(conststd::initializer_list<T>&disp);// Allows to initialize the values of all points of the matrix// Attention. If you pass an array to this function, strictly follow its length// @param raw arrayvoidset(constuint8_tarr[]);
In the list of arguments you can see here the typesRow
,Col
andbuint8_t
.Do not be alarmed. They were introduced for convenience. What they can do for you I will writebelow.In the meantime, you need to know that these types are automatically converted to numbers such asuint8_t
and back.In fact, these types are theuint8_t
+ a little sugar.Then the recordmatrix.on(3, 5);
is absolutely correct.
I will not describe use of all these setters, because their naming and prototypes speak for themselves.
More focus on two.
template<typenameT>voidset(conststd::initializer_list<T>&disp);
This method allows you to fill the matrix on place. Right at compile time, without creating intermediate arrays or anything else.
Here is an example:
matrix.set({0b00000000,0b01100110,0b10011001,0b10000001,0b01000010,0b00100100,0b00011000,0b00000000});
The method
voidset(constuint8_tarr[])
allows to fill the matrix with a previously created array:
uint8_tarr[8]= {0b00000000,0b00100000,0b00000000,0b01100000,0b00100000,0b00100000,0b00100000,0b01110000};matrix.set(arr);
The following group of methods is to retrieve information from the matrix:
// Get state of LED point on matrix// @param row the row of the Led (0..7)// @param col the column of the Led (0..7)boolget(constRow&row,constCol&col)const;// Get the values on row of LED-matrix// @param row the row of the Led (0..7)buint8_tget(constRow&row)const;// Get the values on colomn of LED-matrix// @param col the column of the Led (0..7)buint8_tget(constCol&col)const;// Get the values on row of LED-matrix// @param row the row of the Led (0..7)buint8_tgetRow(constRow&row)const;// Get the values on colomn of LED-matrix// @param col the column of the Led (0..7)buint8_tgetCol(constCol&col)const;
I think any additional comments are not needed.
The points of the matrix, as well as individual rows and columns may be inverted. To do this, use the following methods:
// Invert all points of matrixvoidinvert();// Invert current point on matrix// @param row the row of the LED (0..7)// @param col the column of the LED (0..7)voidinvert(constRow&row,constCol&col);// Invert row on matrix// @param row the row of the LED (0..7)voidinvert(constRow&row);// Invert colomn on matrix// @param col the column of the LED (0..7)voidinvert(constCol&col);// Invert row on matrix// @param row the row of the LED (0..7)voidinvertRow(constRow&row);// Invert colomn on matrix// @param col the column of the LED (0..7)voidinvertCol(constCol&col);
// Shift matrix// @param value is shifting value// @return shifted valuebuint8_tshiftUp(buint8_tvalue=0);buint8_tshiftDown(buint8_tvalue=0);buint8_tshiftLeft(buint8_tvalue=0);buint8_tshiftRight(buint8_tvalue=0);
These methods shift a matrix in one direction or another.The return value is an extracted row or column.As an argument you can pass the value of the replaced row or column.
A few words about the types ofRow
,Col
andbuint8_t
.
Row
andCol
are declared in the header fileRowCol.h. Both these types can be used as a numeric, but they have additional features.
- The variables of
Row
andCol
is always in the range 0..7. - They serve as an iterator and allow a nice overdrive.
That is, instead of the awkward code:
uint8_tfoo(/*...*/) {/*...*/}for(uint8_trow=0;row<8;++row) {matrix.setRow(row,foo(row));}
you can write concise code:
uint8_tfoo(/*...*/) {/*...*/}for(auto&row:matrix.rows()) {matrix.set(row,foo(row));}
There are two methods to getRow
andCol
// Make rows and colomns iterableRowsIteratorrows()const;ColsIteratorcols()const;
These methods return iterators for the rows and columns, respectively.
The typebuint8_t
is defined in the header fileBitInt.h.Its definition is just a specialization of template classBitInt
:
// Types predefinitionusingbuint8_t=BitInt<uint8_t>;// ...
It behaves as uint8_t, but allows you to easily access their binary representation.
buint8_tx=88;// 01011000x[2]=1;// 01111000x[3]= false;// 01101000boola=x[4];// trueboola=x[7];// false// Iteration:for(autov:x) {Serial.print(v ? "{I}" : "{O}");}
Matrixes may be combined in a cascade.
Wiring scheme like this:
-> VVC -> VVC -> -> GND -> GND -> -> DIN DOUT -> DOUT -> DIN -> CS -> CS -> -> CLK -> CLK ->
As a single matrix, the cascade matrix can be controlled by using software SPI and by hardware SPI.
Like single matrix case, software SPI allows you to use any three free pins, the hardware SPI leaves only one free pin (CS):
// Hardware-SPI wiring scheme:// CLK => SCLK (Arduino UNO/Nano/Mini pin 13)// DIN => MOSI (Arduino UNO/Nano/Mini pin 11)// CS => (Arduino any pin)
but the hardware SPI is noticeably faster.
Software-SPI:
#include<MatrixCascade.h>// pin 11 is connected to the DataIn// pin 13 is connected to the CLK// pin 10 is connected to LOAD (cs)constuint8_tCascadeSize=3;// Software-SPIMatrixCascade<CascadeSize>cascade(11,13,10);
Hardware-SPI:
#include<MatrixCascade.h>// pin 11 is connected to the DataIn// pin 13 is connected to the CLK// pin 10 is connected to LOAD (cs)constuint8_tCascadeSize=3;// HardWare-SPIMatrixCascade<CascadeSize>cascade(10);
Note, The classMatrixCascade
is template. And you need to explicitly specify the size of the cascade (MatrixCascade<3>
) at compile time.
To use cascades of matrixes and groups of cascades include the header fileMatrixCascade.h
The familiar methods, which in this case are the group:
// Set the shutdown (power saving) mode for all devicesvoidshutdown()const;// Set the wakeup mode for all devicesvoidwakeup()const;// Set the brightness of all displays.// @param intensity the brightness of the display. (0..15)voidsetIntensity(uint8_tintensity)const;// Switch all LEDs on all displays to off.voidclear();// Switch all LEDs on all displays to on.voidfill();// Invert all points of all matrixesvoidinvert();// How many times to rotate all matrixes clockwise// @param From 0 to 3voidsetRotation(uint8_ttimes=1);// Reset rotation flag for all matrixes to defaultvoidresetRotation();
The method allowing to know the size of the cascade:
// Returns the number of devices on this MatrixCascadeconstexpruint16_tsize()const;
Access to the matrix by index:
LedMatrix&get(uint16_tindex);
ClassMatrixCascade
has a traits of an array. Contained matrixes can be accessed through the operator[]
:
cascade[0].setRotation(3);cascade[1].setRotation(1);
ClassMatrixCascade
is iterable:
for(auto&matrix:cascade) {matrix.shiftUp();}
Cascades of matrices may, in turn, combined into a super cascades.The difference between a cascade and a supercascade is only in the way of constructing any object. In fact it is the sameMatrixCascade
.
To create a supercascade, you need to use the functioncombineCascades()
.Example:
autocascade=combineCascades(MatrixCascade<5>(10),MatrixCascade<8>(12),MatrixCascade<7>(1,2,3),MatrixCascade<8>(4,5,6),MatrixCascade<8>(7,8,9),MatrixCascade<3>(14),MatrixCascade<6>(15), );
Variablecascade
is the object of typeMatrixCascade<45>
.Accordingly, it will control the 45-th matrices.This makes it possible to lift the restrictions8 matrices per cascade imposed chipsMAX7219 andMAX7221The actual limitation is the number of free pins.
More detailed information is available in thesource code, which I tried to provide comments, and in theexamples.
The library does not implement the means to print a text string on the cascade of matrices. This is intentional.Since the matrix can be mounted in an arbitrary manner.And entering code into the library involving a particular type of installation would be a violation of integrity.Especially to write any superstructure library with the desired functionality is not difficult.All the necessary functions are in the library.
A couple of examples how to make a running line:1,2
Initially, the library was a fork of the libraryLedControl library.I completely reworked the original library. From the original library code has remained just a couple of lines. So it was moved to a separate repository.
Feel free to report bugs and send your suggestions.
About
Flexible and powerful an Arduino library to control LED matrixes on chips MAX7219 and MAX7221