voiceql

Speak a data question.
Get a spoken answer in under three seconds.

An Arduino Uno R4 WiFi records your voice, a FastAPI backend runs it through Whisper for transcription and Claude for SQL, queries SQLite, and speaks the result back through the board. Everything below is playable: the database is real and runs in this page.

2.01s
button press to spoken answer
12
rows of live sample data
6
questions it ships with
5
stages in the pipeline
voiceql — live1/12
REC
whisper >
claude >
cycling automatically

00Try it

arduino/VoiceQL.ino + /query/voice

Pick a question, press the button. The state machine, the stage timings and the SQL are the real ones; the answer is whatever SQLite returns right now, in your browser.

ARDUINO UNO R4 WIFI
VoiceQL ready
press the button
68.6 x 53.4mm
0msstate: IDLEautopilot
/query/voice, stage by stage
EchoKit record + POSTclient · 200ms
Whisper transcriptionawaited · 600ms
Claude SQL generationawaited · 800ms
SQLite queryblocks the loop · 10ms
Google TTS synthesisblocks the loop · 400ms
response headers, as the sketch reads them
X-Transcript
X-SQL
X-Summary
X-Row-Count
X-Latency-Ms

01Ask it anything

backend/services/llm.py

Watch the agent work: it reads the schema, writes SQL a token at a time, runs it against the twelve rows, then phrases the answer. Questions cycle on their own; click one to hold it, or edit the SQL and run it.

reading schemagenerating SQLexecutingsummarising
you > What is the total revenue this year?
the SQL it writes
cycling
running against SQLite...
speaker > Total revenue is 137,800.
schema it is shown
sales
iddateproductcategoryregionunitsrevenue
query_history
idtimestampvoice_inputgenerated_sqlresult_summarylatency_ms
columns in green are the ones this query touches

02The data it answers from

backend/database/db.py

Twelve rows of sales, the sample set the project ships with. The grouping rotates on its own; every bar is a live SUM() over the same in browser database the questions above run against.

cycling
SELECT region, SUM(revenue), SUM(units) FROM sales GROUP BY region ORDER BY 2 DESC
0 total revenue across 12 rows

03Where the two seconds go

README.md latency table

Button press to spoken answer, broken down by stage. Hover a band to isolate it. Speech to text and the model dominate; the database is the cheapest thing in the whole pipeline.

EchoKit record + POST200ms (10%)
Whisper transcription600ms (30%)
Claude SQL generation800ms (40%)
SQLite query10ms (0%)
Google TTS synthesis400ms (20%)
2.01send to end, inside the 3 second targett+0000ms

04The board

arduino/VoiceQL.ino

The sketch is a five state machine. It steps through on its own; click any state to hold it and see what the board does and what the OLED shows. (stepping)

IDLE

Waiting on the push to talk button. The LED matrix is dark.

what the OLED shows
VoiceQL ready_
leaves on: button press
bill of materials
partrolespec
Arduino Uno R4 WiFiWiFi, HTTP, orchestration68.6 x 53.4mm
EchoKitMic array, speakerI2S
SSD1306 OLEDTranscript and result128x64, I2C 0x3C
Push button + 10kPush to talkdigital in