Skip to content

An Arduino display driver for Max7219-controlled LED panels

License

Notifications You must be signed in to change notification settings

mbrethes/vidmax7219

Repository files navigation

A display driver for 4x(8x8) Max7219 controlled monochrome LED panels

License & Disclaimer

This program is (C) 2018-2022 Mathieu Brèthes.

This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with this program. If not, see https://www.gnu.org/licenses/.

The included font to display text has been adapted from HomeTown 3 by Aaron D. Chand.

What it does

This library allows a sketch to control a row of 4 8x8 led panels, for a total of 256 leds. The LED panels are controlled by Max7219 controllers, chained together and connected to the following Arduino Ports:

  • DIN : digital port 10;
  • CS : digital port 9;
  • CLK : digital port 8;

It offers functions to display arbitrarily-sized images with 4 shades of red (with some flicker) at any location of the panel (including negative coordinates), to set or get the intensity of a pixel on the panel.

The images are generated from GIF or palettized PNG files using the Python helper tool gif2c.

It also has a function to display text with an included font, and a function to automatically rotate this text to the left forever.

It was tested on Arduino Mini and Arduino Pro (with ATMega328 microcontrollers).

Requirements and limitations

  • It uses MsTimer2, so you can't use that on your sketch.
  • At this point you can't remove the font to save space, and you can't change the ports
  • You can only have one instance of the class running.
  • There is a bug if you try to display text at a negative coordinate.

Documentation

Setup

To use this library you need to download the ZIP from github (click on the green "code" button and choose "download zip" and import it in your Arduino IDE following Arduino's instructions.

Then include the library in your sketch by adding the following line at the top of it, outside of any functions:

#include <vidmax7219.h>

To set the library up, create an instance of the VidMax7219 class outside of any function (the best way is to add this line just below the #include):

VidMax7219 video;

You are now ready to use the video driver. There is no need to add anything in the setup() part of your sketchn, although you may want to change the display's brightness before doing anything else with vidSetPower() (see below).

Functions

VidMax7219();

The constructor does the initialization. It is called when you write VidMax7219 video; . It returns an instance of the VidMax7219 class.

Note that you can only have one instance of the class in your sketch.

The display's intensity is by default initialized to 0x0A08 (from a range of 0x0A00... 0x0A0F). See vidSetPower() below for a detailed explanation.

void vidOn();

Turns the display on.

void vidOff();

Turns the display off.

void vidSetPower(unsigned int intensity, bool pausetimer=TRUE);

You want to call this function to set the maximum intensity of your led panels. You can use it to generate a dimming effect, for example.

This may require trial and error as drawing too much power may crash your Arduino when all leds are lit. Careful!

  • intensity goes from a range of 0x0A00 to 0x0A0F. For an explanation of intensity, see the Max7219 specification. In a nutshell, 0x0A00 is 1/16th of maximum intensity, and 0x0A0F is 100% maximum intensity. The relationship between intensity and power used by the LED panels is not linear, and you may need to scale your power source accordingly.
  • pausetimer is TRUE by default, and you can safely leave it that way.

void vidClear();

Clears the drawing buffer. Always call this before drawing your images, otherwise they will be drawn above whatever was displayed!

void vidDrawImage(int pos_x, int pos_y, byte img_w, byte img_h, const byte* img_a, const byte* img_b, const byte* img_c, const byte* img_d);

This draws one of the frames generated by gif2c.py on the drawing buffer. The image is drawn

  • pos_x : the x coordinate of leftmost corner, may be outside of the drawing zone (0-31)
  • pos_y : the y coordinate of topmost corner, may be outside of the drawing zone (0-7)
  • img_w : the width of the frame (should be 1 < 128)
  • img_h : the height of the frame (should be 1 < 128)
  • img_a : a reference to the subframe a generated by gif2c
  • img_b : a reference to the subframe b
  • img_c : a reference to the subframe c
  • img_d : a reference to the subframe d

Your typical call for an image named myImage generated by gif2c should look like this:

vidDrawImage(x, y, myImage_x, myImage_y, myImage_names_a[s], myImage_names_b[s], myImage_names_c[s], myImage_names_d[s]);

Where x and y are the coordinates where you want to draw the image and s is the frame number in your animation sequence (from 0 to up to 127 frames, or just 0 if you generated a single frame).

void vidPrintText(char* text, int posX, int posY);

Draws a text on the drawing buffer. The text may contain letters A-Z, numbers 0-9, special characters !?-/ and space.

You can't change the font.

There is a bug if you try drawing on coordinates < 0.

void vidSwitchBuffers();

Once you are finished drawing and writing text, call this function to display your drawing on the LED panels. The drawing buffer then becomes the display buffer, and vice versa.

void vidPrintRotateInit(char *text);

This function and the next one create a text banner with an arbitrary string of text scrolling to the left, beginning at position 32,0 (off the right side of the screen). It will loop once the last sign fully disappears on the left side of the display.

This function sets up a new text banner, replacing any previous text that was scrolling, and resets the position of the text.

void vidPrintRotate();

This function clears the drawing buffer, redraws the text previously setup with vidPrintRotateInit() by scrolling it left 1 pixel, and switches between the draw and display buffers.

It also includes a delay of 20 milliseconds.

Call this function repeatedly to achieve the banner effect (see this example ).

byte vidGetPixel(int x, int y, byte img_w, byte img_h, const byte* img_a, const byte* img_b, const byte* img_c, const byte* img_d);

This helper function returns a value of a single pixel by combining the bits of the four buffers given as input, into a single byte.

The intensity (from 0=off to 4=100%) can be computed by adding the 4 lowmost bits of the returned byte, like so:

tmp = vidGetPixel(...);
value = (tmp>>4)&1+(tmp>>3)&1+(tmp>>2)&1+tmp&1;
  • x : the x coordinate of the pixel
  • y : the y coordinate of the pixel
  • img_w : the width of the buffer. If you wish to read from the drawing or display buffer, that would be 32. You can also point to frame data.
  • img_h : the height of the buffer. That would be 8 for the display or drawing buffers.
  • img_a...d : references to buffers or image data arrays as generated by gif2c.

void vidPutPixel(int pos_x, int pos_y, byte pixel);

This helper function allows to set a single pixel's value in the drawing buffer.

Note that drawing stuff this way is much slower than drawing full images using vidDrawImage().

  • pos_x : the x position of the pixel (between 0 and 31)
  • pos_y : the y position of the pixel (between 0 and 7)
  • pixel : a byte defining the intensity. Use 0x0F for 100%, 0x0E for 75%, 0x05 for 50%, 0x01 for 25%, and 0x00 for 0%.

TODO

  • more examples
  • allow to change ports
  • allow to remove font, or change font
  • allow for other panel configurations (less or more than 4 panels, square organization, etc.)
  • (help me!) testing with ATMega168 and others

About

An Arduino display driver for Max7219-controlled LED panels

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages