🚀 On-device Voice AI & LLMs
Build commercial, non-commercial, research projects using the Forever-Free Plan.
Start Free

TLDR: Build a fully offline Arduino voice assistant with custom wake words and natural language voice commands. This tutorial demonstrates how to run an end-to-end, on-device voice pipeline on a microcontroller using Picovoice's intent-based voice assistant architecture.

Adding Voice Control to Arduino

Embedding voice assistants in microcontrollers is fundamentally different from building voice assistants for web or phone applications. Boards like the Arduino Nano 33 BLE Sense run without an operating system, lack built-in Wi-Fi, and must process audio in real time within strict CPU and memory limits.

In this tutorial, we'll build an offline voice assistant for Arduino, with wake word detection and intent recognition running on the microcontroller within its CPU and memory constraints. The Arduino listens for a custom wake word using Porcupine Wake Word, then processes custom voice commands with Rhino Speech-to-Intent.

This natural language understanding pipeline directly maps user intent from voice commands without an intermediate transcription step, allowing the engine to achieve a benchmarked command acceptance rate exceeding 97% and outperform major big-tech alternatives.

What You'll Build

Based on Picovoice's pico-cookbook recipe, we will build a voice-controlled timer on Arduino Nano 33 BLE Sense featuring:

  • Wake Word Detection — Activates when you say "Hey Assistant"
  • Voice Command Recognition — Recognizes intents like start, stop, check, reset, and set timer with custom durations
  • LED Visual Feedback — Has different colored feedback for different states
    • 🟣 Magenta flash — Wake word detected (listening for command)
    • 🟢 Solid green — Timer running
    • 🔴 Solid red — Timer paused
    • 🔵 Blue blinks 3x — Checking timer
    • ⚪ White flash 3x — Timer reset
    • 🌈 RGB cycling — Timer complete

Build time: 15-20 minutes

Prerequisites

