Community project

Tiny Robot AI Assistant

Raspberry Pi Pico
Photo of Tiny Robot AI Assistant
Generated with AI

Shaikh Tajmul haque

Published September 13, 2026

This project brings a tiny AI assistant to life on a Raspberry Pi Pico, complete with an expressive OLED face that responds to sound. The robot listens through a microphone amplifier, displays animated expressions on a 128×64 screen, and replies with audio through a small speaker powered by a Class-D amplifier.

The guide provides a complete wiring diagram, parts list, and step-by-step assembly instructions to connect the microphone input stage, speaker output stage, and display. Firmware is included to handle sound detection, facial animation, and audio playback, letting makers build an interactive desk companion that reacts to voice and sound in real time.

Wiring diagram

Wiring diagram for Tiny Robot AI Assistant

Gather all the parts

QtyComponent
1

SSD1306 OLED

0.96 in, 128×64, I2C (0x3C)

0.96 inch 128x64 OLED display with I2C interface

1

MAX4466 Microphone Amplifier

Adjustable gain microphone module

Adafruit MAX4466 electret microphone amplifier breakout with a manual gain trim pot (25x-125x). Outputs analog audio biased at ~VCC/2, swinging roughly 200mVpp at speaking volume up to ~1Vpp, readable by any 3.3V or 5V ADC. Unlike the AGC-based MAX9814 the gain is fixed by the trimmer, so it is best when you want a set gain and predictable dynamic range rather than auto-leveling.

1

PAM8302 2.5W Class-D Amplifier

Mono amplifier module

Adafruit PAM8302 mono 2.5W class-D audio amplifier breakout. VIN accepts 2.0-5.5V, A+/A- are differential audio inputs (tie A- to ground for single-ended PWM/audio), and OUT+/OUT- are bridge-tied speaker outputs that connect directly to the speaker, not to MCU GPIO or ground.

1

8Ω Speaker

8 Ω, 0.5 W or greater

Generic small 8Ω 0.5-3W loudspeaker (~28mm typical). Pair with an I2S amp (MAX98357A) or class-D amp (TPA3116D2) for usable volume; do not drive directly from a GPIO pin. Audio output for music/voice playback.

Assemble it in 5 steps

1. Keep the screen as the robot face

Leave the OLED where it is and check its four wires: VCC → Pico Mini 3V3 (power), GND → Pico Mini GND (ground), SDA → GP4 (data), and SCL → GP5 (timing).

  • Keep the OLED pin labels visible while you add the other parts.
  • Make sure VCC and GND are not swapped — swapped power can damage the screen.

2. Wire the microphone board

Connect MAX4466 VCC → Pico Mini 3V3 (power), MAX4466 GND → Pico Mini GND (ground), and MAX4466 OUT → Pico Mini GP26 (sound signal). Put the microphone opening on the outside of the robot case so your voice can reach it.

  • Use short wires for OUT so electrical noise is less likely to trigger false replies.
  • Start with the tiny gain screw near its middle position.
  • Do not connect the microphone OUT wire to a 5V pin — GP26 accepts only the Pico Mini's 3.3V-level signal.

3. Wire the speaker amplifier

Connect PAM8302 VIN → Pico Mini 3V3 (power), PAM8302 GND → Pico Mini GND (ground), PAM8302 A+ → Pico Mini GP6 (audio signal), and PAM8302 A- → Pico Mini GND (audio reference). Leave the amplifier SD pin unconnected.

  • Use red for VIN and black for every GND wire so you can inspect the power wiring easily.
  • Do not connect the amplifier OUT+ or OUT- terminals to Pico Mini GND — they are two amplified speaker wires.

4. Connect the small speaker

Connect speaker POS → PAM8302 OUT+ (sound signal) and speaker NEG → PAM8302 OUT- (sound return). Mount the speaker with its front facing a hole or grille in the robot body so the sound can get out.

  • Either speaker wire can be swapped for this single speaker; keep the two wires away from loose metal parts.
  • Never connect the speaker directly to a Pico Mini pin — it needs the amplifier board.

5. Test the talking robot

With the USB cable unplugged, inspect every wire once more. Plug the Pico Mini into USB, speak close to the microphone or clap once, and the screen should show I HEAR YOU while the speaker plays a three-note robot reply.

  • If it responds continuously, turn the microphone gain screw down a little.
  • If it never responds, turn the microphone gain screw up a little and speak closer.
  • Disconnect USB before moving any wire so a loose wire cannot touch the wrong pin.

Review all connections

1. Connections between "oled_1" and "Raspberry Pi Pico"

Functionoled_1Raspberry Pi Pico
powerVCC3V3
groundGNDGND
i2cSDAGPIO 4
i2cSCLGPIO 5

2. Connections between "mic_1" and "Raspberry Pi Pico"

Functionmic_1Raspberry Pi Pico
powerVCC3V3
groundGNDGND
analogOUTGPIO 26

3. Connections between "amp_1" and "Raspberry Pi Pico"

Functionamp_1Raspberry Pi Pico
powerVIN3V3
groundGNDGND
pwmA+GPIO 6
groundA-GND
dataOUT+8Ω Speaker POSEXT
dataOUT-8Ω Speaker NEGEXT

Deploy the firmware

#include <Arduino.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>


// Forward declarations
void drawEye(int centerX, bool happy);
void drawFace(const char *message, bool happy);
int readSoundLevel();
void playRobotReply();

constexpr int OLED_SDA_PIN = 4;
constexpr int OLED_SCL_PIN = 5;
constexpr int MIC_PIN = 26;
constexpr int SPEAKER_PIN = 6;
constexpr uint8_t SCREEN_WIDTH = 128;
constexpr uint8_t SCREEN_HEIGHT = 64;
constexpr uint8_t OLED_ADDRESS = 0x3C;
constexpr unsigned long SAMPLE_WINDOW_MS = 45;
constexpr unsigned long REPLY_COOLDOWN_MS = 1800;
constexpr int SOUND_THRESHOLD = 115;

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
unsigned long lastReplyAt = 0;

void drawEye(int centerX, bool happy) {
  display.fillRoundRect(centerX - 11, 18, 22, 21, 8, SSD1306_WHITE);
  display.fillCircle(centerX, happy ? 27 : 29, 5, SSD1306_BLACK);
  display.fillCircle(centerX + 2, happy ? 25 : 27, 2, SSD1306_WHITE);
}

void drawFace(const char *message, bool happy) {
  display.clearDisplay();
  display.drawRoundRect(1, 1, 126, 62, 9, SSD1306_WHITE);
  display.fillRoundRect(51, 4, 26, 4, 2, SSD1306_WHITE);
  drawEye(35, happy);
  drawEye(93, happy);
  if (happy) {
    display.drawLine(53, 46, 75, 46, SSD1306_WHITE);
    display.drawPixel(52, 45, SSD1306_WHITE);
    display.drawPixel(76, 45, SSD1306_WHITE);
  } else {
    display.drawLine(54, 48, 74, 48, SSD1306_WHITE);
  }
  display.setTextColor(SSD1306_WHITE);
  display.setTextSize(1);
  const int16_t textX = (128 - strlen(message) * 6) / 2;
  display.setCursor(textX, 53);
  display.print(message);
  display.display();
}

int readSoundLevel() {
  int lowValue = 1023;
  int highValue = 0;
  const unsigned long started = millis();
  while (millis() - started < SAMPLE_WINDOW_MS) {
    const int value = analogRead(MIC_PIN);
    if (value < lowValue) lowValue = value;
    if (value > highValue) highValue = value;
  }
  return highValue - lowValue;
}

void playRobotReply() {
  tone(SPEAKER_PIN, 660, 120);
  delay(145);
  tone(SPEAKER_PIN, 880, 160);
  delay(185);
  tone(SPEAKER_PIN, 1047, 220);
  delay(245);
  noTone(SPEAKER_PIN);
}

void setup() {
  pinMode(MIC_PIN, INPUT);
  pinMode(SPEAKER_PIN, OUTPUT);
  analogReadResolution(10);
Wire.begin();

  if (!display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDRESS)) {
    for (;;) delay(1000);
  }
  drawFace("SAY HELLO", false);
}

void loop() {
  const int soundLevel = readSoundLevel();
  const unsigned long now = millis();
  if (soundLevel >= SOUND_THRESHOLD && now - lastReplyAt >= REPLY_COOLDOWN_MS) {
    lastReplyAt = now;
    drawFace("I HEAR YOU", true);
    playRobotReply();
    drawFace("SAY HELLO", false);
  }
}

Remix this project

Make it yours in one click

Open a full copy of this project in your own Schematik workspace — diagram, code, parts, and assembly steps included. Swap the sensor, add features, or redesign the whole thing with AI. The author's original stays untouched.

Open in Schematik