Voice-Controlled AI Home Assistant using Raspberry pi pico



Build your own intelligent voice-controlled home assistant using Raspberry Pi Pico! Control LED lights, check temperature, get time updates, and manage home automation devices using natural voice commands. Features speech recognition simulation, text-to-speech responses, and a complete smart home control system. Perfect for learning AI assistant concepts - test everything in Wokwi simulator first!

Key Features

  • Voice command recognition with keyword detection
  • Text-to-speech responses (simulated audio feedback)
  • Smart home control - lights, fan, temperature monitoring
  • Weather updates with temperature display
  • Time and alarm management
  • OLED visual feedback showing recognized commands
  • Multi-color LED status indicators
  • Serial command interface for testing (simulates voice input)
  • Customizable wake word ("Hey Assistant")
Code:
from machine import Pin, I2C, ADC
import time
import framebuf
import dht

# SSD1306 OLED Driver (128x64)
class SSD1306_I2C:
    def __init__(self, width, height, i2c, addr=0x3C):
        self.i2c = i2c
        self.addr = addr
        self.width = width
        self.height = height
        self.pages = height // 8
        self.buffer = bytearray(self.pages * width)
        self.framebuf = framebuf.FrameBuffer(self.buffer, width, height, framebuf.MONO_VLSB)
        self.init_display()
   
    def init_display(self):
        for cmd in (
            0xAE, 0xD5, 0x80, 0xA8, 0x3F, 0xD3, 0x00, 0x40, 0x8D, 0x14,
            0x20, 0x00, 0xA1, 0xC8, 0xDA, 0x12, 0x81, 0xCF, 0xD9, 0xF1,
            0xDB, 0x40, 0xA4, 0xA6, 0xAF
        ):
            self.write_cmd(cmd)
        self.fill(0)
        self.show()
   
    def write_cmd(self, cmd):
        self.i2c.writeto(self.addr, bytearray([0x00, cmd]))
   
    def write_data(self, buf):
        self.i2c.writeto(self.addr, b'\x40' + buf)
   
    def show(self):
        for page in range(self.pages):
            self.write_cmd(0xB0 + page)
            self.write_cmd(0x00)
            self.write_cmd(0x10)
            self.write_data(self.buffer[page * self.width:(page + 1) * self.width])
   
    def fill(self, color):
        self.framebuf.fill(color)
   
    def text(self, string, x, y, color=1):
        self.framebuf.text(string, x, y, color)
   
    def rect(self, x, y, w, h, color):
        self.framebuf.rect(x, y, w, h, color)
   
    def fill_rect(self, x, y, w, h, color):
        self.framebuf.fill_rect(x, y, w, h, color)

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

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

# LED Indicators (Smart Devices)
led_living = Pin(10, Pin.OUT)
led_bedroom = Pin(11, Pin.OUT)
led_kitchen = Pin(12, Pin.OUT)

# Buzzer for Audio Feedback
buzzer = Pin(13, Pin.OUT)

# Wake Button
wake_button = Pin(14, Pin.IN, Pin.PULL_UP)

# System State
devices = {
    "living_room": False,
    "bedroom": False,
    "kitchen": False
}
temperature = 0.0
humidity = 0.0
listening = False

# Text-to-Speech Simulator (Buzzer Tones)
def speak(message, tone_pattern="short"):
    """Simulate speech with buzzer tones and display text"""
    print(f"🔊 Assistant: {message}")
   
    # Display on OLED
    oled.fill(0)
    oled.rect(0, 0, 128, 64, 1)
    oled.text("ASSISTANT", 30, 5)
    oled.fill_rect(0, 16, 128, 1, 1)
   
    # Split message into lines (max 16 chars per line)
    words = message.split()
    lines = []
    current_line = ""
   
    for word in words:
        if len(current_line + word) < 16:
            current_line += word + " "
        else:
            lines.append(current_line.strip())
            current_line = word + " "
    if current_line:
        lines.append(current_line.strip())
   
    # Display up to 4 lines
    y_pos = 25
    for line in lines[:4]:
        oled.text(line, 5, y_pos)
        y_pos += 10
   
    oled.show()
   
    # Audio feedback
    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)

# Update Temperature
def update_temperature():
    global temperature, humidity
    try:
        dht_sensor.measure()
        temperature = dht_sensor.temperature()
        humidity = dht_sensor.humidity()
    except:
        pass

