Guardian: The camera that never blinks (private fall detection for seniors on Arduino VENTUNO Q) ExecuTorch Hackathon, IoT track. Guardian watches a room for falls, asks the person out loud whether they're OK, and alerts a family member's watch only if they stay down. It needs no wearable for the person at risk, and video never leaves the house. How it works: Cheap triggers on the CPU, always on: a loud thud on the USB camera's microphone, or motion followed by stillness in the camera view (what a fall looks like). NPU confirmation: each trigger wakes one InternVL3-1B check on the Hexagon NPU (ExecuTorch + QNN): "Is a person lying, sitting or collapsed on the floor?". Nobody on the floor means a false alarm, which is logged and ignored. Ask: the board's speaker says "Are you okay? … please get up". The NPU rechecks every 4 s. If the person gets up, the incident is cancelled. Alert: still down after 20 s, the family member's M5Stack StopWatch vibrates, beeps and shows the model's description. Tapping "I'm on my way" makes the board tell the person that help is coming. STM32 + Modulino Pixels show the state on the device itself. The microcontroller owns the light timing, a camera-on privacy light, and a fault light if the Linux app stops sending heartbeats. Brio camera ──frames──▶ motion-then-still (CPU) ─┐ Brio mic ─────audio──▶ thud detector (CPU) ──────┤ trigger ▼ FastAPI app on VENTUNO Q (state machine, care log) │ one stdin line per check │ Arduino Bridge (msgpack-RPC) ▼ ▼ qnn_multimodal_persistent (ExecuTorch) STM32H5 ──I2C──▶ Modulino Pixels │ QNN HTP / FastRPC ▼ Hexagon NPU: InternVL3-1B Board speaker ◀── espeak-ng / Piper (CPU) Family StopWatch ◀── Wi-Fi WebSocket ──▶ "I'm on my way" Caregiver page ◀── http://<board>:8000 Camera aiming page ◀── http://<board>:8000/aim States: MONITORING → VERIFYING (NPU looks) → CHECKIN (asks; 20 s, rechecks every 4 s) → ALERT (family watch). Pixels Meaning pixel 0 dim green monitoring; pixel 6 yellow = family watch offline amber sweep NPU is checking a trigger amber bar shrinking asking the person to get up (countdown run by the MCU) all red flashing family alerted (latched until they answer or the person gets up) pixel 0 blinking blue Linux app not responding (MCU heartbeat timeout) pixel 7 white camera is on Measured on the board (VENTUNO Q, QCS8275, QNN 2.49, ExecuTorch from the track archive) Metric Value InternVL3-1B load (once, kept warm) 7.9 s cold, 2.3 s cached One camera check (NPU) 0.9–1.5 s (prefill 0.86 s at 316 tok/s, decode 37 tok/s) Trigger → spoken check-in 2.7–2.8 s (sound trigger, including a 1.5 s settle) Trigger → family alert (person stays down) 22.5 s (20 s check-in by design) Person gets up → incident cancelled ≤ 6 s (NPU recheck every 4 s) Runner memory 574 MiB RSS Empty floor 1/1 "no" Person standing 5/5 "no" Doll lying on the floor 6/6 "yes": a known limitation, see below Person lying on the open floor (full body, mounted camera) 5/5 "yes", 1.1–2.4 s Thud while the person is standing rejected as a false alarm (NPU: "not lying down") Power cycle Guardian, the NPU runner and the STM32 app all restart on their own Known limitation: the 1B model treats a doll on the floor as a person, and stricter prompts made it worse (7/12). Guardian handles this in the system design instead: camera triggers need motion followed by stillness, so an object that has lain still all along never triggers a check. A real person also gets the spoken check-in before anyone is alerted. Models and runtime All are from the track's VENTUNO Q bundle (QCS8275, QNN). Use File Fall check InternVL3-1B_QCS8275_ctxt_1000/: .pte decoder, _vision_encoder_qnn.pte, _tok_embedding_qnn.pte, tokenizer.json Runner qnn_multimodal_persistent from ventuno_executorch_source.tar.gz (extracted to ~/git/executorch); loads the model once and serves one request per stdin line QNN runtime libqnn1, libqnn-dev, qnn-tools 2.49 from the Qualcomm Ubuntu PPA (ppa:ubuntu-qcom-iot/qcom-ppa) Speech espeak-ng (or Piper) on the CPU. These are not ExecuTorch models Preprocessing matches the exporter: 448×448 RGB, ImageNet mean/std, float32 NCHW, written to a .raw file (board/guardian/vision.py:preprocess). Repository Path What board/guardian/ Linux app: fusion.py (state machine), vision.py (NPU runner client), audio.py (thud detector), camera.py (capture + motion gate), bridge.py (router RPC), tts.py (speaker), store.py (hash-chained care log), app.py (FastAPI), static/ (caregiver and aim pages) board/tests/ 17 tests: state machine, runner protocol with a fake runner, bridge protocol, thud detector, full app flow board/tools/ fake_watch.py, capture_refs.py, bench_vision.py board/guardian.service systemd user service (starts at boot) mcu/guardian-mcu/ Arduino App for the STM32: sketch (guardian_set over Bridge, Pixels) watch/guardian_watch/ StopWatch firmware: the family alert Setup 1. Board (VENTUNO Q, Ubuntu 24.04) sudo add-apt-repository -y ppa:ubuntu-qcom-iot/qcom-ppa && sudo apt update sudo apt install -y libqnn1 libqnn-dev qnn-tools python3.12-venv espeak-ng tar -xzf ventuno_executorch_source.tar.gz -C ~ # -> ~/git/executorch (track bundle) # copy InternVL3-1B_QCS8275_ctxt_1000/ to ~/models/ git clone https://github.com/gj-labs/guardian.git ~/guardian && cd ~/guardian/board cp config.example.toml config.toml # check camera/mic/speaker devices mkdir -p ~/.config/systemd/user && cp guardian.service ~/.config/systemd/user/ systemctl --user daemon-reload && systemctl --user enable --now guardian Open http://<board-ip>:8000 (caregiver page) and http://<board-ip>:8000/aim to point the camera at the floor. Device names: arecord -l (mic, e.g. plughw:1,0 for the Brio 101), wpctl status (speaker: pair a Bluetooth speaker or plug in a USB one; speaker = "default" uses PipeWire's default output). 2. STM32 + Pixels Plug the Modulino Pixels into the Qwiic port, then on the board: ~/guardian/mcu/deploy.sh # builds + flashes via arduino-app-cli arduino-app-cli properties set default ~/ArduinoApps/guardian-mcu # start at boot 3. Family StopWatch On a computer with arduino-cli, the M5Stack board package and the libraries M5Unified, WebSockets and ArduinoJson: copy watch/guardian_watch/config.example.h to config.h (Wi-Fi + board IP), then compile and upload for the StopWatch. Off-board rehearsal (laptop, all mocks) python3 -m venv .venv && .venv/bin/pip install -r board/requirements.txt cd board && ../.venv/bin/python -m pytest ../.venv/bin/uvicorn guardian.app:app --port 8000 # dashboard rehearsal buttons drive the flow Demo (about 2 minutes) False alarm: drop a bag near someone standing. The mic triggers and the Pixels sweep amber; the NPU sees nobody on the floor, so it goes back to green and the watch shows "False alarm". Fall: a teammate lies down on the mat. Guardian asks out loud, the Pixels count down, then the family watch buzzes with the model's description and the caregiver page shows the snapshot and latency. I'm on my way: tap the watch. The board says help is coming. Gets up: repeat, and stand up during the countdown. The NPU recheck cancels the incident. Privacy: "Pause camera" turns off the MCU's camera light. Privacy Camera frames and audio are processed in memory on the board and are not stored. Only the alert snapshot is kept (keep_snapshots = false disables it), in a local, hash-chained care log. Nothing is sent to the cloud.
Built at ExecuTorch Hackathon — IoT Track
Guardian
Guardian: The camera that never blinks (private fall detection for seniors on Arduino VENTUNO Q) ExecuTorch Hackathon, IoT track. Guardian watches a room for falls, asks the person out loud whether they're OK, and alerts a family member's watch only if they stay down. It needs no wearable for the person at risk, and video never leaves the house. How it works: Cheap triggers on the CPU, always on: a loud thud on the USB camera's microphone, or motion followed by stillness in the camera view (what a fall looks like). NPU confirmation: each trigger wakes one InternVL3-1B check on the Hexagon NPU (ExecuTorch + QNN): "Is a person lying, sitting or collapsed on the floor?". Nobody on the floor means a false alarm, which is logged and ignored. Ask: the board's speaker says "Are you okay? … please get up". The NPU rechecks every 4 s. If the person gets up, the incident is cancelled. Alert: still down after 20 s, the family member's M5Stack StopWatch vibrates, beeps and shows the model's description. Tapping "I'm on my way" makes the board tell the person that help is coming. STM32 + Modulino Pixels show the state on the device itself. The microcontroller owns the light timing, a camera-on privacy light, and a fault light if the Linux app stops sending heartbeats. Brio camera ──frames──▶ motion-then-still (CPU) ─┐ Brio mic ─────audio──▶ thud detector (CPU) ──────┤ trigger ▼ FastAPI app on VENTUNO Q (state machine, care log) │ one stdin line per check │ Arduino Bridge (msgpack-RPC) ▼ ▼ qnn_multimodal_persistent (ExecuTorch) STM32H5 ──I2C──▶ Modulino Pixels │ QNN HTP / FastRPC ▼ Hexagon NPU: InternVL3-1B Board speaker ◀── espeak-ng / Piper (CPU) Family StopWatch ◀── Wi-Fi WebSocket ──▶ "I'm on my way" Caregiver page ◀── http://<board>:8000 Camera aiming page ◀── http://<board>:8000/aim States: MONITORING → VERIFYING (NPU looks) → CHECKIN (asks; 20 s, rechecks every 4 s) → ALERT (family watch). Pixels Meaning pixel 0 dim green monitoring; pixel 6 yellow = family watch offline amber sweep NPU is checking a trigger amber bar shrinking asking the person to get up (countdown run by the MCU) all red flashing family alerted (latched until they answer or the person gets up) pixel 0 blinking blue Linux app not responding (MCU heartbeat timeout) pixel 7 white camera is on Measured on the board (VENTUNO Q, QCS8275, QNN 2.49, ExecuTorch from the track archive) Metric Value InternVL3-1B load (once, kept warm) 7.9 s cold, 2.3 s cached One camera check (NPU) 0.9–1.5 s (prefill 0.86 s at 316 tok/s, decode 37 tok/s) Trigger → spoken check-in 2.7–2.8 s (sound trigger, including a 1.5 s settle) Trigger → family alert (person stays down) 22.5 s (20 s check-in by design) Person gets up → incident cancelled ≤ 6 s (NPU recheck every 4 s) Runner memory 574 MiB RSS Empty floor 1/1 "no" Person standing 5/5 "no" Doll lying on the floor 6/6 "yes": a known limitation, see below Person lying on the open floor (full body, mounted camera) 5/5 "yes", 1.1–2.4 s Thud while the person is standing rejected as a false alarm (NPU: "not lying down") Power cycle Guardian, the NPU runner and the STM32 app all restart on their own Known limitation: the 1B model treats a doll on the floor as a person, and stricter prompts made it worse (7/12). Guardian handles this in the system design instead: camera triggers need motion followed by stillness, so an object that has lain still all along never triggers a check. A real person also gets the spoken check-in before anyone is alerted. Models and runtime All are from the track's VENTUNO Q bundle (QCS8275, QNN). Use File Fall check InternVL3-1B_QCS8275_ctxt_1000/: .pte decoder, _vision_encoder_qnn.pte, _tok_embedding_qnn.pte, tokenizer.json Runner qnn_multimodal_persistent from ventuno_executorch_source.tar.gz (extracted to ~/git/executorch); loads the model once and serves one request per stdin line QNN runtime libqnn1, libqnn-dev, qnn-tools 2.49 from the Qualcomm Ubuntu PPA (ppa:ubuntu-qcom-iot/qcom-ppa) Speech espeak-ng (or Piper) on the CPU. These are not ExecuTorch models Preprocessing matches the exporter: 448×448 RGB, ImageNet mean/std, float32 NCHW, written to a .raw file (board/guardian/vision.py:preprocess). Repository Path What board/guardian/ Linux app: fusion.py (state machine), vision.py (NPU runner client), audio.py (thud detector), camera.py (capture + motion gate), bridge.py (router RPC), tts.py (speaker), store.py (hash-chained care log), app.py (FastAPI), static/ (caregiver and aim pages) board/tests/ 17 tests: state machine, runner protocol with a fake runner, bridge protocol, thud detector, full app flow board/tools/ fake_watch.py, capture_refs.py, bench_vision.py board/guardian.service systemd user service (starts at boot) mcu/guardian-mcu/ Arduino App for the STM32: sketch (guardian_set over Bridge, Pixels) watch/guardian_watch/ StopWatch firmware: the family alert Setup 1. Board (VENTUNO Q, Ubuntu 24.04) sudo add-apt-repository -y ppa:ubuntu-qcom-iot/qcom-ppa && sudo apt update sudo apt install -y libqnn1 libqnn-dev qnn-tools python3.12-venv espeak-ng tar -xzf ventuno_executorch_source.tar.gz -C ~ # -> ~/git/executorch (track bundle) # copy InternVL3-1B_QCS8275_ctxt_1000/ to ~/models/ git clone https://github.com/gj-labs/guardian.git ~/guardian && cd ~/guardian/board cp config.example.toml config.toml # check camera/mic/speaker devices mkdir -p ~/.config/systemd/user && cp guardian.service ~/.config/systemd/user/ systemctl --user daemon-reload && systemctl --user enable --now guardian Open http://<board-ip>:8000 (caregiver page) and http://<board-ip>:8000/aim to point the camera at the floor. Device names: arecord -l (mic, e.g. plughw:1,0 for the Brio 101), wpctl status (speaker: pair a Bluetooth speaker or plug in a USB one; speaker = "default" uses PipeWire's default output). 2. STM32 + Pixels Plug the Modulino Pixels into the Qwiic port, then on the board: ~/guardian/mcu/deploy.sh # builds + flashes via arduino-app-cli arduino-app-cli properties set default ~/ArduinoApps/guardian-mcu # start at boot 3. Family StopWatch On a computer with arduino-cli, the M5Stack board package and the libraries M5Unified, WebSockets and ArduinoJson: copy watch/guardian_watch/config.example.h to config.h (Wi-Fi + board IP), then compile and upload for the StopWatch. Off-board rehearsal (laptop, all mocks) python3 -m venv .venv && .venv/bin/pip install -r board/requirements.txt cd board && ../.venv/bin/python -m pytest ../.venv/bin/uvicorn guardian.app:app --port 8000 # dashboard rehearsal buttons drive the flow Demo (about 2 minutes) False alarm: drop a bag near someone standing. The mic triggers and the Pixels sweep amber; the NPU sees nobody on the floor, so it goes back to green and the watch shows "False alarm". Fall: a teammate lies down on the mat. Guardian asks out loud, the Pixels count down, then the family watch buzzes with the model's description and the caregiver page shows the snapshot and latency. I'm on my way: tap the watch. The board says help is coming. Gets up: repeat, and stand up during the countdown. The NPU recheck cancels the incident. Privacy: "Pause camera" turns off the MCU's camera light. Privacy Camera frames and audio are processed in memory on the board and are not stored. Only the alert snapshot is kept (keep_snapshots = false disables it), in a local, hash-chained care log. Nothing is sent to the cloud.
Keep exploring what builders shipped.
Magic Mirror
Magic Mirror
Project brief ExecuTorch Hackathon — Founders, Inc., October 17–18, 2026. Everything below runs on the Arduino VENTUNO Q on the desk: no cloud, no account, no network needed once the board is flashed. The pitch A store fixture that puts the shopper in the product photo. Stand in front of a camera and you appear wearing the garment — the head cutout, the body matte, the garment placement and the generated try-on image are all computed on the board's Hexagon NPU, with the web page that shows the result served from the same device. What's built and measured Piece Where it runs Cost Virtual billboard (BiSeNet head matte → product photo) NPU 12 ms compute, ~1 fps end to end Person segmentation (SegFormer human parsing) NPU 24.9 ms Generated try-on (Stable Diffusion + ControlNet-Canny) NPU ~0.3 s per step Face swap into a studio shot (GHOST, Apache-2.0) NPU 82 ms, fp16 LLM text generation (Gemma 4 E2B) NPU 188 tok/s prompt, 16.3 tok/s gen, 494 MiB Vision Q&A (InternVL3-1B) NPU 0.5 s encode, ~33 tok/s Live speech (Whisper-tiny → Gemma translate) NPU 1.8–2.6 s transcript, ~9 s translated LLM baseline (Llama 3.2 1B, XNNPACK) CPU 10.1 tok/s The NPU numbers are the point: prompt eval is ~12× the CPU baseline on a model twice the size, with resident memory a fraction of it, because the weights live in the NPU context. How it fits together Hugging Face model → optimum-cli export executorch → quantized .pte → ExecuTorch runtime. The same .pte runs on the Mac and on the board, which is what makes iterating on a laptop and demoing on hardware the same workflow. NPU models go through the track bundle's QNN AOT path (Linux only) and are driven by a warm persistent runner — 468 ms per inference launched cold, 26 ms held open with scratch on tmpfs. Two independent routes to the same effect, kept separate on purpose: overlay moves a garment onto a live frame (garment_overlay.py, garment_clip.py), and face swap moves the shopper's face into a studio shot that already has the garment, lighting and pose (board_faceswap_*). Hardware QCS8275, Cortex-A78C big cores, 14 GB RAM, Ubuntu 24.04 aarch64 over adb — not Android, despite answering adb, and considerably better than its published spec. No root; the compiler, the runners and the Python environment were all installed without it. Status and limits Board path: working, demoed, including the web UI and the walkthrough deck. Android/XR app (android/): compiles, never run — no device was attached. macOS cannot do QNN ahead-of-time compilation, so NPU work happens on the board. Thin segmentation classes (arms) lose accuracy at 8a8w; silhouettes don't. The board reboots under heavy load, so long board-side jobs are resumable.
Harshith Ande's team
Kamikaze
Kamikaze is an edge-AI vision system built on the Arduino VENTUNO Q that converts physical consumer items into interactive 3D digital twins in real time. Powered by an on-device Qualcomm Hexagon NPU, the pipeline uses YOLO-World, DINOv2, RapidOCR, and HSV color gating to identify smartphones and beverage cans during a guided five-second scan. An integrated FastMCP server then resolves metric-accurate 3D models by cross-referencing local CAD caches, 1:1 dummy repositories, and procedural mesh generators with live-stitched label textures—all while enforcing a zero-cloud privacy boundary. The resulting Smart Kiosk interface pairs Modulino RGB LED feedback and real-time hardware telemetry with an auto-orienting 3D viewport that dynamically mirrors the physical pose of the object in the user's hand.
Team AAA
Depth Perception
Collating Arduino distance sensor readings with video to train camera-alone depth perception
