Voice-Controlled AI Home Assistant using Raspberry pi pico

Voice-Controlled AI Home Assistant with Raspberry Pi Pico – MicroPython Guide | MakeMindz
🎤 Advanced · Raspberry Pi Pico · MicroPython

Voice-Controlled
AI Home Assistant

Build an intelligent smart home voice assistant using Raspberry Pi Pico and MicroPython — with OLED display, DHT22 sensor, multi-room LED control, and buzzer audio feedback.

· By MakeMindz

Raspberry Pi Pico MicroPython SSD1306 OLED DHT22 Wokwi Simulation

🔬 No hardware needed — run the full project free in your browser

▶ Open Free Wokwi Simulation
// 01

What You'll Build

A simplified AI assistant that listens to commands, controls smart home devices, reads sensor data, and displays responses on an OLED screen — all running on a Raspberry Pi Pico.

🎤

Wake Word

Activates on "Hey Assistant" — just like Alexa or Google Home

💡

3-Zone Lighting

Control living room, bedroom, and kitchen lights independently

🌡️

DHT22 Sensor

Real-time temperature and humidity readings on demand

📟

OLED Display

SSD1306 128×64 shows commands and responses visually

🔊

Audio Feedback

Buzzer simulates text-to-speech with short, long, and alert tones

🧠

State Machine

Idle → Listening → Processing — real AI assistant architecture

Smart Routines

"Good Morning" turns all lights on, "Goodnight" shuts everything off

🔬

Wokwi Ready

Fully simulated in Wokwi — no hardware needed to get started

// 02

Key Features

Everything this assistant can do

Voice & Interaction

Wake Word + Command Recognition

The assistant activates on "Hey" or "Assistant" and then processes the next spoken command using keyword-based NLP parsing. Commands are matched against known patterns for device control, sensor queries, and routines.

Smart Home Control

3-Zone LED Device Control

Three LEDs represent the living room (red), bedroom (green), and kitchen (blue). Each can be individually toggled or all controlled at once. Device states are tracked in a dictionary for status reporting.

Sensor Intelligence

DHT22 Temperature & Humidity

Reads live temperature (°C) and humidity (%) from the DHT22 sensor. Responds to natural queries like "What's the temperature?" or "What's the weather?" and displays readings on the OLED.

System Architecture

Idle → Listening → Processing State Machine

The assistant uses a three-state machine: Idle (showing standby screen), Listening (activated by wake word or button), and Processing (executing commands and updating the OLED). This mirrors real AI assistant design.

// 03

Components Required

All available as virtual parts in Wokwi — or build on real hardware!

01

Raspberry Pi Pico

Main microcontroller running MicroPython firmware — manages all peripherals and game logic

02

SSD1306 128×64 I2C OLED Display

Shows boot screen, listening indicator, command responses, and sensor readings

03

DHT22 Temperature & Humidity Sensor

Provides real-time environment data — responds to temperature and humidity voice queries

04

3× LEDs (Red / Green / Blue)

Represent smart devices: Living Room (red), Bedroom (green), Kitchen (blue)

05

Active Buzzer

Produces short, long, and alert tones to simulate text-to-speech audio feedback

06

Push Button (WAKE)

Physical wake trigger — press to activate the assistant without typing the wake word

07

3× 220Ω Resistors

Current-limiting resistors — one in series with each LED

08

Breadboard + Jumper Wires

For physical builds — all connections are pre-wired in the Wokwi simulation

// 04

Pin Wiring Reference

All GPIO connections for Raspberry Pi Pico

ComponentPico PinNotes
OLED SDAGP0I2C data
OLED SCLGP1I2C clock
OLED VCC3V33.3V power
DHT22 SDAGP15Data signal
LED Living RoomGP10220Ω series
LED BedroomGP11220Ω series
LED KitchenGP12220Ω series
🔊 Buzzer (+)GP13(−) to GND
🟢 Wake ButtonGP14PULL_UP, active LOW
💡 I2C Address The SSD1306 OLED uses I2C address 0x3C by default. The Pico uses I2C bus 0 with GP0 (SDA) and GP1 (SCL) at 400 kHz.
💡 PULL_UP on Wake Button The wake button uses Pin.PULL_UP internally — no external resistor needed. Button reads 0 when pressed, 1 when released.
// 05

