Saturday, February 07, 2026

One Cable, Many Screens: A Self-Hosting PoE Raspberry Pi 4 Infotainment System

This is version 2 of my multi-screen Raspberry Pi infotainment project. The first version (DIY In-Car Infotainment) required a separate pocket router for DHCP, DNS, and DLNA. This version eliminates that dependency — one prebuilt SD card image works for all terminals, and the system configures itself automatically at boot.

Last updated: February 7, 2026

What's New in v2

  • No external router needed — The GL-MT300N-V2 pocket router is eliminated. One Pi automatically becomes the network master.
  • Automatic master election — Whichever Pi has USB media attached becomes the master. No manual configuration.
  • Self-hosted services — Master provides DHCP, DNS, NTP, and DLNA — all built into the same image.
  • Simpler deployment — One image, flash to all SD cards, connect, power on.
  • Time synchronization — All terminals sync their clocks from the master via NTP.

System Overview

Raspberry Pi 4 multi-screen infotainment system setup diagram showing PoE switch, master terminal with USB, and client terminals

System diagram: One master Pi (with USB media) provides DHCP, DNS, NTP, and DLNA to all client terminals via a PoE switch.

A typical deployment uses:

  • 1 master Pi4 terminal (with USB media attached)
  • 3 client Pi4 terminals
  • 1 PoE switch (5-port or larger)

The topology is a pure star connection: every terminal connects directly to the PoE switch via a single Ethernet cable that provides both power and network. No AV matrix or special head-end hardware required.

How It Works

  1. PoE switch powers on
  2. All Pi4 terminals boot from identical SD cards
  3. Each terminal checks for USB storage
  4. The terminal with USB media becomes the master automatically
  5. Master starts DHCP (192.168.8.100-200), DNS, NTP, and DLNA services
  6. Client terminals get their IP address, time sync, and media access from master
  7. All terminals launch Kodi and connect to the DLNA source
  8. Users choose Personal Mode or Sync Mode

Two Operating Modes

Personal Mode

Each user gets their own screen and audio path:

  • Analog headset via 3.5mm jack, or
  • Bluetooth headset

This feels similar to in-flight seatback entertainment. Each passenger independently browses the DLNA media library in Kodi and plays whatever they want.

Sync Mode

When shared viewing is needed, the master terminal can synchronize all clients:

  • A mini 3-key USB keyboard connects to the master
  • Press KEY_1: master checks current playback state
  • Master sends JSON-RPC commands to all clients
  • Clients open the same stream and align to master's timestamp
  • All screens play the same content in sync

Master audio can feed a central sound system (vehicle speakers, room PA, etc.) for group viewing.

Hardware List

For a 4-terminal setup:

Component Qty Notes
Raspberry Pi 4 (4GB) 4 2GB works but 4GB recommended
PoE HAT 4 Official or compatible 802.3af HAT
MicroSD card (32GB+) 4 Class 10 or faster
Full HD touch display 4 7" to 10" HDMI displays work well
PoE switch 1 5-port minimum, 802.3af/at
Ethernet cables 4 Up to 50m runs supported
USB storage 1 NTFS, FAT32, or ext4 formatted
3-key USB keyboard 1 For sync mode control

Compared to v1, you no longer need the GL-MT300N-V2 pocket router — the master Pi handles all network services.

Real-World Use Cases

In-Car / Fleet Passenger Infotainment

Ideal for vehicles with multiple passengers:

  • Each passenger watches independent content with personal audio
  • One key press switches everyone to synchronized shared playback
  • Master audio routes to vehicle speakers for group viewing

Gives both freedom (personal playback) and coordination (sync playback) in one system.

Multi-Room Shared Viewing

Use case diagram showing multi-room shared viewing with synchronized screens in overflow rooms

Multi-room use case: synchronized playback across overflow rooms, halls, or training centers.

For venues where people are spread across rooms:

  • House of worship overflow rooms
  • Community halls
  • Training centers
  • Small campuses

A single PoE star network keeps wiring simple and operations predictable.

Quick Start

Option 1: Pre-built Image (Recommended)

  1. Download the pre-built SD card image (~1.2GB)
  2. Flash the image to all SD cards using Raspberry Pi Imager or balenaEtcher
  3. Insert SD cards into Pi4 terminals
  4. Connect all terminals to PoE switch
  5. Insert USB media (NTFS, FAT32, or ext4) into one terminal
  6. Power on the PoE switch
  7. Wait for all terminals to boot into Kodi

