Real-time high-performance camera feed displayed on a 64x32 RGB LED matrix.
Camera → Computer (Pi, Mac, PC) → USB Serial (4M baud) → Matrix Portal M4 → LED Matrix
- Render Speed: ~24 FPS (Optimized from 5 FPS)
- Tech Stack: Python 3.14+, CircuitPython 10, Optimized
bitmaptools - Resolution: 64x32 pixels, RGB565 color
| Folder | Name | Description |
|---|---|---|
pro/ |
Professional | Modular, production-ready Python application. Uses uv, strict typing, and advanced config. |
hs/ |
High School | Educational, single-folder version (hs/src) for students. Simplified code, cross-platform. |
matrix-portal/ |
Firmware | CircuitPython apps for the Adafruit Matrix Portal M4 — see Matrix Portal Demos below. |
utils/ |
Utilities | ledportal-utils library for snapshot export (PNG, blocks, circles). |
macropad/ |
MacroPad Remote | CircuitPython macro pages for the Adafruit MacroPad RP2040. Physical button controller for all camera feed commands. |
The on-device CircuitPython apps in matrix-portal/, selected from the boot hub screen using the onboard UP / DOWN buttons:
| Demo | Hub selection | Description |
|---|---|---|
| Camera Mirror | MIRROR (default) |
Displays the live USB camera feed streamed from the host ledportal app. |
| Photo Slideshow | UP → PHOTOS |
Cycles built-in images stored on the device (dog.png, kitten.png, …). |
| Silly Bird | DOWN → BIRD |
A silly bird fly through gates game, playable in portrait or landscape. |
See matrix-portal/README.md for deployment and matrix-portal/NAVIGATION.md for the full screen-flow diagram.
Best: VS Code Remote SSH - develop on Mac, run on Pi hardware
# In VS Code: CMD+Shift+P → "Remote-SSH: Connect to Host"
# See pro/README.md for full setupAlternative: Git clone + uv on Pi
git clone <repo>
cd pro
uv sync
uv run ledportalSimplest: get the code, then let uv handle Python + dependencies in one command:
git clone https://github.com/deangoodmanson/MatrixPortalDemos.git
cd MatrixPortalDemos/hs
uv run python src/camera_feed.py # uv installs Python 3.14 + all deps on first runGetting the code without git: download the repo ZIP from GitHub
(Code → Download ZIP), unzip, then run the same cd hs && uv run …. For a
classroom, a teacher can distribute the hs/ folder over a shared network drive
(SMB/NFS), cloud folder, or USB stick — each student just needs the hs/ folder
(it includes pyproject.toml, so uv knows what to install).
See hs/README.md and pro/README.md for detailed workflows.
No LED matrix or Matrix Portal hardware is required to develop or run the software.
The app works with just a webcam — use the preview window (w) to see the LED
simulation on screen. The --no-display flag skips serial port detection entirely.
You have two options:
Fast, configurable, and robust.
cd pro
uv sync
uv run ledportalGreat for learning how it works.
cd hs
uv run python src/camera_feed.py # uv reads hs/pyproject.toml — no manual venv or pipTo display on a physical LED matrix:
- Install CircuitPython 10.0.3+ on your Matrix Portal M4.
- Install required library:
circup install adafruit_display_text - Copy
matrix-portal/code.pyto yourCIRCUITPYdrive. - Additional libraries needed in
lib/:adafruit_display_text,adafruit_matrixportal.
- Auto-Detection: Code automatically finds the Matrix Portal USB device.
- Cross-Platform: Works on macOS, Linux, Raspberry Pi, and Windows.
- Orientation:
llandscape (default) ·pportrait - Processing:
ccenter crop (default) ·sstretch ·ffit (letterbox) - Effects:
bB&W toggle ·mmirror ·zzoom (100→75→50→25%) ·orender algorithm ·+/-LED size - Actions:
Spacesnapshot (with PDF export) ·vavatar capture - Demo:
xauto demo ·Shift+Xmanual demo ·./,next/prev step - Preview:
wtoggle preview window with camera + LED side-by-side - System:
ttoggle transmission ·ddebug ·rreset ·hhelp ·qquit
We achieved a ~500% performance increase (5 FPS → 24 FPS) by:
- Firmware: Replaced Python pixel loops with
bitmaptools.arrayblit(C-level memory copy). - Transport: Increased USB Serial baud rate to 4,000,000.
- Pipeline: Optimized frame resizing and RGB565 conversion in Python.
If the physical LED matrix shows color artifacts (wrong-colored pixels) that do not appear in the software BMP snapshot, use the comparison script to investigate:
uv run --project pro python docs/compare_rgb565.py [pro/snapshot_*.bmp]This produces a side-by-side 10× PNG (saved next to the BMP):
| Panel | Content |
|---|---|
| Left | Original BMP — what the software saved / preview shows |
| Centre | After RGB565 roundtrip — what the matrix actually receives |
| Right | |difference| × 4 — artifact map |
The script also prints per-pixel and per-channel shift statistics. A max shift of ≤7 counts rules out RGB565 quantization as the cause.
See docs/compare_rgb565.py for the full methodology, RGB565 bit-layout
reference, and a guide to distinguishing rolling-shutter artifacts, camera
bloom, hardware LED variation, and serial bit flips.
"Matrix Portal not found"
- Check your USB cable (some are power-only!).
- Ensure
code.pyis running on the device (screen should say "WAITING FOR USB").
"Permission denied" (Linux/Pi)
- You may need to add your user to the
dialoutgroup:sudo usermod -a -G dialout $USER.