Hardware and software setup

Max7219 and a couple of wires. Ticker

Everyone has long been accustomed to the fact that everyone electronic device there is a screen through which it gives a person any useful information. The MP3 player shows the name of the track being played, the quadcopter remote displays flight telemetry, even washing machine displays the time until the end of the wash, and the smartphone generally hosts a whole desktop of a personal computer! Most likely, your next device will also need some small display 🙂 Let's try to make a simple electronic clock! And as a scoreboard we use a common and cheap character liquid crystal display 1602. Just like in the picture: In addition to 16x2, a 20x4 character display (four lines of 20 characters each) is considered quite popular, as well as a graphic display with a resolution of 128x64 pixels. Here they are in pictures:

1. Connecting the character LCD display 1602

The 1602 display has 16 pins. Usually they are numbered from left to right, if you look at it as in the picture. Sometimes the conclusions are signed, such as: DB0, DB1, EN, etc. And sometimes they just indicate the output number. In any case, the list of pins is always the same: 1 - "GND", ground (power minus); 2 - "Vcc", +5V supply; 3 - "VEE", contrast; 4 - "RS", register selection; 5 - "R / W", data transfer direction (write / read); 6 - "EN", synchronization; 7-14 - "DB0", "DB1", .., "DB7" - data bus; 15 - backlight anode ( +5V); 16 - backlight cathode (ground). Lines VEE, RS and four data lines DB4, DB5, DB6, DB7 are connected to the digital outputs of the controller. We will connect the “R / W” line to the “ground” of the controller (since we only need the function of writing to the display memory). We will not connect the backlight for now, I believe you can easily figure it out yourself 🙂 Schematic diagram of connecting the display to Arduino Uno
Layout appearance
Just in case, also in the form of a plate:
LCD display 1602 1 2 4 6 11 12 13 14 15 16
Arduino Uno GND +5V 4 5 6 7 8 9 +5V GND

2. Program "Hello, world!"

To work with LCD displays of various sizes and types, the Arduino IDE editor has a special library liquid crystal. To include the library, we write the following expression as the first line of our program: #include Next, we need to specify which Arduino pins we used to connect the display. We will specify this information when initializing the module: LiquidCrystal lcd(4, 5, 6, 7, 8, 9); Here, the first two arguments are the RS and EN pins, and the remaining four are the DB4-DB7 data bus lines. Next, specify the display size using the "begin" command: lcd.begin(16, 2); As a reminder, our display has two lines of 16 characters each. Finally, we need a simple "print" function to print text. The output of this well-known phrase will look like this: lcd.print("Hello, world!"); The complete program will look like this: #include LiquidCrystal lcd(4, 5, 6, 7, 8, 9); void setup()( lcd.begin(16, 2); lcd.print("Hello, world!"); ) void loop()( ) Load it on the Arduino Uno and see what's happening on the display. There can be three main situations 🙂 1) The display will show “Hello, world!”. So you connected everything correctly, and the contrast somehow miraculously turned out to be initially correctly configured. We rejoice and move on to the next chapter. 2) The display will show whole line black rectangles - contrast adjustment required! That is why we added a potentiometer with a knob to the circuit. We twist it from one edge to the other, until a clear inscription appears on the display. 3) Two rows of black rectangles. Most likely, you messed up something when connecting. Triple check all wires. If you do not find an error - ask the cat to check!

3. Program the watch

Now that the display is working accurately, let's try to turn our simple device into a real electronic clock. Attention! To display the time, we need the "Time" library. If it is not installed yet, then you can download the archive from the link. Let's include it: #include Then we set the current date and time using the "setTime" function: setTime(23, 59, 59, 12, 31, 2015); Everything is clear here: hours, minutes, seconds, month, day, year. To display the date, we use a bunch of functions:
  • year() - will return the year to us;
  • month() - month;
  • day() - day;
  • hour() - hour;
  • minute() - returns the minute;
  • second() - second.
Now let's pay attention to this fact. If we count the number of characters in a typical date record: “12/31/2015 11:59:59 PM”, we get 19. And we have only 16! It does not fit, however, in one line. One more problem can be solved useful feature- "setCursor". This function sets the cursor to the desired position. For example: lcd.setCursor(0,1); Sets the cursor to the beginning of the second line. The cursor is the location of the character from which text output will begin with the next "print" command. Let's use this function to display the date on the first line and the time on the second. With the output of the date and time, everything is now clear. Remained routine things. For example, after each filling of the display, we will clean it with the "clear()" function: lcd.clear(); And it also makes no sense for us to display data more than once a second, so let's pause 1000 milliseconds between two iterations. So, putting everything together, we get the following program: #include #include LiquidCrystal lcd(4, 5, 6, 7, 8, 9); void setup()( lcd.begin(16, 2); setTime(7,0,0,1,10,2015); // 7am, January 10th, 2015 ) void loop()( lcd.clear(); lcd.print(day()); lcd.print("."); lcd.print(month()); lcd.print("."); lcd.print(year()); lcd.setCursor(0 , 1); lcd.print(hour()); lcd.print(":"); lcd.print(minute()); lcd.print(":"); lcd.print(second()); delay (1000); ) Upload the sketch to the Arduino Uno and watch the clock move! 🙂 In order to consolidate the knowledge gained, I recommend pumping our clock to a full-fledged alarm clock. All you need to do is add a couple of buttons and a buzzer 🙂

