<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Abhinav krishna N</title>
    <description>The latest articles on DEV Community by Abhinav krishna N (@abhinavkrishna3211).</description>
    <link>https://dev.to/abhinavkrishna3211</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4151403%2F4595bd5d-cf95-46f2-b425-274cb05e0a33.jpeg</url>
      <title>DEV Community: Abhinav krishna N</title>
      <link>https://dev.to/abhinavkrishna3211</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/abhinavkrishna3211"/>
    <language>en</language>
    <item>
      <title>Every alarm clock punishes laziness. My Arduino UNO Q rewards it: a radar watches me sleep and lets me stay in bed 🦥</title>
      <dc:creator>Abhinav krishna N</dc:creator>
      <pubDate>Mon, 26 Oct 2026 06:38:29 +0000</pubDate>
      <link>https://dev.to/abhinavkrishna3211/sloth-clock-slow-and-steady-wins-the-morning-an-offline-ai-alarm-that-rewards-you-for-sleeping-in-5bl7</link>
      <guid>https://dev.to/abhinavkrishna3211/sloth-clock-slow-and-steady-wins-the-morning-an-offline-ai-alarm-that-rewards-you-for-sleeping-in-5bl7</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-week3-2026-10-19"&gt;Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Every alarm clock punishes laziness.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It rings at the same minute whether you slept like a log or stared at the ceiling until 3 a.m. Then it hands you a snooze button, so you can chop your last half hour into nine-minute pieces of broken sleep. Snooze, snooze, snooze.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sloth Clock 🦥 rewards it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It's a bedside sloth built on one &lt;strong&gt;Arduino UNO Q&lt;/strong&gt;. A &lt;strong&gt;60 GHz radar&lt;/strong&gt; watches how you actually slept, through the blanket, with no camera and no wearable. If the night was rough, or it's &lt;strong&gt;raining outside&lt;/strong&gt; (a microphone listens for rain, keeping only sound features, never audio), it &lt;strong&gt;lets you stay in bed longer&lt;/strong&gt;: up to 30 minutes, decided early, and never past the time you must be up. No morning run in the rain anyway. Then it wakes you the way a sloth would want, &lt;strong&gt;slowly&lt;/strong&gt;: a sunrise climbs the LED matrix, a soft chime follows, and &lt;strong&gt;Gemma 3 1B, running on the clock itself&lt;/strong&gt;, tells you why you got the lie-in:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;06:45. Good morning, dear. Your sleep was a bit restless, so I've given you a longer rest.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's a real message, written by the model on the board, offline.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbsa9j5rpzlmu6vso8tcs.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbsa9j5rpzlmu6vso8tcs.jpg" alt="Sloth Clock on the nightstand" width="800" height="600"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The cardboard sloth: the UNO Q's LED matrix shows through the front, the radar on top faces the bed, and the no-glow e-paper card shows the morning.&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;📡 &lt;strong&gt;Senses:&lt;/strong&gt; a 60 GHz mmWave radar reads breathing, heart rate and restlessness, and a small microphone listens for rain. No camera, no wearable, nothing to charge.&lt;/li&gt;
&lt;li&gt;🧮 &lt;strong&gt;Decides:&lt;/strong&gt; plain code scores the night and picks the alarm, inside health limits it cannot break.&lt;/li&gt;
&lt;li&gt;🌅 &lt;strong&gt;Acts:&lt;/strong&gt; an LED-matrix sunrise, a chime, a Gemma-written note, and an e-paper card.&lt;/li&gt;
&lt;li&gt;🔌 &lt;strong&gt;One Arduino UNO Q, fully offline.&lt;/strong&gt; No phone, no cloud, no account, no API key.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  Lazy, but only the safe kind
&lt;/h3&gt;

&lt;p&gt;Sleeping in is the easiest feature in the world to get wrong. So the sloth has rules it cannot break:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Rule&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;💤 Restless night (score below 60)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;+15 min&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🌧️ Raining outside&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;+15 min&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🧱 Never more than&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;+30 min&lt;/strong&gt; in total&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;⏰ Never past&lt;/td&gt;
&lt;td&gt;your "must be up by" time&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🚫 Snooze&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;does not exist&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;📅 Two days in a row&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;no&lt;/strong&gt;, unless last night was very poor (score below 40)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🤷 Not enough radar data&lt;/td&gt;
&lt;td&gt;normal alarm, and an honest &lt;strong&gt;"not sure"&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;They're hard-coded in one small file, not settings. &lt;em&gt;Future sleepy me does not get a vote.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Slow and steady, all the way down
&lt;/h3&gt;

&lt;p&gt;The theme isn't just the name. Every part of the clock is slow on purpose, and that's exactly what makes it reliable:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Part&lt;/th&gt;
&lt;th&gt;Slow&lt;/th&gt;
&lt;th&gt;Why slow is fine&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;🌅 Wake-up&lt;/td&gt;
&lt;td&gt;A sunrise that climbs the LED matrix, then a soft chime&lt;/td&gt;
&lt;td&gt;Nobody wants to wake up to a fire alarm&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🧠 Gemma 3 1B&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;~4.4 tokens/s&lt;/strong&gt; on the board's Arm CPU, 20–38 s per note&lt;/td&gt;
&lt;td&gt;The decision is made &lt;strong&gt;45 minutes&lt;/strong&gt; before the alarm, so the model has 70× the time it needs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🪜 Your to-do list&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;One tiny step a day&lt;/strong&gt; (5, 15 or 30 min)&lt;/td&gt;
&lt;td&gt;Slow and steady is how a sloth gets anywhere&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/VAv-Pj1k01o" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;The video shows a full run: a 6-minute &lt;strong&gt;demo nap&lt;/strong&gt; (tossing and turning on purpose), the decision (&lt;strong&gt;+15 min, restless night, score 33&lt;/strong&gt;), the sunrise, the chime, and Gemma's note. Demo mode exists because you shouldn't have to sleep eight hours to see an alarm clock work. That would be a little &lt;em&gt;too&lt;/em&gt; on-theme.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It sees you breathe.&lt;/strong&gt; Here's the live page while I lie still, then while I hold my breath for a few seconds:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7phsfzovhm0zmjygivu5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7phsfzovhm0zmjygivu5.png" alt="Live breathing, heart rate and movement" width="799" height="225"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Breathing 15/min, heart rate 63 bpm, movement near zero. Nothing touches me.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fepllscyxrwmneciz4vbz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fepllscyxrwmneciz4vbz.png" alt="Breathing rate dips when I hold my breath" width="799" height="216"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Holding my breath: the breathing rate drops from about 15 to 2.5 per minute, then recovers.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The whole page, on any phone or laptop on the same network:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkppqdz60uly1f0kls4xp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkppqdz60uly1f0kls4xp.png" alt="The Sloth Clock web page" width="800" height="732"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Live readings, the night score with every term, the alarm decision and the wake note, all served by the UNO Q itself.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The decision, with every rule shown:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpt6go2jz65fp36pobaya.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpt6go2jz65fp36pobaya.png" alt="The last decision and Gemma's note" width="799" height="304"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Alarm 06:45 (usual 06:30, must be up by 07:00): +15 min, because the night scored 33 out of 100.&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/Abhinavkrishna3211" rel="noopener noreferrer"&gt;
        Abhinavkrishna3211
      &lt;/a&gt; / &lt;a href="https://github.com/Abhinavkrishna3211/Sloth-Clock" rel="noopener noreferrer"&gt;
        Sloth-Clock
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A bedside sloth on Arduino UNO Q: a 60 GHz radar watches your sleep, the alarm gives you extra minutes when it’s safe, and a no-glow e-paper card moves procrastinated jobs forward one tiny step a day. Fully offline.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Sloth Clock 🦥&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Slow and steady wins the morning.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Most alarm clocks punish you for being tired. Sloth Clock does the opposite: it watches how you slept, and
if the night was rough, it lets you sleep in, safely. Then it asks for the smallest possible step on the job
you keep putting off. Not the whole job. One tiny step.&lt;/p&gt;
&lt;p&gt;Laziness, done properly, is a strategy. Rest when you need it, move a little every day, never panic
That is how a sloth gets where it is going.&lt;/p&gt;
&lt;p&gt;Everything runs offline on one Arduino UNO Q. No cloud, no account, no camera, no wearable.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;The three lazy things it does for you&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;1. It lets you sleep in, and it earns that right&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;A 60 GHz mmWave radar on the nightstand reads breathing, heart rate and restlessness through the blanket
In the morning the board scores the night. A…&lt;/p&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/Abhinavkrishna3211/Sloth-Clock" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Path&lt;/th&gt;
&lt;th&gt;What lives there&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;app/sketch/sketch.ino&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;STM32: radar line parser, 10 s rows, LED-matrix face and sunrise, chime, button, backup alarm&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;app/python/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Linux: SQLite, night score, alarm decision, Gemma notes + validator, tiny-step engine, web page&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;firmware/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The radar kit's XIAO ESP32C6 and the e-paper card's XIAO ESP32-S3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;tests/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Decision, validator, night score and on-board Gemma tests&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;docs/measurements.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Every number in this post, with date, setup and trials&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;MIT licensed.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Hardware
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4t9dx0o0hyyv31ujof7a.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4t9dx0o0hyyv31ujof7a.jpg" alt="All the parts" width="800" height="1067"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Everything in the clock. Top left: the XIAO ePaper Display Board EE04 with the 7.5" e-paper panel. Left, top to bottom: the round INMP441 microphone, the green PAM8403 amplifier, and the small cavity speaker for the chime. Bottom: the 60 GHz radar in its case, and the Arduino UNO Q.&lt;/em&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Part&lt;/th&gt;
&lt;th&gt;Job&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Arduino UNO Q (4 GB)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The whole brain: an STM32U585 microcontroller and a Qualcomm QRB2210 running Linux, on one board&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Seeed MR60BHA2 60 GHz mmWave kit&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Breathing, heart rate, presence and movement, without contact&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Seeed XIAO ePaper Display Board EE04 + 7.5" 800×480 panel&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The no-glow card&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;PAM8403 amplifier + small cavity speaker&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The soft chime, driven by a tone from the STM32&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;INMP441 microphone&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Listens for rain. The STM32 keeps only a few sound features, never audio&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Everything runs from USB: low voltage, no mains, nothing that heats up or moves. And the enclosure? &lt;strong&gt;Cardboard.&lt;/strong&gt; I don't have a 3D printer, so the sloth lives in a box I cut and taped in an evening. Lazy &lt;em&gt;and&lt;/em&gt; free.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbg8ka3sa8tp3w1n6fkq2.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbg8ka3sa8tp3w1n6fkq2.jpg" alt="The Arduino UNO Q" width="800" height="1067"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The Arduino UNO Q: Linux and an STM32 on one board, with the 8×13 LED matrix that draws the sunrise.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fznp4jbhxf4kr1c3y9pgd.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fznp4jbhxf4kr1c3y9pgd.jpg" alt="The radar" width="800" height="1067"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The 60 GHz radar on top of the sloth, tilted down toward the bed.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9ykos5c7kwmulw4yoncq.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9ykos5c7kwmulw4yoncq.jpg" alt="The e-paper card and its driver board" width="800" height="1067"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The 7.5" e-paper panel and the XIAO ePaper Display Board EE04 that drives it. Even on the desk it shows the morning: wake up 06:45, "+15 min of slow morning, never later than 07:00", the month, what's coming up, today's tiny step and the note. And a sloth hanging from a garland of lights.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6x4u702fbb7p6kqesj5z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6x4u702fbb7p6kqesj5z.png" alt="Wiring" width="800" height="566"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;One-sheet wiring: the chime on D3, the button on D2, and the radar and card talking to the board.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Why the UNO Q, specifically
&lt;/h3&gt;

