DBDelve
Dive deep into your data. A fast, native, multi-engine database client written in Rust. Free and open source, no telemetry.
A Commodore PET-style desk terminal on an ESP32-C6: clock, weather, Home Assistant, two configurable keys.
Translation pending
Developer toolsC++GitHub @Krasnov777OnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
A Commodore PET-style desk terminal on an ESP32-C6: clock, weather, Home Assistant and two configurable keys on a 128x64 OLED — BASIC boot, tape-loading weather, 10 PRINT screensaver.
Translation pending
Loading the full README.
Read the full README ↗A Commodore PET–style desk terminal on an ESP32-C6. A clock, the weather, your
Home Assistant lights — and two keys that do whatever you tell them to. It boots
into BASIC, loads the weather from tape, and fills the screen with 10 PRINT
when you leave it alone.
Project page · Quick start · Wiring · 3D-printable case on Printables
READY. prompt, a live program LISTing, Home Assistant, and system status.PRESS PLAY ON TAPE sequence
around every weather fetch, CRT wipes and a power-off collapse on the OLED,
and a web page with scanlines and phosphor glow.The centre key steps through them; pick which ones on the web page.
Every weather refresh is loaded from "tape" — then RUN prints the reading:
Screen changes get a scan-line wipe or a vertical-hold roll, and at night the picture collapses to a line and a dot like a CRT switching off. All of it can be turned off.
Everything is set from http://pet-pc.local/ — no app, no reflashing. The page
is a single file in the firmware, so it also works over the device's own hotspot.
Every setting explains itself. Save stays disabled until the settings have
loaded, only what you changed is sent (and marked until saved), bad values are
flagged before sending — ?SYNTAX ERROR — and changes that would drop the
connection ask first. Green, amber or white phosphor; CRT effects can be
switched off.
| Part | Notes |
|---|---|
| Waveshare ESP32-C6-Zero | ESP32-C6, 4 MB flash, native USB-C for flashing and serial |
| SSD1306 128×64 I²C OLED (0.96″) | the common 4-pin module, address 0x3C, powered from 3.3 V. Yellow/blue two-colour panels work too: turn on Two-colour panel under Display |
| 3 × MX-style key switches | clicky or tactile suit it best — the switch is the only click there is |
| A PET-style case | the 3D-printable case on Printables (print-ready 3MF + build guide), or any box with three 14 × 14 mm switch cutouts |
No resistors, diodes or matrix: each switch goes from a GPIO to ground and the firmware turns on the internal pull-ups. The OLED lands on four consecutive header pins, so one straight 4-wire ribbon connects it.
| Signal | Pin |
|---|---|
| OLED SCL / SDA | GP0 / GP1 (next to GND and 3V3) |
| Left / centre / right key | GP18 / GP19 / GP20 |
Pin map, wiring diagram, the one-GND workaround and assembly tips:
WIRING.md. A different pin is a one-line change in
board_config.h.
You need PlatformIO Core 6.2 or newer (or the VS Code extension) and a USB-C data cable.
git clone https://github.com/Krasnov777/esp32-pet-pc.git
cd esp32-pet-pc/firmware
pio run -t upload # first build downloads the toolchain; then flashes over USB-C
pio device monitor # optional: the boot log, 115200 baud, same cable
If the board does not show up as a serial port: hold BOOT, tap RST, release BOOT, and upload again.
First boot. With no WiFi configured, PET-PC opens an open hotspot called
PET-PC-XXXX (the name is on the screen).
If PET-PC cannot join the network — wrong password, or the router still booting after a power cut — the hotspot comes back, and while nobody is connected to it PET-PC retries your network every five minutes.
cp src/secrets.h.example src/secrets.h # optionally set WIFI_SSID / WIFI_PASSWORD, then build and upload
secrets.h is git-ignored. Its WiFi values only seed the first boot; after
that, settings live on the device and are edited from the web page.
src/secrets.h is required. The build fails without it, because it holds
the OTA password and the web UI login (WEB_USER / WEB_PASSWORD, HTTP Basic
auth on every page and /api/* route). Copy src/secrets.h.example and set
long random values.
pio run -e ota -t upload --upload-port <device-ip>
The OTA password is OTA_PASSWORD from secrets.h; platformio.ini reads it
from the environment: export PETPC_OTA_PASSWORD=... before uploading. (Older
builds used the public default pet-pc. Change it if a unit still has that.)
Pass the IP rather than pet-pc.local: espota's .local lookup hangs
on macOS. An upload takes about a minute; settings survive every update.
| Key | Press | Hold (0.8 s) |
|---|---|---|
| Left | your choice | your choice (default: same as press) |
| Centre | next screen · on BASIC: run the next command · on HOME: pick the next switch | refresh the weather · on BASIC: leave · on HOME: toggle the picked switch |
| Right | your choice | your choice (default: same as press) |
The centre key is fixed, so the box always navigates the same way. The outer keys can:
| Action | For example |
|---|---|
| Send an HTTP request (POST or GET, http or https) | an ESPHome button (http://desk.local/button/desk_up/press), a Node-RED / n8n flow, an HA webhook |
| Show a screen | hold left → HOME |
| Next / previous screen | the out-of-the-box setting |
| Refresh the weather | |
| Toggle a Home Assistant entity | light.desk_lamp |
| Run a Home Assistant action | an automation, scene or script, light.turn_off, input_select.select_next (cycle through modes): see below |
Running a Home Assistant action. The key sends HA two things: the Action, which is what to do, and the optional Entity, which is what to do it to. HA lists automations and scenes as entities, so their IDs go in Entity, under the action that runs them:
| To run | Action | Entity |
|---|---|---|
| an automation | automation.trigger | automation.night_lights |
| a scene | scene.turn_on | scene.movie_time |
| a script | script.night_mode (or script.turn_on) | (empty, or script.night_mode) |
| a built-in action | light.turn_off, cover.open_cover… | light.desk_lamp |
| cycle a selector | input_select.select_next | input_select.house_mode |
automation.night_lights in the Action box does nothing: HA has no action by
that name and answers with an error, so the key shows "failed". The Keys tab
flags it before you save. Only entity_id is sent, no other data, so for a
brightness, colour or anything else with options, wrap it in a script and run
the script.
Anything that goes to the network shows "sending…" on the screen, then the result.
http://homeassistant.local:8123; https:// works too), the token, and up to
six entities. Save, then Test connection.Each entity is a Value — shown as HA reports it, with its unit (21.4C,
612 ppm) — or a Switch — ON/OFF, picked with a centre press and
toggled with a centre hold. The type is suggested from the entity's domain
(light., switch., fan., input_boolean., automation., cover. are
switches); change it to watch a light without being able to toggle it.
PET-PC reads one entity at a time, so each request is small; a full round takes 30 s by default, about one entity a second while HOME is on screen. If HA is down or refuses the token, the screen says so and PET-PC backs off for a minute.
The token is write-only: the page never shows it again, a blank field keeps it, and changing the URL clears it — so it is never sent to a server it was not entered for.
The page uses a small JSON API, open to your own scripts too. Every route needs
the web login (HTTP Basic, WEB_USER / WEB_PASSWORD from secrets.h):
| Method | Path | |
|---|---|---|
GET | /api/state | settings and live status (the WiFi password and HA token are never included) |
POST | /api/settings | a JSON patch in the same shape — only the keys you send change |
POST | /api/key?key=left|center|right&hold=0|1 | press or hold a key |
POST | /api/mode | next screen |
POST | /api/ha/test | test the saved Home Assistant connection |
POST | /api/reboot | restart |
GET | /shot.bmp | the current screen as a 1-bit BMP |
curl -u admin:<pw> -X POST 'http://pet-pc.local/api/key?key=right' # press the right key
curl -u admin:<pw> -X POST -H 'Content-Type: application/json' \
-d '{"display":{"contrast_day":90}}' http://pet-pc.local/api/settings
secrets.h). Requests must be addressed to the device itself (its IP or hostname), and cross-site POSTs are refused. Basic
auth travels in clear text over plain HTTP, so it keeps out casual LAN
clients, not someone sniffing your network. The WiFi password and HA token
are never sent back by the API.OTA_PASSWORD from secrets.h; there is no default.PlatformIO and the pioarduino ESP32 platform (Arduino core 3.x), U8g2 for the display, ArduinoJson, weather from Open-Meteo (free, no key), and the PxPlus IBM CGA font by VileR standing in for the PET's character ROM. The renders use the Cherry MX switch model from keyswitch-kicad-library (MIT, © keyswitch-kicad-library contributors).
MIT.
PET-PC is an unofficial, independent project. It is not affiliated with, endorsed by or sponsored by Commodore; "PET" is used only to describe the design inspiration, and all trademarks belong to their owners.