AI Storytelling Puppet Robot with Raspberry Pi | Kids Robotics Project

AI Storytelling Puppet Robot with Raspberry Pi | Kids Robotics Project

✨ How Does the Magic Work?

Five simple steps from "Tell me a story!" to puppet show time.

🎤

1. Child Speaks

Microphone listens for a story request

🧠

2. AI Thinks

Claude AI creates a brand new story

📢

3. Robot Narrates

Text-to-speech reads the story aloud

🤖

4. Pi Controls

Raspberry Pi sends commands to servos

🎭

5. Puppets Act!

Puppets move and perform the scenes

💡

Fun Fact for Young Makers!

This project combines three types of engineering — mechanical (moving puppets), electrical (circuits and motors), and software (Python and AI coding). Real robotics engineers use all three together!

🛒 Parts You Will Need

Most of these can be found at electronics shops or ordered online. Ask a grown-up to help!

🫐

Raspberry Pi 4

The brain of the robot. 2GB RAM or more works great.

× 1
🔌

PCA9685 Servo Driver

Controls up to 16 servos at once via I2C.

× 1
⚙️

SG90 Micro Servo Motors

Tiny, lightweight — perfect for puppet arms and heads.

× 4–6
🎤

USB Microphone

Plug-and-play mic to capture the child's story request.

× 1
🔊

USB Speaker / 3.5mm

For the AI narrator's voice to come out loud and clear.

× 1
🧵

Puppet Figures

Foam, felt, or toy puppets. Attach servos to their limbs!

× 2–4
📦

Cardboard / Wood Frame

Build a mini puppet stage to mount everything on.

× 1
🔋

5V 3A Power Supply

Official Raspberry Pi power adapter — servos need good power!

× 1
🪛

Jumper Wires + Breadboard

For making all the connections between components.

× 1 set
⚠️

Parent / Guardian Note

You'll also need a free API key from Anthropic (claude.ai) or OpenAI for the AI story generation. Always get an adult to handle API key setup and wiring.

⚡ Circuit Wiring Diagram

Here's exactly how to connect everything together. Take it one wire at a time!

🔌 Complete Wiring Connection Table

From (Raspberry Pi) To (Component) Wire Colour Purpose
Pin 3 — GPIO 2 PCA9685 → SDA 🔵 Blue I2C Data Line
Pin 5 — GPIO 3 PCA9685 → SCL 🟡 Yellow I2C Clock Line
Pin 1 — 3.3V PCA9685 → VCC 🔴 Red Logic Power
Pin 6 — GND PCA9685 → GND ⚫ Black Ground
External 5V PSU PCA9685 → V+ 🔴 Red Servo Power (separate!)
PCA9685 → CH0 Servo 1 (Puppet Head) 🟠 Orange (signal) PWM Control
PCA9685 → CH1 Servo 2 (Left Arm) 🟠 Orange (signal) PWM Control
PCA9685 → CH2 Servo 3 (Right Arm) 🟠 Orange (signal) PWM Control
PCA9685 → CH3 Servo 4 (Body / 2nd Puppet) 🟠 Orange (signal) PWM Control
USB Port A USB Microphone USB Cable Voice Input
3.5mm Audio Jack Speaker Audio Cable Story Narration Output
⚠️

Important Wiring Rule!

Always power servos from a separate 5V source, NOT directly from the Raspberry Pi's GPIO pins. Too much current from servos will damage your Pi. Use the PCA9685's V+ and GND terminals for servo power.

🔧 Step-by-Step Build Instructions

Work through these steps in order. Take your time — a good build always wins!

1

Set Up Your Raspberry Pi

Install the OS and enable I2C

🫐

Download Raspberry Pi OS (64-bit) from the official site and flash it to your SD card using Raspberry Pi Imager.

  • Boot up the Pi and connect keyboard, monitor, and mouse
  • Go to Preferences → Raspberry Pi Configuration → Interfaces
  • Enable I2C — this lets the Pi talk to the servo driver
  • Connect your USB microphone and USB speaker, then test sound
terminal — install libraries
# Update the system first
sudo apt update && sudo apt upgrade -y

# Install required Python libraries
pip3 install adafruit-circuitpython-pca9685
pip3 install SpeechRecognition
pip3 install pyttsx3
pip3 install anthropic
pip3 install smbus2
sudo apt install python3-pyaudio espeak -y
2

Build the Puppet Stage

Create the physical theatre

🎪

Cut a cardboard box to make a mini theatre stage approximately 50cm wide × 40cm tall.

  • Paint or decorate it with curtains, stars, and backdrops
  • Mount servo motors at the top of the stage using hot glue or zip ties
  • Attach puppet figures to servo arms using thin fishing line or stiff wire
  • Servo 1 (CH0) → puppet head nod | Servo 2 (CH1) → left arm wave
  • Servo 3 (CH2) → right arm | Servo 4 (CH3) → second puppet body
  • Place the speaker inside or behind the stage for best sound effect
