Ever wanted a sleek, external display showing your PC’s vitals—OS, RAM usage, CPU load, and more? This project turns that idea into reality using the ultra-compact LattePanda Mu as the data source and the Beetle ESP32-C3 as the display driver. The result? A modular, real-time PC telemetry dashboard housed in a custom 3D-printed case by JUSTWAY.
🔧 Project Overview- PC Telemetry Source: LattePanda Mu runs Windows and collects system stats (OS, RAM, CPU, etc.) via Python.
- Data Transmission: Stats are sent over UART to the Beetle ESP32-C3.
- Display Output: ESP32-C3 parses the data and renders it on an I2C TFT display.
- Enclosure: JUSTWAY 3D printed the custom case for a polished, desk-friendly finish.
UART: LattePanda Mu → Beetle ESP32-C3
- TX (Mu) → RX (ESP32-C3 GPIO20)
- RX (Mu) → TX (ESP32-C3 GPIO20)
- GND (Mu) → GND (ESP32-C3)
Ensure baud rate is matched (e.g., 9600) and both devices share a common ground.
I2C TFT Display: Beetle ESP32-C3
- SDA → GPIO21
- SCL → GPIO22
- VCC → 3.3V
- GND → GND
For this build, I partnered with JUSTWAY, a trusted name in precision 3D printing and rapid prototyping. Their services helped bring the enclosure design to life with clean lines, accurate tolerances, and a professional finish that complements the tech inside.
🔍 About JUSTWAYJUSTWAY offers a wide range of manufacturing services including.
- FDM, SLA, and SLS 3D printing
- CNC machining and injection molding
- Rapid quoting and global shipping
Their platform is maker-friendly, with intuitive file uploads, material selection, and instant pricing. Whether you're prototyping a sensor module or finalizing a product enclosure, JUSTWAY delivers consistent quality and speed.
My Experience- Material Used: Matte black PLA (FDM)
- Finish: Smooth surface with crisp cutouts for the LattePanda Mu
- Fit & Accuracy: Excellent—no post-processing needed
- Support: Their team flagged a minor tolerance issue and suggested a fix before printing
JUSTWAY’s intuitive quoting tool and fast production cycle make them ideal for makers and professionals alike. You can explore their services on JUSTWAY’s official site or read a detailed review on 3D Print Beginner.
The LattePanda Mu runs Windows, making it ideal for collecting system telemetry using Python. I used the psutil
and platform
libraries to extract OS details, RAM usage, CPU load, and more.
import psutil
import platform
import socket
import time
import serial
import json
from datetime import datetime
# Serial config
PORT = "COM17"
BAUD = 9600
# Helper: Format bytes
def get_size(bytes, suffix="B"):
factor = 1024
for unit in ["", "K", "M", "G", "T"]:
if bytes < factor:
return f"{bytes:.2f}{unit}{suffix}"
bytes /= factor
try:
ser = serial.Serial(PORT, BAUD, timeout=1)
time.sleep(2) # Wait for ESP32 reset
print(f"✅ Connected to {PORT} at {BAUD} baud.")
print("📡 Sending JSON system stats every second...\n")
while True:
# System info
uname = platform.uname()
boot_time = datetime.fromtimestamp(psutil.boot_time()).strftime("%Y-%m-%d %H:%M:%S")
cpu = psutil.cpu_percent()
ram = psutil.virtual_memory()
disk = psutil.disk_usage('/')
# Network info
ip = mac = "N/A"
for iface, addrs in psutil.net_if_addrs().items():
for addr in addrs:
if addr.family == socket.AF_INET:
ip = addr.address
elif hasattr(addr.family, 'name') and addr.family.name == 'AF_LINK':
mac = addr.address
# Build JSON object
data = {
"host": uname.node,
"os": f"{uname.system} {uname.release}",
"boot_time": boot_time,
"cpu_percent": cpu,
"ram": {
"used": get_size(ram.used),
"total": get_size(ram.total),
"percent": ram.percent
},
"disk": {
"used": get_size(disk.used),
"total": get_size(disk.total),
"percent": disk.percent
},
"network": {
"ip": ip,
"mac": mac
}
}
# Serialize and send
json_data = json.dumps(data) + "\n"
ser.write(json_data.encode('utf-8'))
print("Sent:\n" + json_data)
time.sleep(5)
except serial.SerialException as e:
print(f"❌ Serial error: {e}")
except KeyboardInterrupt:
print("\n🛑 Transmission stopped by user.")
ser.close()
- Output Format: JSON string over UART
- Baud Rate: 9600
- Interval: 2 seconds (adjustable)
This script runs as a background service and streams telemetry to the Beetle ESP32-C3 via UART.
PC ResponseHere is the output from the system that gives the system details.
The ESP32-C3 receives the JSON string, parses it, and displays the data on an I2C TFT screen. Here's a simplified version of the Arduino sketch:
🧠 Arduino Sketch (Core Logic)#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Arduino_JSON.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
void setup() {
Serial.begin(115200);
Serial1.begin(9600, SERIAL_8N1, 20, 21); // RX=20, TX=21
Serial.println("Serial1 ready");
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println("OLED init failed");
while (true);
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.println("Waiting for JSON...");
display.display();
}
void loop() {
if (Serial1.available()) {
String msg = Serial1.readStringUntil('\n');
Serial.print("Received via Serial1: ");
Serial.println(msg);
JSONVar data = JSON.parse(msg);
if (JSON.typeof(data) == "undefined") {
Serial.println("JSON parsing failed");
return;
}
// Extract fields
String host = (const char*)data["host"];
String os = (const char*)data["os"];
String boot = (const char*)data["boot_time"];
double cpu = double(data["cpu_percent"]);
String ramUsed = (const char*)data["ram"]["used"];
String ramTotal = (const char*)data["ram"]["total"];
double ramPct = double(data["ram"]["percent"]);
String ip = (const char*)data["network"]["ip"];
String mac = (const char*)data["network"]["mac"];
// Display everything on one page
display.clearDisplay();
display.setCursor(0, 0);
display.setTextSize(1);
display.println(host);
display.println(os);
display.print("CPU: "); display.print(cpu); display.println("%");
display.print("RAM: "); display.print(ramUsed); display.print("/"); display.print(ramTotal);
display.print(" ("); display.print(ramPct); display.println("%)");
display.print("IP: "); display.println(ip);
display.print("MAC: "); display.println(mac);
display.display();
delay(5000); // Show for 5 seconds before checking again
}
}
🔧 Notes- Uses
ArduinoJson
for parsing - Compatible with DFRobot’s Gravity TFT or similar I2C/GDI displays
- Modular for adding more metrics (e.g., memory, uptime)
To test the system, I have used DFRobot, Rainbow Link to check the system here is the response.
This is before the system got the data.
This is the system response, once it got the data.
Here is the final test setup on the LattePanda Mu.
After the assembly
This project blends embedded design, PC telemetry, and desktop aesthetics into one modular build. Using the LattePanda Mu as a telemetry source and the Beetle ESP32-C3 as a display driver, I created a real-time system monitor that’s:
- Portable: Small enough to sit beside your keyboard or mount on a wall
- Modular: Easily upgradable with new metrics or display types
- Community-Friendly: Built with open-source tools and documented for remixing
Special thanks to JUSTWAY for the precision 3D printing and to DFRobot for reliable display hardware. STL files, wiring diagrams, and code will be available in the attachments section.
Comments