Hello Guys. Today we will cut down the running line on the LED modules MAX7219 and Arduino. The task is very simple and does not require us to have great knowledge in the field of electronics and programming. To begin with, I propose to study a little theory on the device of the LED matrix, the principle of its connection and watch the video of the result, which we will strive for throughout the article.

The LED Matrix is ​​a graphical indicator that can be used to display simple images, letters and numbers. I do not set the task to deal in detail with the device of matrix indicators, however, it is worth noting that, in fact, the matrix consists of 8x8 LEDs. In fact, everything comes down to dynamic indication. Based on this, it is 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 in a good way also the ULN2003 chip.

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

LED Matrix Module with MAX7219 Chip

The module is a board with a microcircuit, the strapping necessary 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 fixed to some surface with screws, and then the matrices can be inserted into them.

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

Input connector / Output connector:

  • VCC, GND - power;
  • DIN - data input;
  • CS - module selection (chip select);
  • CLK - clock pulse.

The module operates on a voltage of 5 volts.

Pixel output 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 article.

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

#include #include #include int pinCS = 10; int numberOfHorizontalDisplays = 1; // number of matrices horizontally int numberOfVerticalDisplays = 1; // vertical number of matrices Max72xxPanel matrix = Max72xxPanel(pinCS, numberOfHorizontalDisplays, numberOfVerticalDisplays); void setup() ( matrix.setIntensity(4); // brightness from 0 to 15 ) void loop() ( matrix.drawPixel(3, 4, HIGH); // light up the pixel at (3,4) matrix.write (); // draw all pixels to the matrix delay(300); matrix. drawPixel(3, 4, LOW); // blank out the pixel matrix. write(); delay(300); )

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 drawPixel, you need to call the function write. Without the write function, the pixels will not light up on the matrix!

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

#include #include #include int pinCS = 10; int numberOfHorizontalDisplays = 1; // number of matrices horizontally int numberOfVerticalDisplays = 1; // vertical number of matrices 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 function setRotation, which specifies the orientation of the image on the matrix. For example, if we want to rotate the smiley by 90 degrees, we will need to immediately after calling the function setIntensity call setRotation with appropriate arguments:

matrix.setRotation(0, 1);

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

Text output with Adafruit-GFX-Library

In a similar 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 dreary, and of course someone has already done this before us.

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

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. The background is 0 or LOW. Let's make the last parameter "size" equal to 1.

Let's write a program that will display in turn all the letters of the phrase: "HELLO WORLD!"

#include #include #include int pinCS = 10; int numberOfHorizontalDisplays = 1; int numberOfVerticalDisplays = 1; Max72xxPanel matrix = Max72xxPanel(pinCS, numberOfHorizontalDisplays, numberOfVerticalDisplays); String tape = "HELLO WORLD"; int wait = 800; void setup() ( matrix.setIntensity(1); // 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 the 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 the points (0,0) and (3,6).

Running line on max7219

And so I hope we figured out the device and the principle of output to a single matrix. Now let's go directly to the running line.

What will be required?

To implement the idea, you need very few details:

  • two LED modules, consisting of four matrices of 8 by 8 pixels;
  • connecting wires;
  • Arduino Nano board;

Scheme

On the printed circuit board of the LED module used, there are 4 matrices 8 by 8 pixels in size. Each LED board is controlled by a MAX7219 chip.

The MAX7219 is a controller for up to 64 LED displays, common cathode arrays, and discrete LEDs. For a more comfortable perception of information displayed on the LED display, it is recommended to install several modules. To do this, they are combined into series-connected groups, that is, the output of the first module (out) is connected to the input of the second module (in). My assembly consists of two modules (16 matrices), the length of which is quite enough for convenient reading of entire sentences. In this case, the assembly is connected to the Arduino in the same way as to a single module.

Running line programming.

The running line from Arduino and LED modules under control of MAX7219 is almost ready. It is time to move on to the final program part.