&lt;p&gt;An alarm clock is a strange mix of jobs. Part of it must be &lt;strong&gt;hard real time&lt;/strong&gt;: the alarm &lt;em&gt;must&lt;/em&gt; ring and the button &lt;em&gt;must&lt;/em&gt; work. Part of it is &lt;strong&gt;heavy and slow&lt;/strong&gt;: a language model. Most boards make you pick one.&lt;/p&gt;

&lt;p&gt;The UNO Q is &lt;strong&gt;two computers on one board&lt;/strong&gt;, and Sloth Clock gives each the job it's good at:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;⚡ STM32U585 (real time)&lt;/th&gt;
&lt;th&gt;🐧 QRB2210 (Linux)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Sense&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Parse every radar line, count bad ones, build a 10 s summary row&lt;/td&gt;
&lt;td&gt;Store rows in SQLite&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Think&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Night score, alarm decision with hard limits, Gemma 3 1B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Act&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;LED-matrix sunrise, chime, button, &lt;strong&gt;backup alarm&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Validate every note, serve the web page, update the card&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;They talk over the &lt;strong&gt;Arduino Bridge&lt;/strong&gt;. Each summary row is a handful of integers, and its largest possible message is &lt;strong&gt;33 bytes&lt;/strong&gt;, well under the Bridge's 256-byte limit.&lt;/p&gt;

&lt;p&gt;That split is what makes it a trustworthy alarm clock:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🔘 &lt;strong&gt;The button lives on the microcontroller&lt;/strong&gt;, so it works even while Linux is busy running a model.&lt;/li&gt;
&lt;li&gt;⏰ &lt;strong&gt;The microcontroller has a backup alarm.&lt;/strong&gt; If Linux ever misses the alarm, the STM32 rings on its own.&lt;/li&gt;
&lt;li&gt;🕰️ &lt;strong&gt;No model is on the critical path.&lt;/strong&gt; If Gemma is slow, down or wrong, a plain template is used and the alarm still rings on time.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The night score is explainable, not magic
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;score = 100 − (restless % + 0.5 × irregular-breathing % + 10 × long awakenings)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each term is a share of the minutes observed, so a 6-minute demo nap and a full night use the same scale. The page shows every term, so you can see exactly why you did or didn't get your lie-in.&lt;/p&gt;

&lt;h3&gt;
  
  
  Gemma only words things. Code decides everything.
&lt;/h3&gt;

&lt;p&gt;This was the most interesting part. A 1B model is lovely at sounding warm and bad at facts, and an alarm clock that &lt;em&gt;lies about what time it is&lt;/em&gt; is worse than no alarm clock. So:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Code makes the decision&lt;/strong&gt; and writes the reason in plain words.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gemma only rephrases it&lt;/strong&gt; in a sleepy, kind sloth's voice.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A validator checks every note&lt;/strong&gt; before you see it:

&lt;ul&gt;
&lt;li&gt;every number and time must appear in the decision record (&lt;code&gt;6:45&lt;/code&gt; is one time, not 6 and 45, and &lt;code&gt;2:10–3:30&lt;/code&gt; is a range, not a minus sign)&lt;/li&gt;
&lt;li&gt;number words count too ("twenty" is a number)&lt;/li&gt;
&lt;li&gt;no "snooze", and no "extra time" if the alarm didn't move&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code writes the wake time&lt;/strong&gt; at the front. The model never copies it.&lt;/li&gt;
&lt;li&gt;One retry with a stricter prompt, then a template. &lt;strong&gt;Something honest always comes out.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Every rule exists because the model broke it. In one early test, on two nights where the alarm had &lt;strong&gt;not moved at all&lt;/strong&gt;, Gemma cheerfully said "I've given you a little extra time" 😅. Each failure became a validator rule and a test.&lt;/p&gt;

&lt;p&gt;On the board, across 10 different decision records:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Prompt version&lt;/th&gt;
&lt;th&gt;✅ Valid first try&lt;/th&gt;
&lt;th&gt;🔁 Valid after retry&lt;/th&gt;
&lt;th&gt;📄 Template&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Model writes the time itself&lt;/td&gt;
&lt;td&gt;4 / 10&lt;/td&gt;
&lt;td&gt;1 / 10&lt;/td&gt;
&lt;td&gt;5 / 10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Code writes the time, model writes the reason&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;8 / 10&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;2 / 10&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0 / 10&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;No wrong number got through.&lt;/strong&gt; What the validator &lt;em&gt;can't&lt;/em&gt; catch: in one retry, the model turned "you slept badly, but you already slept in yesterday" into "you've already had a restful sleep". Every number was right, but the meaning wasn't. Rules can check facts. They can't fully check feelings.&lt;/p&gt;

&lt;h3&gt;
  
  
  One tiny step a day
&lt;/h3&gt;

&lt;p&gt;You type the job you keep avoiding. Gemma splits its first step into three sizes (5, 15 and 30 minutes), a checker rejects anything with invented numbers, and each morning the card shows &lt;strong&gt;one&lt;/strong&gt; step. After a bad night, it shows the tiniest one. Rest counts too.&lt;/p&gt;

&lt;h3&gt;
  
  
  The open-source AI at the core
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;🧠 &lt;strong&gt;Gemma 3 1B&lt;/strong&gt; (open weights, QAT Q4_0 GGUF): wake notes and step splitting.&lt;/li&gt;
&lt;li&gt;⚙️ &lt;strong&gt;llama.cpp &lt;code&gt;llama-server&lt;/code&gt;&lt;/strong&gt; on the UNO Q's Arm CPU: 3 threads, no GPU, no internet, started at boot.&lt;/li&gt;
&lt;li&gt;🧩 &lt;strong&gt;Arduino App Lab&lt;/strong&gt;: one app made of a Python container, the MCU sketch and the web UI.&lt;/li&gt;
&lt;li&gt;🧮 &lt;strong&gt;TabPFN v2&lt;/strong&gt; (open tabular foundation model): guesses which step size you'll actually finish, with a small numpy fallback built in. Tested on synthetic data so far, since real mornings take time to collect.&lt;/li&gt;
&lt;li&gt;📡 &lt;strong&gt;Seeed's open mmWave library&lt;/strong&gt; and &lt;strong&gt;Seeed_GFX&lt;/strong&gt; on the two XIAOs.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Measured on the UNO Q&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Gemma generation&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;4.42–4.45 tok/s&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;First token, cold prompt&lt;/td&gt;
&lt;td&gt;2.4 s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Wake note, including retries&lt;/td&gt;
&lt;td&gt;20–38 s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Alarm decision + health limits&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;12 / 12&lt;/strong&gt; test cases&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Note validator&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;20 / 20&lt;/strong&gt; test cases&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sketch size&lt;/td&gt;
&lt;td&gt;97 KB flash (12%), 44 KB RAM (16%)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Radar vs manual breath count + reference heart rate&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~80–90%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Every number here is logged in &lt;code&gt;docs/measurements.md&lt;/code&gt; with date, setup and trials.&lt;/p&gt;

&lt;h3&gt;
  
  
  What it can't do (yet)
&lt;/h3&gt;

&lt;p&gt;I'd rather say this than have you find it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Radar accuracy:&lt;/strong&gt; about &lt;strong&gt;80–90%&lt;/strong&gt; against a manual breath count and a reference heart rate in my tests. That's enough to tell a restless night from a calm one, but not enough for medicine. The movement number still jumps too easily, so calibration is next.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rain bonus:&lt;/strong&gt; it passes my tests at home, but it hasn't lived through a full monsoon of real mornings yet. A loud fan or a shower could still fool it.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;It's a comfort device, not a medical one.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  My Agent Session
&lt;/h2&gt;