🎨

Make It Yours!

Decorate with themes — jungle animals, space explorers, fairy tale characters! The story AI will adapt to whatever puppets you create.

3

Wire Up the Circuit

Connect Pi → PCA9685 → Servos

Follow the wiring table above carefully. Work with the power OFF at all times when connecting wires.

  • Connect I2C wires: GPIO 2 (SDA) and GPIO 3 (SCL) to the PCA9685
  • Connect 3.3V and GND from Pi to PCA9685's logic power pins
  • Connect your separate 5V PSU to PCA9685's V+ and GND (for servo power)
  • Plug each servo into CH0, CH1, CH2, CH3 on the PCA9685
  • Orange wire = signal | Red = 5V | Brown/Black = GND (on each servo)

After wiring, run this quick test to check I2C is detecting the board:

terminal — test I2C
# Should show 0x40 (the PCA9685 address)
i2cdetect -y 1
4

Get Your AI API Key

Connect to Claude AI for story generation

🧠

Ask a parent or guardian to do this step. The AI key lets the robot generate new stories!

  • Go to console.anthropic.com and create a free account
  • Generate an API key under "API Keys"
  • Never share this key publicly or put it directly in code you share
  • Store it safely as an environment variable on your Pi
terminal — save API key safely
# Add to ~/.bashrc so it loads every time
echo 'export ANTHROPIC_API_KEY="your_key_here"' >> ~/.bashrc
source ~/.bashrc

🐍 The Complete Python Code

This is the full program. Copy it into a file called puppet_storyteller.py on your Raspberry Pi.

puppet_storyteller.py
#!/usr/bin/env python3
# ========================================================
#  🎭 AI PUPPET STORYTELLER ROBOT
#  Raspberry Pi + PCA9685 + Claude AI
#  Kids Robotics Project
# ========================================================

import os
import time
import re
import threading
import speech_recognition as sr
import pyttsx3
import anthropic
import board
import busio
from adafruit_pca9685 import PCA9685
from adafruit_motor import servo

# ── SETUP ────────────────────────────────────────────
# Initialize I2C and PCA9685 servo driver board
i2c = busio.I2C(board.SCL, board.SDA)
pca = PCA9685(i2c)
pca.frequency = 50  # Standard servo frequency: 50 Hz

# Create servo objects for each puppet part
# SG90 servos operate between 500μs and 2400μs pulse width
servos = {
    "head":       servo.Servo(pca.channels[0], min_pulse=500, max_pulse=2400),
    "left_arm":  servo.Servo(pca.channels[1], min_pulse=500, max_pulse=2400),
    "right_arm": servo.Servo(pca.channels[2], min_pulse=500, max_pulse=2400),
    "body":       servo.Servo(pca.channels[3], min_pulse=500, max_pulse=2400),
}

# Initialize AI client and speech engine
ai_client  = anthropic.Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])
tts_engine = pyttsx3.init()
tts_engine.setProperty("rate", 145)      # Slightly slower for kids
tts_engine.setProperty("volume", 0.95)   # Nice and loud
recognizer = sr.Recognizer()

# ── PUPPET ANIMATIONS ───────────────────────────────
def move_servo_smooth(servo_obj, start_angle, end_angle, steps=20):
    """Smoothly move a servo from start to end angle."""
    for i in range(steps + 1):
        angle = start_angle + (end_angle - start_angle) * i / steps
        servo_obj.angle = angle
        time.sleep(0.02)

def reset_puppets():
    """Move all puppets to neutral resting position."""
    print("🎭 Resetting puppets to start position...")
    for name, s in servos.items():
        move_servo_smooth(s, s.angle or 90, 90)

def puppet_idle_dance():
    """Gentle idle animation while waiting for a story request."""
    servos["head"].angle = 80
    time.sleep(0.4)
    servos["head"].angle = 100
    time.sleep(0.4)
    servos["head"].angle = 90