#include #include #include int pinCS = 10; // Connect CS to pin 10, DIN to MOSI and CLK to SCK int numberOfHorizontalDisplays = 1; // Number of modules horizontally int numberOfVerticalDisplays = 8; // Number of modules vertically Max72xxPanel matrix = Max72xxPanel(pinCS, numberOfHorizontalDisplays, numberOfVerticalDisplays); String tape = ""; int wait = 10; // Scroll speed in milliseconds int spacer = 1; // Gap between characters (number of dots) int width = 5 + spacer; // Character width /* Convert Russian font from UTF-8 to Windows-1251 */ String utf8rus(String source) ( int i,k; String target; unsigned char n; char m = ( "0", "\0" ); k = source.length(); i = 0; while (i< k) { n = source[i]; i++; if (n >= 0xC0) ( switch (n) ( case 0xD0: ( n = source[i]; i++; if (n == 0x81) ( n = 0xA8; break; ) if (n >= 0x90 && n<= 0xBF) n = n + 0x2F; break; } case 0xD1: { n = source[i]; i++; if (n == 0x91) { n = 0xB7; break; } if (n >= 0x80 && n<= 0x8F) n = n + 0x6F; break; } } } m = n; target = target + String(m); } return target; } /* Код для работы с com-портом */ String Serial_Read() { unsigned char c; // переменная для чтения сериал порта String Serial_string = ""; // Формируемая из символов строка while (Serial.available() >0) ( // If there are characters in the serial port c = Serial.read(); // Read the character //Serial.print(c,HEX); Serial.print(" "); Serial.print(c); if (c == "\n") ( // If this is the end of the string return Serial_string; // Return the string ) if (c == 0xB8) c = c - 0x01; // Correction of character codes for the table???? since Russian characters in the table are shifted relative to the standard utf encoding by 1 character if (c >= 0xBF && c<= 0xFF) c = c - 0x01; Serial_string = Serial_string + String(char(c)); //Добавить символ в строку } return Serial_string; } void setup() { Serial.begin(9600); tape = utf8rus("сайт Amateur Radio WorkShop"); // Этот текст выводиться при включении или если в com-порт не пришла информация matrix.setIntensity(3); // Яркость от 0 до 15 matrix.setRotation(matrix.getRotation()+3); //1 - 90 2 - 180 3 - 270 } void loop() { if (Serial.available()){ tape=Serial_Read(); } 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; // Центрируем текст по вертикали 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); } }

I don't see the point in writing code. He is well commented. However, there are some features worth mentioning.

Note. Important. The Adafruit_GFX standard library initially supports only English fonts, so the guys from Russia did their best and rewrote the library by adding Russian fonts and all sorts of goodies. All libraries and sketch are available on my GitHUB page.

A piece of code for working with the com-port is needed in order to quickly change the text of the message displayed on the LED module. However, we need it not only for this. In the future, through this function, we will connect ours and the running line on the Arduino.

To work with character graphic displays, we suggest using the LiquidCrystal library, which is included in the standard set of Arduino IDE and is designed to work on an 8-bit (4-bit) parallel interface. If your display is connected to the Arduino via the I2 bus, then you need to install the LiquidCrystal_I2C library (most of the functions of which repeat the functions of the first library).

Supported displays:

Display Connection and initialization
LCD1602 - character display (16x02 characters),


#include
[ , 8 , 9 , 10 , 11 ]);
void setup()( lcd.begin(16 , 2);}

// Explanation:

void setup()( OBJECT.begin(NUM_COLUMNS, NUM_ROWS); )


LiquidCrystal OBJECT(RS, E, D0, D1, D2, D3, D4, D5, D6, D7);


with I2C interface (blue)

#include
#include
LiquidCrystal_I2C lcd(0x27 or 0x3F, 16 , 2);
void setup()( lcd.init(); }

// Explanation:



LCD1602 I2C - character display (16x02 characters),
with I2C interface (green)

#include
#include
LiquidCrystal_I2C lcd(0x27 or 0x3F, 16 , 2);
void setup()( lcd.init(); }

// Explanation:
LiquidCrystal_I2C OBJECT(ADDRESS_I2C , NUM_COLUMNS, NUM_ROWS);
// ADDRESS_I2C can be either 0x27 or 0x3F

LCD2004 - character display (20x04 characters),
with parallel interface (blue)

#include
LiquidCrystal lcd(2 , 3 , 4 , 5 , 6 , 7[ , 8 , 9 , 10 , 11 ]);
void setup()( lcd.begin(20 , 4);}

// Explanation:
LiquidCrystal OBJECT(RS, E, D4, D5, D6, D7);
void setup()( OBJECT.begin(NUM_COLUMNS, NUM_ROWS); )

// If 8 data bus wires are used, then specify all of them
LiquidCrystal OBJECT(RS, E, D0, D1, D2, D3, D4, D5, D6, D7);