&lt;p&gt;I built Sloth Clock with &lt;strong&gt;Claude Code&lt;/strong&gt; as my coding agent. Here's how we split the work:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;🧑 Me&lt;/th&gt;
&lt;th&gt;🤖 Claude Code&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;The idea, and the safe-laziness rules&lt;/td&gt;
&lt;td&gt;Wrote most of the Python app, the STM32 sketch and the two XIAO firmwares&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Picking, wiring and placing the hardware&lt;/td&gt;
&lt;td&gt;Wrote the tests and the note validator, one rule per failure I found&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Flashing, testing and every measurement on the board&lt;/td&gt;
&lt;td&gt;Debugged from the logs and readings I sent back&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deciding what ships, and what the post claims&lt;/td&gt;
&lt;td&gt;Kept &lt;code&gt;docs/measurements.md&lt;/code&gt; and the progress notes up to date&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The best part: every time Gemma broke a rule on the board, I pasted the bad note back, and the agent turned it into a validator rule and a test. That loop is why no wrong number got through.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;p&gt;Because this device lives &lt;strong&gt;in your bedroom, watching you breathe.&lt;/strong&gt; 🛏️&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🔒 &lt;strong&gt;Your data never leaves the nightstand.&lt;/strong&gt; No audio, no camera, and no raw radar waveform is stored anywhere. Only small rows go into a file on the board: a breathing rate, a heart rate and a movement number every 10 seconds. That's health data. With a closed API, every wake note would be a little report about your night sent to someone else's server.&lt;/li&gt;
&lt;li&gt;🔌 &lt;strong&gt;It works offline.&lt;/strong&gt; An alarm can't depend on the internet, a server, or an API key that expires. The radar is wired straight to the clock, and nothing leaves the room. If the Wi-Fi dies at 3 a.m., the sloth doesn't notice.&lt;/li&gt;
&lt;li&gt;💸 &lt;strong&gt;It costs nothing to run.&lt;/strong&gt; No tokens, no subscription. A year of wake notes costs $0.&lt;/li&gt;
&lt;li&gt;🔁 &lt;strong&gt;I can swap the model.&lt;/strong&gt; It's one GGUF file and one command line. When a better small open model comes out, the clock gets better without asking anyone's permission.&lt;/li&gt;
&lt;li&gt;🔍 &lt;strong&gt;I can read every layer:&lt;/strong&gt; the radar library, the inference server, the model. When something broke, I could find out &lt;em&gt;why&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A closed model could write a slightly nicer sentence. It couldn't do it on a nightstand, offline, for free, without learning when you sleep.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Lazy Payoff
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;😴 &lt;strong&gt;Up to 30 more minutes of sleep&lt;/strong&gt; on exactly the mornings you need it, with zero risk of being late.&lt;/li&gt;
&lt;li&gt;🧠 &lt;strong&gt;Zero decisions before coffee.&lt;/strong&gt; No more bargaining with a snooze button, half asleep. The sloth already did the maths.&lt;/li&gt;
&lt;li&gt;⌚ &lt;strong&gt;Zero effort to track sleep.&lt;/strong&gt; No wearable to charge, no app to open, no button at bedtime. The laziest sleep tracker is the one you never touch.&lt;/li&gt;
&lt;li&gt;🪜 &lt;strong&gt;Progress without willpower.&lt;/strong&gt; One tiny step a day, and a smaller one after a bad night.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Arduino:&lt;/strong&gt; the whole agent lives on &lt;strong&gt;one Arduino UNO Q&lt;/strong&gt;, and each half does the job it's built for. It &lt;strong&gt;senses&lt;/strong&gt; with a 60 GHz radar: the STM32 parses every line and builds 33-byte summary rows. It &lt;strong&gt;decides&lt;/strong&gt; on Linux: night score, alarm logic with hard health limits, and &lt;strong&gt;Gemma 3 1B running on the board&lt;/strong&gt;, offline. It &lt;strong&gt;acts&lt;/strong&gt; on the STM32: the LED-matrix sunrise, the chime through a PAM8403 and a small speaker, the button, and a &lt;strong&gt;backup alarm that rings even if Linux doesn't&lt;/strong&gt;. The two halves talk over the Arduino Bridge, packaged as one App Lab app. The STM32 also carries a register-level I2S driver and a hand-written FFT for the INMP441 microphone (the core has no I2S library or CMSIS-DSP), so the microcontroller itself listens for rain and passes on only a few numbers, never audio.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Gemma:&lt;/strong&gt; &lt;strong&gt;Gemma 3 1B&lt;/strong&gt; runs on the board through llama.cpp, offline. It writes every wake note and splits avoided jobs into tiny steps. Code writes the facts, and a validator checks every number Gemma writes: &lt;strong&gt;10 / 10 notes valid on the board (8 on the first try, 2 after one retry), 0 wrong numbers through.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
    </item>
    <item>
      <title>Project Pulse: an offline vibration stethoscope that diagnoses and stops a failing machine</title>
      <dc:creator>Abhinav krishna N</dc:creator>
      <pubDate>Sun, 18 Oct 2026 21:54:34 +0000</pubDate>
      <link>https://dev.to/abhinavkrishna3211/project-pulse-an-offline-vibration-stethoscope-that-diagnoses-and-stops-a-failing-motor-1cd7</link>
      <guid>https://dev.to/abhinavkrishna3211/project-pulse-an-offline-vibration-stethoscope-that-diagnoses-and-stops-a-failing-motor-1cd7</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-week2-2026-10-12"&gt;Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A low-cost, offline machine-monitoring probe built around an Arduino, designed to bring predictive maintenance within reach of small businesses.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;Where I live in Kerala, many small businesses depend on machines to keep running. Think of the grinder in a batter-making business, the machinery in a flour mill, a water pump on a farm, or the machines in a small workshop.&lt;/p&gt;

&lt;p&gt;When a machine starts to fail, the warning signs can go unnoticed until it breaks down. A repair technician might listen to the machine, feel its vibration and rely on experience to diagnose the problem. That experience matters, but what if they also had measurements to back it up?&lt;/p&gt;

&lt;p&gt;Project Pulse is designed for both technicians who want to check machines periodically, like using a stethoscope during a routine inspection, and business owners who want to monitor multiple machines across their setup. Deploy multiple probes across a workshop, factory or farm, and each can learn the normal behaviour of its assigned motor and flag unusual changes. Instead of waiting for a breakdown, the goal is to spot warning signs earlier and make maintenance decisions with better information.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;That's why I built Project Pulse: a stethoscope for small motors.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It's a handheld probe with a magnet at its tip. Attach it to a running machine, and it measures vibration while capturing sound. It estimates vibration severity, identifies possible fault patterns and explains what to investigate in language a shop owner can understand.&lt;/p&gt;

&lt;p&gt;Everything runs on an &lt;strong&gt;Arduino UNO Q&lt;/strong&gt;. No cloud, no account, no internet connection required.&lt;/p&gt;

&lt;p&gt;It has two modes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Check mode, for repair technicians.&lt;/strong&gt; Take a reading, see the severity zone, review possible faults such as imbalance or looseness, and generate a report. The report can be downloaded as a PDF and shared with the customer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Guard mode, for machine owners.&lt;/strong&gt; Leave the probe on a motor. It first measures the motor while switched off, then learns that specific motor's normal running pattern in about three minutes. It watches for sustained changes and tracks an estimated heat/overload budget. An LED shows the state: blue for learning, green for healthy, amber for watch, red for stop, and off when the motor isn't running. A red stop state stays latched until a person clears it. At the end of the day, the device generates a short note.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Who would pay for it?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Independent repair technicians&lt;/strong&gt; could carry one probe between customer sites, check motors during routine maintenance, identify unusual vibration patterns and provide customers with a report backed by actual measurements.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Small business owners&lt;/strong&gt; could use Project Pulse to monitor the motors their operations depend on, helping them spot unusual behaviour before it leads to unexpected downtime.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Factories and workshops&lt;/strong&gt; could deploy multiple probes across their equipment, monitoring individual motors as a fleet rather than relying entirely on manual inspections. Each probe learns the normal behaviour of its assigned motor and flags sustained abnormalities.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agricultural and industrial operators&lt;/strong&gt; could use the portable probe to inspect pumps, motors and other rotating machinery at regular intervals, even where internet connectivity is unreliable.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Industrial vibration-monitoring systems already exist, but many come with high hardware costs, cloud connectivity requirements and recurring subscription fees. These can make continuous monitoring difficult to justify for small businesses that only need to monitor a handful of machines. Project Pulse explores a more accessible alternative: an affordable, fully offline tool with no recurring AI or cloud costs. It can work as a handheld diagnostic stethoscope for periodic inspections or be deployed across multiple machines for continuous, individual monitoring. The goal is to make predictive maintenance accessible without the infrastructure and ongoing costs traditionally associated with industrial monitoring systems.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;


&lt;div&gt;
    &lt;iframe src="https://www.youtube.com/embed/Q8JpMbTgCFg" width="315" height="560"&gt;
    &lt;/iframe&gt;
  &lt;/div&gt;


&lt;p&gt;I didn't have access to an industrial machine for the demonstration, so I started with what I had at home: a fan. To test whether Project Pulse could detect unusual vibration, I taped a coin to one of the fan blades to introduce an imbalance and observed how the system responded.&lt;/p&gt;

&lt;p&gt;It was a simple, controlled experiment using an everyday appliance, but it gave me a way to test the complete sensing and alerting loop with a real motor. The prototype detected the sustained induced imbalance during my test. It's an initial proof of concept, and testing across different motors and real-world fault conditions is the next step.&lt;/p&gt;

&lt;p&gt;Here's the hardware before it went into the enclosure:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2ck3w0ugpb9eojwbhtsg.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2ck3w0ugpb9eojwbhtsg.jpeg" alt=" " width="800" height="1067"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;UNO Q, KX134, INMP441, RGB LED, three resistors, and the magnet that lets the probe snap onto a motor casing.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I don't own a 3D printer, so I made the enclosure from cardboard, cutting, folding and gluing it by hand. The magnet sits at the bottom, letting the probe attach to a motor casing. It's not a production-ready enclosure, but it contains the working electronics used for the prototype.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fawkrlib5uozmd3djbews.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fawkrlib5uozmd3djbews.jpeg" alt=" " width="800" height="1422"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Red means stop. The heartbeat line was the only part of this build that didn't need debugging.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F22l7h7gymgn9yhh1v0er.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F22l7h7gymgn9yhh1v0er.png" alt=" " width="800" height="519"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The probe's wiring, start to finish: KX134 over SPI, INMP441 over I2S, everything else just GPIO.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fd61pq31233txp3u1glck.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fd61pq31233txp3u1glck.png" alt=" " width="799" height="434"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Check mode, live: severity zone, the raw numbers underneath it, and the button that turns them into a report.&lt;/em&gt;&lt;/p&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgh08iltfy3aun49o2bf6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgh08iltfy3aun49o2bf6.png" alt=" " width="800" height="398"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The PDF a technician hands the customer. Every number in the paragraph above the table is checked against the table itself before it ships.&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/Abhinavkrishna3211" rel="noopener noreferrer"&gt;
        Abhinavkrishna3211
      &lt;/a&gt; / &lt;a href="https://github.com/Abhinavkrishna3211/ProjectPulse" rel="noopener noreferrer"&gt;
        ProjectPulse
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A magnetic stethoscope for small motors: snap it on, get a fault diagnosis in 30 seconds, or pair it with a plug that stops the motor. Offline on Arduino UNO Q with an open-weight model.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Project Pulse&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;A magnetic stethoscope for small motors, with an optional plug that can stop them.&lt;/p&gt;
&lt;p&gt;Snap the probe onto a running machine and in about 30 seconds it tells you how hard the motor is shaking
what the likely fault is (imbalance, looseness, overload, bearing wear) and what to check, in plain words
Leave it mounted and pair it with the stop plug, and it guards that motor: it learns what normal looks like,
warns when something drifts, and cuts power when it has to. Everything runs on an Arduino UNO Q; nothing goes to the cloud.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Two units&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Probe:&lt;/strong&gt; Arduino UNO Q, KX134 accelerometer, INMP441 microphone, RGB LED, magnet base.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stop plug:&lt;/strong&gt; XIAO ESP32-S3 and a relay. An ordinary socket until paired; once paired, it keeps power on only while the probe keeps saying so.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Two modes&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Check:&lt;/strong&gt; for repair technicians. Severity zone, likely fault and a short…&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/Abhinavkrishna3211/ProjectPulse" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Hardware
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Arduino UNO Q (4 GB):&lt;/strong&gt; combines an STM32U585 microcontroller with a Qualcomm QRB2210 Linux processor.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;KX134 accelerometer:&lt;/strong&gt; measures vibration over SPI.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;INMP441 microphone:&lt;/strong&gt; captures sound over I2S.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RGB status LED and button:&lt;/strong&gt; provide a simple physical interface.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Magnet:&lt;/strong&gt; attaches the probe to a motor casing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;XIAO ESP32-S3 + relay:&lt;/strong&gt; planned as an optional stop plug; see the limitations below.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Sense: the microcontroller side
&lt;/h3&gt;

&lt;p&gt;The STM32 samples the KX134 at about &lt;strong&gt;1,600 Hz&lt;/strong&gt; (measured: 1,623–1,627 Hz). Every second it runs a hand-written FFT and turns the raw samples into one small feature row:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;vibration velocity (mm/s)&lt;/li&gt;
&lt;li&gt;the motor's rotation frequency&lt;/li&gt;
&lt;li&gt;the strength of the first three harmonics (1×, 2×, 3×)&lt;/li&gt;
&lt;li&gt;band energies, kurtosis and crest factor&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That row goes to the Linux side over the UNO Q's Bridge. It's about 60–70 characters, well under the Bridge's 256-byte message limit.&lt;/p&gt;

