Windows software for the Turing Smart Screen 3.5" (TURZX) USB display.
Animated themes, a layout editor, real CPU and GPU temperatures and screens for Claude Code and Spotify, without the 1 fps.
Note
Ember is vibe-coded. The code was written by Claude Opus 5.5, Anthropic's AI model, working from my prompts. I directed the project, tested every build on a real screen and decided what went in. More in How this was built.
The little 3.5" screens sold as Turing Smart Screen, TURZX or USB35INCHIPSV2 come with an app that updates about once a second. Ember runs in the tray, starts with Windows and keeps the screen moving: gauges sweep, the network graph runs like a scope trace and the seconds flow, for about 0.3% of the CPU.
- Download
Ember-Setup-x.y.z.exefrom Releases. - Run it. Ember ships with its own .NET runtime, so there is nothing else to install. It goes into the Start menu and starts with Windows.
- Leave Install the PawnIO driver ticked if you want CPU temperature (see Sensors).
The installer isn't code-signed yet, so SmartScreen may say "Windows protected your PC". Click More info, then Run anyway. Uninstall it from Settings > Apps like anything else. Your own themes stay in %APPDATA%\Ember.
Windows 10 (version 2004 or newer) or 11, 64-bit.
Which screen. Ember talks to the Turing Smart Screen 3.5" revision A: USB ID 1a86:5722, shows up as a COM port, sold under the Turing and TURZX names. The 2.1", 5" and 8.8" models and the XuanFang revision B speak other protocols and don't work yet. Close the vendor app first, only one program can hold the port.
Nine come built in. Every one of them was tuned against the link budget described below, so they stay smooth on the real panel, not only in screenshots.
Got one of your own? Post it in Share your themes.
![]() |
![]() |
Turn them on under Apps. While Claude Code (or the Claude app) is open or music is playing, the panel shows the theme for 15 seconds, then each app screen for 10, fading through black between them. Both times can be changed, and a global shortcut steps theme > Claude > Spotify > theme by hand, with or without the automatic switching. The app screens take the background, font and colours of whatever theme is on.
- Claude Code reads Claude Code's own session logs in
~/.claude/projects: cost and tokens in the current five-hour session and when it resets, today, and the month at API prices next to the price of your plan. Once you have hit a limit, the logs say when that session ended and roughly how much it held, which gives an estimate of how much of the limit is used. Nothing is sent anywhere and no credentials are read. Usage on claude.ai or the phone shares the limit but isn't in those logs, so treat the limit as an estimate. - Spotify comes from the Windows media controls: the cover, title, artist, album and progress, with the progress bar in the cover's colour.
The same values work in your own themes. The editor's Add list has Music, Cover and Claude blocks, and any text can use keys like {spotify.title}, {spotify.pos:mss} or {claude.block.cost:usd}.
The Screen page mirrors the panel live. From here you switch themes, set brightness and rotation, and see at a glance whether CPU temperature is readable. Turn on Show traffic and the preview tints every part of the screen that is being sent over USB, so you can see what a theme costs while it runs.
The gallery thumbnails run on your own sensor data. Click one to put it on the screen.
The editor is a canvas with layers. Drag things, resize them, let them snap to each other's edges and centres, and change any property on the right. Everything can be undone. Turn on Live on the screen and each change lands on the panel while you make it. Above the canvas, Link shows how much of the USB link the theme needs, simulated in the background after every change; above about 80% animations start to lag. The navigation pane folds to icons while you edit, so the canvas gets the room.
These panels tend to come out blue. Settings > Screen colors has colour temperature, gamma and a gain per channel. Only the panel is corrected, the preview keeps the theme's own colours.
The tray icon has the rest: theme, brightness, turn the screen off, quit. When Windows turns the monitors off or the PC goes to sleep, the panel goes dark too.
The panel's USB link moves about 157 KB/s, whatever baud rate you ask for. A full 480 × 320 frame in RGB565 is 300 KB, so redrawing the whole screen takes almost two seconds.
Both sides run the Ember theme through the same simulated link at 157 KB/s and 30 updates a second, using Ember's own sender. On the right, every update is the whole frame: it crawls down the screen for 1.9 s, so values are two to four seconds old and the digits tear where the new frame meets the old one. Splitting the work into fewer, bigger writes doesn't help either. Measured on the panel, 300 rectangles of 16 × 8 pixels move pixels as fast as one full frame, so all that matters is how many bytes go over.
Ember never redraws the whole screen. Each frame is rendered in memory with SkiaSharp, in under a millisecond, and compared with what the panel already shows in 16 × 8 pixel tiles. Only the rectangles that changed go over the wire, the oldest first, within a budget per frame, so a big change arrives over a few frames instead of freezing everything else. The themes are drawn with that in mind: digits have fixed widths so going from 41 to 42 resends one glyph, gauges move in half-pixel steps, graphs sweep like an oscilloscope instead of scrolling, and the RGB565 dithering uses a fixed pattern so pixels that didn't change stay identical.
On the right, pink marks every pixel that crossed the link during ten seconds of the Ember theme. That is about 88 KB/s, 57% of what the link carries, and the reason the small animations reach 20 to 30 fps.
Ember reads the hardware through LibreHardwareMonitor:
- CPU: load overall and per thread, clock, power, temperature
- GPU (NVIDIA, AMD, Intel): load, temperature, hot spot, memory junction, clocks, power, fan, VRAM
- RAM, the system drive, network upload and download, uptime, time and date
Any other sensor LibreHardwareMonitor finds is available too. The Sensors page lists them all with their keys.
CPU temperature needs administrator rights and the PawnIO driver. Ember starts itself from Task Scheduler with administrator rights, so there is no UAC prompt at logon. PawnIO is the signed driver LibreHardwareMonitor now uses in place of WinRing0, the old driver that many monitoring tools shipped and that antivirus software flags. The installer, or the button on the Screen page, downloads the official PawnIO setup and checks that it is signed by its author before running it.
Ember leaves the riskier parts of LibreHardwareMonitor off: memory SPD over SMBus is never touched and motherboard sensors are opt-in.
Measured on a Ryzen 5 9600X with an RTX 5060 Ti, window closed, default theme:
| CPU | about 0.3% (33 ms of work per second) |
| GPU | 0% |
| Memory | about 70 MB |
| DPC and interrupt time | no measurable change |
With the window open it uses around 2% while it is on screen, most of it for the live preview. Minimised or closed, the window stops drawing.
If you write your own monitoring tool, one thing worth knowing: LibreHardwareMonitor asks NVIDIA for PCIe throughput on every update, two NVML calls that each wait about 30 ms in the driver. Ember switches that off.
The editor is the easy way. Themes are JSON files in %APPDATA%\Ember\themes, so you can also write them by hand and share them with Export and Import.
{
"name": "Mine", "font": "Bahnschrift", "bg": "#0D0C0B",
"palette": { "a1": "#FFB347", "a2": "#FF6A1F", "text": "#EEE8E2", "track": "#2A2623" },
"widgets": [
{ "type": "gauge", "x": 20, "y": 44, "w": 116, "h": 116, "sensor": "cpu.load", "colors": ["a1", "a2"], "glow": 10, "mode": "dot" },
{ "type": "text", "x": 78, "y": 90, "align": "center", "text": "{cpu.temp:0}°", "size": 28, "sensor": "cpu.temp", "warn": 80, "crit": 90 }
]
}Widgets are drawn in order, first at the bottom. Colours are #RGB, #RRGGBB, #RRGGBBAA or a palette name, optionally with an opacity like a1/30. With warn and crit set, the colour shifts smoothly to the palette's warn and crit colours.
| Type | For | Main fields |
|---|---|---|
text |
labels and values | text with {key:format}, font, size, weight, stretch, align, spacing, glow, mode: upper, blink |
gauge |
arcs and rings | sensor, min, max, thickness, start, sweep, segments, gap, mode: dot, flat, ticks, alternate |
bar |
bars | sensor, min, max, radius, segments, gap, mode: vertical |
graph |
history | sensor, points, max (leave out for automatic), mode: sweep, dot, grid, sharp, nofill |
cores |
a bar per CPU thread | sensor is the prefix (cpu.t), gap, radius |
rect, glow, icon, image |
backgrounds, cards, glows, Segoe Fluent icons, pictures | color or colors, angle, radius, stroke, shadow, glyph, src |
Formats inside {}: any .NET number format (0, 0.0), rate (bytes per second as KB/s or MB/s), ratev and rateu (just the number or just the unit), mbit, ghz, mss and hmm (seconds as 3:05), tok (12K, 9.4M), usd ($12.40), and date formats for {time} and {date} (HH:mm, dddd, d MMMM). A text with mode: ellipsis and a width cuts long values with … instead of shrinking them, and an image with src: "@art" shows the cover of what is playing. Text in the built-in themes follows the interface language. Click any row on the Sensors page to copy its key.
Ember picks up theme files as soon as they are saved, so you can also keep one open in a text editor and watch the panel change.
The interface and the built-in themes come in English and Polish (Settings > Language), including day names and decimal separators on the panel. A new language is one dictionary in Strings.cs.
You need the .NET 9 SDK.
git clone https://github.com/cybvlsky/Ember
cd Ember
dotnet run -c Release
A few switches help while working on it:
Ember.exe --selftestchecks the protocol encoding, colour conversion, the diff sender against a virtual panel, the translations and every theme in both languages.Ember.exe --render <folder>writes a PNG of every theme and app screen, its bandwidth heat map, a bandwidth report and the frames of the comparison above.Ember.exe --demoruns on made-up sensor readings.python tools/make-docs.py <Ember.exe>rebuilds the images in this README.
GitHub Actions builds every release from a tag. Add a ## x.y.z section to CHANGELOG.md, commit, then git tag vx.y.z and git push --tags. The workflow runs the self-test, builds a self-contained installer with Inno Setup and publishes the release with that changelog section as its notes.
Ember is vibe-coded. I described what I wanted and Claude Opus 5.5 by Anthropic wrote, debugged and refined the code. My part was directing the project, testing each build on real hardware, measuring performance and deciding how it should look and behave.
To find out how the stock software talks to the display, I also used REA (Reverse Engineer Anything).
I'm not hiding the AI involvement. Ember is open source because the stock software wasn't good enough for me, and I wanted other owners of these little screens to have a better option. What matters to me is that it works, runs light and is useful.
- LibreHardwareMonitor (MPL 2.0) reads the sensors.
- PawnIO by namazso gives it safe access to the CPU.
- SkiaSharp (MIT) draws everything.
- turing-smart-screen-python by mathoudebine documented the panel's protocol.
Ember is not affiliated with Turing or TURZX.


















