Arduino: LED matrix with max7219 driver. How to add additional fonts to landing pages in LPgenerator

January 13, 2017 at 6:15 pm

Russification of the openGLCD library for Arduino

  • Electronics for Beginners

Writing Russian-language text on graphic displays with the ks0108 controller or its analogues still presents significant difficulties. The openGLCD library, which is recommended by the official Arduino websites, in the original configuration of the latter on this moment version does not contain any Cyrillic fonts, except for the font cp437font8x8. In practice, it is of little use because in the Russian-language part it supports Win-1251 encoding. Therefore, in order to display characters in this font, they must either be inserted into the text in octal or hexadecimal codes(and at the same time there remain ambiguities with lowercase letter“I”, as the creator of the font himself indicates in the commentary), or write it anyway separate function recoding, as arduinec did for the Adafruit-GFX library.

Among other things, cp437font8x8 is too large for 128x64 pixel screens. Optimal size The font for auxiliary inscriptions on such a display remains System5x7. Here we will focus on Russification specifically system font, although the reader can use this example to independently Russify any other font (especially if it has a larger screen).

What's the problem?

First, let's delve into the roots of the problem. Arduino environment IDE is a plain text one Windows editor, which works in the universal UTF-8 encoding, like any other in modern versions Windows (Notepad, for example). UTF-8 is a low-cost version of multibyte UNICODE encodings. In UTF-8, English characters, numbers, dots, commas, parentheses and all sorts of other characters are represented by one byte, which matches the standard ASCII encoding. Therefore, their representation in the sketch code does not present any difficulties: a string of English characters after compilation is transferred to the loaded hex file without changes and is understandable to the 8-bit controller, as they say, “without translation.”

In the process of this conversion, each character, as in any program in any programming language, is represented directly in the form of its code, that is, a serial number in the font table, from which the program extracts the graphic style of the corresponding character. In the font file System5x7.h openGLCD library number of characters represented by variable font_Char_Count type uint8_t, that is, cannot exceed the size of one byte. Therefore, Cyrillic characters, which occupy two bytes in UTF-8, cannot be passed to the controller in the usual way.

Previous solution attempts

Note that this was not always the case. Versions of Arduino 1.0.x (and, according to rumors, 1.6.0) truncated the two-byte code to one-byte, simply discarding the high byte (which for Cyrillic, as follows from the UTF-8 table in the link above, is equal to either 0xD0 or 0xD1). Therefore, to refine the font in these versions of the environment, the old GLCD v3 library is suitable, in which the font array was simply supplemented with Cyrillic letter characters so that their positions coincided with the low byte of the UTF-8 encoding (bytes 0x80 to 0xBF). This modernization is described in more detail in the author’s article “Working with text on a graphic display”. I repeat - it requires one of the versions of Arduino IDE 1.0.x in conjunction with the GLCD v3 library, and not their more modern versions.

In new Arduino versions IDEs have become increasingly complex. The library resolutely refuses to understand double-byte character numbers, outputting instead empty place, so simply changing the font will not do. We have to supplement it with a function for converting double-byte characters into single-byte ones.

Solution

The author did not delve into the depths of library functions, but wrote an add-on for openGLCD in the form of a function outstr(), which iterates through all elements of the input string, passing them through the selection operator Switch. It extracts Cyrillic characters from a string and replaces them with single-byte codes corresponding to the modernized font file System5x7R.h.

For example, for the capital Russian letter “F” the replacement string will be like this:

Case "F": GLCD.PutChar(0xA4); break;
Here 0xA4 is the low byte of the encoding of the letter “F” in UTF-8 (see link above). Compiled in accordance with this encoding new file font System5x7R.h. In principle, with this approach, you can use any encoding of Russian characters and any other glyphs that you want to insert into the font. If only their total number does not exceed 128 pieces: from the beginning of the table to the symbol 0x7F (127 is the last symbol standard table ASCII) it is advisable to leave the font intact.

True, a couple of liberties with ASCII table I gave myself permission. The fact is that in the original font System5x7.h the degree icon is placed in last line tables, occupying the character 0x80, which in our case already belongs to the Cyrillic alphabet. In order not to violate the order of constructing the Cyrillic table in accordance with UTF-8, this line is removed from the file. And the degree icon is attached instead ASCII character“~” (number 0x7E), which was not used for its intended purpose in the font anyway. But this replacement allows you to enter the degree icon in the text of the sketch directly from the keyboard in the form of the “~” symbol.