# Display Idle Screen
def show_idle_screen():
    oled.fill(0)
    oled.rect(0, 0, 128, 64, 1)
    oled.text("AI ASSISTANT", 20, 5)
    oled.fill_rect(0, 16, 128, 1, 1)
    oled.text("Say 'Hey'", 30, 25)
    oled.text("or", 52, 35)
    oled.text("Press Button", 20, 45)
    oled.show()

# Display Listening Screen
def show_listening_screen():
    oled.fill(0)
    oled.rect(0, 0, 128, 64, 1)
    oled.text("LISTENING...", 25, 20)
    oled.fill_rect(20, 35, 88, 8, 1)
    oled.show()

# Command Processing
def process_command(command):
    """Parse and execute voice commands"""
    cmd = command.lower().strip()
   
    # Device Control Commands
    if "living" in cmd or "living room" 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")
   
    # All Lights Control
    elif "all lights" in cmd or "all light" in cmd:
        if "on" in cmd:
            led_living.on()
            led_bedroom.on()
            led_kitchen.on()
            devices["living_room"] = True
            devices["bedroom"] = True
            devices["kitchen"] = True
            speak("All lights on", "long")
        elif "off" in cmd:
            led_living.off()
            led_bedroom.off()
            led_kitchen.off()
            devices["living_room"] = False
            devices["bedroom"] = False
            devices["kitchen"] = False
            speak("All lights off", "long")
   
    # Temperature Query
    elif "temperature" in cmd or "hot" in cmd or "cold" in cmd:
        update_temperature()
        speak(f"Temp {temperature}C", "short")
   
    # Humidity Query
    elif "humidity" in cmd:
        update_temperature()
        speak(f"Humidity {humidity}%", "short")
   
    # Weather Query
    elif "weather" in cmd:
        update_temperature()
        speak(f"{temperature}C {humidity}%", "short")
   
    # Time Query
    elif "time" in cmd:
        t = time.localtime()
        speak(f"{t[3]}:{t[4]:02d}", "short")
   
    # Good Morning Routine
    elif "good morning" in cmd or "morning" in cmd:
        led_living.on()
        led_bedroom.on()
        led_kitchen.on()
        devices["living_room"] = True
        devices["bedroom"] = True
        devices["kitchen"] = True
        update_temperature()
        speak("Good morning!", "long")
        time.sleep(1)
        speak(f"{temperature}C", "short")
   
    # Goodnight Routine
    elif "goodnight" in cmd or "good night" in cmd:
        led_living.off()
        led_bedroom.off()
        led_kitchen.off()
        devices["living_room"] = False
        devices["bedroom"] = False
        devices["kitchen"] = False
        speak("Goodnight!", "long")
   
    # Status Check
    elif "status" in cmd:
        count = sum(devices.values())
        speak(f"{count} devices on", "short")
   
    # Help
    elif "help" in cmd:
        speak("Say turn on or off device", "long")
   
    else:
        speak("Not understood", "alert")

# Boot Screen
def show_boot_screen():
    oled.fill(0)
    oled.rect(0, 0, 128, 64, 1)
    oled.text("AI ASSISTANT", 20, 10)
    oled.text("============", 15, 20)
    oled.text("Voice Control", 18, 32)
    oled.text("Initializing..", 15, 45)
    oled.show()
    time.sleep(2)

# Main Program
print("=" * 40)
print("🎤 AI VOICE ASSISTANT STARTING...")
print("=" * 40)

show_boot_screen()
update_temperature()

print("\n📋 AVAILABLE COMMANDS:")
print("  • 'Turn on/off [living room/bedroom/kitchen]'")
print("  • 'Turn on/off all lights'")
print("  • 'What's the temperature?'")
print("  • 'What's the humidity?'")
print("  • 'What time is it?'")
print("  • 'Good morning' / 'Goodnight'")
print("  • 'Status' / 'Help'")
print("\n💡 Type commands in Serial Monitor to simulate voice!")
print("   Or press the wake button.\n")

show_idle_screen()

