If you have multiple identical panels, you can extend a single display across them, vertically, horizontally, or both.
Inspect the rear of your panel. There are two 10-pin connectors. You can "chain" multiple displays by using a ribbon cable to hook the "OUT" of one panel to the "IN" of the next panel.
Many of Adafruit's panels include a ribbon cable; check the description.
Next, you'll need to power all your panels. Each panel has a 4-pin power connector, and most of Adafruit's panels include a Y-splitter power cable which can be connected to 2 panels. The power supply current requirement increases according to the number of panels, but the voltage requirement is always 5V. Remember that we recommend a 5V 4A supply for a single 64x32 pixel panel, so our recommendation becomes 4×2=8A for 2 panels and 4×4=16A for 4 panels. By using dimmer colors and avoiding big solid areas on the display, you may be able to get by with a smaller power supply.
More displays also means more memory (RAM) usage. Using bit_depth=6
, approximate RAM usage is as follows:
- one 64×32 panel uses 17kB
- two 64×32 panels use 33kB
- four 64×32 panels use 65kB
Using bit_depth=3
, approximate RAM usage is as follows:
- one 64×32 panel uses 11kB
- two 64×32 panels use 21kB
- four 64×32 panels use 42kB
Using bit_depth=1
, approximate RAM usage is as follows:
- one 64×32 panel uses 7kB
- two 64×32 panels use 13kB
- four 64×32 panels use 25kB
The total number of panels is limited by RAM usage, CPU usage and refresh rate. Other arrangements than those shown, such as 1×3, 3×1, 2x3, 3x2, etc., are possible.
This script for MatrixPortal will be used to demonstrate the different chaining and tiling options:
import displayio import board import rgbmatrix import framebufferio bit_depth = 1 base_width = 64 base_height = 32 chain_across = 1 tile_down = 1 serpentine = True width = base_width * chain_across height = base_height * tile_down addr_pins = [board.MTX_ADDRA, board.MTX_ADDRB, board.MTX_ADDRC, board.MTX_ADDRD] rgb_pins = [ board.MTX_R1, board.MTX_G1, board.MTX_B1, board.MTX_R2, board.MTX_G2, board.MTX_B2, ] clock_pin = board.MTX_CLK latch_pin = board.MTX_LAT oe_pin = board.MTX_OE displayio.release_displays() matrix = rgbmatrix.RGBMatrix( width=width, height=height, bit_depth=bit_depth, rgb_pins=rgb_pins, addr_pins=addr_pins, clock_pin=clock_pin, latch_pin=latch_pin, output_enable_pin=oe_pin, tile=tile_down, serpentine=serpentine, ) display = framebufferio.FramebufferDisplay(matrix)
We'll focus on the effect of these 3 settings:
chain_across
tile_down
serpentine
Note how chain_across
is used to calculate the width
from the base_width
and similarly that tile_down
is used to calculate the height
from the base_height
.
The total number of displays is chain_across * tile_down
.
-
chain_across
= 2 -
tile_down
= 1 -
serpentine
doesn't matter
Uses two panels, total display size is 128x32
-
chain_across
= 4 -
tile_down
= 1 -
serpentine
doesn't matter
Uses four panels, total display size is 256x32
Purely vertical arrangements
The value called "serpentine" controls whether every alternate row of panels is rotated 180 degrees. This is generally more convenient, due to the positions of the connectors. The approximate path of the ribbon cables are shown with the arrows.
-
chain_across
= 1 -
tile_down
= 4 -
serpentine
=True
Uses four panels, total display size is 64x128. Notice how displays 2 and 4 are rotated 180 degrees to minimize the length of ribbon cables required.
-
chain_across
= 1 -
tile_down
= 4 -
serpentine
=False
Uses four panels, total display size is 64x128. Note how the ribbon cables are longer than with serpentine
=True
. This is usually less convenient.
-
chain_across
= 2 -
tile_down
= 2 -
serpentine
=True
Uses four panels, total display size is 128x64. Note how displays 3 and 4 are rotated 180 degrees to minimize the length of ribbon cables required.
-
chain_across
= 2 -
tile_down
= 2 -
serpentine
=False
Uses four panels, total display size is 128x64.
Note how long the ribbon cable is from panel 2 to 3. This is why the "serpentine" arrangement is usual preferable to the non-serpentine arrangement.
The effect of display rotation
All of the above examples show a display with rotation=0
. You can change the rotation of a screen by passing in a rotation=
parameter to the FramebufferDisplay
constructor, or by setting the .rotation
property of the display
object at any time.
This rotation, which can be any of 0, 90, 180, or 270 degrees counterclockwise, affects the whole display rather than the individual panels.
Text editor powered by tinymce.