Embedded Systems / PC Companion / System Monitoring / Visual Display

Rolez Pocket

Rolez Pocket is a real-time PC system statistics display and visual experience device built for the LilyGO T-Display-S3. It connects to a Windows P...

Rolez Pocket

Category: Embedded Systems / PC Companion / System Monitoring / Visual Display
Platform: LilyGO T-Display-S3 (ESP32-S3) + Windows PC Companion App
Firmware: Arduino via PlatformIO | C++
Companion: Python (Windows system tray application)
Status: Active — Production Ready (v1.0)


Project Overview

Rolez Pocket is a real-time PC system statistics display and visual experience device built for the LilyGO T-Display-S3. It connects to a Windows PC via USB serial and renders a richly animated Neon City graphical scene on its 320x170 display that reacts dynamically to live PC performance metrics — CPU load, GPU usage, RAM usage, disk activity, network throughput, system temperature, volume level, and more.

The project consists of two tightly coupled components:

  1. ESP32-S3 Firmware — "Smart mode" firmware that reads JSON telemetry packets from the USB serial port and renders the Neon City visualisation at ~30fps using a custom sprite-based rendering engine
  2. Windows Companion App — A Python system-tray application that continuously samples Windows system metrics using psutil and LibreHardwareMonitor, serialises them as JSON, and streams them to the device at 10Hz (100ms intervals)

The device also supports a "dumb display" mode where the PC (using a Godot application) renders the entire frame and streams raw RGB565 pixel data directly to the ESP32, which pushes it straight to the display — offloading all rendering to the PC.


Neon City Visual Scene

The Neon City is a custom-designed animated cityscape renderer implemented entirely in the ESP32-S3 firmware. Key characteristics:

  • Rendered into a PSRAM-backed double-buffer sprite (prevents screen tearing)
  • Targets ~30fps (33ms frame budget)
  • Scene components include:
    • Animated neon skyline buildings with glowing windows
    • Dynamic foreground elements (traffic, street-level details)
    • Atmospheric effects (rain, particles, scan lines)
    • System metric visualisations embedded directly in the scene
    • Colour palette driven by the ColorPalette utility module

Scene State System

The SceneState struct holds all current metric values and is updated from the incoming JSON serial stream. The NeonCity renderer reads this state every frame to:

  • Vary visual intensity based on CPU/GPU load
  • Change colour temperature with temperature readings
  • Animate network traffic indicators with throughput data
  • Modulate particle density with disk activity

Demo Mode

If no PC companion is connected for more than 2 seconds, the firmware automatically enters a simulation mode — generating synthetic metric data to keep the scene animated for demonstration purposes.


Windows Companion Application

Architecture

The companion app (rolez_companion.py) runs as a lightweight Windows system tray application built with pystray. It operates a background thread that continuously samples system metrics and writes them to a serial port connected to the T-Display-S3.

Metric Collection

Metric Source Notes
CPU Usage (%) psutil.cpu_percent() Per-call sampling
RAM Usage (%) psutil.virtual_memory() Used / total
Disk Activity psutil.disk_io_counters() Read/write bytes delta
Network Throughput psutil.net_io_counters() Upload/download bytes/s
CPU Temperature LibreHardwareMonitor (LHM) Via subprocess / COM interface
GPU Usage (%) LibreHardwareMonitor (LHM) NVIDIA/AMD GPU load
GPU Temperature LibreHardwareMonitor (LHM) Degrees Celsius
System Volume pycaw (Windows Core Audio) Current output level 0-100%
Notification Count Custom notification listener Background Windows notification tap

Serial Protocol

Metrics are serialised to compact JSON and transmitted at 10Hz (100ms) over USB CDC serial at 115200 baud:

{
  "cpu": 45,
  "ram": 62,
  "disk": 12,
  "net_up": 1024,
  "net_dn": 8192,
  "cpu_temp": 72,
  "gpu": 38,
  "gpu_temp": 65,
  "vol": 75,
  "notif": 2
}

COM Port Management

  • Auto-detects the T-Display-S3 COM port by scanning available serial ports and identifying the device by USB VID/PID
  • Falls back to user-configured port in config.json if auto-detection fails
  • Auto-reconnects if the USB cable is disconnected and reconnected

System Tray Integration

  • Runs minimised to the Windows system tray — no taskbar entry
  • Right-click tray icon provides: Open Config, Refresh Connection, Exit
  • System tray icon pulses/changes colour based on connection state

LibreHardwareMonitor Integration

  • Interfaces with LibreHardwareMonitor (LHM) for temperature and GPU readings
  • LHM path is configurable in config.json (defaults to auto-discovery)
  • Gracefully degrades to 0 values if LHM is unavailable

Build / Packaging

  • build.bat script packages the companion into a standalone Windows executable using PyInstaller
  • Distributable .exe requires no Python installation on the target machine

Firmware Architecture

Smart Mode (Default)

USB Serial (JSON @ 10Hz)
    └── SerialProtocol.poll() → SceneState update
            └── SceneState.updateDerived() → derived animations/transitions
                    └── NeonCity.drawFrame() → sprite render → TFT push

Dumb Display Mode (Alternative)

USB Serial (raw RGB565 stream)
    └── Dumb firmware receiver → pushes bytes directly to ST7789

Both firmware modes are supported in the same PlatformIO project via separate build environments:

  • env:rolez-pocket — Smart mode (JSON protocol, ESP32 renders)
  • env:rolez-pocket-dumb — Dumb mode (PC renders, streams raw pixels)

Technical Architecture

Firmware

Component Detail
MCU ESP32-S3 @ 240 MHz
Display ST7789 1.9" IPS — 320x170 pixels (landscape)
Display Library TFT_eSPI
Render Buffer PSRAM-backed TFT_eSprite (double buffer)
Serial Protocol USB-CDC at 115200 baud, JSON framing
JSON ArduinoJson v7.3.1 — streaming deserializer
Target Frame Rate ~30fps (33ms frame budget)
Memory 16MB Flash / 8MB OPI PSRAM

Companion App

Component Detail
Language Python 3
Metrics psutil — CPU, RAM, Disk, Network
Hardware Temps LibreHardwareMonitor (external process)
Audio pycaw — Windows Core Audio API
Serial pyserial — USB CDC serial output
System Tray pystray + Pillow
Notifications Custom Windows notification listener
Packaging PyInstaller (standalone .exe)

Configuration

companion/config.json:

{
  "com_port": "auto",
  "brightness": 255,
  "lhm_path": "auto"
}
Key Description
com_port "auto" for auto-detection, or explicit "COM12"
brightness TFT brightness value 0-255
lhm_path Path to LibreHardwareMonitor.exe, or "auto"

Use Cases

  • Gaming rig secondary display showing real-time PC performance
  • Developer workstation ambient system monitor
  • Streaming setup hardware monitor (CPU, GPU, RAM visible at a glance)
  • Desktop art piece — visually appealing animated scene driven by real system data
  • Hardware enthusiast project combining PC telemetry with embedded art
Return to Projects