diagram.json

Paste this into Wokwi to auto-load the full circuit in seconds

1

Open Wokwi

Go to wokwi.com → New Project → Raspberry Pi Pico. Log in with Google to save and share your project.

2

Paste diagram.json

Click the diagram.json tab → select all (Ctrl+A) → delete → paste the JSON below → Ctrl+S to save.

3

Paste main.py

Switch to the main.py tab → paste the full MicroPython code → click ▶ Play to start the simulation.

4

Test via Serial Monitor

Open the Serial Monitor tab → type Hey Assistant to wake it, then type a command like turn on living room.

diagram.json — paste into Wokwi
{
  "version": 1,
  "author": "Voice Assistant Project",
  "editor": "wokwi",
  "parts": [
    { "type": "wokwi-pi-pico", "id": "pico", "top": 0, "left": 0, "attrs": {} },
    {
      "type": "wokwi-ssd1306", "id": "oled1",
      "top": -137.33, "left": 122.67,
      "attrs": { "i2cAddress": "0x3C" }
    },
    {
      "type": "wokwi-dht22", "id": "dht1",
      "top": -145.2, "left": -115.2, "attrs": {}
    },
    {
      "type": "wokwi-led", "id": "led_red",
      "top": 120, "left": -180,
      "attrs": { "color": "red", "label": "Living Room" }
    },
    {
      "type": "wokwi-led", "id": "led_green",
      "top": 120, "left": -100,
      "attrs": { "color": "green", "label": "Bedroom" }
    },
    {
      "type": "wokwi-led", "id": "led_blue",
      "top": 120, "left": -20,
      "attrs": { "color": "blue", "label": "Kitchen" }
    },
    { "type": "wokwi-resistor", "id": "r1", "top": 110, "left": -210, "attrs": { "value": "220" } },
    { "type": "wokwi-resistor", "id": "r2", "top": 110, "left": -130, "attrs": { "value": "220" } },
    { "type": "wokwi-resistor", "id": "r3", "top": 110, "left": -50,  "attrs": { "value": "220" } },
    {
      "type": "wokwi-buzzer", "id": "buzzer1",
      "top": 90, "left": 100,
      "attrs": { "volume": "0.8" }
    },
    {
      "type": "wokwi-pushbutton", "id": "btn1",
      "top": -60, "left": -220,
      "attrs": { "color": "green", "label": "WAKE" }
    }
  ],
  "connections": [
    ["pico:GP0",      "oled1:SDA",     "green",   ["v0"]],
    ["pico:GP1",      "oled1:SCL",     "blue",    ["v0"]],
    ["pico:3V3(OUT)", "oled1:VCC",     "red",     ["v0"]],
    ["pico:GND.8",    "oled1:GND",     "black",   ["v0"]],
    ["pico:3V3(OUT)", "dht1:VCC",      "red",     ["v0"]],
    ["pico:GND.3",    "dht1:GND",      "black",   ["v0"]],
    ["pico:GP15",     "dht1:SDA",      "orange",  ["v0"]],
    ["pico:GP10",     "r1:1",          "red",     ["v0"]],
    ["r1:2",          "led_red:A",     "red",     ["v0"]],
    ["led_red:C",     "pico:GND.4",    "black",   ["v0"]],
    ["pico:GP11",     "r2:1",          "green",   ["v0"]],
    ["r2:2",          "led_green:A",   "green",   ["v0"]],
    ["led_green:C",   "pico:GND.5",    "black",   ["v0"]],
    ["pico:GP12",     "r3:1",          "blue",    ["v0"]],
    ["r3:2",          "led_blue:A",    "blue",    ["v0"]],
    ["led_blue:C",    "pico:GND.6",    "black",   ["v0"]],
    ["pico:GP13",     "buzzer1:1",     "magenta", ["v0"]],
    ["buzzer1:2",     "pico:GND.7",    "black",   ["v0"]],
    ["pico:GP14",     "btn1:1.l",      "yellow",  ["v0"]],
    ["btn1:2.l",      "pico:GND.2",    "black",   ["v0"]]
  ],
  "dependencies": {}
}
⚠️ Important Copy the full JSON including the opening and closing { } braces, or Wokwi will throw a parse error.
// 06

