Level 2 · Build & Play · 🖨️ 3D-printed · ~2 sessions (90 min) · Ages 9–12 Controllers: wired KY-023 joystick and wireless PS3 gamepad — you will program the maze both ways.
Roll a steel marble (guli) from Start to the goal hole by tilting a 3D-printed labyrinth. Two servo motors lift and drop the board on the X and Y axes, and you control the tilt.
🎯 Learning goals
By the end of this lesson you can:
- Mount and centre two servo motors on the Maker ESP32 Pro.
- Use the
mapblock to turn a controller number into a servo angle (0–180°). - Drive the maze two ways — a wired KY-023 joystick and a wireless PS3 gamepad — and explain the trade-off.
- Add a win sensor, an OLED timer and a buzzer to turn a mechanism into a real game.
🧰 What you need
| Part | Qty | Plugs into |
|---|---|---|
| Maker ESP32 Pro | 1 | — |
| MG90S servo | 2 | pin 25 (X), pin 26 (Y) |
| KY-023 joystick | 1 | VRx → 34, VRy → 35, +5V, GND |
| Bluetooth PS3 gamepad | 1 | wireless (pair by MAC code) |
| IR sensor (goal) | 1 | one GPIO (e.g. 18) |
| OLED display | 1 | I²C |
| Buzzer | 1 | one GPIO (e.g. 19) |
| 7.4 V LiPo | 1 | power |
| 3D-printed maze parts + steel marble | 1 set | build files |
☀️ Warm-up (5 min)
Put a marble on a flat tray and try to roll it to one corner by tilting the tray with your hands. Tip it too far and the marble flies off! Today your hands are replaced by two servos, and your tilt comes from a joystick or a game controller. Same idea — smoother control.
💡 New concept — a servo holds an angle
A normal motor spins round and round. A servo is different: you tell it an angle from 0° to 180° and it goes there and holds. That is perfect for tilting a board a little, precisely.
- 90° = board level (flat).
- less than 90° = tilt one way · more than 90° = tilt the other way.
The controller doesn't give you an angle, though — it gives a number. So we map that number onto an angle:
- KY-023 joystick → an analog number 0…4095 (middle ≈ 2048).
- PS3 stick → a number −128…127 (middle = 0).
The map block stretches one range onto another. That single idea makes any controller work.
🔩 Mission 1 — Build the rig
1a · Print & assemble. Print the gimbal frame, the two servo arms and the maze top from the build files. Clip the frame together so the inner ring tilts on the X axis and the outer ring tilts on the Y axis.
1b · Mount the servos. Fit one MG90S to the X axis and one to the Y axis. Press-fit the maze top onto the inner ring. Gently move it by hand — both axes should swing freely with no grinding.
✅ Mission 1 done when: the board tilts smoothly on both axes by hand.
(Add a photo of the finished rig here: )
⚡💻 Mission 2 — Make it tilt
2a · Wire & centre the servos. Plug servo X → pin 25, servo Y → pin 26. Now make the board sit level so we have a known starting point:
when ESP32 starts
set servo (pin 25) angle (90) // X level
set servo (pin 26) angle (90) // Y level
✅ Board sits flat when powered on.
2b · Control it — pick your method (do both!).
Method A — wired KY-023 joystick
Wire VRx → 34, VRy → 35. Read the joystick, map it to an angle, send it to the servo — forever:
forever
set [angleX] to ( map (read analog pin 34) from (0, 4095) to (0, 180) )
set servo (pin 25) angle (angleX)
Push the stick left/right — the board tilts X. 🎉
Method B — wireless PS3 gamepad
In Mind+, import the PS3 user library and type your pad's MAC code into the init block (printed on the back of the controller). Then read the left stick and map its −128…127 range:
when ESP32 starts
PS3 init ["02:00:01:23:45:67"] // your pad's MAC
forever
if < PS3 connected? > then
set [angleX] to ( map (PS3 left-stick X) from (-128, 127) to (0, 180) )
set servo (pin 25) angle (angleX)
💡 Compare: the joystick is wired (cheap, always works); the PS3 pad is wireless (move around freely, but must be paired first). Same
mapidea — only the input block changes.
✅ Mission 2 done when: one axis follows your controller smoothly.
🎮 Mission 3 — Play the game
3a · Add the second axis. Repeat 2b for Y (joystick pin 35 / PS3 left-stick Y → servo pin 26). Now you have full X-Y tilt control.
3b · Make it a real game. Put an IR sensor at the goal hole, an OLED timer and a buzzer:
when ESP32 starts
reset timer
OLED show ["Roll to the goal!"]
forever
... (tilt control from Mission 2, both axes) ...
OLED show (join ["Time: "] (timer))
if < read digital pin 18 = 0 > then // marble reached the goal
OLED show (join ["WIN! "] (timer))
play tone (pin 19) note (C5) for (0.5)
play tone (pin 19) note (E5) for (0.5)
play tone (pin 19) note (G5) for (0.5)
stop this script
✅ Mission 3 done when: the timer runs, and reaching the goal stops it with a victory tune.
🧪 Try it yourself
- Show a "Best time" on the OLED (keep the lowest time in a variable).
- Make the marble start only after the player presses a button / the PS3 X button.
🧩 Mini-challenge
- Hard mode: limit the tilt to 70°–110° (
map … to (70, 110)) so the board moves less — much harder! - Penalty beep: if the player tilts to the extreme, sound a short warning buzz.
🚀 Upgrades (innovate!)
- 📱 Go fully wireless — control everything from the PS3 pad, no wires to the player.
- ♿ Assist mode — add an MPU6050 so the board can auto-level itself; great for younger players (links to SDG 4 · Quality Education and accessibility).
- 🧱 Design your own maze — model and print a new maze top, then swap it in. Share your hardest design with the class (SDG 9 · Innovation).
📌 Recap
- A servo holds an angle (0–180°); 90° = level.
mapturns any controller number into an angle — that's why both the joystick and the PS3 pad work with almost the same code.- Sensors + OLED + buzzer turn a mechanism into a game: sense (IR) → decide (
if) → react (tune + stop).
🏠 Homework
Write 3–4 sentences (or a short video): which controller did you prefer — the wired joystick or the wireless PS3 pad — and why? Then sketch one idea for your own maze layout.
Mind+ blocks used
set servo (pin) angle · read analog pin · map … from … to … · read digital pin · PS3 init / PS3 connected? / PS3 left-stick X/Y · variables · if · forever · timer / reset timer · OLED show · play tone.