try:
    while True:
        # Check wake button
        if wake_button.value() == 0:  # Button pressed (active low)
            listening = True
            show_listening_screen()
            speak("Yes?", "short")
            time.sleep(0.5)
           
            # Wait for button release
            while wake_button.value() == 0:
                time.sleep(0.1)
       
        # Simulate voice input via serial (for Wokwi testing)
        # In real implementation, this would be actual speech recognition
        user_input = input("🎤 You: ").strip() if listening else ""
       
        if user_input:
            # Check for wake word
            if "hey" in user_input.lower() or "assistant" in user_input.lower():
                listening = True
                show_listening_screen()
                speak("Yes?", "short")
            elif listening:
                # Process command
                process_command(user_input)
                listening = False
                show_idle_screen()
        else:
            # Update display periodically
            time.sleep(0.1)

except KeyboardInterrupt:
    print("\n\n🛑 Shutting down AI Assistant...")
    led_living.off()
    led_bedroom.off()
    led_kitchen.off()
    buzzer.off()
    oled.fill(0)
    oled.text("GOODBYE!", 35, 28)
    oled.show()

Components Required

diagram.json:

{
  "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": {}
}

  • Raspberry Pi Pico (simulated in Wokwi)
  • 0.96" OLED Display (SSD1306, I2C) - Visual feedback
  • DHT22 Sensor - Temperature/humidity monitoring
  • 3x LEDs (Red, Green, Blue) - Smart device indicators
  • Active Buzzer - Audio feedback/alarms
  • Push Button - Manual wake/command trigger
  • 3x 220Ω Resistors (for LEDs)
  • 10kΩ Resistor (DHT22 pull-up)
  • Breadboard and jumper wires
  • MicroPython firmware on Pico

Circuit Connections

OLED Display (I2C):

  • SDA → GPIO0
  • SCL → GPIO1
  • VCC → 3.3V
  • GND → GND

DHT22 Temperature Sensor:

  • VCC → 3.3V
  • GND → GND
  • Data → GPIO15 (with 10kΩ pull-up to 3.3V)

LED Indicators:

  • Red LED (Living Room) → GPIO10 → 220Ω → GND
  • Green LED (Bedroom) → GPIO11 → 220Ω → GND
  • Blue LED (Kitchen) → GPIO12 → 220Ω → GND

Buzzer (Voice Feedback):

  • Positive → GPIO13
  • Negative → GND

Wake Button:

  • One side → GPIO14
  • Other side → GND (with internal pull-up)

Applications

  • Smart Home Control: Voice-activated lights, fans, and appliances
  • Hands-Free Automation: Control devices while cooking or working
  • Accessibility Aid: Help users with mobility limitations
  • Weather Station: Check temperature and humidity by voice
  • Morning Routine: "Good morning" command turns on lights, shows weather
  • Energy Management: "Goodnight" command turns off all devices
  • Elderly Care: Simple voice commands for seniors
  • Learning AI Concepts: Understand natural language processing basics

What You'll Learn

  • Voice command parsing and keyword matching
  • Natural language processing fundamentals
  • State machine design for AI assistants
  • Multi-device control and synchronization
  • DHT22 sensor integration with voice queries
  • OLED display programming for visual feedback
  • Audio feedback generation (buzzer tones)
  • Command context and intent recognition
  • Real-time system response design
  • Simulated text-to-speech implementation

Voice Commands Supported

Device Control:

  • "Turn on living room light" / "Turn off living room"
  • "Turn on bedroom light" / "Bedroom off"
  • "Turn on kitchen light" / "Kitchen off"
  • "Turn on all lights" / "Turn off all lights"

Information Queries:

  • "What's the temperature?" / "How hot is it?"
  • "What's the humidity?"
  • "What time is it?" / "Tell me the time"
  • "What's the weather?" (shows temp + humidity)

System Commands:

  • "Good morning" (turns on all lights, shows weather)
  • "Goodnight" (turns off all lights, sets sleep mode)
  • "Status" / "System status" (shows all device states)
  • "Help" (displays available commands)

Code Structure

Your MicroPython code will include:

  1. Import libraries (machine, time, DHT, OLED driver)
  2. Initialize all components (OLED, DHT22, LEDs, buzzer, button)
  3. Command dictionary mapping phrases to actions
  4. Voice recognition simulator (serial input parser)
  5. Command processing engine with keyword matching
  6. Device control functions (lights, temperature queries)
  7. Text-to-speech simulator (buzzer tones + OLED text)
  8. Main loop listening for wake word and commands
  9. Status display showing system state

Comments