&lt;p&gt;The INMP441 runs at the same time at &lt;strong&gt;16 kHz&lt;/strong&gt; (measured: 16,004–16,031 Hz). The UNO Q's Arduino core has no I2S library, so I drove the chip's SAI audio peripheral directly through its registers. That taught me two lessons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;My first build read every sample as 0 or 32767, because the clock-edge bit (&lt;code&gt;CKSTR&lt;/code&gt;) was left at its reset value.&lt;/li&gt;
&lt;li&gt;The KX134 delivered no samples at all until I set its data-ready enable bit (&lt;code&gt;DRDYE&lt;/code&gt;). Its WHO_AM_I check passed perfectly the whole time, so the real bug was hiding one register away from where I was looking.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Decide: the Linux side, all open source
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fault rules&lt;/strong&gt; (&lt;code&gt;rules.py&lt;/code&gt;): the vibration velocity maps to the ISO 10816 severity zones that technicians use for small machines. Textbook signatures then name the likely fault:

&lt;ul&gt;
&lt;li&gt;a dominant 1× peak means imbalance&lt;/li&gt;
&lt;li&gt;strong 2×/3× harmonics mean looseness or misalignment&lt;/li&gt;
&lt;li&gt;rotation slower than the rated speed means overload&lt;/li&gt;
&lt;li&gt;high-band energy plus high kurtosis means bearing wear&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Learned normal&lt;/strong&gt; (&lt;code&gt;model.py&lt;/code&gt;, scikit-learn IsolationForest): in Guard mode it trains on the board from the motor's own healthy running rows. Both the anomaly flag and the rule faults are &lt;strong&gt;debounced&lt;/strong&gt;: a condition has to hold for 5 consecutive rows before the light turns amber. The motor-off state reads from the same per-motor calibrated floor, not a fixed number. I tried a fixed "off" threshold first, and it broke the moment I tested it on a second, quieter fan. Every motor needs its own baseline; there's no shortcut around that.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Heat budget&lt;/strong&gt; (&lt;code&gt;heat.py&lt;/code&gt;): there's no temperature sensor yet. Instead, a slow budget fills with run time and overload and drains at rest. When it's full, the stop latches.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gemma 3 1B&lt;/strong&gt; via llama.cpp, running on the board, writes the Check report and the Guard daily note.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The rule I built Gemma around:&lt;/strong&gt; the model never makes a decision. Pass/fail and stop/no-stop stay with the rules, the anomaly model and the heat budget. Gemma's only job is to turn a decision that's already been made into sentences a shop owner can read. A validator then checks &lt;strong&gt;every number in Gemma's text against the real measurements&lt;/strong&gt;. If one doesn't match, it retries once, then falls back to a fixed template built from the real numbers. The report can be wrong in tone, never in its numbers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Act
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The RGB LED and the web page (live readings, Guard state, report and note, PDF download) show the result.&lt;/li&gt;
&lt;li&gt;A red stop &lt;strong&gt;latches&lt;/strong&gt; until a human clears it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What I measured
&lt;/h3&gt;

&lt;p&gt;Every number here is from a test I actually ran. The full details (date, setup and number of trials) are in &lt;code&gt;docs/measurements.md&lt;/code&gt; in the repo.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Test&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;KX134 sample rate (target 1,600 Hz)&lt;/td&gt;
&lt;td&gt;1,623–1,627 Hz, no clipping, mic running concurrently&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;INMP441 sample rate (target 16 kHz)&lt;/td&gt;
&lt;td&gt;16,004–16,031 Hz, proportional response 150 Hz–1 kHz, no clipping&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Feature row over the Bridge&lt;/td&gt;
&lt;td&gt;~60–70 bytes per second, no Bridge errors&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gemma 3 1B on the board&lt;/td&gt;
&lt;td&gt;6.5 tok/s prompt, 4.5 tok/s generation (llama.cpp, 3 threads)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gemma reports passing the number validator&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;8 / 8&lt;/strong&gt; once two bugs were fixed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Guard mode on a real motor (an old, slightly wobbly desk fan)&lt;/td&gt;
&lt;td&gt;full calibrate, learn, guard cycle. A genuine 8-row imbalance run turned the light amber and held it steady; shorter blips didn't&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Guard mode false-alarm soak (same fan, healthy)&lt;/td&gt;
&lt;td&gt;zero false amber/red over a ~10 minute guarding window&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Bugs that mattered:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;My number validator read the dash in "10–800 Hz" as a minus sign and rejected every correct Gemma answer. There's a regression test for it now.&lt;/li&gt;
&lt;li&gt;The llama-server was only listening on localhost, so the app's container couldn't reach it.&lt;/li&gt;
&lt;li&gt;With a 3-row debounce, the fan's normal variation made the light flicker amber. Five rows fixed it without hiding the real fault.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;It has to work where there's no internet.&lt;/strong&gt; A flour mill or a roadside repair stall isn't a data centre. An open-weight model on the board keeps working with the router unplugged.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It has to cost nothing to run.&lt;/strong&gt; A technician isn't going to pay a monthly AI bill to check a machine. Open weights on a one-time board are what make a ₹-priced tool possible at all.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It has to learn one motor, not every motor.&lt;/strong&gt; The anomaly model trains on the owner's own machine, on the device, in minutes. A general cloud API knows nothing about a 20-year-old grinder, and never will.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;I needed to control the model, not just call it.&lt;/strong&gt; With an open model I can pick the size that fits the board, keep it out of the decision path, and check its output before anyone sees it. A closed API hands me a black box behind a network call I can't guarantee.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  My Agent Session
&lt;/h2&gt;

&lt;p&gt;I used Claude Code as a coding agent for the App Lab side: the web page and the Python app logic. Everything it wrote was reviewed and tested by me on real hardware before it stayed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who This Is For
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Who&lt;/th&gt;
&lt;th&gt;Why it fits them&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Independent repair technicians&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Visit several small shops a day, currently diagnose by ear and experience alone&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Small business owners&lt;/strong&gt; (flour mills, juice carts, tea stalls, small workshops)&lt;/td&gt;
&lt;td&gt;Own one or two motors their daily income depends on, can't afford unplanned downtime&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Rental and tool-library operators&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;More on this below; one of the more interesting angles once the probe is cheap and small enough&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Appliance and small-machine repair shops&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Front-counter diagnostic to show a customer the actual reading instead of just a verbal opinion&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Market and Business Potential
&lt;/h2&gt;

&lt;p&gt;Small motors are everywhere in the informal and small-business economy: home appliances, small workshops, agricultural pumps, kitchen equipment, retail fans and mixers. This segment is usually the last to get any kind of predictive maintenance, because every existing vibration-monitoring product is priced, sized and documented for a factory floor, not a single shop owner with one machine.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tier&lt;/th&gt;
&lt;th&gt;Sold as&lt;/th&gt;
&lt;th&gt;Why it works&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Check mode&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;One-time tool purchase, technician&lt;/td&gt;
&lt;td&gt;Pays for itself the first time it turns a guess into a confident, documented diagnosis&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Guard mode&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Bundle: probe + stop plug&lt;/td&gt;
&lt;td&gt;The "insurance" tier for an owner protecting one critical motor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Rental&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Day or week rate, tool library&lt;/td&gt;
&lt;td&gt;No setup beyond a magnet, no network; fits alongside multimeters and clamp meters technicians already rent&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Rental potential&lt;/strong&gt;, in more detail: a technician who doesn't do enough vibration diagnosis to justify owning one can rent it for a day's rounds. A shop owner deciding whether a motor is worth repairing can rent it for a single Check-mode reading instead of buying outright. That's the group least able to justify buying specialist equipment, and renting gets it into their hands anyway.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scalability:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Factor&lt;/th&gt;
&lt;th&gt;Why it scales&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Software cost&lt;/td&gt;
&lt;td&gt;Fault rules, anomaly model and report generation run the same for one probe or a thousand; nothing leaves the device, so there's no cloud bill that grows with usage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hardware cost&lt;/td&gt;
&lt;td&gt;Commodity MCU/MPU board plus two off-the-shelf sensors, prices that drop with order volume, unlike a purpose-built industrial sensor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Per-unit setup&lt;/td&gt;
&lt;td&gt;Guard mode's "normal" is learned on-device from the specific motor it's attached to, so the same firmware works on a desk fan, a flour mill or a water pump with no per-machine tuning from me&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Upsell path&lt;/td&gt;
&lt;td&gt;Check mode is the low-friction, one-time entry point; Guard mode plus the stop plug is the recurring-value tier once someone trusts the diagnosis&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  SWOT Analysis
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Strengths&lt;/th&gt;
&lt;th&gt;Weaknesses&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Fully offline AI-assisted monitoring with no recurring cloud or AI inference fees&lt;/td&gt;
&lt;td&gt;Field validation is at an early stage, with initial testing on two household fans; broader testing across different motor types and fault conditions is the next milestone&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Learns each motor's individual baseline, making the approach adaptable to different machines instead of relying entirely on fixed thresholds&lt;/td&gt;
&lt;td&gt;The optional relay-based stop plug is designed but still needs hardware validation; the current prototype demonstrates a latched warning state rather than a verified automatic power cut-off&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Combines vibration analysis, anomaly detection and Gemma 3 1B on a single Arduino UNO Q platform&lt;/td&gt;
&lt;td&gt;Direct temperature and current sensing are planned extensions; the current heat budget is an estimate based on runtime and overload conditions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Keeps critical decisions in transparent rules and anomaly detection, while validating every number generated by the language model&lt;/td&gt;
&lt;td&gt;The current enclosure is a functional, low-cost prototype; a durable enclosure is needed before deployment in demanding industrial environments&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Supports both handheld inspections and a scalable architecture with multiple independent monitoring probes&lt;/td&gt;
&lt;td&gt;Long-term reliability and diagnostic performance under real industrial operating conditions remain to be established&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Opportunities&lt;/th&gt;
&lt;th&gt;Threats&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;A potential underserved market among small businesses, workshops, farms and factories that need monitoring without expensive industrial infrastructure&lt;/td&gt;
&lt;td&gt;Established industrial monitoring companies could introduce lower-cost alternatives&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deploy multiple probes across a facility to monitor individual motors, enabling a gradual move from manual inspections to continuous condition monitoring&lt;/td&gt;
&lt;td&gt;Incorrect fault indications could affect user trust, making transparent measurements, validation and field testing essential&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A rental or tool-library model could make vibration diagnostics accessible to technicians who cannot justify buying specialist equipment&lt;/td&gt;
&lt;td&gt;Dust, vibration, accidental drops and other harsh operating conditions could challenge hardware durability&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Expand fault detection with additional sensors, more fault signatures and improved datasets without replacing the core architecture&lt;/td&gt;
&lt;td&gt;Different motor types and operating conditions may require further calibration and validation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Generate understandable, potentially multilingual maintenance reports locally using the existing Gemma pipeline&lt;/td&gt;
&lt;td&gt;Adoption will depend on demonstrating practical accuracy, reliability and value compared with existing alternatives&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Build a cost-effective alternative for organisations that want to monitor multiple machines without paying recurring cloud inference fees&lt;/td&gt;
&lt;td&gt;Safety-critical automatic shutdown requires rigorous hardware testing and safeguards before real-world deployment&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Best Use of Arduino&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Runs models on the board:&lt;/strong&gt; the fault rules, an IsolationForest trained on the device, and Gemma 3 1B through llama.cpp, all offline on the UNO Q.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A physical agent that senses and acts:&lt;/strong&gt; it senses vibration (KX134) and sound (INMP441), and acts through a status LED and a latched stop a human has to clear.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Uses what makes the UNO Q different:&lt;/strong&gt; the STM32 handles the real-time sampling, the FFT and the button/LED; Linux handles the learning, the language and the web page; the two talk over the Bridge.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Best Use of Gemma&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Gemma 3 1B writes every report and daily note &lt;strong&gt;on the board&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;It's kept out of the decision path on purpose, and every number it writes gets checked against the measurements before anyone sees it (8/8 passed).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Limits and what's next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The stop plug&lt;/strong&gt; (XIAO ESP32-S3 + relay, paired over Wi-Fi with signed "OK to run" permits, fail-safe on any lost signal) is coded but &lt;strong&gt;not yet tested on real hardware&lt;/strong&gt;. That's the next step, so right now the "stop" is the latched red state, not a verified mains cut-off.&lt;/li&gt;
&lt;li&gt;Validated so far on &lt;strong&gt;two real motor&lt;/strong&gt; (two desk fans(one new and one a old fan)). Induced-fault trials on more machines, bearing faults especially, are next.&lt;/li&gt;
&lt;li&gt;No winding temperature or current sensing yet. The heat budget is an estimate from run time and load.&lt;/li&gt;
&lt;li&gt;No 3D printer on hand, so the enclosure is a hand-built cardboard prototype. A printed or molded shell comes once i get access to a 3D printer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Power:&lt;/strong&gt; the prototype runs off USB for convenience while building it. A real deployment doesn't need to stay tied to a cable. A handheld Check-mode probe makes more sense on a rechargeable battery, while a Guard-mode unit left mounted on one motor could just as well stay on mains/USB power full-time. The electronics don't force this choice either way; the power source is picked per use case.&lt;/li&gt;
&lt;li&gt;It's a diagnostic aid, not a certified instrument. The ISO zones are field indications.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
    </item>
    <item>
      <title>Daybreak: a phone box that only opens after you've touched grass, offline on an Arduino UNO Q</title>
      <dc:creator>Abhinav krishna N</dc:creator>
      <pubDate>Mon, 12 Oct 2026 06:45:06 +0000</pubDate>
      <link>https://dev.to/abhinavkrishna3211/daybreak-a-phone-box-that-only-opens-after-youve-touched-grass-offline-on-an-arduino-uno-q-4kh3</link>
      <guid>https://dev.to/abhinavkrishna3211/daybreak-a-phone-box-that-only-opens-after-youve-touched-grass-offline-on-an-arduino-uno-q-4kh3</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-week1-2026-10-05"&gt;Hacktoberfest Open-Source AI Challenge Week 1: Touch Grass&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;I snooze, then I scroll. The phone is the last thing I see at night and the first thing I grab in the morning, and my alarm can't fix that, because the alarm lives on the device I'm trying to get away from.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Daybreak&lt;/strong&gt; is a bedside box that keeps my phone overnight and only gives it back after I've carried the box outside, walked, and stood in daylight. "Touch grass" is literally the unlock condition. While I'm out there, the phone is still in the box, so those minutes are screen-free too.&lt;/p&gt;