Option 2: Manual Installation

On an existing Raspberry Pi OS Lite installation:

git clone https://github.com/hackboxguy/media-mux.git
cd media-mux
sudo ./setup-selfhosted.sh

Troubleshooting

DLNA source shows "Couldn't connect to network server"

  • Check if master terminal has USB media attached
  • Verify minidlna is running: pgrep -f minidlnad
  • Check master log: cat /var/log/media-mux-selfhosted.log
  • Ensure USB is mounted: mount | grep /media/usb

Client terminal not getting IP address

  • Verify master booted first and has USB attached
  • Check dnsmasq is running on master: systemctl status dnsmasq
  • Try rebooting the client terminal

Time is wrong on client terminals

  • Wait a few minutes after boot for NTP sync
  • Check chrony status: chronyc sources
  • Verify master chrony is running: pgrep -f chronyd

Sync playback not working

  • Ensure 3-key keyboard is connected to master terminal
  • Check kodisync log on master: cat /var/log/kodisync.log
  • Verify all clients are on the same network (192.168.8.x)

USB media not detected

  • Supported formats: NTFS, FAT32, ext4
  • Check dmesg for USB detection: dmesg | grep -i usb
  • Try a different USB port or cable

Current Limitations

The system works reliably for practical deployments, but there are areas for future improvement:

  • No automatic master failover if master is disconnected
  • No web dashboard for status monitoring
  • Role is determined by USB presence (no manual pinning)

SOURCE CODE

github.com/hackboxguy/media-mux — pre-built images and release notes in Releases section

Monday, February 02, 2026

Remote-Kit: Pocket Router for Remote Hardware Bring-up

A compact "lab-in-a-box" that turns a $30 GL-MT300N-V2 pocket router into a remote hardware bring-up station. You get serial console, PoE power control, SD card image swapping, USB power cycling, PiKVM video/keyboard, and a camera feed over a single box.

Last updated: February 2, 2026

Quick start: Flash the Remote-Kit firmware, log in at http://192.168.20.1, wire in PoE switch + PiKVM, then update port-forwards to match device IPs.

What Remote-Kit does

  • Serial terminal to the DUT over SSH (screen)
  • Virtual SD card image loading via SDWire (no physical card swaps)
  • Remote USB power cycle (Tasmota-based XY-WSUSB)
  • PoE power on/off and power measurements (Netgear GS308EP)
  • PiKVM remote display + USB keyboard/mouse emulation
  • Optional USB webcam stream for bench visibility
  • FTP/TFTP for bootloader RAM loading

System overview

Hardware setup diagram for Remote-Kit with Raspberry Pi 4 as DUT

Example bench wiring for a Pi 4 DUT with PoE power, PiKVM, SDWire, and camera.

Security note: Default credentials — Remote-Kit SSH: root / remote-kit-000, PoE switch (GS308EP): password, WiFi SSID/key: remote-kit-000 / remote-kit-000. Change all default passwords before exposing any service to your corporate or public network.

Hardware (Bill of Materials)

Below is a reference setup for a Raspberry Pi 4 as DUT. Prices are from the time of writing and will vary.

Item Qty Unit Price (EUR) Notes
GL.iNet GL-MT300N-V2130Remote-Kit router
5V MicroUSB PSU (router)1105V/3A adapter
Netgear GS308EP PoE switch190PoE power control + measurements
5V PoE splitter (USB-C)215Power PiKVM + DUT
3-port USB hub15Any basic hub
USB flash drive (16 GB)110Image storage
Raspberry Pi 4250One for PiKVM, one as DUT
MicroSD card (16 GB+)110PiKVM image
Geekwork PiKVM kit185PiKVM hardware
USB webcam (UVC)170Bench visibility
Tasmota WiFi smart socket110Power control (alt to PoE)
USB-TTL serial adapter115Serial console
Sinilink XY-WSUSB dongle18USB power cycle (Tasmota)
SDWire (SD card mux)190Virtual SD card swapping

Firmware and services

  • Custom OpenWrt image for GL-MT300N-V2
  • Port forwarding for PiKVM, PoE switch, camera, and smart plugs
  • SSH access for scripted automation
  • Utilities: screen, ntgrrc, SDWire scripts