Hardware

  • Arduino Nano 33 BLE Sense — Built-in microphone (Available from Arduino Store)
  • Micro-USB cable — For programming and power (ensure it's a data cable, not charge-only)

Software

Step 1: Install the Arduino SDK

Open Arduino IDE and install the Picovoice_EN library:

  1. Go to "Tools" → "Manage Libraries"
  2. Search "Picovoice_EN"
  3. Click Install

Step 2: Get Arduino's UUID

Every Arduino Nano 33 BLE Sense has a unique hardware identifier (UUID). You'll need this to train voice models for your specific board. Models trained for one board won't work on others without the correct UUID.

Connect your Arduino and load the UUID extraction sketch:

  1. Go to "File" → "Examples" → "Picovoice_EN" → "GetUUID"
  2. Select board: "Tools" → "Board" → "Arduino Nano 33 BLE"
  3. Select port: "Tools" → "Port" → Select the port connected to the Arduino (e.g., /dev/ttyACM0 for Linux, or COM port on Windows)
  4. Click "Upload"
  5. Copy the displayed UUID (format: 27 0f f3 da f2 a0 d1 c8) from "Tools" → "Serial Monitor"

Step 3: Train Custom Voice Models

Get Your AccessKey

Sign up for an account on the Picovoice Console to get your AccessKey. You'll add this to your Arduino sketch later.

Train a Wake Word Model

Create a custom wake word using Porcupine Wake Word Engine:

  1. Navigate to the Porcupine page in the Picovoice Console.
  2. Click "Train Wake Word" and enter a custom phrase such as "Hey Assistant."
  3. Select platform ("Arm Cortex-M"), board type ("Arduino Nano 33 BLE Sense"), and paste your board UUID.
  4. Click "Train" and download the .zip file containing your wake word model.

Train a Context Model for Custom Voice Commands

Create voice commands using Rhino Speech-to-Intent:

  1. Navigate to Rhino Page in the Picovoice Console.
  2. Click "Create Context" and name it.
  3. Click the "Import YAML" button in the top-right corner of the Console. Paste the YAML provided below to add the intents and expressions for the voice assistant:
  1. Select platform ("Arm Cortex-M"), board type ("Arduino Nano 33 BLE Sense"), and paste your board UUID.
  2. Click "Train" and download the .zip file containing your speech-to-intent model.

The Rhino context defines the vocabulary of voice commands that the voice assistant understands. Each intent maps to natural variations of voice commands that users might say.

Step 4: Open the Arduino Sketch to build the Voice Assistant

Open the Arduino IDE and go to:

"File" → "Examples" → "Picovoice_EN" → "IntentBasedVoiceAssistantExample"

The sketch opens with two tabs:

  • IntentBasedVoiceAssistantExample.ino — Main logic
  • pv_params.h — Model parameters (contains default wake word and context)

Step 5: Configure the Sketch with Custom Voice Models

Update pv_params.h

Unzip the downloaded files from Picovoice Console. You'll have:

Wake word package:

  • .h file containing KEYWORD_ARRAY
  • .ppn file

Context package:

  • .h file containing CONTEXT_ARRAY
  • .rhn file

In the pv_params.h tab, replace:

  • KEYWORD_ARRAY with the array from your wake word .h file
  • CONTEXT_ARRAY with the array from your context .h file

Update AccessKey

In the IntentBasedVoiceAssistantExample.ino tab, find this line and replace with your AccessKey from Picovoice Console:

Step 6: Run & Test Voice Commands on Arduino

  1. Click "Upload" in Arduino IDE and open the "Serial Monitor"
  2. Say "Hey Assistant." You should see a wake word detection message in the Serial Monitor.
  3. After wake word detection, say a voice command e.g., "Start the timer"

The Serial Monitor displays the detected intent and any extracted "slots" or parameters.

Step 7: Add Voice-Controlled Timer & LED Feedback to Arduino

Now let's implement the LED feedback using the Arduino Nano 33 BLE Sense's built-in RGB LED. The timer will support counting up, counting down, pause/resume, and completion alerts.

If you want to skip the breakdown of the code and see the final logic, scroll down to the full code section.

LED Helper Functions for Arduino

Add LED pin definitions and helper functions at the top of your sketch (after the includes):

Create Timer State Machine

Add timer state variables and core timing functions:

Create Timer Control Functions

Add functions to control the timer:

Implement Voice Commands on Arduino

Add a function to map voice intents to timer actions:

Modify the Callback Functions

Update wake_word_callback to add LED feedback:

In inference_callback, call the intent handler when a command is understood:

Initialize LED & Serial Monitor Updates for Arduino

Initialize LED pins:

Add timer display updates at the end of loop():

Full Code for On-Device Voice Control on Arduino

Upload the full voice assistant code to your Arduino and run the voice-controlled timer.

Test the Voice Assistant with these commands:

  • "Hey Assistant, start the timer"
  • "Hey Assistant, count down for 30 seconds"
  • "Hey Assistant, pause timer"
  • "Hey Assistant, check timer"

Watch the LED colors change and monitor status updates in the Serial Monitor

Troubleshooting

Upload fails with "No device found"

  • Try a different USB cable (must support data, not just charging)
  • Double-tap reset button on Arduino for bootloader mode

Wake word not detecting

  • Check Serial Monitor for error messages
  • Verify AccessKey is correct in sketch
  • Ensure models were trained with correct UUID

Intent not understood

  • Use exact phrases from your Rhino context YAML
  • Check that context was trained with your Arduino's UUID
  • View Serial Monitor to see what Rhino heard

Compilation errors

  • Ensure AccessKey is in quotes: "your-key-here"
  • Verify pv_params.h contains both KEYWORD_ARRAY and CONTEXT_ARRAY

Extend Your Arduino Voice Assistant: What to Build Next

Add More Voice Commands

Expand your timer context with additional intents:

  • Multiple timer slots - "set study timer," "set workout timer"
  • Custom notifications - "alert me when timer reaches 5 seconds"

Integrate with Hardware

Connect additional components:

  • Relay modules - Control appliances, lights, or actuators
  • LCD displays - Visual timer display
  • Sensors - Voice-activated data logging ("record temperature")

Build on Multiple Platforms

Explore additional recipes in pico-cookbook:

  • LLM Voice Assistant — Add local LLM intelligence with picoLLM
  • Android/iOS — Build mobile voice assistants
  • Python — Build desktop voice applications
  • STM32 — Build with other ARM Cortex-M microcontrollers

Resources

You can start building your own commercial or non-commercial projects leveraging Picovoice's self-service Console.

Start Building

Frequently Asked Questions

Can I add multiple wake words to the project?
Yes. Porcupine Wake Word supports using multiple wake words simultaneously. You can also create contextual wake words that activate different features.
Can I use this commercially?
Yes. Picovoice offers commercial licenses for production deployments. Free tier includes development and personal projects. Visit pricing for commercial licensing.
Does this support languages other than English?
Yes. Picovoice supports multiple languages including Spanish, French, German, and more. Install the appropriate language library (e.g., Picovoice_ES for Spanish).