Inspiration One of our teammates was recently stuck in a parking lot because the mechanical gate failed and the software system couldn't recover — leaving a line of frustrated drivers waiting with no resolution in sight. It made us realize how much of our day-to-day relies on parking infrastructure that's brittle, expensive to maintain, and disrespectful of people's time. Most existing systems are built around proprietary hardware locked to a single vendor, or they offload everything to cloud-based ALPR services that introduce latency, cost, and privacy concerns. We wanted to build something that solves both the business problem (lower deployment cost, less downtime, no per-plate cloud fees) and the customer problem (cars get in and out fast, with no manual intervention) — using commodity edge hardware that anyone can buy off the shelf. The goal was to prove that modern edge AI accelerators are powerful enough to replace racks of cloud GPUs for real-world computer vision tasks, and to give parking operators a system that just works without holding people hostage at the gate.

What it does Ticketeer is an end-to-end edge-AI parking management system. When a vehicle approaches an entry or exit lane, an ultrasonic sensor on an ESP32 detects its arrival and signals the Rubik Pi 3 over UART. The Rubik Pi triggers one of two Logitech cameras, captures a frame, runs YOLOv8 license-plate detection optimized for the Hexagon NPU to locate the plate region, then runs EasyOCR to read the characters. The extracted plate text is forwarded over ESP-NOW to a second ESP32 that logs each entry and exit to Google Sheets and maintains a local cache for offline resilience. A live dashboard streams both camera feeds with real-time detection overlays, status indicators, and per-camera inference timing — all hosted directly on the Rubik Pi.

How we built it We split the system into three coordinated nodes. The Rubik Pi 3 runs a Flask server that manages camera capture, runs the inference pipeline, hosts the dashboard, and serves status APIs. We used Qualcomm AI Hub to compile and quantize YOLOv8 to a QNN context binary targeting the QCS6490's v68 Hexagon architecture, achieving a benchmarked 4.5 ms inference time at 254 ops on NPU. The ESP32 Decisionmaker handles ultrasonic triggering and UART communication with the Rubik Pi, while the ESP32 Storage node receives plate data over ESP-NOW and pushes logs to Google Sheets. The two cameras are differentiated by their USB bus paths and stream MJPEG at 640×480 to share USB bandwidth. The whole pipeline operates without internet for inference — only the Storage node touches the cloud, and only for logging.

Challenges we ran into The biggest challenge was getting NPU acceleration working on Ubuntu — Qualcomm's QAIRT SDK ships as a proprietary .qik package that requires their Electron-based QPM desktop tool to extract, which doesn't exist for macOS or ARM Linux. We ended up extracting the SDK inside an x86 Docker container running QPM headlessly, then SCP'ing only the ARM64 libQnnHtp.so and Hexagon v68 skeleton libraries over to the Rubik Pi. We also fought version mismatches between the AI Hub-compiled model and the runtime libraries, USB 2.0 bandwidth limits when running two cameras simultaneously (solved by forcing MJPEG and reducing resolution), captive-portal networks blocking Tailscale relays during initial setup, and Python 3.14 incompatibility with the Qualcomm Python SDK on the Mac side.

Accomplishments that we're proud of We got a fully working edge-AI license plate recognition pipeline running end-to-end on three coordinated devices in roughly a day. The model is NPU-optimized through Qualcomm AI Hub with documented 4.5ms inference time on the Hexagon DSP — a 15x speedup over the CPU baseline. The dashboard shows live dual-camera streams with real-time detection overlays, status badges, and continuous-inference mode all served from a single Flask process. The ESP32-to-Rubik-Pi-to-ESP32 architecture is fully decoupled and can scale to multiple lanes without changing the core inference code. Most importantly, no inference data ever leaves the local network — privacy is built in by design, not bolted on as an afterthought.

What we learned We learned how Qualcomm's edge AI ecosystem actually works in practice — from AI Hub model compilation, to QNN context binaries, to the QAIRT runtime libraries — and where the rough edges still are for ARM Linux deployment. We also learned how to architect a multi-device embedded system using the right protocol for each link: UART for low-latency wired control, ESP-NOW for fast wireless ESP32-to-ESP32 communication, and HTTP only at the cloud boundary. On the practical side, we learned how much USB bandwidth a high-bitrate webcam actually consumes and how to work around hardware constraints with codec selection.

What's next for Ticketeer The most immediate next step is swapping EasyOCR for an NPU-accelerated CRNN OCR model, also compiled via Qualcomm AI Hub, which would give us a fully NPU-accelerated pipeline end-to-end and bring total latency from seconds down to tens of milliseconds. After that, we want to add multi-frame voting so the system captures three frames per trigger and chooses the highest-confidence plate, dramatically improving accuracy in low-light or motion-blur scenarios. Longer term, we want to add vehicle re-identification so we can match an entry plate to its corresponding exit and automatically calculate parking duration, integrate with payment systems through the ESP32 Storage node, and explore deploying the same architecture to drive-thru analytics, gated community access, and fleet tracking.

Built With

Share this project:

Updates