The mini display from the first article was more suitable for smaller devices. This article is intended to show how a large-scale display can be implemented with Python knowledge. In this case, the means of choice are LED matrix elements, each with 8 x 8 = 64 individual LEDs. By stringing together several units, displays of almost unlimited size can be set up. These are suitable, for example, as a "live ticker" for stock market prices or as displays for scores on the home sports field. With just a few Python instructions, large-scale time or temperature displays can be created, which can be used very effectively in advertising on many occasions.
Dot matrix displays
Dot matrix displays allow the display of numbers and letters as well as any symbols and simple graphics. This makes them superior to the classic seven-segment displays, which only allow the digits 0 to 9 to be displayed. In addition, seven-segment displays are limited to the sizes that have been determined once, while dot matrices can be scaled as desired. In addition, significantly greater brightness levels can be achieved compared to OLED displays. With LED matrices, display areas several meters long and wide can be achieved. This display variant is therefore often used for large-scale display or advertising boards in busy squares, train stations or airports, in public buses and trains and so on. In the stock exchange rooms of the world, they show the current stock prices as so-called “live tickers”. Incidentally, dot matrices are particularly popular in Asia, as they can also be used to display Far Eastern characters without any problems, as shown in Figure 1.
Control
LED matrices with 5 x 7 = 35 LEDs are widely used. But a wide variety of other designs are also available. Elements with 8 x 8 LEDs can often be found. Directly driving 8 x 8 points would require 65 lines since 64 anode terminals and a common cathode would have to be connected. With a matrix you can get by with far fewer connections. Here 8 LEDs are interconnected in a column and a row. Only 8 + 8 = 16 connections are required. Figure 2 shows the principle for a 3 x 4 matrix. Instead of 13 connections for individual control of the LEDs, only 7 connections are required here.
For example, to activate the 2nd LED in the 2nd row in a matrix, all but the second row connections must be set to HIGH. The second connection, on the other hand, must have GND potential. In the case of the columns, high potential may only be present in the second column. The direct control of point matrices ties up a large part of the controller's resources. If sensor values are also to be recorded or actuators are to be controlled, even a powerful ESP32 controller quickly reaches its limits. The control of larger displays with hundreds or more LEDs would also quickly become a problem, on the one hand because of the required computing power and on the other hand because of the limited number of pins available on a controller. In addition, the relatively low execution speed of Python code would also have a negative effect here. It is therefore advisable to use inexpensive display drivers such as the MAX7219. These components have an SPI-compatible interface and can therefore drive displays with up to 8 x 8 = 64 matrix elements with just three digital pins. The SPI interface (Serial Peripheral Interface) has become widespread and is used particularly frequently in entertainment electronics. The bus system and in particular its use under MicroPython are described in detail in an Elektor book by the author. The drivers are available together with the actual matrix element as complete modules. Picture 3 shows an example.
Connecting the driver components to the ESP32 is very simple. Only the three SPI pins have to be connected to the controller board:
MAX7219_data (DIN) port D02
MAX7219_load (CS) port D05
MAX7219_clock (CLK) port D04
MAX7219_GND ESP32 GND
Due to the relatively high power consumption, it is advisable to provide the power supply externally. It should be noted that the supply voltage of the modules should be around 3.3 V to 4 V to ensure compatibility with the ESP32. In this way, the modules still receive the minimum permissible supply voltage according to the data sheet. On the other hand, an overload of the controller inputs is avoided. Alternatively, a bidirectional 3.3/5 V level converter can also be used. Sufficient blocking capacitors must also be provided. Low-impedance VCC and ground lines are also essential. If these instructions are taken into account, displays of almost any size can be set up. There is hardly any load on the controller since only individual commands have to be sent via the SPI bus. In addition, enough pins remain free to operate external sensors or other peripherals. Nothing stands in the way of realizing large-scale displays for advertising purposes or at sporting events. Figure 4 shows the complete circuit diagram for setting up a 6-digit matrix display with an ESP32 controller module.
Success with the right library
A link for a suitable Python library for controlling the Maxim ICs can be found in the download package. After the driver file Max7219.py has been loaded onto the controller, the following instructions are available:
spi = SPI(1, baudrate=10000000, polarity=1, phase=0, sck=Pin(CLK), mosi=Pin(DIN))
ss = Pin(CS, Pin.OUT)
For the pinout given above:
CLK = 4
DIN = 2
CS = 5
to set. Then a display object can be created:
display = max7219.Matrix8x8(spi, ss, MN)
where MN is the number of matrix elements used. You can then use the commands in Listing 1 to design text and graphics. This allows you to create effective ads that can be read well from a distance of several meters.
LED matrix in action
The following code shows an application example for a display with six 8x8 matrix elements:
# LED_matrix_test.py
import max7219
from machine import Pin, SPI
spi = SPI(1, baud rate=10000000, polarity=1, phase=0, sck=pin(4), mosi=pin(2))
ss = Pin(5, Pin.OUT)
display = max7219.Matrix8x8(spi, ss, 6)
display.text('Python',0,0,1)
display.show()
After the program has been loaded onto the ESP controller, the text is shown on the display (Figure 5).
The display can easily be expanded with additional matrix modules. Figure 6 shows an array with 12 elements. However, not only static displays and texts can be displayed. Moving graphics can also be easily implemented in Python. The next section shows a corresponding example.
Marquee and stock ticker
The scroll function can be used to create tickers and the like. This means that longer texts can also be output on small or short displays. The program in Listing 2 scrolls the lettering "Python" from right to left across a dot matrix display.
The individual letters are over
display.text('...',40,0,1)
created on the right edge of the display. Then they are shifted to the left by the value pixelDistance using the moveLeft function:
for i in range(8):
display.scroll(-1,0)
sleep(speedFactor)
The running speed can be changed via the speedFactor value. The display can be seen live in action in a YouTube video.
Large format temperature display
Many pharmacies, banks or retailers try to attract the attention of potential customers by advertising with large-scale temperature or time displays. Such displays are also always an eye-catcher at sporting events, trade fairs, exhibitions or for FabLabs. In order to implement a temperature display, for example, you only have to add an appropriate sensor to the structure presented above. A particularly suitable variant is the DS18x20 from Maxim Integrated (formerly Dallas). With the appropriate Python library, the sensor can be read out without any problems. These sensors communicate via the one-wire bus and thus only occupy a single I/O pin of the ESP32. A ready-to-use Python library is also available for this sensor series. In addition to the sensor itself, only a 4.7 kΩ pull-up resistor is required. When using the ESP32 internal pull-up even this can be omitted. The sensor has the following performance characteristics:
Supply voltage: 3.0 V to 5.5 V
Temperature range: - 55°C to +125°C
Measurement accuracy: ±0.5°C (-10°C to +85°C)
Resolution: 9-bit, corresponding to approx. 1/10 °C
Measurement period duration: 750 ms (max.)
Not only a single sensor per pin can be evaluated via One-Wire-Bus. Thanks to the special protocol of the one-wire bus system, almost any number of temperature sensors can be queried in parallel via a single controller pin. In the following, however, only a single sensor is to be used.
Picture 7 shows the connection of the DS18x20 to the ESP32.
An evaluation program for the DS18x20 displays the recorded temperature values on the console:
# DS18x20_TempSens_demo.py
from machine import pin
import onewire
import ds18x20
import time
ow = onewire.OneWire(Pin(25)) # init one wire bus
ow.scan()
ds=ds18x20.DS18X20(ow) # create ds18x20 object while True: units=ds.scan() # scan for ds18x20 units ds.convert_temp() # convert temperature for unit in units: print(ds.read_temp(unit )) #display time.sleep(1) print()
The modules for reading the sensor are again available by default in the MicroPython firmware.
The program can be expanded to include the LED matrix display in just a few lines, see Listing 3.
Picture 8 shows the result. Further details on the connection of various sensors for light intensity, humidity or magnetic fields, among other things, can be found in the book.
Animated graphics
In addition to letters and numerical data, graphics and even animations can also be presented on the LED matrix. The program in Listing 4 conjures up any pixel graphic on the display.
The graphic is created using the bitmap icon. Points that should light up later are to be marked with a "1". Dark dots get a "0":
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 0, 0, 1, 1, 0],
[0, 1, 1, 0, 0, 1, 1, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 0, 1, 0],
[0, 0, 1, 1, 1, 1, 0, 0],
In this way, any icon can be created. The enumerate function converts the bitmap into a displayable graphic:
for y, row in enumerate(icon):
for x, c in enumerate(row):
display.pixels(x, y, c)
This results in figure 9 on the LED matrix. With the scroll function in the main loop, the image generated in this way can then be moved across the display unit (see also the YouTube video).
Summary and outlook
After the elementary commands were presented in the first article of the series [1], they could now be used in various practical applications in the second part. Powerful libraries make it possible to implement impressive projects with just a few lines of code. This confirms the remarkable performance of MicroPython for controller applications as well. Further information and many practical projects can be found in the book "MicroPython for microcontrollers". Among other things, the control of servos, wireless data transmission via RFID, the MQTT protocol and the transmission of sensor values to the Internet are discussed in detail there. The combination of Python with the rapidly growing field of machine learning and artificial intelligence is also discussed applications that were previously unthinkable will be possible in the near future. Together with Python-based image processing algorithms, the developer has a wide range of future-oriented options open to him. 210179-B-02
Any questions or comments?
Do you have technical questions or comments about this article? Write to us at redaktion@elektor.de!