def perform_scene(scene_type):
    """Perform a choreographed puppet animation based on scene type."""
    print(ff"🤖 Performing scene: {scene_type}")

    if scene_type == "greeting":
        # Both arms wave hello
        for _ in range(3):
            move_servo_smooth(servos["left_arm"],  90, 45)
            move_servo_smooth(servos["right_arm"], 90, 135)
            move_servo_smooth(servos["left_arm"],  45, 90)
            move_servo_smooth(servos["right_arm"], 135, 90)

    elif scene_type == "walk":
        # Alternating arm swing like walking
        for _ in range(4):
            servos["left_arm"].angle  = 60
            servos["right_arm"].angle = 120
            time.sleep(0.25)
            servos["left_arm"].angle  = 120
            servos["right_arm"].angle = 60
            time.sleep(0.25)

    elif scene_type == "surprised":
        # Head jerks up, arms fly out
        servos["head"].angle = 50
        servos["left_arm"].angle  = 30
        servos["right_arm"].angle = 150
        time.sleep(0.6)
        reset_puppets()

    elif scene_type == "happy":
        # Bouncy up-down body movement
        for _ in range(4):
            move_servo_smooth(servos["body"], 90, 75, steps=8)
            move_servo_smooth(servos["body"], 75, 105, steps=8)
        servos["body"].angle = 90

    elif scene_type == "scared":
        # Shake trembling
        for _ in range(6):
            servos["head"].angle = 85
            time.sleep(0.08)
            servos["head"].angle = 95
            time.sleep(0.08)

    elif scene_type == "fight":
        # Arms punch outward alternately
        for _ in range(3):
            servos["left_arm"].angle  = 20
            time.sleep(0.2)
            servos["left_arm"].angle  = 90
            servos["right_arm"].angle = 160
            time.sleep(0.2)
            servos["right_arm"].angle = 90

    else:  # default: slow head nod
        move_servo_smooth(servos["head"], 90, 70)
        move_servo_smooth(servos["head"], 70, 110)
        move_servo_smooth(servos["head"], 110, 90)

# ── STORY KEYWORDS → PUPPET SCENES ─────────────────
SCENE_MAP = {
    "walk":      ["walked", "ran", "ran", "hopped", "skipped", "travelled"],
    "greeting":  ["hello", "hi", "waved", "met", "greeted"],
    "surprised": ["suddenly", "gasped", "surprised", "shocked", "wow"],
    "happy":     ["happy", "excited", "cheered", "laughed", "celebrated"],
    "scared":    ["scared", "frightened", "trembled", "afraid", "monster"],
    "fight":     ["fought", "battled", "defeated", "dragon", "villain"],
}

def detect_scene_from_sentence(sentence):
    """Pick the best puppet animation based on story sentence keywords."""
    sentence_lower = sentence.lower()
    for scene, keywords in SCENE_MAP.items():
        if any(kw in sentence_lower for kw in keywords):
            return scene
    return "default"

# ── VOICE RECOGNITION ───────────────────────────────
def listen_for_story_request():
    """Listen via microphone and return the child's story request."""
    with sr.Microphone() as source:
        print("🎤 Listening... say 'Tell me a story about...' ")
        recognizer.adjust_for_ambient_noise(source, duration=1)
        tts_engine.say("Hello! What story shall I tell you today?")
        tts_engine.runAndWait()
        puppet_idle_dance()

        try:
            audio = recognizer.listen(source, timeout=8, phrase_time_limit=8)
            request = recognizer.recognize_google(audio)
            print(ff"✅ Heard: {request}")
            return request
        except sr.WaitTimeoutError:
            tts_engine.say("I didn't hear anything! Try again?")
            tts_engine.runAndWait()
            return None
        except sr.UnknownValueError:
            tts_engine.say("Hmm, I couldn't understand. Could you say it again?")
            tts_engine.runAndWait()
            return None

# ── AI STORY GENERATION ─────────────────────────────
def generate_story(request):
    """Ask Claude AI to write a child-friendly puppet story."""
    print("🧠 Asking AI to write a story...")
    tts_engine.say("Ooh, let me think of a wonderful story for you!")
    tts_engine.runAndWait()

    prompt = f"""You are a friendly puppet theatre narrator for young children aged 4-10.
Write a short puppet show story (5-7 sentences) based on: "{request}"

Rules:
- Simple, fun, age-appropriate language only
- Include action words like: walked, waved, jumped, fought, laughed, ran, surprised
- Have a clear beginning, middle and happy ending
- Each sentence on its own line
- No scary or sad endings"""

    response = ai_client.messages.create(
        model="claude-sonnet-4-6",
        max_tokens=400,
        messages=[{"role": "user", "content": prompt}]
    )
    story = response.content[0].text.strip()
    print(ff"\n📖 STORY:\n{story}\n")
    return story

# ── PERFORMANCE ENGINE ───────────────────────────────
def perform_story(story):
    """Split story into sentences, narrate each one, and animate puppets."""
    sentences = [s.strip() for s in story.split("\n") if s.strip()]

    tts_engine.say("Lights! Camera! Action!")
    tts_engine.runAndWait()
    time.sleep(0.5)

    for i, sentence in enumerate(sentences):
        print(ff"🎤 [{i+1}/{len(sentences)}]: {sentence}")

        # Determine puppet animation from sentence content
        scene = detect_scene_from_sentence(sentence)

        # Run narration and animation in parallel threads
        narrate_thread = threading.Thread(
            target=lambda s=sentence: (tts_engine.say(s), tts_engine.runAndWait())
        )
        animate_thread = threading.Thread(
            target=perform_scene, args=(scene,)
        )

        narrate_thread.start()
        animate_thread.start()
        narrate_thread.join()
        animate_thread.join()

        time.sleep(0.3)  # Brief pause between sentences

    reset_puppets()
    tts_engine.say("The End! I hope you loved the show! Clap clap clap!")
    tts_engine.runAndWait()
    perform_scene("happy")  # Bow after the show!