Setup steps

  1. Flash the Remote-Kit firmware to the GL-MT300N-V2 (source on GitHub).
  2. Connect your PC to the LAN side and log in to http://192.168.20.1.
  3. Connect WiFi accessories (smart socket, XY-WSUSB) to SSID remote-kit-000 (key: remote-kit-000).
  4. Wire PoE switch, PiKVM, SDWire, and camera to the LAN ports.
  5. Change the default GS308EP password from password to something secure.
  6. Update port-forwards in OpenWrt to match your device IPs.

The firmware ships with these default port-forward rules (all via the router's LAN IP):

Service Port
OpenWrt UI80
USB webcam8080
PoE switch (GS308EP)8081
PiKVM4433
Nous smart socket8082
XY-WSUSB dongle8083
Remote-Kit setup diagram: pocket router controlling PoE switch, PiKVM, SDWire, webcam, and DUT

Setup diagram for overwriting OEM firmware and wiring up the Remote-Kit router.

Access points: OpenWrt UI on http://remote-kit-000, PiKVM on https://remote-kit-000:4433, PoE switch on http://remote-kit-000:8081.

Common remote workflows

1) Load a new SD image onto the DUT

ssh root@remote-kit-000  #pw: remote-kit-000
root@remote-kit-000:~# wget -O /mnt/sda1/libreelec-image.img.gz https://releases.libreelec.tv/LibreELEC-RPi4.aarch64-11.95.1.img.gz
root@remote-kit-000:~# ntgrrc login --password Remotekit000 --address GS308EP
root@remote-kit-000:~# ntgrrc poe set -p 1 --power disable --address GS308EP
root@remote-kit-000:~# sd-wire-load-image.sh /mnt/sda1/libreelec-image.img.gz
root@remote-kit-000:~# ntgrrc login --password Remotekit000 --address GS308EP
root@remote-kit-000:~# ntgrrc poe set -p 1 --power enable --address GS308EP
root@remote-kit-000:~# #LibreElec will now boot on Pi-4-DUT - you can see this booting from a remote location using PiKVM's WebUI.

2) Power cycle the DUT (PoE)

ssh root@remote-kit-000  #pw: remote-kit-000
ntgrrc login --password Remotekit000 --address GS308EP
ntgrrc poe set -p 1 --power disable --address GS308EP
ntgrrc poe set -p 1 --power enable --address GS308EP

3) Open serial console

ssh root@remote-kit-000  #pw: remote-kit-000
screen -R serial /dev/ttyUSB0 115200

4) Simulate Ethernet cable unplug

ssh root@remote-kit-000  #pw: remote-kit-000
ntgrrc login --password Remotekit000 --address GS308EP
ntgrrc port set -p 1 -s 'Disable' --address GS308EP  #unplug
ntgrrc port set -p 1 -s 'Auto' --address GS308EP     #plug

5) Measure PoE power draw

ssh root@remote-kit-000  #pw: remote-kit-000
ntgrrc login --password Remotekit000 --address GS308EP
ntgrrc poe status --address GS308EP       #print status in table format
ntgrrc poe status --address GS308EP -f json  #print in json format

Large images: The router has limited RAM — do not decompress multi-GB images on it. For large files (e.g. raspios-bookworm-arm64.img.xz at 2.4 GB): decompress on your PC first, then scp the raw .img to /mnt/sda1/, and run sd-wire-load-image.sh.

Use cases

  • Remote OS image testing for embedded boards
  • Regression testing of bootloaders and kernels
  • Remote lab access for distributed teams
  • Automated power and peripheral cycling in CI pipelines

Saturday, January 31, 2026

CAN Bus Multi-Sensor Node with ESP32 and KiCad PCB

Ambient Light + Air Quality + More — a reliable, low-cost sensor network for home, lab, and in-vehicle prototypes, built around CAN with OTA updates and multi-node management.

Last updated: February 3, 2026

Why CAN for sensors?

CAN was designed for noisy, distributed environments and it shines when you want dependable, multi-drop communication over long cables. That makes it a strong backbone not only for vehicles, but also for home automation and lab setups where Wi-Fi can be unreliable or too power-hungry.

This project builds a CAN-based sensor node and a companion display client that together provide:

  • Ambient light, temperature, humidity, pressure, IAQ, CO₂eq, VOC
  • Multi-node addressing (up to 16 nodes on the same bus)
  • OTA firmware updates over CAN (~3.3 KB/s)
  • Device management and automated sanity testing with a CLI tool

System overview

The system has three pieces:

  1. Sensor nodes — ESP32-C3 + ALS + BME680/BME688 + CAN transceiver
  2. Monitor/display node — ESP32-C3 + OLED + CAN transceiver
  3. Host toolcan-sensor-tool for monitoring, management, and OTA (Linux / SocketCAN)