Another liberties are connected with the fact that the author cannot stand the crossed out zero - the archaism of the times of the ATsPU and monochrome text displays. That’s why the zero in the modernized font has been replaced by the glyph of the letter “O”. Those who adhere to puristic principles can simply delete the font in the file System5x7R.h this insertion (the old glyph of the crossed zero there is left commented out, its code is 0x30).

In the modernized library openGLCD, which you can download from the link at the end of the article, another correction has been made - the order of connecting the pins for displays with the ks0108 controller has been changed. Why the author of the library chose this order (see the table at the link on the official Arduino website) is unknown. In the modernized version, the display connection (the popular MT-12864J was chosen as an example) is carried out according to the following diagram:

Connection diagram MT-12864J


Variable resistor R1 is connected here according to the manufacturer's recommendations, and resistor R2 serves to limit the backlight current if it is not connected to a voltage of 5 V, but directly to an input power source (Arduino Vin pin) with a higher voltage.

An example of displaying the Russian alphabet mixed with Latin on the MT-12864J display, as well as numbers and a degree icon, is shown in the photo:


Sketch text for this example:

The text of the sketch with the output of the Russian alphabet

#include //include the library #include //file with function for outputting Russian letters #include //file with Russian letter codes void setup() ( GLCD.Init(); //initialization GLCD.ClearScreen(); ) void loop() ( GLCD.SelectFont(System5x7R); //select the font GLCD.CursorTo(0, 0); //set the cursor to the initial position //output mixed English-Russian lines: outstr("ABC AVGDEZHZIKLMNOP\n"); outstr("PRQ RSTUFHTSCHSHSHYYYYAY\n"); ("xyz rtstufhchshshshshyey\n"); GLCD.println("1234567890"); GLCD.CursorTo(19,4); //set the cursor to the penultimate position of the 5th line GLCD.print("~C"); degree C GLCD.println("@;/.,|<>()=-_()\"""); GLCD.CursorTo(4,7); //set the cursor to position 4 of line 8 GLCD.print("MT-12864J"); )


Since files with the function outstr.h and font System5x7R.h placed in root directory modernized library, then they should be placed individual links at the beginning of the sketch using the directive #include. For English-language inscriptions it is still convenient to use standard features println/print, but if you need a line feed in Russian text, you must explicitly specify the “\n” character.

You can download the corrected version of the library

The LED Matrix is ​​a graphical indicator that can be used to display simple images, letters and numbers. We got acquainted with the structure of matrix indicators in detail at. Then it became clear that grouping several matrices together is not an easy task. For each new row or column of matrices you need to add a new shift register along with wires and resistors, and also a ULN2003 microcircuit.

Fortunately, engineers have long developed specialized microcircuits for controlling various kinds of indicators. In this tutorial we will look at the matrix module with the MAX7219 chip. As will become clear later, working with such a module is a pleasure.

1. LED matrix module with MAX7219 chip

The module is a board with a microcircuit, the necessary wiring for it and, in fact, a matrix indicator. Usually the indicator is not soldered into the board, but inserted into the connector. This is done so that a group of modules can first be secured to some surface with screws, and then the matrices can be inserted into them.

And this is what the module looks like with the matrix.

The module has five pins on each side. On one side, data enters the module, on the other hand, data exits the module and is transferred to the next one. This allows you to connect matrices in a chain.

Input connector:

  • VCC, GND - power supply;
  • DIN - data input;
  • CLK - sync pulse.

Output connector:

  • VCC, GND - power supply;
  • DOUT - data output;
  • CS - module selection (chip select);
  • CLK - sync pulse.

The module operates on a voltage of 5 Volts.

Connection

We connect the matrix module to the Arduino Uno controller according to the following scheme:

8x8 LED Matrix with MAX7219 VCC GND CIN C.S. CLK
Arduino Uno +5V GND 11 9 13

Schematic diagram

Layout appearance

2. Outputting pixels using the Max72xxPanel library

To control the MAX7219 chip we will use the library Max72xxPanel. You can download it from the links at the end of the lesson.

Let's install the library and write small program, which will display only one point with coordinates x=3 and y=4. The dot will blink with a period of 600 milliseconds.

#include #include #include int pinCS = 9; int numberOfHorizontalDisplays = 1; // number of matrices horizontally int numberOfVerticalDisplays = 1; // number of matrices vertically Max72xxPanel matrix = Max72xxPanel(pinCS, numberOfHorizontalDisplays, numberOfVerticalDisplays); void setup() ( matrix.setIntensity(4); // brightness from 0 to 15 ) void loop() ( matrix.drawPixel(3, 4, HIGH); // light the pixel with coordinates (3,4) matrix.write (); // output all pixels to the matrix delay(300); matrix.drawPixel(3, 4, LOW); // blank the pixel matrix.write();