MicroPython Code

Full main.py — paste into Wokwi's editor

① Imports & Pin Setup

main.py — setup
from machine import Pin, I2C, ADC
import time, framebuf, dht

# I2C + OLED
i2c  = I2C(0, scl=Pin(1), sda=Pin(0), freq=400000)
oled = SSD1306_I2C(128, 64, i2c)

# DHT22 Sensor
dht_sensor = dht.DHT22(Pin(15))

# Smart device LEDs
led_living  = Pin(10, Pin.OUT)
led_bedroom = Pin(11, Pin.OUT)
led_kitchen = Pin(12, Pin.OUT)

# Buzzer + Wake button
buzzer      = Pin(13, Pin.OUT)
wake_button = Pin(14, Pin.IN, Pin.PULL_UP)

# Device state dictionary
devices = {
    "living_room": False,
    "bedroom":     False,
    "kitchen":     False
}
temperature = 0.0
humidity    = 0.0
listening   = False

② speak() — Audio + OLED Output

main.py — speak()
def speak(message, tone_pattern="short"):
    """Display on OLED + buzzer audio feedback"""
    print(f"🔊 Assistant: {message}")
    oled.fill(0)
    oled.rect(0, 0, 128, 64, 1)
    oled.text("ASSISTANT", 30, 5)

    # Word-wrap message to 16-char lines
    words = message.split()
    lines, line = [], ""
    for word in words:
        if len(line + word) < 16: line += word + " "
        else: lines.append(line.strip()); line = word + " "
    if line: lines.append(line.strip())

    y = 25
    for l in lines[:4]:
        oled.text(l, 5, y); y += 10
    oled.show()

    # Buzzer tones
    if tone_pattern == "short":
        buzzer.on(); time.sleep(0.1); buzzer.off()
    elif tone_pattern == "long":
        for _ in range(2):
            buzzer.on(); time.sleep(0.15)
            buzzer.off(); time.sleep(0.05)
    elif tone_pattern == "alert":
        for _ in range(3):
            buzzer.on(); time.sleep(0.05)
            buzzer.off(); time.sleep(0.05)
    time.sleep(2)

③ process_command() — Voice NLP Parser

main.py — command parser
def process_command(command):
    cmd = command.lower().strip()

    if "living" in cmd:
        if "on" in cmd:
            led_living.on(); devices["living_room"] = True
            speak("Living room on", "short")
        elif "off" in cmd:
            led_living.off(); devices["living_room"] = False
            speak("Living room off", "short")

    elif "bedroom" in cmd:
        if "on" in cmd:
            led_bedroom.on(); devices["bedroom"] = True
            speak("Bedroom on", "short")
        elif "off" in cmd:
            led_bedroom.off(); devices["bedroom"] = False
            speak("Bedroom off", "short")

    elif "kitchen" in cmd:
        if "on" in cmd:
            led_kitchen.on(); devices["kitchen"] = True
            speak("Kitchen on", "short")
        elif "off" in cmd:
            led_kitchen.off(); devices["kitchen"] = False
            speak("Kitchen off", "short")

    elif "all" in cmd:
        state = "on" in cmd
        led_living.value(state); led_bedroom.value(state)
        led_kitchen.value(state)
        for k in devices: devices[k] = state
        speak(f"All lights {'on' if state else 'off'}", "long")

    elif "temperature" in cmd or "weather" in cmd:
        dht_sensor.measure()
        temperature = dht_sensor.temperature()
        humidity    = dht_sensor.humidity()
        speak(f"{temperature}C {humidity}%", "short")

    elif "time" in cmd:
        t = time.localtime()
        speak(f"{t[3]}:{t[4]:02d}", "short")

    elif "good morning" in cmd or "morning" in cmd:
        led_living.on(); led_bedroom.on(); led_kitchen.on()
        for k in devices: devices[k] = True
        speak("Good morning!", "long")

    elif "goodnight" in cmd or "good night" in cmd:
        led_living.off(); led_bedroom.off(); led_kitchen.off()
        for k in devices: devices[k] = False
        speak("Goodnight!", "long")

    elif "status" in cmd:
        count = sum(devices.values())
        speak(f"{count} devices on", "short")

    elif "help" in cmd:
        speak("Say turn on/off device", "long")

    else:
        speak("Not understood", "alert")

