"Running line" - dynamic indication on the example of the LED matrix RL-M2388 and Arduino Mega
This article does not purport to be interpreted as the only possible method for displaying and scrolling information on an LED array. I would love to hear your comments and suggestions for improving the method / functions. This article is a statement of personal experience and a description of the result I achieved.
A bit of theory
This LED matrix has 64 red LEDs. If you display the contacts of each LED separately, you will need 64 contacts on the matrix housing and a microcontroller with 65 digital I / O ports. It is inexpedient and unprofitable. Therefore, at the factory, the LEDs are combined into matrices of various sizes (in our case, 8x8), that is, into 8 groups in rows and columns as follows:
In this case, we only need 16 digital I / Os. For example, in order to light the LED in the upper left corner, we need to send a log 1 to pin13 (see picture) and a log to pin9. This display method is called a static display. ')
“Well, and if we, for example, need to light several LEDs in different positions of the matrix, and leave all the others off?” You ask. With a static display, this is not possible. To do this, use a dynamic display.
Dynamic display
The fast flickering object appears constantly to the human eye. This property of the human eye is inertness. As you guessed, the method of displaying information in the LED matrix is ​​based on this property. For example, in order to display a certain character on the “screen”, you need to sequentially, passing all the “pixels” of the matrix at high speed, turn on the LED in the right place.
The conditions that must be met when programming the dynamic display matrices: 1. The display duration of each column / row (“pixel” in my case) is constant, the same for all columns / rows (“pixel” in my case). 2. The frequency of changing columns / rows (“pixels” in my case) does not change.
The principle of operation of the microcontroller firmware
I admit, when I got a debug board on the Atmega1280 MK and an LED matrix, I had no idea what a dynamic display is and what it is for. I came to the understanding of the need for its use by the method of sampling and the “spear” method.
The principle of the firmware:
1. Display a character on the screen
Let's imagine that our LED matrix is ​​a two-dimensional array of dimension I on J, which coincides with the dimension of our matrix. In our case, this is 8 by 8 pixels. So, there is a two-dimensional array of type boolean. For example:
In the cycle, we check if the element of the array A [i] [j] = 1, then turn on the LED on the matrix in position (I; J), pause the display of the LED and turn off the LED in position (I; J). As a result of the work of the program according to this algorithm, the symbol “A” is displayed on the screen of the matrix (this symbol is displayed in a two-dimensional array). Let's call this algorithm "Display" . So, with the display of information on the screen using a dynamic display sorted out.
2. Scrolling information on the screen
Of course, it’s cool to display still information, but it would be more interesting to “revive” it - to make it move. Consider the algorithm for moving information:
In an infinite loop we execute: 1. Call the algorithm "Display" . 2. Take the 1st column of matrix A and write it to the buffer (two-dimensional array BUFFER [8] [1]). 3. Write the contents of the matrix from the position A [i] [j + 1] to the position A [i] [j]. That is, we essentially “shifted” the matrix to the left by one column. 4. Write to the last column of matrix A (to the free one, since we shifted the matrix to the left by one column) the contents of the buffer BUFFER. Let's call this algorithm "Scrolling Information" .
That's the whole scrolling algorithm for information on the screen. Now, knowing the algorithms for displaying and scrolling information using dynamic display, we can begin to practice.
Matrix connection to the debug board
Each of the 16 matrix pins is numbered. In accordance with these numbers, 8 contacts responsible for the rows and 8 contacts responsible for the columns were soldered and output. For example, my matrix is ​​connected as follows:
The conclusions responsible for lines 23,25,27,29,31,33,35,37 are the pin numbers of the legs of the microcontroller; The conclusions responsible for the columns 39,41,43,45,47,49,51,53 are the pin numbers of the microcontroller legs.
Programming
Programming and flashing the microcontroller is done in the Arduino IDE development environment.
What you need to know to understand the program code written below:
PinMode () function Sets the operation mode of the specified input / output (pin) as an input or as an output. pinMode (pin, mode), where pin: the input / output number (pin) you want to set; mode: mode one of two values ​​- INPUT or OUTPUT, sets to input or output, respectively.
Digitalwrite () function Gives HIGH or LOW value to digital input / output (pin). digitalWrite (pin, value), where pin: input / output number (pin); value: the value is HIGH or LOW
DelayMicroseconds () function Stops program execution for the number of microseconds specified in the parameter (1,000,000 microseconds in 1 second). delayMicroseconds (us), where us: the number of microseconds for which the program is suspended. (unsigned int)
The structure of any program (the sketch, since in the development environment Arduino programs are called that way) has the following form:
voidsetup(){ … } voidloop(){ … }
In the setup () function, the I / O ports of the MK are configured, the settings of the connected devices to the MK, the periphery of the MK, and everything that needs to be done ONCE. In the loop () function, the program body is written, which will be executed cyclically while the microcontroller is on.
Perform the configuration of the outputs of the microcontroller. There are two types of I / O port states: configured for input or output. In our case, you need to configure the output.
constint row[8]={23,25,27,29,31,33,35,37}; constint col[8]={39,41,43,45,47,49,51,53}; int v=3; int dms=400; boolean A[8][8] = {0,0,1,1,1,1,0,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,1,1,1,1,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0, 0,1,0,0,0,0,1,0}; voidsetup(){ for (int i=0; i<8; i++) { pinMode(row[i],OUTPUT); pinMode(col[i],OUTPUT); } for (int i=0; i<8; i++) { digitalWrite(row[i],HIGH); } } voidloop(){ paint(A, v); scroll(A); } voidpaint(boolean screen[8][8], int v){ int i, j; for (int c=0; c <v; c ++) { for (i=0; i<8; i++) for (j=0; j<8; j++) { if (screen[i][j]==1) { digitalWrite(row[i], LOW); digitalWrite(col[j], HIGH); delayMicroseconds(dms); digitalWrite(row[i], HIGH); digitalWrite(col[j], LOW); } else { digitalWrite(row[i], HIGH); digitalWrite(col[j], LOW); delayMicroseconds(dms); digitalWrite(row[i], HIGH); digitalWrite(col[j], LOW); } } } } voidscroll(boolean screen[8][8]){ boolean buf[8][1]; for (int i=0; i<8; i++) { buf[i][0]=screen[i][0]; } for (int i=0; i<8; i++) for (int j=0; j<8; j++) { screen[i][j]=screen[i][j+1]; } for (int i=0; i<8; i++) { screen[i][8-1]=buf[i][0]; } }
That's all. Pour this program into your microcontroller and watch how the letter "A" will "run" to the left. I will add that you should not limit yourself to an array of 8 by 8 elements. For example, I used an 8 by 86 array. I wrote a whole phrase in it, as seen in this video.