As mentioned earlier, matrix modules with the MAX7219 chip can be easily combined. It is for this purpose that at the beginning of the program we set the number of matrices horizontally and vertically. In this case, one matrix is ​​used, so both of these parameters will be equal to 1.

It is important to note that after turning pixels on and off using the function drawPixel, you need to call the function write. Without the write function, the pixels will not be displayed on the matrix!

Now let's write a program that will display a smiley from the past on the matrix. We will encrypt the smile using an array of eight bytes. Each byte of the array will be responsible for a row of the matrix, and each bit in the byte will be responsible for a point in the row.

#include #include #include int pinCS = 9; int numberOfHorizontalDisplays = 1; // number of matrices horizontally int numberOfVerticalDisplays = 1; // number of matrices vertically Max72xxPanel matrix = Max72xxPanel(pinCS, numberOfHorizontalDisplays, numberOfVerticalDisplays); const byte data = ( 0b00111100, 0b01000010, 0b10100101, 0b10000001, 0b10100101, 0b10011001, 0b01000010, 0b00111100 ); void setup() ( matrix.setIntensity(7); // brightness from 0 to 15 matrix.fillScreen(LOW); // clearing the matrix for (int y = 0; y< 8; y++) { for (int x = 0; x < 8; x++) { // зажигаем x-й пиксель в y-й строке matrix.drawPixel(x, y, data[y] & (1<

Note. The Max72xxPanel library has a setRotation function, which sets the orientation of the image on the matrix. For example, if we want to rotate a smiley by 90 degrees, we will need to call setRotation with the appropriate arguments immediately after calling the setIntensity function:

matrix.setRotation(0, 1);

the first parameter is the matrix index, in our case it is equal to zero; the second parameter is the number of 90 degree turns.

3. Outputting text using the Adafruit-GFX-Library library

In the same way, you can display any other symbol, for example, a letter, on the matrix. But in order to be able to display any letter of the English alphabet, we will need to define as many as 26 eight-byte arrays in the program! This is very tedious, and of course someone has already done this before us.

In addition to functions for working with graphics and text, the popular Adafruit-GFX-Library also contains a database of Latin letters in upper and lower case, as well as all punctuation marks and other service symbols. The link to the library is at the end of the lesson.

You can display a symbol on a matrix using the function drawChar.

drawChar(x, y, character, color, background, size);

The first two parameters of the function are responsible for the coordinates of the upper left corner of the symbol. The third parameter is the symbol itself. The color of the symbol in our case will be equal to 1 or HIGH, since the matrix is ​​two-color. Background is 0 or LOW. Let's set the last parameter “size” to 1.

Let's write a program that will one by one display on the matrix all the letters of the phrase: “HELLO WORLD!”

#include #include #include int pinCS = 9; int numberOfHorizontalDisplays = 1; int numberOfVerticalDisplays = 1; Max72xxPanel matrix = Max72xxPanel(pinCS, numberOfHorizontalDisplays, numberOfVerticalDisplays); String tape = "HELLO WORLD!"; int wait = 20; void setup() ( matrix.setIntensity(7); // brightness from 0 to 15 ) void loop() ( for (int i = 0 ; i< tape.length(); i++) { matrix.fillScreen(LOW); matrix.drawChar(0, 0, tape[i], HIGH, LOW, 1); matrix.write(); } delay(wait); }

Note. The Adafruit_GFX library has many functions for working with graphics. For example, drawCircle(3, 3, 2, HIGH) will draw a circle with center (3,3) and radius 2. The last parameter is color, but in the case of a monochrome matrix it is 1 or HIGH. The drawLine(0, 0, 3, 6, HIGH) function will draw a line between points (0,0) and (3,6).

3. Program. Creeping line on max7219

To display several letters at once, we will need to connect several LED matrices in a chain. As mentioned earlier, this is done very simply. The diagram for connecting six modules will look like this.

Schematic diagram

Layout appearance

Program

We will create a running line by shifting the coordinates of the letters. To display the letter in the required coordinates, we use the same drawChar function.