All nodes communicate at 500 kbps over a standard CAN bus.

CAN-based sensor setup diagram

System overview: sensor nodes + monitor node + CAN-USB adapter + RJ-11 junction board.

Hardware design

Core components

  • ESP32-C3 SuperMini (~$2 board)
  • SN65HVD230 CAN transceiver (3.3 V native — no level-shifting needed)
  • ALS sensor: VEML7700 or OPT3001 (board footprint supports either; mount only one)
  • BME680/BME688 for temperature, humidity, pressure, and IAQ data
  • On-board buck converter: 6–30 V input (12 V typical), generates stable 5 V / 3.3 V locally

Power-over-CAN using 6P4C (RJ-11)
The system uses a two-pair telephone cable: one pair for CAN-H / CAN-L, one pair for power. Simple, low-cost, and practical. Tested reliably to 15 m with standard RJ-11 cables.

RJ-11 junction board

RJ-11 junction board — low-cost two-pair power + CAN distribution. This is a ready-made off-the-shelf board available from common electronics marketplaces.

Sensor board

Sensor board photo

Sensor board: ESP32-C3, ALS footprint, BME680, SN65HVD230 transceiver, buck converter, and RJ-11 connector.

Sensor board 3D render

3D render of the sensor board PCB.

Sensor board sub-modules

Sensor board sub-modules: base PCB with ESP32-C3 SuperMini, SN65HVD230 CAN transceiver, BME680 environmental sensor, VEML7700/OPT3001 ALS, buck converter, and RJ-11 connector.

Monitor board

Monitor board with OLED showing live data

Monitor board with OLED display showing live values: 22 lux, 25.9 °C, 32 % RH, 989 hPa, IAQ 51 (Good).

Monitor board 3D render

3D render of the monitor board PCB.

Monitor board sub-modules

Monitor board sub-modules: base PCB with ESP32-C3 SuperMini, SN65HVD230 CAN transceiver, SSD1306 OLED display, buck converter, and RJ-11 connector.

Sensor auto-detection (one firmware, many boards)

The sensor firmware auto-detects what's connected at boot:

  • ALS: VEML7700 (0–120 K lux) or OPT3001 (0–83 K lux)
  • Environmental: BME680 or BME688

A single firmware image works across all hardware variants — no build-time configuration needed.

CAN architecture (high-level)

Each node gets 32 CAN message IDs (0x20 spacing):

  • 0x100–0x10F: sensor data for Node 0 (ALS at +0x00, ENV at +0x01, AIQ at +0x02, …)
  • 0x110–0x11F: control/management for Node 0 (stop, start, reboot, OTA, discovery, …)

The same layout repeats at +0x20 per node, supporting up to 16 nodes on a single bus. Reserved offsets are available for future sensor types (gas selectivity, mm-wave presence, etc.).

Full frame layouts and byte-level formats are documented in the repo README.

Real measurements (sample log)

Below is a snippet captured with can-sensor-tool monitor:

[Node 0] ALS (OPT3001): 79 lux, seq=13, config=201, status=OK
[Node 0] ENV: 24.83°C, 38% RH, 991.2 hPa, status=OK
[Node 0] AIQ: IAQ=50 (Good), accuracy=0, CO2=500 ppm, VOC=0 ppm, status=OK
...
[Node 0] ALS (OPT3001): 192 lux, seq=20, config=203, status=OK
[Node 0] ENV: 25.09°C, 36% RH, 991.2 hPa, status=OK
[Node 0] AIQ: IAQ=50 (Good), accuracy=0, CO2=500 ppm, VOC=0 ppm, status=OK
...
[Node 0] ALS (OPT3001): 0 lux, seq=24, config=200, status=OK
[Node 0] ENV: 25.15°C, 35% RH, 991.2 hPa, status=OK

Over this run, light levels ranged from 0 (near-dark) to ~192 lux while temperature stayed around 25 °C. IAQ reported "Good" with CO₂eq at 500 ppm throughout.

Automated sanity testing

The can-sensor-tool includes a sanity-test command that exercises the full node lifecycle in one shot — discovery, start/stop, interval accuracy, reboot, node-ID change, factory reset, OTA update, and final re-discovery:

$ can-sensor-tool sanity-test ./build/esp32-can-sensor.bin