&lt;p&gt;The box has a voice: &lt;strong&gt;Jarvis&lt;/strong&gt;, a dry-witted butler that runs &lt;strong&gt;fully offline on an Arduino UNO Q&lt;/strong&gt;. Jarvis wakes me up, takes tomorrow's plan by voice the night before, reads me today's plan while I'm standing outside in the sunlight waiting for the box to unlock, and talks me through a short rest session when I can't sleep.&lt;/p&gt;

&lt;p&gt;A day with Daybreak:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Evening:&lt;/strong&gt; an hour before bedtime, Jarvis nudges me: &lt;em&gt;"An hour to bedtime, sir. Shall we plan tomorrow?"&lt;/em&gt; I say &lt;em&gt;"Hey Jarvis, tomorrow I have a lab at 9:30 and lunch with Amal at noon."&lt;/em&gt; Jarvis repeats back the checked plan and writes tomorrow's briefing overnight.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;To-do list:&lt;/strong&gt; &lt;em&gt;"Hey Jarvis, add buy filament to my list."&lt;/em&gt; · &lt;em&gt;"What's on my to-do list?"&lt;/em&gt; · &lt;em&gt;"Mark buy filament done."&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bedtime:&lt;/strong&gt; phone into its little bed, blanket shut. &lt;em&gt;"Hey Jarvis, sleep time."&lt;/em&gt; → &lt;em&gt;"Locked. Alarm at 6:30, sir. Sleep well."&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Can't sleep:&lt;/strong&gt; &lt;em&gt;"Hey Jarvis, I can't sleep."&lt;/em&gt; → Jarvis offers a guided rest session (10 or 20 minutes, NSDR-style), a 5-minute wind-down or a 2-minute breathing reset, all in his calm voice and ending in silence. After bedtime he speaks quieter and slower, and skips the chime.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Morning:&lt;/strong&gt; Jarvis wakes me. The blanket stays locked.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The gate:&lt;/strong&gt; I carry the box outside. It checks that the steps are real walking (steady cadence, carried upright, so shaking it in bed doesn't count), then that I'm actually outside in real daylight.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;While I wait in the sun:&lt;/strong&gt; Jarvis reads me today's plan (the briefing, written the night before), and I can keep talking: &lt;em&gt;"How long left?"&lt;/em&gt;, &lt;em&gt;"What's next?"&lt;/em&gt;, &lt;em&gt;"Add buy filament to my list."&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unlock:&lt;/strong&gt; &lt;em&gt;"Daylight confirmed. Releasing your phone, sir."&lt;/em&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It's for anyone whose phone wins the first ten minutes of the day. That's me.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fidgtnb67zu049cf0thqq.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fidgtnb67zu049cf0thqq.jpeg" alt=" " width="800" height="1067"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Everything inside: Arduino UNO Q, light and UV sensors, motion sensor, RTC, two N20 gear motors, mic, speaker.&lt;/em&gt;&lt;/p&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F21wdkg7m7nvw67mwz3o1.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F21wdkg7m7nvw67mwz3o1.jpeg" alt=" " width="800" height="1082"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The 3D-printed parts: a little bed for the phone, with a blanket that locks over it.&lt;/em&gt;(Edited from an Open source design of HTX Studios)&lt;/p&gt;
&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;



&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/G9Y8Y0Z6kww" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;em&gt;"Hey Jarvis" → chime → I speak → Whisper transcribes → Jarvis answers in his own voice, all on the board with Wi-Fi off.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/Abhinavkrishna3211" rel="noopener noreferrer"&gt;
        Abhinavkrishna3211
      &lt;/a&gt; / &lt;a href="https://github.com/Abhinavkrishna3211/Daybreak" rel="noopener noreferrer"&gt;
        Daybreak
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A box that keeps your phone until you've been outside in real daylight, then tells you your day, and talks you down at night, all offline.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Daybreak&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;A bedside box that keeps your phone until you've stood in real daylight, then tells you your day. Fully offline on an Arduino UNO Q.&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Night:&lt;/strong&gt; put the phone in and say "Hey Jarvis, sleep time". The box locks and stays locked until morning (override button always works).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Morning:&lt;/strong&gt; one alarm, snooze off by default. The lid stays shut until you carry the box outside, walk, and stand in daylight for long enough. A UV-to-visible ratio (plus optional mains-flicker detection) separates sunlight from lamps and phone torches.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unlock:&lt;/strong&gt; the lid releases and an offline voice reads your plan: what, when and where.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Evening:&lt;/strong&gt; press &lt;em&gt;talk&lt;/em&gt; and say tomorrow's plan. Speech to text → rules extract the times and places → a validator rejects anything that wasn't actually said. The plan is built by rules alone, never by the language model: on this board the model got the structure wrong…&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/Abhinavkrishna3211/Daybreak" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;The repo is a proper App Lab app (importable as a zip) with a full build guide (&lt;code&gt;TUTORIAL.md&lt;/code&gt;), every benchmark in &lt;code&gt;docs/measurements.md&lt;/code&gt;, and the raw CSVs in &lt;code&gt;data/bench/&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Used
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Hardware&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Part&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Arduino UNO Q (4 GB)&lt;/td&gt;
&lt;td&gt;Linux side (Qualcomm QRB2210): speech, Gemma, voice, dashboard. STM32U585 side: sensors, lock, alarm, safety&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;BH1750 ambient light sensor&lt;/td&gt;
&lt;td&gt;Measures lux for the daylight check&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GUVA-S12SD UV sensor&lt;/td&gt;
&lt;td&gt;UV level, to tell real sunlight from lamps and phone torches&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MPU6050 (GY-521)&lt;/td&gt;
&lt;td&gt;Counts steps, checks walking cadence and that the box is carried upright&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DS3231 RTC + coin cell&lt;/td&gt;
&lt;td&gt;Keeps the alarm on time through power cuts, with no internet&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2× N20 gear motors&lt;/td&gt;
&lt;td&gt;Roll the 3D-printed blanket shutter over the phone&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DRV8833 dual motor driver&lt;/td&gt;
&lt;td&gt;Drives the two lock motors&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Microswitch + reed switch&lt;/td&gt;
&lt;td&gt;Phone in the bed / blanket shut&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Active 5 V buzzer&lt;/td&gt;
&lt;td&gt;Alarm, run by the MCU alone&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2 push buttons&lt;/td&gt;
&lt;td&gt;Override (always opens) and talk&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;USB microphone + USB speaker&lt;/td&gt;
&lt;td&gt;Jarvis's ears and voice&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Powered USB-C hub + 30 W+ USB-C charger&lt;/td&gt;
&lt;td&gt;Power and audio through the UNO Q's single port&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10,000 mAh power bank&lt;/td&gt;
&lt;td&gt;Runs the box on the walk outside&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3D-printed enclosure (PLA)&lt;/td&gt;
&lt;td&gt;The phone's bed, blanket shutter and sensor window&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Software and models (all open, all offline)&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Arduino App Lab + bricks (&lt;code&gt;keyword_spotting&lt;/code&gt;, &lt;code&gt;web_ui&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;App structure, wake word, dashboard&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Edge Impulse&lt;/td&gt;
&lt;td&gt;Trained my own "Hey Jarvis" wake-word model&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Whisper (whisper.cpp / pywhispercpp)&lt;/td&gt;
&lt;td&gt;Speech to text&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gemma 3 1B QAT Q4_0 via llama.cpp &lt;code&gt;llama-server&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Morning briefing and open questions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Piper TTS&lt;/td&gt;
&lt;td&gt;Jarvis's voice&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Python + pytest&lt;/td&gt;
&lt;td&gt;Planner, gate, assistant logic and 200+ tests&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Arduino (STM32 sketch)&lt;/td&gt;
&lt;td&gt;Sensors, motors, alarm, watchdog&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;KiCad&lt;/td&gt;
&lt;td&gt;Schematic&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Schematic
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbr1lavfuolxu61pomu7l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbr1lavfuolxu61pomu7l.png" alt=" " width="800" height="481"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;KiCad schematic: UNO Q with the I²C sensors (BH1750, DS3231, MPU6050), GUVA-S12SD UV, DRV8833 driving the two N20 motors, buzzer, buttons, and the phone and lid switches.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;p&gt;The UNO Q fits this project because it's two computers in one. &lt;strong&gt;The STM32 handles everything that must never fail&lt;/strong&gt; (sensors, the blanket lock, alarm, safety timers). &lt;strong&gt;Linux on the Qualcomm QRB2210 handles everything smart.&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Open tech&lt;/th&gt;
&lt;th&gt;Runs on&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Wake word&lt;/td&gt;
&lt;td&gt;My own &lt;strong&gt;Edge Impulse&lt;/strong&gt; "Hey Jarvis" model, App Lab &lt;code&gt;keyword_spotting&lt;/code&gt; brick&lt;/td&gt;
&lt;td&gt;Linux&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Speech to text&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Whisper&lt;/strong&gt; (whisper.cpp via pywhispercpp), &lt;code&gt;base.en&lt;/code&gt;, &lt;code&gt;audio_ctx=512&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Linux&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Language&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Gemma 3 1B QAT Q4_0&lt;/strong&gt; via a supervised &lt;code&gt;llama-server&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Linux&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Voice&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Piper&lt;/strong&gt;, British male voice&lt;/td&gt;
&lt;td&gt;Linux&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dashboard&lt;/td&gt;
&lt;td&gt;App Lab &lt;code&gt;web_ui&lt;/code&gt; brick, port 7000&lt;/td&gt;
&lt;td&gt;Linux&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sensing and safety&lt;/td&gt;
&lt;td&gt;BH1750 light, GUVA-S12SD UV, MPU6050 motion, DS3231 clock, phone/lid switches, buzzer&lt;/td&gt;
&lt;td&gt;STM32&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;The lock&lt;/td&gt;
&lt;td&gt;2× N20 gear motors on a DRV8833 driver, rolling the 3D-printed blanket shutter over the phone&lt;/td&gt;
&lt;td&gt;STM32&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  The most useful thing I measured: where Gemma does &lt;em&gt;not&lt;/em&gt; belong
&lt;/h3&gt;