LCD2004 I2C - character display (20x04 characters),
with I2C interface (blue)
#include
#include
LiquidCrystal_I2C lcd(0x27 or 0x3F, 20 , 4);
void setup()( lcd.init(); }

// Explanation:
LiquidCrystal_I2C OBJECT(ADDRESS_I2C , NUM_COLUMNS, NUM_ROWS);
// ADDRESS_I2C can be either 0x27 or 0x3F

#1 Example

We display the inscription on the LCD1602 display connected via the I2C bus. To work with the LCD2004 display, you need to change line 3 to LiquidCrystal_I2C lcd(0x27,20,4);

#include // We connect the library for working with the LCD display via the I2C bus LiquidCrystal_I2C lcd(0x27,16,2); // Declare a library object, specifying the display parameters (I2C address = 0x27, number of columns = 16, number of rows = 2) // If the inscription does not appear, replace the address 0x27 with 0x3F void setup()( // lcd.init(); // Initiate work with the LCD display lcd.backlight(); // Turn on the backlight of the LCD display lcd.setCursor(0, 0); // Set the cursor to position (column 0, row 0) lcd.print("LCD"); // Print the text "LCD" starting at the current cursor position lcd.setCursor(0, 1); // Set the cursor to position (column 0, row 1) lcd.print("www.iarduino.ru"); // We display the text "www.iarduino.ru", starting from the set cursor position ) // // void loop()() // The code inside the loop function is constantly executed. But since we are displaying static text, it is enough for us to display it 1 time at startup, without using the loop code

#2 Example

We display the inscription on the LCD1602 display connected via a 4-bit parallel bus. To work with the LCD2004 display, you need to change line 5 to lcd.begin(20, 4);

#include // We connect the LiquidCrystal library to work with the LiquidCrystal LCD display lcd(2,3,4,5,6,7); // Declare a library object, specifying display pins (RS,E,D4,D5,D6,D7) // If 8 data bus wires are used, then specify (RS,E,D0,D1,D2,D3,D4,D5, D6,D7) void setup()( // lcd.begin(16, 2); // Initiate work with the LCD display, specifying the number (columns, rows) lcd.setCursor(0, 0); // Set the cursor to the position (0 column, 0 row) lcd.print("LCD2004"); // Print the text "LDC1602" starting at the current cursor position lcd.setCursor(0, 1); // Set the cursor to position (0 column, 1 row ) lcd.print("www.iarduino.ru"); // Print the text "www.iarduino.ru" starting from the set cursor position ) // // void loop()() // The code inside the loop function is constantly executed . But since we are displaying static text, it is enough for us to display it 1 time at startup, without using the loop code

#3 Example

We display the inscription "Russian language" on the LCD1602 display connected via the I2C bus:

#include // Connect the library to work with the I2C bus #include // We connect the library for working with the LCD display via the I2C bus LiquidCrystal_I2C lcd(0x27,16,2); // Declare a library object, specifying the display parameters (I2C address = 0x27, number of columns = 16, number of rows = 2) // uint8_t symbol = ( // Declare an array of 6 own symbols (k and y i z s), each symbol consists of 8 bytes ( 0, 0,18,20,24,20,18, 0 ), // to ( 0, 0,17,19,21,25,17, 0 ), // and (10, 4 ,17,19,21,25,17, 0 ), // th ( 0, 0.15,17,15, 5, 9, 0 ), // i ( 0, 0.14,17, 6.17 ,14, 0 ), // z( 0, 0.17,17,29,19,29, 0 )); // s // void setup()( // lcd.init(); // Initiate work with the LCD display lcd.backlight(); // Turn on the LCD backlight lcd.createChar(1, symbol); // Load 1 character "k" into display RAM lcd.createChar(2, symbol); // Load character 2 "and" into display RAM lcd.createChar(3, symbol); // Load character 3 "th" into display RAM lcd.createChar (4, symbol); // Load character 4 into display RAM lcd.createChar(5, symbol); // Load character 5 into display RAM lcd.createChar(6, symbol); // Load 6 character "s" in display RAM lcd.setCursor(0, 0); // Set cursor to position (column 0, row 0) lcd.print("Pycc\1\2\3 \4\5\6\1" ); // Output the text "Pyccky language", where "Pycc" is written in Latin, and "kycc" is written in characters from the display RAM ) // If you need to print a character from the display RAM, then write \ and the character number // void loop( )() // The code inside the loop function is constantly being executed. But since we are displaying static text, it is enough for us to display it 1 time at startup, without using the loop code

#4 Example

We display the time elapsed after the start on the LCD1602 display connected via the I2C bus:

#include // Connect the library to work with the I2C bus #include // We connect the library for working with the LCD display via the I2C bus LiquidCrystal_I2C lcd(0x27,16,2); // Declare a library object, specifying the display parameters (I2C address = 0x27, number of columns = 16, number of rows = 2) // uint8_t tim_D, tim_H, tim_M, tim_S; // Declare variables to store days, hours, minutes, and seconds. uint32_ttim; // We declare a variable to store the total amount of time elapsed since the start. // If the inscription does not appear, replace the address 0x27 with 0x3F void setup()( // lcd.init(); // Initiate work with the LCD display lcd.backlight(); // Turn on the LCD backlight ) // // void loop()( // // Get the time elapsed since the start: // tim = millis() / 1000; // Get the total number of seconds (max 4"294"967 sec ≈ 49.7 days). tim_S = tim % 60 ; // Get seconds: remainder of all seconds divided by minute (60 sec) tim = (tim-tim_S) / 60; // Get total minutes tim_M = tim % 60; // Get minutes: remainder of all minutes per hour (60 min) tim = (tim-tim_M) / 60; // Get the total number of hours tim_H = tim % 24; // Get the hours: remainder of all hours divided by the day (24 hours) tim_D = (tim-tim_H) / 24; // Get the total number of days. // Print the time elapsed since the start: // if (millis()%1000<100){ // Условие выполняется в течении 100 первых миллисекунд каждой новой секунды. delay(100); lcd.setCursor(0, 0); // Устанавливаем курсор в позицию (0 столбец, 0 строка). lcd.print("Days: "); // Выводим текст. if(tim_D<10){lcd.print(0);} // Выводим 0 перед количеством дней. lcd.print(tim_D); // Выводим количество дней. lcd.setCursor(0, 1); // Устанавливаем курсор в позицию (0 столбец, 1 строка) lcd.print("Time: "); // Выводим текст. if(tim_H<10){lcd.print(0);} // Выводим 0 перед количеством часов. lcd.print(tim_H); // Выводим количество часов. lcd.print(":"); // Выводим символ. if(tim_M<10){lcd.print(0);} // Выводим 0 перед количеством минут. lcd.print(tim_M); // Выводим количество минут. lcd.print(":"); // Выводим символ. if(tim_S<10){lcd.print(0);} // Выводим 0 перед количеством секунд. lcd.print(tim_S); // Выводим количество секунд. } // } //

Functions common to LiquidCrystal and LiquidCrystal_I2C libraries:

  • begin( cols, rows, ); – Display initialization with the number of columns, rows and character size.
  • clear();– Clearing the display with the cursor set to 0,0 (Takes a lot of time!).
  • home();– Set cursor to 0,0 (Takes a lot of time!).
  • display();– Quick turn on of the display (without changing data in RAM).
  • noDisplay();– Quick turn off of the display (without changing the data in the RAM).
  • blink();– Activation of the blinking cursor (with a frequency of approx. 1 Hz).
  • noBlink();– Switch off the blinking cursor.
  • cursor();– Enable cursor underlining.
  • noCursor();– Turn off cursor underlining.
  • scrollDisplayLeft();– Scroll display to the left. Shift display coordinates one column to the left (without changing RAM).
  • scrollDisplayRight();– Scroll display to the right. Shift display coordinates one column to the right (without changing RAM).
  • leftToRight();– Specifies to further shift the position of the cursor, after the output of the next character, one column to the right.
  • rightToLeft();– Indicates to further shift the position of the cursor, after the output of the next character, one column to the left.
  • noAutoscroll();– Indicates that the text is further aligned to the left of the cursor position (as usual).
  • autoscroll();– Indicates that the text will be further aligned to the right of the cursor position.
  • createChar( num,array ); – Write a custom character to the display's CGRAM under the specified number.
  • setCursor( col,row ); – Set the cursor to the position indicated by the column and line number.
  • print( text ); – Display text, symbols or numbers on the display screen. The syntax is similar to the function of the same name in the Serial class.

Functions implemented only in the LiquidCrystal_I2C library:

  • init();– Display initialization. Must be the first command of the LiquidCrystal_I2C library after object creation. In fact, this function is also in the LiquidCrystal library, but in that library it is called automatically (by default) when an object is created.
  • backlight();– Turn on the backlight of the display.
  • noBacklight();– Turn off the backlight of the display.
  • setBacklight( flag ); – Backlight control (true - enable / false - disable), used instead of the noBacklight and backlight functions.

Connection:

// For the I2C bus:
#include
#include
LiquidCrystal_I2C lcd( address , col , row );
void setup()(
lcd.init();
}

Parameter:
  • address: Display address on the I2C bus - 0x27 or 0x3F
  • col:
  • row:
