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 schema→generating SQL→executing→summarising
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