&lt;p&gt;My first design had Gemma turn "tomorrow I have a lab at 9:30 and lunch with Amal at noon" into a structured plan. Before trusting it, I benchmarked every Gemma variant that fits the 4 GB board on 20 hand-labelled transcripts.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Best Gemma score: 5/20.&lt;/strong&gt; The fastest model that could hold a JSON schema missed my latency limit by 5× (p90 &lt;strong&gt;108 s&lt;/strong&gt; against a 20 s limit).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Plain Python rules: 20/20, in under a millisecond.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So the measurement changed the architecture. &lt;strong&gt;Python owns the facts&lt;/strong&gt; (times, places, your alarm). &lt;strong&gt;Gemma owns the words:&lt;/strong&gt; it writes the morning briefing and answers open questions, and every draft goes through a deterministic check (every plan time present, no invented times or places, ≤ 45 words) before Jarvis says it.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Briefing setup (full load: wake word + Whisper + Piper + LLM all running)&lt;/th&gt;
&lt;th&gt;Score&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Stock Gemma 3 1B Q4_0&lt;/td&gt;
&lt;td&gt;8/10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;+ QAT weights&lt;/td&gt;
&lt;td&gt;9/10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;+ check and retry (≤ 3 drafts)&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;10/10&lt;/strong&gt;, 1.2 attempts on average&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A full-load briefing takes about 39 s (median), which is far too slow for the morning. So it's written &lt;strong&gt;at night, when the plan is saved&lt;/strong&gt;, and the morning only waits on Piper. Open questions (&lt;code&gt;ask&lt;/code&gt;) score 10/10 at a p90 of 11.3 s.&lt;/p&gt;

&lt;p&gt;Other numbers from the board:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Gemma 270m vs 1B:&lt;/strong&gt; 270m is 3× faster (60 prompt / 18 generation tok/s) but scores 1–4/10 on the briefing. It can't hold the voice and the constraint at once.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Threads:&lt;/strong&gt; prompt speed scales linearly up to 4 cores (15.8 → 61.2 tok/s), but 4 threads under full load &lt;strong&gt;reset the board twice&lt;/strong&gt;, so it ships with 3.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Wake word:&lt;/strong&gt; threshold 0.75 gives 0.90–1.00 recall at 1–3 m (even with a fan running) and one false wake in ten minutes of continuous speech.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Whisper:&lt;/strong&gt; &lt;code&gt;tiny.en&lt;/code&gt; is 1.6 s per command; &lt;code&gt;base.en&lt;/code&gt; costs +1.9 s and is noticeably more accurate on times, so it won.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Bugs I only found by running it on the real board
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Every spoken reply was silently failing: the Piper voice path pointed at a host folder that App Lab doesn't mount into the app container.&lt;/li&gt;
&lt;li&gt;The night lock reused the morning's flat 90-minute limit, so it would have released my phone at 11:30 pm. No test caught it, so I wrote dispatcher tests for &lt;code&gt;main.py&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;A missing light sensor reads as &lt;code&gt;0xFFFFFFFF&lt;/code&gt; = 4.29 billion lux, &lt;em&gt;brighter than the sun&lt;/em&gt;, which would have opened the gate indoors. The gate now rejects anything above 200,000 lux.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Safety (it holds your phone all night)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The blanket opens if the power goes.&lt;/strong&gt; The N20 gearing is backdrivable and the motors are only driven for a moment to move the shutter, so an unpowered box never traps the phone.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Override button&lt;/strong&gt; on the MCU opens it instantly, any time. Emergency calls are one press away.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hard-release timer&lt;/strong&gt; (alarm + 90 min) and a &lt;strong&gt;watchdog&lt;/strong&gt; (Linux silent for 30 s → open).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The alarm runs on the STM32 off a DS3231 RTC,&lt;/strong&gt; so it still rings if the AI side crashes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The science behind it (and where Andrew Huberman comes in)
&lt;/h3&gt;

&lt;p&gt;The idea for Daybreak came from Andrew Huberman's &lt;strong&gt;&lt;a href="https://www.hubermanlab.com/toolkit-for-sleep" rel="noopener noreferrer"&gt;Toolkit for Sleep&lt;/a&gt;&lt;/strong&gt;. He pulls a set of findings into one practical routine: get outside into daylight soon after waking, keep a fixed wake time, and keep bright light (screens) away at night. I kept failing at the first step, because my phone always won. So I built a box that makes the routine the default.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why morning sunlight, and why the cortisol timing matters.&lt;/strong&gt; Your body clock is set mainly by light hitting your eyes. Cortisol is meant to be &lt;strong&gt;high in the morning&lt;/strong&gt;, when it peaks shortly after waking to get you alert and moving, and &lt;strong&gt;low at night&lt;/strong&gt;, so melatonin can rise and you can fall asleep. Bright morning light lines that rhythm up with the actual day. Bright light late at night pushes it the wrong way. Daybreak attacks both ends: daylight in the morning, the phone in bed at night.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The studies behind each feature:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;What the research says&lt;/th&gt;
&lt;th&gt;Source&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Daylight gate&lt;/td&gt;
&lt;td&gt;Bright light in the morning produces an acute &lt;strong&gt;rise in cortisol&lt;/strong&gt;, part of how light signals "daytime" to the body&lt;/td&gt;
&lt;td&gt;Jung CM et al., &lt;em&gt;J Biol Rhythms&lt;/em&gt; 2010&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Daylight gate&lt;/td&gt;
&lt;td&gt;A week of camping with only natural light shifted people's internal clocks about &lt;strong&gt;2 hours earlier&lt;/strong&gt;, lining sleep up with sunrise&lt;/td&gt;
&lt;td&gt;Wright KP Jr et al., &lt;em&gt;Curr Biol&lt;/em&gt; 2013 (n=8); Stothard ER et al., &lt;em&gt;Curr Biol&lt;/em&gt; 2017&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Daylight gate&lt;/td&gt;
&lt;td&gt;People with &lt;strong&gt;brighter days and darker nights&lt;/strong&gt; had lower mortality risk and fewer psychiatric disorders (wrist light sensors, ~86–88k people)&lt;/td&gt;
&lt;td&gt;Windred DP et al., &lt;em&gt;PNAS Nexus&lt;/em&gt; 2024; Burns AC et al., &lt;em&gt;Nature Mental Health&lt;/em&gt; 2023&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Phone in bed at night&lt;/td&gt;
&lt;td&gt;Reading on a light-emitting screen before bed &lt;strong&gt;suppressed melatonin&lt;/strong&gt;, delayed its onset and pushed the body clock later, compared with a printed book, in the same people&lt;/td&gt;
&lt;td&gt;Chang AM et al., &lt;em&gt;PNAS&lt;/em&gt; 2015&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;One fixed wake time&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Sleep regularity&lt;/strong&gt; predicted mortality risk better than sleep duration (~61,000 people)&lt;/td&gt;
&lt;td&gt;Windred DP et al., &lt;em&gt;Sleep&lt;/em&gt; 2024&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Planning tomorrow before bed&lt;/td&gt;
&lt;td&gt;Writing tomorrow's to-do list helped people &lt;strong&gt;fall asleep faster&lt;/strong&gt; (n=57)&lt;/td&gt;
&lt;td&gt;Scullin MK et al., &lt;em&gt;J Exp Psychol Gen&lt;/em&gt; 2018&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Plan says &lt;em&gt;when&lt;/em&gt; and &lt;em&gt;where&lt;/em&gt;
&lt;/td&gt;
&lt;td&gt;"When-then" plans make people far more likely to follow through (meta-analysis of 94 studies, d = 0.65)&lt;/td&gt;
&lt;td&gt;Gollwitzer &amp;amp; Sheeran, 2006&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2-minute breathing reset&lt;/td&gt;
&lt;td&gt;5 minutes a day of cyclic sighing gave the &lt;strong&gt;biggest mood gain&lt;/strong&gt; of the breathing patterns tested (RCT, 111 adults)&lt;/td&gt;
&lt;td&gt;Balban MY et al., &lt;em&gt;Cell Reports Medicine&lt;/em&gt; 2023&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rest sessions (NSDR-style)&lt;/td&gt;
&lt;td&gt;Yoga nidra &lt;strong&gt;lowered salivary cortisol&lt;/strong&gt; and improved sleep in chronic insomnia (RCT); an 11-minute session lowered stress and improved sleep quality in 341 people&lt;/td&gt;
&lt;td&gt;Datta K et al., &lt;em&gt;Natl Med J India&lt;/em&gt; 2021; Moszeik EN et al., &lt;em&gt;Psychol Res&lt;/em&gt; 2022&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No snooze (configurable)&lt;/td&gt;
&lt;td&gt;The evidence on snoozing is mixed, so no-snooze is my choice, not a rule&lt;/td&gt;
&lt;td&gt;Sundelin T et al., &lt;em&gt;J Sleep Res&lt;/em&gt; 2023&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;How Huberman's numbers map to the gate.&lt;/strong&gt; His toolkit suggests going outside within 30–60 minutes of waking for &lt;strong&gt;about 10 minutes on a clear day, 20 when cloudy, and 30–60 when very overcast&lt;/strong&gt;. Daybreak uses these as adjustable defaults: the brighter the light it measures, the shorter you need to stay out. "NSDR" (non-sleep deep rest) is also his term. Jarvis's sessions are my own original scripts in that style, not his recordings or words.&lt;/p&gt;

