制造商零件编号 3211
RGB MATRIX BONNET FOR RASPBERRY
Adafruit Industries LLC
License: See Original Project Displays LED Matrix Raspberry Pi SBC
Courtesy of Adafruit
Guide by Tim C
Overview
Each new generation of the Raspberry Pi brings improvements over the last, and the Raspberry Pi 5 is no exception. However, along with the great new features and enhanced performance can also come some incompatibility with the way things were done on prior versions of the hardware. One such incompatibility with the Pi 5 was the ability to drive HUB75 compatible RGB Matrices like the older Pi's could.
The new Adafruit Blinka Raspberry Pi5 PioMatter library brings this capability to the Raspberry Pi 5 by way of the PIO peripherals.
This guide and library support the Raspberry Pi 5 only. They cannot be used with older Raspberry Pi devices.
Hardware Requirements
You'll need a Raspberry Pi 5, we recommend the official Raspberry Pi 5V power supply for it. There are a variety of matrix panels and power supplies to choose from depending on how big or small your project will be.
Each panel requires up to 4A of power at max brightness with all pixels on. Keeping things a bit dimmer, or not using all the pixels at once will save power. I've had success running 2 panels off of one 4A power adapter, the matrices are still plenty bright for indoor projects.
If you're driving more than 2 panels, you'll need another 4A adapter. The female DC power adapter makes it easy to power additional matrices separate from the two that can be powered from the Bonnet's terminal blocks.
The library supports both the RGB Matrix Bonnet, and the RGB Matrix HAT. Only one is needed though, choice is up to you.
Parts
Raspberry Pi 5 Setup
We recommend you use the latest Raspberry Pi OS flashed onto one of the official Raspberry Pi SDCards. The Raspberry Pi Imager app makes it easy to prepare your SD Card.
Click Choose Device then select the Raspberry Pi 5.
Click Choose OS then select Raspberry Pi OS (64-bit).
Click Choose Storage then select your SDCard adapter. The name will depend on your device, and it may differ from the screenshot.
Once all 3 values are selected you should see them filled in to the appropriate areas of the main screen.
When everything has been set, click the Next button. You'll be asked if you'd like to apply OS customization settings. This step is optional, it allows you to put in username, WiFi credentials, and SSH public key which will get baked into the image that is flashed to the SD Card.
Enter your details and click Yes if you'd like to do it, otherwise click No. Next, you'll be warned that the storage device you've select is going to be erased. Make certain it's the drive you're intending to flash and then click Yes to start the writing process.
A pop-up will be shown once the writing has completed successfully.
Boot & Update
If you did enter your network credentials and SSH key to the OS customization step, and you can use nmap or some other tool to locate the Pi 5 on the network and then you can do this step entirely "headless". If not, you can temporarily plug in an HDMI display and USB keyboard to do it.
Plug in the Pi 5, let it boot up, then update the software on it using the following commands.
sudo apt update
sudo apt upgrade
Create a Virtual Environment
The best practice for installing Python libraries is to use virtual environments to keep things isolated and minimize conflicts between different versions of libraries that might be required for different projects or purposes. You can name your virtual environment anything, but it's best to use something you'll remember and associate with the project your working on. I use the name blinka_venv for the environment containing Adafruit Blinka and all associated libraries on my Pi's.
It's easy to create one with the following command.
python -m venv ~/venvs/blinka_venv
For more info about virtual environments see this guide.
Install Requirements
Next you need to activate the new virtual environment and then install the required libraries within it.
source ~/venvs/blinka_venv/bin/activate
pip install adafruit-blinka
pip install pillow
pip install numpy
pip install Adafruit-Blinka-Raspberry-Pi5-Piomatter
Add PIO Subsystem Rule Configuration
By default, one requires root privilege to access the PIO hardware peripherals. We'll setup a rule that makes it so that the standard user can do it. We need to edit the file /etc/udev/rules.d/99-com.rules.
sudo nano /etc/udev/rules.d/99-com.rules
Add a new empty line or two at the top of the file by pressing enter. Then add this to one of the empty lines.
SUBSYSTEM=="*-pio", GROUP="gpio", MODE="0660"
To save the file press Ctrl-S on the keyboard. Then press Ctrl-X to exit. After you've done this, reboot the Pi with sudo reboot.
Accessing Console
At present time, the python scripts that drive the matrices work best when run from the console context rather than the desktop UI context. There are a few ways you can achieve this and depending on whether your Pi is dedicated to this usage or not you may want to set it up to boot directly to the console.
Temporary
If you don't want to make any config changes then you can simply press Ctrl-Alt-F1 on a keyboard connected to the Pi to change from the desktop context to the console. The HDMI screen will go from showing the desktop to just the basic terminal prompt. At this prompt you can activate your virtual environment as shown above, and then run Python scripts that draw to the matrix. To go back to the desktop context, you can press Ctrl-Alt-F7.
SSH
If you access the Pi over SSH then it already counts as the console so you can activate your virtual environment and run the matrix scripts with nothing further needed.
Auto Boot to Console
If you intend to keep using the same Pi for RGB Matrix projects, and you typically use a keyboard and HDMI screen to interact with the Pi directly, rather than SSH, then it may be convenient to configure your Pi to automatically boot directly to the console rather than the desktop.
To enter the config utility run this command.
sudo raspi-config
Ensure System Options is highlighted, and press enter.
Arrow down to highlight Boot / Auto Login and press enter.
Highlight either B1 Console, or B2 Console Autologin and press enter.
After the setting is applied, you'll be taken back to the main raspi-config screen
Arrow right until Finish is highlighted and press enter.
When prompted to reboot now highlight Yes and press enter.
When the Pi boots up, you'll be ready to activate your virtual environment and run the python scripts that interact with the RGB Matrix.
Wiring
The RGB Matrix Bonnet and RGB Matrix HAT make it easy to wire up the RGB Matrix and required power supply.
It is best to make all of these connections with the power unplugged, and then once everything is connected and you've double-checked that it's all correct, plug in the power to turn everything on. I've found that the Pi can complain about low power if its USB C power is not plugged in prior to the DC jack power on the Bonnet or Hat. So be sure to plug in the USB C power adapter first, then the adapters powering the Bonnet and any additional panels.
For more info see this guide page.
Pi 5 & Bonnet Connections
Attach the Matrix Bonnet or Hat to the Raspberry Pi 5 GPIO pin rows.
Connect the USB C power cable to the USB C jack to power the Pi.
Connect the barrel jack of the DC 5V 4A power adapter into the barrel jack connector on the Matrix Bonnet or Hat.
Connect the fork on the end of GND (black wire) lead on the matrix power cable to the - terminal block on the Matrix Bonnet or Hat.
Connect the fork on the end of the 5V (red wire) lead on the matrix power cable to the + terminal block on the Matrix Bonnet or Hat.
Connect one end of a 2x8 IDC ribbon cable to the 2x8 pin connector on the Matrix Bonnet or Hat.
Matrix Panel Connections
Connect one end of the 4-pin matrix power cable connector to the 4 pin power input connector on the back of the matrix panel.
Connect the other end of the 2x8 IDC ribbon cable to the input 2x8 pin connector on the back of the matrix panel. The input connector is the one that the arrows in the long direction point away from.
Basic Test
Once you're Pi 5 is all set up and you've got the RGB Matrix panels all wired you're ready to test it out!
As always, you need to activate the virtual environment before running the example. If you haven't already then activate it like this.
source ~/venvs/blinka_venv/bin/activate
Next you can run the single_panel_simpletest.py script.
python single_panel_simpletest.py
The code for this example is embedded below. You can download it, or copy/paste the text into a file.
#!/usr/bin/python3
# SPDX-FileCopyrightText: 2025 Tim Cocks for Adafruit Industries
#
# SPDX-License-Identifier: MIT
"""
Display a simple test pattern of 3 shapes on a single 64x32 matrix panel.
Run like this:
$ python simpletest.py
"""
import adafruit_blinka_raspberry_pi5_piomatter as piomatter
import numpy as np
from PIL import Image, ImageDraw
width = 64
height = 32
geometry = piomatter.Geometry(width=width, height=height, n_addr_lines=4,
rotation=piomatter.Orientation.Normal)
canvas = Image.new('RGB', (width, height), (0, 0, 0))
draw = ImageDraw.Draw(canvas)
framebuffer = np.asarray(canvas) + 0 # Make a mutable copy
matrix = piomatter.PioMatter(colorspace=piomatter.Colorspace.RGB888Packed,
pinout=piomatter.Pinout.AdafruitMatrixBonnet,
framebuffer=framebuffer,
geometry=geometry)
draw.rectangle((2, 2, 10, 10), fill=0x008800)
draw.circle((18, 6), 4, fill=0x880000)
draw.polygon([(28, 2), (32, 10), (24, 10)], fill=0x000088)
framebuffer[:] = np.asarray(canvas)
matrix.show()
input("Press enter to exit")
Code Explanation
After initializing the matrix, this example uses the Pillow library (PIL) to draw 3 basic shapes and colors. It can serve as a good test to ensure your wiring and software are all setup properly.
Initialization Config
Initializing matrix panels to display things onto requires 3 main steps:
Create a Geometry object to define the size and shape of the panel(s)
Create a framebuffer to hold display data
Create the PioMatter instance.
Geometry
The Geometry object defines the size and shape of the panel(s) that will serve as the display. There 6 arguments that can be passed to configure it.
width - The total width of the panel(s) in pixels.
height - The total height of the panel(s) in pixels.
n_addr_lines - The number of connected address lines. The number of pixels in the shift register is automatically computed from these values. Many panels use 4 as a standard. The 64x64 panels that we stock use 5 address lines. Set this value according to which panels you're using. Note that using 5 addr lines also requires soldering a jumper as described on this guide page.
serpentine - Controls the arrangement of multiple panels when they are stacked in rows. If it is True, then each row goes in the opposite direction of the previous row. Default is True.
rotation - controls the orientation of the panel(s). Must be one of the Orientation constants. Default is Orientation.Normal. Over valid values are Orientation.R180, Orientation.CW, and Orientation.CCW
n_planes - Controls the color depth of the panel. This is separate from the framebuffer layout. Decreasing n_planes can increase FPS at the cost of reduced color fidelity. The default, 10, is the maximum value.
Framebuffer
Next you need a framebuffer, this is a numpy array that will contain pixel data in the appropriate colorspace. When refreshed the matrix will show the data that is in this framebuffer on the display. Depending on what you're displaying it can be created in a few different ways.
# For displaying an image from PIL, canvas is the PIL.Image instance
framebuffer = np.asarray(canvas) + 0
# For displaying arbitrary data, start with zeros
framebuffer = np.zeros(shape=(geometry.height, geometry.width, 3), dtype=np.uint8)
PioMatter
Now the PioMatter instance can be initialized. Aside from the Geometry, and Framebuffer created above, it also accepts arguments for colorspace and pinout.
colorspace - Controls the colorspace that will be used for data to be displayed. It must be one of the Colorspace constants. Which to use depends on what data you’re displaying and how it is processed before copying into the framebuffer. Many of the examples use Colorspace.RGB888Packed. Other valid values are Colorspace.RGB565 and Colorspace.RGB888.
pinout - Defines which pins the panels are wired to. Different pinouts can support different hardware breakouts and panels with different color order. The value must be one of the Pinout constants Pinout.AdafruitMatrixBonnet, Pinout.AdafruitMatrixBonnetBGR, Pinout.AdafruitMatrixHat, or Pinout.AdafruitMatrixHatBGR.
framebuffer - A numpy.array buffer as noted above.
geometry - A Geometry instance as noted above.
Example Initialization Code
geometry = piomatter.Geometry(width=64, height=32, n_addr_lines=4, rotation=piomatter.Orientation.Normal)
matrix_framebuffer = np.zeros(shape=(geometry.height, geometry.width, 3), dtype=np.uint8)
matrix = piomatter.PioMatter(colorspace=piomatter.Colorspace.RGB888Packed, pinout=piomatter.Pinout.AdafruitMatrixBonnet, framebuffer=matrix_framebuffer, geometry=geometry)
Multiple Matrix Panels
Is one panel too small to contain your epic ideas? No problem, you can chain multiple panels together in a serpentine configuration to assemble a larger total display size. When wiring multiple panels, be sure to pay attention to the arrows on the silkscreen of the back of the matrix panels. The arrows in the long direction point away from the input 2x8 IDC connector and point towards the output 2x8 IDC connector.
Various possible configurations are illustrated below.
Horizontal Layouts
2 x 1 panel layout with a total size of 128x32 pixels.
4 x 1 panel layout with a total size of 256x32 pixels.
2 x 2 panel layout with a total size of 128x64 pixels.
Vertical Layouts
1 x 2 panel layout with a total size of 64x64 pixels.
1 x 4 panel layout with a total size of 64x128 pixels.
Once your panels are properly wired up be sure to update the width and height values used in the code when the matrices are initialized.
Animated GIF
As always, you need to activate the virtual environment before running the example. If you haven't already then activate it like this.
source ~/venvs/blinka_venv/bin/activate
Next you can run the play_gif.py script.
python play_gif.py
The code for this example is embedded below. You can download it, or copy/paste the text into a file.
#!/usr/bin/python3
"""
Display an animated gif
Run like this:
$ python play_gif.py
The animated gif is played repeatedly until interrupted with ctrl-c.
"""
import time
import adafruit_blinka_raspberry_pi5_piomatter as piomatter
import numpy as np
import PIL.Image as Image
width = 64
height = 32
gif_file = "nyan.gif"
canvas = Image.new('RGB', (width, height), (0, 0, 0))
geometry = piomatter.Geometry(width=width, height=height,
n_addr_lines=4, rotation=piomatter.Orientation.Normal)
framebuffer = np.asarray(canvas) + 0 # Make a mutable copy
matrix = piomatter.PioMatter(colorspace=piomatter.Colorspace.RGB888Packed,
pinout=piomatter.Pinout.AdafruitMatrixBonnet,
framebuffer=framebuffer,
geometry=geometry)
with Image.open(gif_file) as img:
print(f"frames: {img.n_frames}")
while True:
for i in range(img.n_frames):
img.seek(i)
canvas.paste(img, (0,0))
framebuffer[:] = np.asarray(canvas)
matrix.show()
time.sleep(0.1)
Code Explanation
After initializing the matrix panel, this example loads a GIF file using PIL. Within the main loop it iterates over the frames of the GIF, pasting each one into the canvas image. The framebuffer gets filled with data from the canvas image and then shown on the matrix panel.
Scrolling Text
As always, you need to activate the virtual environment before running the example. If you haven't already then activate it like this.
source ~/venvs/blinka_venv/bin/activate
Next you can run the quote_scroller.py script.
python quote_scroller.py
The code for this example is embedded below. You can download it, or copy/paste the text into a file.
#!/usr/bin/python3
# SPDX-FileCopyrightText: 2025 Tim Cocks for Adafruit Industries
#
# SPDX-License-Identifier: MIT
"""
Display quote from the Adafruit quotes API as text scrolling across the
matrices.
Requires the requests library to be installed.
Run like this:
$ python quote_scroller.py
"""
import adafruit_blinka_raspberry_pi5_piomatter as piomatter
import numpy as np
import requests
from PIL import Image, ImageDraw, ImageFont
# 128px for 2x1 matrices. Change to 64 if you're using a single matrix.
total_width = 128
total_height = 32
bottom_half_shift_compensation = 1
font_color = (0, 128, 128)
# Load the font
font = ImageFont.truetype("LindenHill-webfont.ttf", 26)
quote_resp = requests.get("https://www.adafruit.com/api/quotes.php").json()
text = f'{quote_resp[0]["text"]} - {quote_resp[0]["author"]}'
#text = "Sometimes you just want to use hardcoded strings. - Unknown"
x, y, text_width, text_height = font.getbbox(text)
full_txt_img = Image.new("RGB", (int(text_width) + 6, int(text_height) + 6), (0, 0, 0))
draw = ImageDraw.Draw(full_txt_img)
draw.text((3, 3), text, font=font, fill=font_color)
full_txt_img.save("quote.png")
single_frame_img = Image.new("RGB", (total_width, total_height), (0, 0, 0))
geometry = piomatter.Geometry(width=total_width, height=total_height,
n_addr_lines=4, rotation=piomatter.Orientation.Normal)
framebuffer = np.asarray(single_frame_img) + 0 # Make a mutable copy
matrix = piomatter.PioMatter(colorspace=piomatter.Colorspace.RGB888Packed,
pinout=piomatter.Pinout.AdafruitMatrixBonnet,
framebuffer=framebuffer,
geometry=geometry)
print("Ctrl-C to exit")
while True:
for x_pixel in range(-total_width-1,full_txt_img.width):
if bottom_half_shift_compensation == 0:
# full paste
single_frame_img.paste(full_txt_img.crop((x_pixel, 0, x_pixel + total_width, total_height)), (0, 0))
else:
# top half
single_frame_img.paste(full_txt_img.crop((x_pixel, 0, x_pixel + total_width, total_height//2)), (0, 0))
# bottom half shift compensation
single_frame_img.paste(full_txt_img.crop((x_pixel, total_height//2, x_pixel + total_width, total_height)), (bottom_half_shift_compensation, total_height//2))
framebuffer[:] = np.asarray(single_frame_img)
matrix.show()
Code Explanation
This example fetches a quote from the Adafruit Quotes API using the requests library. Once fetched the quote is rendered in its entirety in a single line into a very wide image full_txt_img. This image is too wide to display all at once on the matrix hence the need for scrolling.
The matrix gets initialized and then the code moves to the main loop. Once inside, an inner for loop iterates over horizontal pixel indexes. A matrix sized section of the full_text_img is copied out and pasted into single_frame_img. From there it's copied into the framebuffer and shown on the matrix.
Mirror Console
Display Configuration
This example will mirror the console's framebuffer to the matrix panel. In order to make it fit better, and to ensure that the requisite /dev/fb0 exists whether or not an HDMI display is plugged in, there will be a modification to the file /boot/firmware/cmdline.txt that adds a video configuration with the smallest allowed display size.
sudo nano /boot/firmware/cmdline.txt
Scroll to the end of the line by pressing end or holding right arrow for a while.
Press space bar to insert a space at the end of the existing line.
Add the following after the space at the end of the existing line.
video=HDMI-A-1:640x480M@60D
Press Ctrl-S to save the file.
Press Ctrl-X to exit.
Then reboot the Pi for it to take effect
sudo reboot
When the Pi boots back up, the file /dev/fb0 should now exist even if you don't have an HDMI display plugged in. If you do have an HDMI display, you'll notice that the text on it is now scaled bigger since we've overridden the display size to be 640x480
Run The Example
As always, you need to activate the virtual environment before running the example. If you haven't already, then activate it like this.
source ~/venvs/blinka_venv/bin/activate
Next you can run the fbmirror_scaled.py script. The script accepts several arguments to configure the panels. The first 3 are specific to the fbmirror examples.
--scale - a number to scale the full display down by. What is best depends on what you're showing. 2 or 4 are good places to start and then tune it to your content and desired look.
--x-offset - the number of pixels in the x axis to skip when getting the region to mirror.
--y-offset - the number of pixels in the y axis to skip when getting the region to mirror.
The remaining arguments are of the configuration options described on the Initialization Config page. The first two are required.
--width - the number of pixels wide the total panel is. 128px is for a 2x2 matrix panel.
--height - the number of pixels tall the total panel is. 64px is for a 2x2 matrix panel.
The rest are optional if you're using default the configuration for everything.
--orientation - the rotation angle, must be one of Normal, CW, CCW, R180.
--pinout - the pinout to use for the panel(s) e.g. AdafruitMatrixBonnet
--num-address-lines - the number of address lines. The 64x64 panels we stock use 5, all smaller panels use 4
--num-planes - the color depth, defaults to 10. Lower values can improve refresh rate speed.
--serpentine - the organization of multiple panels, serpentine is default. Use --no-serpentine if your panels are wired in the non-serpentine configuration.
The command should look as follows with appropriate values filled in for your panel:
python fbmirror_scaled.py --scale [scale] --width [width] --height [height] --orientation [orientation]
The values for a 2x2 matrix panel rotated 180 are shown below, adjust them for your panel(s).
python fbmirror_scaled.py --scale 3 --width 128 --height 64 --orientation R180
The code for this example is embedded below. You can download it, or copy/paste the text into a file.
#!/usr/bin/python3
"""
Mirror a scaled copy of the framebuffer to RGB matrices,
A portion of the framebuffer is displayed until the user hits ctrl-c.
Control scale, matrix size, and orientation with command line arguments.
Usage: fbmirror_scaled.py [OPTIONS]
Options:
--x-offset INTEGER The x offset of top left corner of the
region to mirror
--y-offset INTEGER The y offset of top left corner of the
region to mirror
--scale INTEGER The scale factor to reduce the display down
by.
--num-address-lines INTEGER The number of address lines used by the
panels
--num-planes INTEGER The number of bit planes (color depth. Lower
values can improve refresh rate in frames
per second
--orientation [Normal|R180|CCW|CW]
The overall orientation (rotation) of the
panels
--pinout [AdafruitMatrixBonnet|AdafruitMatrixBonnetBGR|AdafruitMatrixHat|AdafruitMatrixHatBGR]
The details of the electrical connection to
the panels
--serpentine / --no-serpentine The organization of multiple panels
--height INTEGER The panel height in pixels
--width INTEGER The panel width in pixels
--help Show this message and exit.
The `/dev/fb0` special file will exist if a monitor is plugged in at boot time,
or if `/boot/firmware/cmdline.txt` specifies a resolution such as
`... video=HDMI-A-1:640x480M@60D`.
"""
import adafruit_blinka_raspberry_pi5_piomatter as piomatter
import click
import numpy as np
import PIL.Image as Image
import piomatter_click
with open("/sys/class/graphics/fb0/virtual_size") as f:
screenx, screeny = [int(word) for word in f.read().split(",")]
with open("/sys/class/graphics/fb0/bits_per_pixel") as f:
bits_per_pixel = int(f.read())
assert bits_per_pixel == 16
bytes_per_pixel = bits_per_pixel // 8
dtype = {2: np.uint16, 4: np.uint32}[bytes_per_pixel]
with open("/sys/class/graphics/fb0/stride") as f:
stride = int(f.read())
linux_framebuffer = np.memmap('/dev/fb0',mode='r', shape=(screeny, stride // bytes_per_pixel), dtype=dtype)
@click.command
@click.option("--x-offset", "xoffset", type=int, help="The x offset of top left corner of the region to mirror", default=0)
@click.option("--y-offset", "yoffset", type=int, help="The y offset of top left corner of the region to mirror", default=0)
@click.option("--scale", "scale", type=int, help="The scale factor to reduce the display down by.", default=3)
@piomatter_click.standard_options
def main(xoffset, yoffset, scale, width, height, serpentine, rotation, pinout, n_planes, n_addr_lines):
geometry = piomatter.Geometry(width=width, height=height, n_planes=n_planes, n_addr_lines=n_addr_lines, rotation=rotation)
matrix_framebuffer = np.zeros(shape=(geometry.height, geometry.width, 3), dtype=np.uint8)
matrix = piomatter.PioMatter(colorspace=piomatter.Colorspace.RGB888Packed, pinout=pinout, framebuffer=matrix_framebuffer, geometry=geometry)
while True:
tmp = linux_framebuffer[yoffset:yoffset + height * scale, xoffset:xoffset + width * scale]
# Convert the RGB565 framebuffer into RGB888Packed (so that we can use PIL image operations to rescale it)
r = (tmp & 0xf800) >> 8
r = r | (r >> 5)
r = r.astype(np.uint8)
g = (tmp & 0x07e0) >> 3
g = g | (g >> 6)
g = g.astype(np.uint8)
b = (tmp & 0x001f) << 3
b = b | (b >> 5)
b = b.astype(np.uint8)
img = Image.fromarray(np.stack([r, g, b], -1))
img = img.resize((width, height))
matrix_framebuffer[:, :] = np.array(img)
matrix.show()
if __name__ == '__main__':
main()
Code Explanation
After initializing the matrix panel(s), this example mirrors the /dev/fb0 framebuffer using numpy.memmap. Inside the main loop it copies the current values from the mirrored instance into a PIL Image, scales it down to the specified size, then copies it into matrix_framebuffer to be shown on the panel.
MP4 Video
Playing mp4 video files to the console framebuffer can be done with the VLC application, which is pre-loaded by default in the Raspberry Pi OS. In order to get the video to the matrix panel, we'll use the Mirror Console example from the previous page, so check that out first if you haven't already. The trick is to keep the Mirror Console example running and then play the video so that the video is mirrored to the matrix panels.
You can run the fbmirror_scaled.py script via SSH, or directly from the console with a keyboard. If you run it directly from the console, then you'll need to add & to the end of the command to run it in the background so that you can get a new prompt to run the VLC command.
source ~/venvs/blinka_venv/bin/activate
cd ~/Adafruit_Blinka_Raspberry_Pi5_PioMatter/examples
# Via SSH
python fbmirror_scaled.py --scale 16 --width 128 --height 64 --orentation R180
# Direct Console
python fbmirror_scaled.py --scale 16 --width 128 --height 64 --orientation R180 &
If you ran it directly in the console and want to stop the mirroring process you can do so using the ps and kill commands. First run ps and look for the row with "python" in the CMD column, follow that row to the PID column and note the PID number for the process. Then run kill [number] swapping in the pid number of the process.
The VLC command must be run directly from the console, not via SSH.
Once the display is being mirrored, all that's left is to start up the video. We must use the --vout fb argument to tell VLC to send the video output to the framebuffer. It can also be handy to modify the brightness of the video to darken it some if you see lines or other artifacts in the bright regions of your video. That can be done by adding --video-filter=adjust --brightness=0.85 to the command before the video is specified. Change the 0.85 to whatever brightness percentage you want.
The whole command looks like this.
vlc --vout fb --video-filter=adjust --brightness=0.85 your_video_file.mp4
You can stop the video early by pressing Ctrl-C. If you let the entire video play then it will bring you back to the terminal after it's over, but it will still be waiting for you to exit VLC by pressing Ctrl-C.
The code for this is the fbmirror_scaled.py script from the previous page.