// For a 4-wire parallel bus:
#include
liquid crystal lcd( RS , E , D4 , D5 , D6 , D7 );
void setup()(
lcd.begin( col , row );
}
Parameter:
  • RS:# of the Arduino pin to which the RS pin is connected
  • E: Arduino pin number to which pin E is connected
  • D0...D3: Number of Arduino pins to which pins D0-D3 are connected
  • D4...D7: Number of Arduino pins to which pins D4-D7 are connected
  • col: number of columns implemented in the display
  • row: the number of lines implemented in the display
// For an 8-wire parallel bus:
#include
liquid crystal lcd( RS , E , D0 , D1 , D2 , D3 , D4 , D5 , D6 , D7 );
void setup()(
lcd.begin( col , row );
}
begin( col , row , );
Display initialization with screen sizes and characters.
Parameter:
  • col: number of columns implemented in the display
  • row: the number of lines implemented in the display
  • size: character size, specified by a constant:
    LCD_5x8DOTS (default), or LCD_5x10DOTS
/* For I2C bus: */ #include // Connect the library to work with the I2C bus #include // We connect the library for working with the LCD display via the I2C bus LiquidCrystal_I2C lcd(0x3F,20,4); // Declare the library object, specifying the display parameters (I2C address = 0x3F, number of columns = 20, number of rows = 4) // void setup()( // lcd.init(); // Initiate work with the LCD display lcd.backlight (); // Turn on the backlight of the LCD display... // Display information that should be displayed at startup ) // // void loop()() // ... // Display information that should change according to the algorithm of your code ) // /* For 4-wire parallel bus: */ #include // We connect the LiquidCrystal library to work with the LiquidCrystal LCD display lcd(2,3,4,5,6,7); // Declare a library object, specifying display pins (RS,E,D4,D5,D6,D7) // If 8 data bus wires are used, then specify (RS,E,D0,D1,D2,D3,D4,D5, D6,D7) void setup()( // lcd.begin(16, 2); // Initiate work with the LCD display, specifying the number of (columns, rows) ... // Output information that should be displayed at startup ) / / // void loop()() // ... // Output information that should change according to the algorithm of your code ) //

Display control functions:

display();
Turns on the display after it has been turned off by the noDisplay function.
Note: The function is executed quickly and without changes to the display RAM.
noDisplay();
Turns off the display.
The data on the display will not be displayed until the display function is called, but it will not be erased from the RAM memory, and after the display function is called, it will be displayed again.
Note: The function is executed quickly and without changes to the display RAM.
scrollDisplayLeft();
Shifts the display coordinates one column to the left.



scrollDisplayRight();
Shifts the display coordinates one column to the right.
The constant call of this function will create the effect of a running line.
The coordinates are shifted both for the information on the display and for the one that will be displayed after.
Note: The function is executed without changing the display RAM.
If you call the function 40 times in a row, the coordinate will return to the original point
clear();
Clearing the display with the cursor set to 0,0.
The information on the display will be permanently erased.
Note: Takes a long time.
backlight();
Turn on the backlight of the display.
noBacklight();
Turn off the display backlight.
Note: The function is implemented only in the LiquidCrystal_I2C library.
setBacklight( flag );
Backlight control (instead of noBacklight and backlight functions).
Parameter:
  • flag: true - turns on, and false - turns off the backlight.
Note: The function is implemented only in the LiquidCrystal_I2C library.
/* Display a label to monitor the display control functions: */ lcd.cursor(0,0); // Set the cursor to the uppermost corner of the display (column 0, row 0) lcd.print("iarduino.ru"); // Display the text "iarduino.ru" (the first letter "i" will be at position "0,0", and the last "u" at position "10,0", invisible cursor at position "11,0") // lcd.noDisplay(); // Turn off the display (the inscription will disappear from the display) lcd.display(); // Turn on the display (the label will appear on the display in the same place) lcd.scrollDisplayLeft(); // Shift the column coordinates to the left (the display will show "arduino.ru" without the first letter "i", which will go beyond the display, but remain in its RAM) lcd.scrollDisplayRight(); // Shift the column coordinates to the right (the display will show "iarduino.ru" in the same place where it was originally displayed) lcd.clear(); // Clear the display (the inscription will permanently disappear from the display) lcd. noBacklight(); // Turn off display backlight lcd.backlight(); // Turn on the backlight of the display lcd. setBacklight(0); // Turn off the backlight of the display lcd. setBacklight(1); // Turn on the backlight of the display

Cursor control functions:

setCursor( col , row );
Sets the cursor to the specified position.
Parameter:
  • col: column number (starting from 0).
  • row: line number (starting from 0)