&lt;p&gt;I treat this research as the &lt;strong&gt;reason for the design, not proof that the box works&lt;/strong&gt;. Several of these studies are observational or small. Daybreak is not affiliated with or endorsed by Andrew Huberman or Huberman Lab, isn't a medical device, and the rest sessions are relaxation audio, not treatment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;p&gt;This device &lt;strong&gt;sits in my bedroom, listens for its name, and knows when I sleep and wake.&lt;/strong&gt; A cloud version would mean always-on bedroom audio leaving the house. Open models make the private version possible:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Nothing leaves the box.&lt;/strong&gt; No cloud, no camera, no accounts. Audio is transcribed, then deleted.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It works at 6 AM with the router off.&lt;/strong&gt; An alarm that needs the internet isn't an alarm.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It costs nothing to run.&lt;/strong&gt; No API keys, no subscription.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;I could measure it and change it.&lt;/strong&gt; Because the weights run locally, I could benchmark every Gemma variant, quantisation and thread count on my own board, find out it shouldn't extract plans, and redesign around that. With a closed API I'd just have shipped the 5/20 version.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Anyone can rebuild it&lt;/strong&gt; from the repo, retrain the wake word, or swap the voice.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Best Use of Arduino&lt;/strong&gt;: a physical agent on the UNO Q that senses and acts, with open models running on the board.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Senses (STM32):&lt;/strong&gt; visible light + UV ratio, walking steps and rhythm (IMU), phone in the bay, lid closed, real-time clock&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Acts (STM32):&lt;/strong&gt; lid shutter motors, blanket, alarm buzzer, plus override, 30 s watchdog and hard-release timer that work without Linux&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Thinks (Linux on the QRB2210):&lt;/strong&gt; Edge Impulse "Hey Jarvis" wake word, Whisper, Gemma 3 1B QAT and Piper, all on the board, all offline&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Best Use of Gemma:&lt;/strong&gt; Gemma 3 1B QAT doing checked, real work on a 4 GB board, with every variant benchmarked and the results (including where it failed) published.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;The daylight durations are adjustable defaults inspired by Andrew Huberman's published guideline; not affiliated with or endorsed by him. Daybreak isn't a medical device and makes no health claims.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
    </item>
    <item>
      <title>Project JARVIS: The Offline AI Lab Assistant</title>
      <dc:creator>Abhinav krishna N</dc:creator>
      <pubDate>Mon, 05 Oct 2026 06:56:17 +0000</pubDate>
      <link>https://dev.to/abhinavkrishna3211/jarvis-ai-lab-assistant-18jp</link>
      <guid>https://dev.to/abhinavkrishna3211/jarvis-ai-lab-assistant-18jp</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-weekend-2026-10-01"&gt;Hacktoberfest Weekend Challenge: Build for a Friend&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;Ask a new student in a college lab where the vernier is, and most will say nothing. They'll wander, give up, and not come back.&lt;/p&gt;

&lt;p&gt;The IoT club lab at my college is an open space where anyone can walk in and learn about hardware. Nobody is taught from a podium. Students learn from each other, share what they know, and get their hands on real components, and there are a lot of them. The club also hosts workshops. When I was there I hosted workshops too, and I mentored students and taught them.&lt;/p&gt;

&lt;p&gt;Now my junior, John, coordinates the lab. With so many tools and components, and so many people passing through, finding the right one and keeping track of what has been borrowed is a job in itself. John loves automation and cool tech, and he is a big Iron Man fan, so I thought: why not give him his own JARVIS for his lab? That's what I built: an offline AI assistant you talk to, which points a laser at the tool you need, lights up component boxes, and keeps the lending log.&lt;/p&gt;

&lt;p&gt;It runs entirely on an Arduino UNO Q with 2 GB of RAM: no internet, no cloud account, no API key.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Ask out loud, and the dot lands on the hook.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;New students are often too shy to ask where things are. With JARVIS they just ask the wall. It takes the friction out of a first visit, and it makes the lab a bit more fun, so people get curious and start poking around.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How you use it.&lt;/strong&gt; You say the wake command, "Hey Jarvis", and the assistant comes alive. It answers "Yes, sir?" and waits for you to say what you need. Then you just ask in plain words, and it replies out loud, points, or lights up whatever you asked for. Say "No, thank you" and it goes quiet again until the next "Hey Jarvis".&lt;/p&gt;

&lt;p&gt;Here is what it does today. These are examples of what it can do:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;"Where's the vernier?"&lt;/strong&gt; It answers "The vernier caliper is on hook 2, sir. I've highlighted it for you." A servo tilts a small laser pointer onto that hook. The laser lights with the first word of the reply and switches off when the reply ends. Code on both processors also cuts it after 10 seconds regardless.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"I want to measure the size of this groove."&lt;/strong&gt; It works out the tool for the job (the vernier) and points at it. If you just say "I have a job, which tool should I use?", it asks "What's the job?" first.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"Lend two ESP32s to Arjun till Friday."&lt;/strong&gt; It reads the loan back and saves it only after a spoken "yes" or a tap on the dashboard.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"What's overdue?" / "Who has the soldering iron?"&lt;/strong&gt; It answers from the loan log.&lt;/li&gt;
&lt;li&gt;After each answer it asks "Anything else?", and "No, thank you" ends the conversation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It talks just like JARVIS in the Iron Man movies, with lines inspired by the films themselves, made for my Iron Man fan John.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/YpzhfSV0znc" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;JARVIS running on the UNO Q in the lab: wake word, a spoken request, and the reply, all offline.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/Abhinavkrishna3211" rel="noopener noreferrer"&gt;
        Abhinavkrishna3211
      &lt;/a&gt; / &lt;a href="https://github.com/Abhinavkrishna3211/jarvis-lab-assistant" rel="noopener noreferrer"&gt;
        jarvis-lab-assistant
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Offline voice assistant on an Arduino UNO Q that finds tools, lights component boxes and keeps the lending log for a lab. Gemma 3 1B, whisper.cpp and Piper, all on-device
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;JARVIS: an offline lab assistant on the Arduino UNO Q&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;A voice assistant for an open IoT-club lab. Ask it where a tool is and a laser marks the hook; ask for a
component and the LED under its box lights; lend and return hardware by voice and it keeps the log
Everything runs on the board: no internet, no cloud account.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;How it works&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;mic -&amp;gt; "Hey Jarvis" (App Lab keyword spotting, always listening) -&amp;gt; "Good evening, sir."
    -&amp;gt; record until you pause (6 s max) -&amp;gt; whisper.cpp tiny.en -&amp;gt; fuzzy candidate match (about 10 items)
    -&amp;gt; keyword rules; if they give up on a known item, Gemma 3 1B (App Lab llama.cpp runner,
       JSON-schema constrained) -&amp;gt; validator -&amp;gt; SQLite
    -&amp;gt; Piper reply and Bridge calls to the STM32: point / laser / box_led / ring_state
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The model never touches facts it could invent. It returns one short JSON…&lt;/p&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/Abhinavkrishna3211/jarvis-lab-assistant" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  What I Used
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Hardware&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F44vi8bmvxxlq6t0n9n0i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F44vi8bmvxxlq6t0n9n0i.png" alt=" " width="394" height="295"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Arduino UNO Q, 2 GB version&lt;/li&gt;
&lt;li&gt;Servo, 180 degrees (an SG90), to tilt the laser&lt;/li&gt;
&lt;li&gt;Laser module salvaged from an old keychain pointer, switched through a logic-level MOSFET (IRLZ44N) with a series resistor&lt;/li&gt;
&lt;li&gt;Arducam B0490 camera (2 MP, IMX462 sensor, day and IR night vision, USB), watching the tool wall. Its built-in microphone is the microphone JARVIS listens through&lt;/li&gt;
&lt;li&gt;Bluetooth speaker, for JARVIS's voice&lt;/li&gt;
&lt;li&gt;USB-C hub, to connect the camera and other USB devices to the board&lt;/li&gt;
&lt;li&gt;A separate 5 V supply for the servo, sharing ground with the board&lt;/li&gt;
&lt;li&gt;Status ring and LEDs for the component boxes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Software and models&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Arduino App Lab (Bridge between the Linux side and the STM32)&lt;/li&gt;
&lt;li&gt;Gemma 3 1B through llama.cpp&lt;/li&gt;
&lt;li&gt;whisper.cpp tiny.en&lt;/li&gt;
&lt;li&gt;Piper&lt;/li&gt;
&lt;li&gt;A "Hey Jarvis" wake-word model trained in Edge Impulse&lt;/li&gt;
&lt;li&gt;A FOMO object-detection model trained in Edge Impulse (&lt;a href="https://studio.edgeimpulse.com/public/1128889/live" rel="noopener noreferrer"&gt;public project&lt;/a&gt;), which finds the tools on the wall&lt;/li&gt;
&lt;li&gt;SQLite&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mic -&amp;gt; "Hey Jarvis" (my Edge Impulse keyword model) -&amp;gt; cached greeting
    -&amp;gt; record until you pause -&amp;gt; whisper.cpp tiny.en
    -&amp;gt; keyword rules; only if they give up on a known item: Gemma 3 1B -&amp;gt; one JSON action
    -&amp;gt; validate() -&amp;gt; SQLite / servo + laser / box LED -&amp;gt; Piper voice, sentence by sentence
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Open models, all running locally on the board:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Gemma 3 1B&lt;/strong&gt; (open weights), served by App Lab's llama.cpp runner.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;whisper.cpp tiny.en&lt;/strong&gt; for speech to text.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Piper&lt;/strong&gt; for the voice.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A "Hey Jarvis" wake-word model I trained in Edge Impulse&lt;/strong&gt; (MFE plus a small classifier, classes JARVIS and NOISE, about 10 ms per window). It runs inside App Lab's keyword-spotting brick, swapped in with one variable in &lt;code&gt;app.yaml&lt;/code&gt;. The wake word alone never goes to a model: "Hey Jarvis" by itself gets "Yes, sir?" straight from code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fm4esxaomq5uhccksajo6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fm4esxaomq5uhccksajo6.png" alt=" " width="800" height="702"&gt;&lt;/a&gt;&lt;br&gt;
On its validation set the wake-word model reaches 100% accuracy with a loss of 0.08. That set is small and has only the JARVIS and NOISE classes, so I don't read it as proof the model never wakes by mistake. Testing it with more voices is the first item under Still To Do&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A FOMO object-detection model, also trained in Edge Impulse&lt;/strong&gt;, which finds each tool on the wall in the camera image so the laser can follow it (see The camera below).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcj77qk6t41ktqto9v7j7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcj77qk6t41ktqto9v7j7.png" alt=" " width="800" height="868"&gt;&lt;/a&gt;&lt;br&gt;
On the validation set the model scores an F1 of 96.6%. The multimeter and the wire stripper were found every time, and the vernier 80% of the time; the misses were counted as background. Inference takes 22 ms, with 305.5K of peak RAM and 81.3K of flash. The validation set is small, so a single missed vernier moves that score a lot. I treat these numbers as a first check, not as an accuracy claim.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JARVIS is a physical agent.&lt;/strong&gt; It hears a request, decides what to do, and acts in the room: a servo swings the laser onto the right hook.&lt;/p&gt;