#include #include #include int pinCS = 9; int numberOfHorizontalDisplays = 6; // now we have 6 matrices horizontally int numberOfVerticalDisplays = 1; // and vertically, as before, there is one Max72xxPanel matrix = Max72xxPanel(pinCS, numberOfHorizontalDisplays, numberOfVerticalDisplays); String tape = "site"; // text that will float int wait = 20; // time between extreme movements of letters int spacer = 1; // distance between letters int width = 5 + spacer; // font size void setup() ( matrix.setIntensity(7); // brightness ) void loop() ( for (int i = 0 ; i< width * tape.length() + matrix.width() - 1 - spacer; i++) { matrix.fillScreen(LOW); int letter = i / width; int x = (matrix.width() - 1) - i % width; int y = (matrix.height() - 8) / 2; // center the text vertically while (x + width - spacer >= 0 && letter >= 0) ( if (letter< tape.length()) { matrix.drawChar(x, y, tape, HIGH, LOW, 1); } letter--; x -= width; } matrix.write(); delay(wait); } }

Load the program onto the Arduino Uno and watch the ticker!

Tasks

  1. Digital Watch. Assemble a circuit of four LED matrices and a real-time clock module. Write a program for Arduino that will display hours and minutes on the display from matrices.
  2. Snake game. Assemble a display with a resolution of 16x16 pixels from four LED matrices. Implement such a famous game as “snake” (or “python”) on Arduino. It is necessary to add four buttons to the circuit to control the direction of movement, as well as a buzzer to signal the event of eating apples.

Conclusion

By connecting together matrix modules on the max7219, you can assemble fairly large displays and use them in Arduino projects where output of bright images is required. LED displays, unlike liquid crystal displays, are resistant to low temperatures. For example, a ticker made from matrices can be placed outside even in 30-degree frost.

In addition to single-color matrix modules based on max7219, there are other similar devices. For example, three-color LED displays with a resolution of 32x16 and even 64x32 pixels. We will talk about such modules in the following lessons and articles.

useful links

1. Library Max72xxPanel:

2. Library Adafruit-GFX-Library.

Finally, the matrix modules have arrived from the Middle Kingdom. Each module consists of a MAX7219 () microcircuit, an LED matrix, and there is one capacitor and one resistor in the harness.


Controlled by MAX7219 via SPI interface.


The chips in the cluster are connected in series. I read on the Internet that the maximum possible serial connection allows only 8 MAX7219 pieces. Don't believe it. I connected 16 modules and everything works great.

The modules presented on Ali come in several versions. The most popular are 2 types: with a chip in DIP and in SOIC packages. The module with a DIP chip is larger and not so convenient when connected to a cluster. There will be a bunch of wires to connect.


Modules with a chip in a SOIC package are the size of an LED matrix and are connected by soldering or jumpers. It turns out beautiful and neat.


The most well-known libraries for working with matrices and clusters are MAX72xx Panel by Mark Rice And Parola by MajicDesigns: The first library is easier to use, the second is more complex with more capabilities. I'll describe it in more detail.

MAX72xx Panel

When using MAX72xx Panel, the library must be installed Adafruit GFX.

To Russify the text you will need to download THIS FILE and replace standard file glcdfont.c in the Arduino/Libraries/Adafruit-GFX-Library-master directory. Also in this file, in addition to the necessary letters and numbers, a bunch of all sorts of symbols are described. Not all of them can be useful. The picture below explains how the symbols are formed.

If necessary, you can create your own symbols and replace with them any unused ones in the file. Almost all dot fonts used in various libraries are formed in a similar way.

So, the MAX72xx Panel and Adafruit GFX libraries are installed, the glcdfont.c file is replaced. Launch Arduino IDE, open FILE. The sketch contains the utf8rus function. It provides character table conversion for the Russian language. It is needed only for normal output from the program, that is, in the program required text written in Russian. If text is entered via the COM port, then the character codes are corrected in the Serial_Read function. The developers used different encodings in the IDE and in the console.

At the beginning of the file there are lines necessary for the library to work.

int numberOfHorizontalDisplays = 1;

int numberOfVerticalDisplays = 16;

I have modules with a microcircuit in a SOIC package. They have a small peculiarity. The matrix of the modules is installed rotated 90 degrees. This is a fee for the convenience of connection. If you run the sketches that come with the libraries, they will output text from bottom to top in each module. The text will appear in zigzags. To cure this problem, the library needs to be “told” that there are 16 vertical displays (physically they are located horizontally). And then in void Setup specify the line to the library

matrix.setRotation(matrix.getRotation() + 1);

