Lars Oberhofer
← All work

T1

Voice terminal · 2026

Enclosure / Electronics / Backend software

A voice terminal designed around one dial.

There is no screen, only one dial, one light and a speaker.

T1 assembled: a small white rounded box with a round aluminium grille, one dial and one small light

Left and right arrow keys turn T1. Tab to the seam; Enter lifts or lowers the lid.

T1, assembled. T1’s CAD and board models, with simplified materials.

The enclosure

61 × 55 × 24.5 mm. The board and battery set the footprint.

The form follows the Braun T3 pocket radio, which also gets by with a round grille and a dial. The body is a rounded rectangle like the T3’s, which also suits a rectangular battery.

What you say goes to a backend, and the reply is designed to stream back to the speaker.

My workEnclosure, electronics and backend software. I generate the schematic from one manifest and route the board by hand.

DeviceESP32-S3 · TLV320AIC3100 codec with speaker amplifier · ICS-43434 digital microphone · rotary encoder with push · one LED · USB-C · headphone jack

Decision / No wake word

Hold the dial to talk.
Let go to finish.

T1 uses push-to-talk and has no wake word.

An always-listening device has to cancel the echo of its own speaker, because the microphone hears it whenever you interrupt. Push-to-talk turns playback down while you speak, so T1 needs no echo cancellation. By the design brief’s rough estimates, it also gets about three times the battery life of a wake word.

It listens only while the dial is held, and that is the firmware’s job: the microphone stays powered, because it shares its clock lines with the speaker, and a switched-off microphone would have those pins driven whenever T1 spoke.

Letting go marks the end of speech, so the device never has to detect when you stop talking.

One light carries every state

Off
Nothing to say
Slow breathe
Something is waiting
Two blinks every ten seconds
Battery low
Dim
Charging
Bright
Listening

With no screen, a device in setup mode looks the same as a dead one, so in the setup design T1 speaks its address.

T1 from the front: the dial on the left of the top, the grille on the right, and the small light in the front wall below the dial

Messages T1 would send

TalkStart { utterance_id: 1 }
TalkEnd { utterance_id: 1, frames_sent: 75 }

An example hold of 1.5 seconds: 75 audio frames of 20 ms between the two messages.

Render from T1’s CAD model, with the light off and, while the dial is held, on. The message names and the 20 ms audio frames are from T1’s protocol, version 1. This page asks for no microphone, records nothing and sends nothing.

Build / Board and case

Inside the case.

An ESP32-S3 with one TLV320AIC3100 chip that drives both the headphones and the speaker, and a digital microphone wired straight to the ESP32. Brailly needed three audio chips for the same outputs.

The board is 56 × 50 mm with four layers. The schematic is generated from one manifest and checked by an independent netlist audit: 317 pin connections, no errors. The audit shows that the design is consistent, not that it works.

Case
61 × 55 × 24.5 mm, 31.1 mm with the dial
Shell
PETG, with an aluminium grille of 223 holes
Weight
116 g, estimated, with a brass ballast plate under the cell
Tools
KiCad, and Python scripts for the schematic and the audits
Section through T1 at the USB-C port, showing the board, the battery and the case walls
Render cut through the USB-C port: the board, the battery and the case walls.
The assembled T1 board with the dial encoder, ESP32-S3 module and audio parts
Render of the board: the dial’s encoder, the ESP32-S3 and the audio parts on 56 × 50 mm.
T1 from above: the dial and the round grille
Render from above: the dial and the grille. The light is in the front wall, under the dial.
T1 from the back with USB-C and headphone cables plugged in
Render from the back: USB-C and the headphone jack.

Software / Bun and TypeScript

Testing the audio transport.

The first run, with a fake device and an echo pipeline in place of speech recognition and speech, returned 36,225 audio samples where 36,000 were sent, although every unit test passed.

A buffer slice was a view, not a copy, and added a 50 Hz click to every utterance. A test now counts the samples over the real connection, and five runs out of five return exactly 36,000.

The backend speaks protobuf messages over WebSocket; its 36 tests cover the transport. Speech recognition, the assistant and speech output are defined as interfaces, not yet connected.

Sources: T1’s design brief and mechanical notes, the board’s design manifest and hardware work status, and the software’s requirements, protocol and work status (reconciled 24 September 2026); none is public. Every picture of T1 on this page is a render.