home();
Set cursor to position 0,0. Works like setCursor(0,0);
Note: Takes a long time.
blink();
Turn on the blinking cursor.
Note: The cursor occupies the entire character field and flashes at a frequency of about 1 Hz, in the position where it was previously set.
noBlink();
Turn off the blinking cursor.
Note: The cursor becomes invisible, but its position is preserved.
cursor();
Enable cursor underlining.
Note: The cursor changes to an underscore character and is positioned where it was previously set.
noCursor();
Turn off cursor underlining.
Note: The cursor becomes invisible, but its position is preserved.
lcd.setCursor(0, 1); // Set the cursor to the first character of the second line (row and column numbering starts from 0) lcd.home(); // Set the cursor to the first character of the first line (as when calling lcd.setCursor(0,0);) lcd.blink(); // Make the cursor visible (a rectangle will blink at the cursor location) lcd.noBlink(); // Make the cursor invisible (remove the blinking rectangle) lcd.cursor(); // Make the cursor visible (an underscore will appear in place of the cursor) lcd.noCursor(); // Make the cursor invisible (remove the underscore) // If the cursor lands on a place where there is a character, then this character does not disappear

Direction and alignment functions:

leftToRight();
Specifies that after each new character, the cursor position should move one column to the right.
Note: If the text "abc" is displayed, the display will show "abc" and the text will be to the right of the initial cursor position.
(Normally)
rightToLeft();
Specifies that after each new character, the cursor position should move one column to the left.
Note: If the text "abc" is displayed, the display will show "cba" and the text will be to the left of the initial cursor position.
(Writing from right to left)
noAutoscroll();
Specifies that in the future, the text should be left-aligned from the initial cursor position.
Note: if you set the cursor to position 10.0 and display the text, then the first character of the displayed text will be in this position.
(Normally)
autoscroll();
Specifies that in the future, the text should be right-aligned from the initial cursor position.
Note: if you set the cursor to position 10.0 and display the text, then the cursor will be located at this position.
(The display coordinates will be shifted to the left, as if you called the scrollDisplayLeft function as many times as there are letters in the displayed text)
lcd.leftToRight(); // Tell the cursor to move to the right (As usual in European writing) lcd.clear(); lcd.setCursor(5,0); lcd.print("ABC"); // On the display we will see: " ABC " (After "A" the cursor moved to the right and "B" was displayed, then the cursor moved to the right and "C" was displayed) lcd.rightToLeft(); // Tell the cursor to move to the left (Like writing from right to left) lcd.clear(); lcd.setCursor(5,0); lcd.print("ABC"); // On the display we will see: "CBA" (After "A" the cursor moved to the left and "B" was displayed, then the cursor moved to the left and "C" was displayed) lcd.noAutoscroll(); // Set Left Alignment (As Usual) lcd.clear(); lcd.setCursor(5,0); lcd.print("ABC"); // The display will show: "ABC" (as usual) lcd.autoscroll(); // Set alignment to right (Display coordinates will be shifted to the left by the number of characters displayed) lcd.clear(); lcd.setCursor(5,0); lcd.print("ABC"); // On the display we will see: " ABC " (The display coordinates will be shifted 3 characters to the left, since after each character the scrollDisplayLeft function is called)

Text and character input functions:

createChar(num,array);
Write a custom character to the display's CGRAM at the specified number.
If you want to print the text (using the print function) which should contain the character you set, specify the slash and the number under which this character was written: print("C\1MBO\2").
Parameter:
  • number: the number under which the symbol will be written.
  • array: an array representing the character being written.
Note: The array consists of several bytes, the number of which is equal to the number of strings in the character. Each set bit of the byte corresponds to a set (displayed) character pixel.
print(text);
Display text, symbols or numbers on the display screen.
Parameter:
  • text: character, number, or string to display.