④ Main Loop — State Machine

main.py — main loop
show_boot_screen()
update_temperature()
show_idle_screen()

try:
    while True:
        # Physical wake button (active LOW)
        if wake_button.value() == 0:
            listening = True
            show_listening_screen()
            speak("Yes?", "short")
            while wake_button.value() == 0:
                time.sleep(0.1)

        # Serial input simulates voice (for Wokwi)
        user_input = input("🎤 You: ").strip() if listening else ""

        if user_input:
            if "hey" in user_input.lower() or "assistant" in user_input.lower():
                listening = True
                show_listening_screen()
                speak("Yes?", "short")
            elif listening:
                process_command(user_input)
                listening = False
                show_idle_screen()
        else:
            time.sleep(0.1)

except KeyboardInterrupt:
    led_living.off(); led_bedroom.off(); led_kitchen.off()
    buzzer.off()
    oled.fill(0); oled.text("GOODBYE!", 35, 28); oled.show()
// 07

Supported Voice Commands

Type these in the Wokwi Serial Monitor after saying "Hey Assistant"

💡 Device Control

"Turn on living room light" "Turn off bedroom" "Turn on kitchen" "Turn on all lights" "Turn off all lights"

🌡️ Information Queries

"What's the temperature?" "What's the humidity?" "What time is it?" "What's the weather?"

⏰ Smart Routines

"Good morning" "Goodnight" "Status" "Help"
💡 How to test in Wokwi First type Hey Assistant → press Enter → the OLED shows "LISTENING..." → then type your command e.g. turn on all lights → press Enter.
// 08

What You Will Learn

Key programming and electronics concepts covered by this project

A — Voice NLP Parsing

Keyword-Based Command Matching

Commands are parsed by checking whether keywords like "living", "on", or "temperature" appear in the lowercased input string. This is how simple NLP worked before large language models — fast, lightweight, and perfect for microcontrollers.

B — State Machine Design

Idle → Listening → Processing

The listening boolean flag controls which branch of the main loop runs. This is a classic embedded state machine — the device behaves completely differently based on its current state. Real AI assistants like Alexa use a much more complex version of this same pattern.

C — I2C Communication

OLED Display via I2C Protocol

The SSD1306 OLED communicates over I2C using just two wires (SDA + SCL). The custom driver writes display commands and pixel data via i2c.writeto(). Understanding I2C is essential for connecting sensors, displays, and modules in embedded systems.

D — Sensor Integration

DHT22 Temperature & Humidity

The DHT22 sensor uses a single-wire protocol. Calling dht_sensor.measure() triggers a reading, then .temperature() and .humidity() return the values. Sensor errors are caught with a try/except so the system continues running even if a reading fails.

E — Multi-Device Control

Synchronized Smart Home Logic

All three LEDs share a devices dictionary that tracks on/off state. This lets the "Status" command count active devices, and lets routines like "Good Morning" and "Goodnight" update all lights and their states in a single block of code.

🎤 Raspberry Pi Pico · MicroPython · Smart Home
Voice-Controlled AI Home Assistant · MakeMindz

Comments

try for free