[1/9] Discovery...         PASS: Node 0 responds to PING
[2/9] Device Info...       PASS: FW v1.0.1, sensors=0x13, ALS=OPT3001, partition=ota_1 (valid)
[3/9] Start/Stop...        PASS: Received 3 ALS msgs in 3s, 0 after STOP
[4/9] Monitor Interval...  PASS: Average interval: 977 ms (target: 1000 ms)
[5/9] Reboot...            PASS: Node rebooted and recovered in 2005 ms
[6/9] Set Node ID...       PASS: Successfully changed 0->1->0
[7/9] Factory Reset...     PASS: Factory reset completed in 2204 ms
[8/9] OTA Update...        PASS: OTA OK, node booted v1.0.1 on ota_0 (3.2 KB/s, 106369 ms)
[9/9] Final Discovery...   PASS: Node 0 still responds after all tests

Results: 9/9 passed, 0 failed

This makes it practical to validate firmware changes end-to-end before deploying to multiple nodes.

Device management + OTA over CAN

The can-sensor-tool handles discovery, monitoring, and A/B OTA firmware updates over the CAN bus.

The ESP32 uses an A/B partition scheme: each OTA update writes to the inactive slot, reboots into it, and keeps the previous slot as a rollback target. If the new firmware fails to validate on first boot, the bootloader automatically reverts.

In testing, OTA reached ~3.2–3.3 KB/s, and a ~345 KB firmware image completed in ~106 seconds. This makes it feasible to update multiple nodes on a live bus without physical access.

Use cases

Home & Lab

  • Multi-room light + environment monitoring
  • Low-cost wiring with RJ-11 and a junction board
  • Central monitoring on OLED or a PC via SocketCAN

In-vehicle prototype (POC)

  • Rugged wiring and noise-tolerant communication
  • Deterministic update rates across multiple nodes
  • OTA updates without pulling nodes from the vehicle

In-vehicle smart ambient sensing

  • Monitor cabin temperature, humidity, IAQ, CO₂eq, VOC, and BME688-based gas signals for passenger comfort and safety
  • Feed IVI/ADAS systems with real-time ambient conditions for alerts or policy decisions
  • Use ambient light data to adjust in-vehicle displays — HDR10+ Adaptive and Dolby Vision perform real-time dynamic tone-mapping that requires a continuous ambient light input to optimize frame rendering on the display (the HDR10+ Automotive spec mandates this ambient light feed)
  • Add human presence detection (planned) to enable occupancy-aware safety and convenience features

Enterprise / larger infrastructure

  • CAN as a reliable wired sensor backbone
  • Up to 16 nodes per bus today; extendable with multiple bus segments

Current limitations and roadmap

Current

  • No formal environmental or long-term reliability testing yet
  • Human presence detection (mmWave) not implemented

Planned

  • Add mmWave human presence sensor
  • Expand other sensor types using reserved CAN offsets

BSEC licensing note

BME680/BME688 air-quality outputs use Bosch Sensortec's BSEC 2.x library, which is proprietary and not included in this repo. To enable it, download the BSEC zip from Bosch, accept their license, and pass it to build.sh (see BME680_SETUP.md in the repo).

Build and flash (sensor board)

  1. Install ESP-IDF and download the Bosch BSEC library (e.g. bsec2-6-1-0_generic_release_22102024.zip).
  2. Connect the ESP32-C3 board to your PC via USB.
  3. Clone the sensor firmware repo and build:
git clone https://github.com/hackboxguy/Esp32-CAN-ALS.git
cd Esp32-CAN-ALS
./build.sh --target=esp32c3 --idfpath=$HOME/esp/esp-idf/ \
           --version=1.0.1 \
           --bsecpath=/path/to/bsec2-6-1-0_generic_release_22102024.zip
./build.sh --flash

Build and flash (monitor board)

  1. Install ESP-IDF.
  2. Connect the ESP32-C3 board to your PC via USB.
  3. Clone the display client repo and build:
git clone https://github.com/hackboxguy/Esp32-CAN-Disp-Client.git
cd Esp32-CAN-Disp-Client
idf.py set-target esp32c3
idf.py build flash

SOURCE CODE

github.com/hackboxguy/Esp32-CAN-ALS — sensor node firmware + can-sensor-tool

github.com/hackboxguy/Esp32-CAN-Disp-Client — OLED monitor client firmware

KICAD PCB FILES

CAN-Sensor-Board.zip — sensor board KiCad project + gerbers

CAN-Monitor-Board.zip — monitor board KiCad project + gerbers