Note: The syntax is similar to the function of the same name in the Serial class.
#include // Connect the library to work with the I2C bus #include // We connect the library for working with the LCD display via the I2C bus LiquidCrystal_I2C lcd(0x27,16,2); // Declare a library object, specifying the display parameters (I2C address = 0x27, number of columns = 16, number of rows = 2) // uint8_t symbol_d = (0b00000, // 1 line of symbol "d" 0b00000, // 2 line of symbol "d" " 0b00110, // 3 character string "e" 0b01010, // 4 character string "e" 0b01010, // 5 character string "e" 0b01010, // 6 character string "e" 0b11111, // 7 character string "e" "0b10001); // 8 symbol string "d" The whole array can be written in one line: uint8_t symbol_d=(0,0,6,10,10,10,31,17); // uint8_t symbol_i = (0b00000, // 1st string of the "and" symbol 0b00000, // 2nd string of the "and" symbol 0b10001, // 3rd string of the "and" symbol 0b10011, // 4th string of the "and" symbol 0b10101, // 5 "and" character string 0b11001, // 6 "and" character string 0b10001, // 7 "and" character string 0b00000); // 8th symbol string "and" The whole array can be written in one line: uint8_t symbol_i=(0,0,17,19,21,25,17,0); void setup()( // lcd.init(); // Initiate work with the LCD display lcd.backlight(); // Turn on the LCD backlight lcd.createChar(1,symbol_d); // Load the first lcd character into the display memory .createChar(2,symbol_i); // Load the second symbol into the display memory lcd. clear(); // Clear the screen lcd. setCursor(0,0); // Set the cursor to the uppermost corner lcd. print("Pa\ 1\2o"); // Display the text "Radio", while the characters "P", "a" , "o" are written in Latin, ) // and the characters "e", "and" are displayed from the display memory, indicating their numbers // void loop()( // lcd.setCursor(0,1); lcd.print(" "); // erase the entire bottom line lcd.setCursor(0,1); lcd.print("i"); lcd.print("arduino"); lcd.print(".ru"); // print the text "i" "arduino" ".ru" in the bottom line delay(2000); // wait 2 seconds lcd.setCursor( 0,1); lcd.print(" "); // erase the entire bottom line lcd.setCursor(0,1); lcd.print(12.345); // print the number 12.34 (prints 2 decimal places) delay(2000 ); // wait 2 seconds lcd.setCursor(0,1); lcd.pri nt(""); // erase the entire bottom line lcd.setCursor(0,1); lcd.print(12, HEX); // output 12 as hexadecimal delay(2000); // wait 2 seconds lcd.setCursor(0,1); lcd print(" "); // erase the entire bottom line lcd.setCursor(0,1); lcd print(1); // output the number 1 delay(2000); // wait 2 seconds)

Running line in LCD on HD44780.

The search for a "ready-made solution" for the running line in C did not give any result. So I had to do it myself.

This "piece" of code allows you to display a ticker (from right to left), anywhere and using any number of character spaces, in LCD indicators with an HD44780 controller or similar.

The first thing to note is that the C language does not allow you to work with strings "directly". That is, it is not possible to copy a character from one string to another using the assignment operator ( = ) ... for this you need to use a special function strncpy(). Generally speaking, several functions are used to work with strings in C. In Self-Tormentors, a separate chapter is devoted to the use of these functions. In Help "e on CV_AVR, the description of functions for working with strings is in the section "String Functions". The prototypes of these functions are in the file string.h.

"...initial string..." - string characters from which you want to display in the "running" line;

"...displayed characters..." - actually "creeping line".

The following algorithm was chosen to organize the running line:

1. Displayed characters are shifted from right to left. The extreme left is "lost".

2. After the shift, the next character from the source string is copied into the rightmost character.

3. When the end of the source string is reached, the first character of the source string becomes next.

For character shift - for the cell being shifted, the character code is read from the HD44780 on-screen RAM (DDRAM) and written to the left-hand RAM cell.

According to the DataSheet on the HD44780, the left character of the top row has a DDRAM address of 0x00 and the left character of the bottom row is 0x40. It must be remembered that in order to refer specifically to the screen RAM (and not to the character generator RAM), it is necessary that the RS bit be equal to 1 (RS is the high bit in the address byte, see DataSheet).

As a result, we get that in order to "refer" to the second character from the left of the top line, you need to "work" with the address 0x01 | 0x80 = 0x81.

The functions of writing and reading the "internal content" of the HD44780 are in the library (prototypes in lcd.h).... therefore.. the actual program:

/* for CV_AVR

In this example, the running line is displayed in bits 8 (0xC7) through 16 of the bottom line of a 16-bit indicator.

. ......

#include

unsigned char n_sim=1,m_end=43; //43 - line length in the example
...........

beg_string()(
unsigned char i;

// ticker shift

if(beg_str)(
for(i=0;i<9;i++)lcd_write_byte(0xC7+i,lcd_read_byte(0xC8+i));
beg_str=0;

// write the next character to the rightmost position

lcd_gotoxy(15,1);
lcd_putchar(ish_str);
if(++n_sim>m_end)n_sim=1;
}
}

Glossary:

n_sim - pointer to the position of the current character in the source string;

m_end - total number of characters in the source string;

beg_str- shift enable bit. With it, you can adjust the speed of "running";

ish_str - source string.

Most likely, each of the existing C compilers has library functions for working with the HD44780. Therefore, it will not be difficult to "remake" the program for "your" compiler.

I "cook" the source string using the well-known utility "HD44780.exe". When using it, the comments indicate the length of the line: "/* Maximum length of a line: 43 byte */"

Liked the article? Share with friends!
Was this article helpful?
Yes
Not
Thanks for your feedback!
Something went wrong and your vote was not counted.
Thanks. Your message has been sent
Did you find an error in the text?
Select it, click Ctrl+Enter and we'll fix it!