# ── MAIN LOOP ─────────────────────────────────────────
def main():
    print("🎭 AI Puppet Storyteller Robot Starting Up!")
    reset_puppets()
    time.sleep(1)

    while True:
        try:
            request = listen_for_story_request()

            if request:
                story = generate_story(request)
                perform_story(story)
                print("⏳ Waiting 3 seconds before next story...\n")
                time.sleep(3)

        except KeyboardInterrupt:
            print("\n👋 Show's over! Goodbye!")
            reset_puppets()
            pca.deinit()
            break
        except Exception as e:
            print(ff"❌ Error: {e}")
            tts_engine.say("Oops, something went wrong! Let's try again.")
            tts_engine.runAndWait()
            time.sleep(2)

if __name__ == "__main__":
    main()
▶️

Running the Program

Open a terminal on your Raspberry Pi and type: python3 puppet_storyteller.py — then say "Tell me a story about a brave lion!"

🛡️ Safety Rules for Young Makers

Safety is the most important part of any build. Every real engineer follows these rules!

Power Off First

Always unplug everything before connecting or changing wires. Never work on live circuits.

👁️

Adult Supervision

Always have a parent or guardian nearby when working with electronics and tools.

🔍

Check Wires Twice

Double-check all connections before powering on. Crossed wires can damage your Pi.

🔋

Right Power Supply

Use only the official Raspberry Pi 5V/3A adapter. Wrong voltage can break components.

🔑

Keep API Keys Secret

Never share your AI API key publicly or put it in code you upload online.

🌬️

Ventilate Your Pi

Raspberry Pi can get warm. Keep it in a case with ventilation holes — don't cover it!

🚀 Cool Upgrade Ideas

Once your basic puppet bot is working, try these awesome additions!

💡

LED Stage Lights

Add WS2812B LED strips to light up the stage in different colours for mood lighting!

🌐

Web Control Panel

Build a Flask web app so you can request stories from a phone or tablet browser.

📷

Camera + Face Detection

Add a Pi Camera — the puppets could turn to look at whoever is watching the show!

🌍

Multi-Language Stories

Add a language selection button — tell stories in Tamil, Hindi, French, or Spanish!

🎶

Background Music

Play royalty-free music tracks that match the story mood using pygame.mixer.

🎓

Educational Mode

Modify the AI prompt to turn any story into a science lesson or maths adventure!

🌟

You Did It, Young Engineer!

Building this project means you've touched AI, robotics, electronics, coding, and creative design all at once. That's exactly what real engineers and inventors do every day. Keep building, keep asking questions, and keep making amazing things!

A complete kids robotics project combining Raspberry Pi, servo motors, Python, and AI to create an interactive puppet theatre.

Built with ❤️ for young makers and curious minds everywhere.

Comments

Product Cards
Buddy Bot eBook
⭐ New 2026 Release
Build Your
Own Robot!
3D design, wiring &
Arduino coding.
Young inventors love it!
🖨️
3D Print
All parts
Wire it
Circuit guide
💻
Code it
Arduino IDE
🤖
Watch it
Walk & react
📋 Your Details
Enter your name
Valid 10-digit no.
Enter a valid email
Special Website Offer
₹499 300
🌍 International: $5 USD
One-time · Instant digital delivery
🔒 Secured by Razorpay · Your data is safe
📄 Download Free Sample Copy
🔒 Secured by Razorpay · Your data is safe
🍓
Raspberry Pi Pico Mastery
21 Projects
⚡ Launch Price — 80% OFF
Learn Pico
Build 21 Projects!
MicroPython · Wokwi
IoT · Certificate
Perfect for beginners!
🖥️
Wokwi
No hardware
🐍
MicroPy
From zero
🔨
21 Projects
IoT + sensors
📄
Certificate
Verified cert
📋 Your Details
Enter your name
Valid 10-digit no.
Enter a valid email
Special Launch Offer
₹999 200 80% OFF
🌍 International: $5 USD
One-time · Lifetime access · No subscription
🔒 Secured by Razorpay · UPI · Cards · NetBanking
🎉

You're in!

Payment successful! Your Buddy Bot eBook is ready. Time to build!

📖 Access Your eBook Now
🎉

Enrolled!

Payment successful! Lifetime access to all 21 Pico Projects is yours!

🍓 Go to My Course