&lt;p&gt;The UNO Q's two processors split the work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Linux side (Qualcomm MPU):&lt;/strong&gt; the wake word, whisper.cpp, the keyword rules and Gemma, the validator, SQLite and Piper.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;STM32 side (microcontroller):&lt;/strong&gt; the servo, the laser, the status ring and the box LEDs, called from Python over App Lab's Bridge in about 7 ms per call.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Wiring
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fs5c2crcaoykatv8ibeva.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fs5c2crcaoykatv8ibeva.png" alt=" " width="800" height="566"&gt;&lt;/a&gt;&lt;br&gt;
The main wiring schematic, drawn in KiCad.&lt;/p&gt;

&lt;h3&gt;
  
  
  The pointer
&lt;/h3&gt;

&lt;p&gt;It's built from scrap. The laser module and the servo came from old electronic parts I had at home, not bought.&lt;/p&gt;

&lt;p&gt;What I planned, and what I built. I designed a pan-tilt head: two servos, one to swing the laser sideways and one to tilt it, inside a 3D-printed enclosure. I wrote the wiring and the code for both axes. But I had only one servo and no 3D printer. So the prototype in the demo is a simpler version: one SG90 servo on a cardboard mount, glued together, that moves the laser up and down. The hooks hang in a single column, so one axis is enough to point at the tool, and the camera tells JARVIS where along that column the tool is.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F59kcnofakjcc78adm2pp.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F59kcnofakjcc78adm2pp.jpeg" alt=" " width="800" height="1067"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The old keychain pointer, from a drawer at home.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fonxxip3iriq7l6zwf8q7.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fonxxip3iriq7l6zwf8q7.jpeg" alt=" " width="800" height="1067"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Opened up: the board and contacts I reused. The cells and case stayed behind.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The laser is the module from a keychain pointer with its cells removed. I never measured its output power, so I treat it as an unrated pointer and keep it away from people. It's switched from pin D3 through a logic-level MOSFET (IRLZ44N) and fed from 5 V through a series resistor that limits the current. The servo runs from a separate 5 V supply that shares ground with the board, and the sketch detaches it after each move so it doesn't jitter.&lt;/p&gt;

&lt;p&gt;I started with fixed hook angles (50°, 65° and 79° for the three tools on the wall), found by jogging the servo until the dot sat on the hook. I used them for the first validation, to check that the laser pointed at the right place. Later I trained a FOMO object-detection model in Edge Impulse, and now the laser follows the tool wherever it is placed.&lt;/p&gt;

&lt;h3&gt;
  
  
  The camera
&lt;/h3&gt;

&lt;p&gt;A camera watches the tool wall. I trained a FOMO object-detection model of the wall in Edge Impulse (&lt;a href="https://studio.edgeimpulse.com/public/1128889/live" rel="noopener noreferrer"&gt;public project&lt;/a&gt;). It finds each tool in the camera image, JARVIS turns that position into a servo angle, and the laser points at the tool wherever it hangs. If someone puts the vernier on the wrong hook, the laser follows the tool and JARVIS says "Someone has moved the vernier caliper, sir."&lt;/p&gt;

&lt;h3&gt;
  
  
  Safety
&lt;/h3&gt;

&lt;p&gt;The laser's limits live on the microcontroller as well as in Python. The sketch caps every laser-on at 10 seconds and switches it off by itself, even if Linux crashes mid-reply. The module is current-limited, and I keep it aimed at the wall, never at people.&lt;/p&gt;

&lt;h3&gt;
  
  
  The model never gets the last word
&lt;/h3&gt;

&lt;p&gt;It returns one small JSON action. Code checks that the item exists, the quantity is in stock, the borrower is a name and the date is real, and code does all the date and stock arithmetic. Nothing the model says reaches the database or the laser without that check.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Measured
&lt;/h2&gt;

&lt;p&gt;All numbers come from the board; full tables are in &lt;code&gt;docs/measurements.md&lt;/code&gt;. The 60-command evaluation uses &lt;strong&gt;typed&lt;/strong&gt; commands. The speed numbers come from &lt;strong&gt;spoken&lt;/strong&gt; requests through the mic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A 1B model lost to keyword rules.&lt;/strong&gt; On 60 typed test commands, Gemma 3 1B got 22 right and simple keyword rules got 40. Gemma handled loose wording better, but it labelled almost every loan and return as a search. It also invented answers to small talk: "what's the weather" came back as "the multimeter". On top of that, it takes 28-56 s per request on this board.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So JARVIS uses both.&lt;/strong&gt; The rules answer first, in under a second. Gemma is asked only when the rules give up and the request mentions a known item, and JARVIS says "One moment, sir" before it starts. In a second run on the board, that hybrid scored 45/60, against 41/60 for the rules alone in the same run (the rules scored 40 in the first run; the one-command difference is run-to-run variation). Gemma was called on 18 of the 60 commands, and the net gain was 4 commands the rules missed. When it was wrong, it almost always answered with a search, never a loan or a return, so a mistake costs a wrong pointer, not a wrong record.&lt;/p&gt;

&lt;p&gt;Since then I've added rules for asking about a tool by its job, and the rules alone now score 51/60. One caveat: I wrote the rules while looking at the same 60 commands, so these numbers are optimistic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Speed.&lt;/strong&gt; In the first version the reply took a while to start. Three changes cut that down:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Change&lt;/th&gt;
&lt;th&gt;Before&lt;/th&gt;
&lt;th&gt;After&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Greetings cached at start-up&lt;/td&gt;
&lt;td&gt;2.2-3.6 s from wake to first word&lt;/td&gt;
&lt;td&gt;about 0 s of synthesis&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Replies spoken sentence by sentence (next one synthesised while this one plays)&lt;/td&gt;
&lt;td&gt;2.4-5.5 s before the first word&lt;/td&gt;
&lt;td&gt;1.2-2.3 s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A short filler ("Right, sir.") once whisper has heard words&lt;/td&gt;
&lt;td&gt;silence&lt;/td&gt;
&lt;td&gt;something to hear while it thinks&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;whisper.cpp takes about 1.7 s for a short request. The Bridge call is about 7 ms.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Went Wrong (and Stays In)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Whisper heard "wire stripper" as &lt;strong&gt;"wise triple"&lt;/strong&gt;. The rules gave up, and Gemma recovered the right tool. That one example is the reason for the hybrid design.&lt;/li&gt;
&lt;li&gt;Whisper also transcribed the wake word: "Hey Aradino" matched the &lt;em&gt;Arduino Uno&lt;/em&gt; and lit its box. The wake word is now stripped before parsing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A desk fan&lt;/strong&gt; pushed the mic to full scale for whole recordings. Whisper heard nothing, and JARVIS kept saying "Could you repeat that?" until I found the fan.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The laser pointed at the floor&lt;/strong&gt; for a tool whose hook only existed in placeholder data. Now a tool without a measured hook angle gets a spoken answer and no laser.&lt;/li&gt;
&lt;li&gt;I tried to calibrate the laser by having the camera find the red dot. It never saw the dot on the white foam board. In the end I jogged the servo a few degrees at a time while watching the dot, and wrote the three hook angles down by hand.&lt;/li&gt;
&lt;li&gt;At full volume the Bluetooth speaker distorted. 85% volume and a slower, calmer voice fixed that.&lt;/li&gt;
&lt;li&gt;The Bluetooth speaker paired without bonding and forgot the board on every reboot. It needed &lt;code&gt;pairable on&lt;/code&gt; before pairing.&lt;/li&gt;
&lt;li&gt;JARVIS could wake itself: its own voice came back through the mic. Wake words are now ignored while it speaks and for 1.5 s after (Bluetooth audio lags about a second).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Still To Do
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Retrain "Hey Jarvis" with more voices and an "other speech" class. It only knows JARVIS and NOISE today, so other words can wake it.&lt;/li&gt;
&lt;li&gt;Wire the LED strip under the component boxes and test it on the board.&lt;/li&gt;
&lt;li&gt;Measure the laser's pointing error.&lt;/li&gt;
&lt;li&gt;Load the lab's full inventory: three tools hang on the wall today.&lt;/li&gt;
&lt;li&gt;Record spoken commands from other club members and report accuracy on those.
-Build the two-servo pan-tilt head. It needs a second servo and a 3D-printed enclosure.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;p&gt;A college open lab can't run on an API key. Someone has to pay for it, it needs Wi-Fi that works, and it stops the day the free tier ends. Open-weight models and open runtimes let the whole assistant live on a board we own, work with the router unplugged, and cost nothing per question.&lt;/p&gt;

&lt;p&gt;Because everything is open, I could also measure each piece honestly. When the 1B model lost to plain keyword rules, I could see it, and change the design to use it only where it actually helps.&lt;/p&gt;

&lt;h2&gt;
  
  
  My Agent Session
&lt;/h2&gt;

&lt;p&gt;I built JARVIS with Claude as my coding agent. It wrote most of the Python and the sketch. I did the hardware, the wiring, the Edge Impulse wake-word training, the Edge Impulse Vision model, the testing in the lab and the design decisions. The rules it worked under are in &lt;code&gt;AGENTS.md&lt;/code&gt; in the repo: the model only returns one JSON action, loans need a spoken "yes", the laser always times out, and nothing goes to the cloud. Every number in this post was measured on the board, not estimated.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Arduino:&lt;/strong&gt; JARVIS runs entirely on the Arduino UNO Q: wake word, FOMO model, speech to text, Gemma and the voice on the Linux side, and the servo, laser and LEDs on the STM32 over the Bridge. It senses (it listens), decides, and acts physically (the laser marks the hook), with the laser's safety limits enforced on the microcontroller.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Gemma:&lt;/strong&gt; Gemma 3 1B runs locally on the board through App Lab's llama.cpp runner. It's constrained to emit one JSON action, and code does the stock, dates and validation. I measured it honestly against keyword rules on the same 60 commands and used it where it actually helps.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devchallenge</category>
      <category>weekendchallenge</category>
      <category>hf26challenge</category>
    </item>
  </channel>
</rss>