It will reverse each matrix programmatically. And everything will be displayed normally.

Modules with DIP chip packages do not have this. Everything is beautiful there, except for a bunch of wires.

The MAX72xx Panel library is quite modest. Visual effects there is no conclusion. The cluster is perceived as one whole. Things are much better with MD Parola.

Parola by MajicDesigns.

Owners of modules with a chip in a SOIC package will also face the problem of orienting the modules in the cluster. It just looks a little different than in the MAX72xx. Here the modules will seem to be out of order.


HelloWorld sketch from samples included with library.

I was unable to cure this disease programmatically in the sketch. I treated him differently. In the file Adruino/libraries/MD_MAX72xx_lib.h at the end you need to find the lines like in the picture.


And correct the highlighted 1 to 0 in the selected line. Save the file. The Arduino IDE does not need to be rebooted. Let's fill it up and take a look.


Now you can use 24 animation effects. The animation is started with the command P.displayText("Text to display", "text alignment", speed, display delay, appearance effect, disappearance effect). As you can see, there are quite a lot of settings.

And the best part is dividing the cluster into virtual zones. Working with zones is not very difficult. I’m not posting the sketch, it’s in the samples that come with the library. Now you can display a clock at the beginning of the cluster and a news ticker on the remaining modules without any problems, almost.

As you may already guess, the problem is with in Cyrillic letters. It is also solvable. Near previous file in the same directory there is a file MD_MAX72xx_font.cpp. This is a font file. The characters in it are formed similarly to the GFX library font file. There is a slight difference. Here the symbol size can be less than 5 points. In the Adafruit GFX library Exclamation point, for example, is also 5 dots wide, like any other symbol, only one row of dots is used. The rest do not light up, but are used as a symbol. In Parola, the same exclamation mark also occupies one row of dots, but not next to it. empty dots, or there may be adjacent symbols. It will be clearer from the picture.


Add file Cyrillic characters similar to the file from the first library considered, there is no time yet. If someone does this and sends me a file, I will add it to this article, and both I and the guests of my site will be grateful to you.

Bottom line. The MAX72xx Panel library from Mark Rice is easy to use and understand, but has poor functionality.

The Parola library from MajicDesigns is more complex and its capabilities are sufficient for almost any application.

Hello, Dear users LPgenerator!

Please note: in order to connect the font in a standard way, use a ready-made tool. It's easy to use and allows you to add additional fonts without any extra effort:

In this post, you will learn how to add an additional font to your landing page using Google service Fonts through adding scripts.

2. Be sure to indicate the alphabet, that is, a set of characters.

If the landing page is in Russian, then select Latin ( Latin) and Cyrillic ( Cyrillic):

3. Select the font(s) you like and click " +":

4. Go to the collection of added fonts. To do this, click on the black bar below:

5. In the window that opens, the first item displays the previously selected fonts.

Remember: use large quantity various fonts Google Fonts may slow down your landing page loading time. The impact of the selected styles on page loading speed is displayed on the right.

6. If the set and appearance you are satisfied with the added fonts, go to the "EMBED" section and completely copy the contents of the "STANDART" field:

Don't close Google tab Fonts, we will need it later.

Open the desired landing page in LPgenerator editor and click tool "Scripts":

  • in the window that opens, click "Add new script";
  • write down the name of the script;
  • select the script position "Inside the HEAD tag";
  • paste the copied code;
  • don't forget to save your changes.

7. Return to the Google Fonts tab.

Copy the CSS code that is generated to use the loaded fonts.

Each font uses its own CSS.

For example, for the Lobster font the code looks like this: font-family: "Lobster", cursive;

8. Return to the LPgenerator editor and click on the element (text or button) to which you want to apply the downloaded font.

There are features of applying styles for different elements of the landing page.

CTA elements

To change the font style on a button, just click on it and in the advanced properties on the right, add CSS for the font (copied in step eight).

Landing page text blocks

In order to apply an external font to a text block for which you have already changed the font, it is not enough to simply specify the style in its advanced properties. You must also reset the current formatting. To do this, select the text and click the “Remove Formatting” button in the text editing block.

Please note: this will reset any changes you have made to size, font style, alignment, etc.

You can then specify size, alignment, and other attributes again.

If this is the first time you've created a text block on a landing page and you haven't changed its font, you can simply click on the text and add CSS for the font in the element's advanced properties.

9. Save the changes and admire the result.

Please note: in the LPgenerator editor the font will remain the same, additional fonts are displayed only in the preview and when visiting a published landing page.