A 3D Printed Hexapod Robot
This agile, 3D-printed hexapod robot is designed to work with either a Raspberry Pi PICO or an ESP32, providing flexibility and enhanced performance. Equipped with stronger and faster 21G servos, it offers a range of advanced features, including:
- Robust, durable structure: 3D-printed parts designed for strength and easy assembly
- WiFi-enabled remote control: Control your hexapod wirelessly from your smartphone or computer
- Smooth, agile movement: Advanced motion algorithms for natural walking patterns
- Web-based calibration interface: Easy servo calibration through your browser with real-time adjustment
- Over-the-air (OTA) firmware updates: Update firmware without cables for easy maintenance
This project will guide you through building a fully functional hexapod robot with 18 degrees of freedom (3 joints per leg × 6 legs). The complete build typically takes 8-12 hours, including 3D printing, assembly, and calibration.
- Beginner-Intermediate: Basic soldering and mechanical assembly skills required
- Tools needed: Soldering iron, hex key set, wire cutters/strippers
| Name | Thumbnail | Required # | Specifications | Note |
|---|---|---|---|---|
| Controller Board | or ![]() |
1 | ESP32 or Raspberry Pi Pico W/2W | Purchase ESP32 version or RPi Pico version. |
| MG92B Servo | ![]() |
18 | 180° rotation | Ensure all servos are from the same batch for consistency |
| Toggle Switch | ![]() |
1 | SPST, 6mm diameter | |
| 18650 Battery | ![]() |
2 | 3.7V Li-ion, 2000mAh+ recommended | Use protected batteries for safety |
| 18650 Battery Holder | ![]() |
1 | 2-cell holder with wire leads |
Follow these steps in order for the best results:
- 3D Print all parts (see parts list below)
- Prepare hardware (organize screws, nuts, bearings, and pins)
- Assemble body (install servos and controller)
- Build legs (joint → leg → foot for each leg)
- Attach legs to body
- Wire and test (connect servos, upload firmware, calibrate)
Print Settings Recommendations:
- Layer height: 0.2mm
- Infill: 20-30%
- Material: PLA or PETG
- Supports: Required for some parts (check STL orientation)
Assembly Tips:
- Install servos before closing the body
- Route wires neatly to avoid pinching
- Test fit all parts before final assembly
| Filename | Thumbnail | Required # |
|---|---|---|
| body_base | ![]() |
1 |
| body_side | ![]() |
6 |
| body_top | ![]() |
1 |
| body_head | ![]() |
1 |
| body_battery_top | ![]() |
1 |
| body_servo_side | ![]() |
12 |
Important: Pay attention to joint orientation! Three legs use standard joints, three use mirrored joints.
- Left side legs: Use mirrored joints
- Right side legs: Use standard joints
Refer to the fully assembled robot images for correct joint orientations
| Filename | Thumbnail | Required # |
|---|---|---|
| joint_bottom | ![]() |
12 |
| joint_cross | ![]() |
6 |
| joint_top | ![]() |
12 |
Assembly Notes:
- Ensure bearings are properly seated
- Pins should slide in smoothly without forcing
- Check for smooth joint rotation before proceeding
| Filename | Thumbnail | Required # |
|---|---|---|
| leg_bottom | ![]() |
6 |
| leg_side | ![]() |
12 |
| leg_top | ![]() |
6 |
Important: Match foot orientation with joint orientation!
- Left side legs: Use mirrored feet with mirrored joints
- Right side legs: Use standard feet with standard joints
Refer to the fully assembled robot images for correct foot orientations
| Filename | Thumbnail | Required # | Note |
|---|---|---|---|
| foot_bottom | ![]() |
6 | |
| foot_top | ![]() |
6 | |
| foot_ground | ![]() |
6 | |
| foot_tip | ![]() |
6 | Recommend to print with TPU |
Pro Tip: Organize all hardware into labeled containers before assembly to save time!
| Name | Spec | Required # | Usage |
|---|---|---|---|
| Screw | M2 × 6mm hex socket | 36 | Servo mounting |
| Screw | M2 × 12mm countersunk | 180 | General assembly |
| Nuts | M2 hex nut | 216 | Securing screws |
| Pin | M4 × 6mm stainless steel (304) | 18 | Joint pivots |
| Bearing | MR74-2RS (4mm ID, 7mm OD, 2.5mm Bore) | 18 | Smooth joint rotation |
Where to Buy: These are standard metric hardware available from Amazon, AliExpress, or local hardware stores.
- Arduino IDE (version 2.x recommended)
- USB cable compatible with your controller board
- Required Libraries (install via Arduino Library Manager):
- ESP32:
Adafruit_PWMServoDriver(for PCA9685 control) - ESP32:
AsyncUDPandArduinoOTA(included with arduino-esp32) - Pico: No additional libraries needed (uses custom PicoPWM)
- ESP32:
-
Install Arduino IDE from arduino.cc
-
Add ESP32 Board Support:
-
Follow the official ESP32 Arduino installation guide
-
Or add to Arduino IDE → File → Preferences → "Additional Board Manager URLs":
https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json -
Then install via Tools → Board → Boards Manager → Search "ESP32"
-
-
Install Required Library:
- Go to Sketch → Include Library → Manage Libraries
- Search for "Adafruit PWM Servo Driver"
- Click Install
-
Configure Board Settings:
- Board: "ESP32 Dev Module"
- Upload Speed: "115200"
- Flash Frequency: "80MHz"
- Partition Scheme: "Default 4MB with spiffs"
-
Open and Configure Code:
-
Open
./software/hexapod_esp32/hexapod_esp32.ino -
Edit
config.hto set your WiFi credentials (default: SSID="hexapod", password="hexapod_1234"):#define APSSID "hexapod" #define APPSK "hexapod_1234"
-
Configure servo pin mappings if using custom wiring:
static int left_legs[3][3] = {{1, 2, 3}, {5, 6, 7}, {9, 8, 10}}; static int right_legs[3][3] = {{10, 9, 8}, {13, 14, 15}, {7, 6, 5}};
-
Adjust calibration offset values after assembly (see Calibration section)
-
-
Upload Firmware:
- Connect ESP32 via USB
- Select correct COM port in Tools → Port
- Click Upload button
- Open Serial Monitor (115200 baud) to see the WiFi AP IP address (default: 192.168.4.1)
-
Install Arduino IDE and Arduino-Pico Core:
- Install Arduino IDE
- Follow arduino-pico installation guide
- Add board manager URL:
https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json
-
Configure Board Settings:
- Board: "Raspberry Pi Pico W" (or "Raspberry Pi Pico 2W")
- Flash Size: Must select option with "FS: 1MB" (e.g., "2MB (Sketch: 1MB, FS: 1MB)")
- Upload Method: "Default (UF2)"
-
Open and Configure Code:
- Open
./software/hexapod_pico/hexapod_pico.ino - Edit
config.hfor WiFi credentials (default: SSID="hexapod", password="hexapod_1234") - Configure servo pin mappings and calibration offsets as needed
- Open
-
Upload Firmware:
- Hold BOOTSEL button while connecting Pico via USB
- Release button when Pico appears as mass storage device
- Select the Pico board and upload through Arduino IDE
- Robot will perform boot-up sequence after upload
ESP32 Version (./software/hexapod_esp32/):
hexapod_esp32.ino: Main Arduino sketch with control logicconfig.h: WiFi credentials, servo pin mappings, and calibration offsetsmotion.h: Pre-generated motion look-up tables for smooth walkingREADME.md: ESP32-specific documentation
Pico Version (./software/hexapod_pico/):
hexapod_pico.ino: Main sketch optimized for RP2040config.h: Configuration settingsmotion.h: Motion look-up tablesPicoPWM.cpp/h: Custom PWM library for precise servo controlREADME.md: Pico-specific documentation
Path Tool (./software/path_tool/):
path_tool.py: Tool for generating custom walking patternslut_generator.ipynb: Jupyter notebook for motion path visualizationpath_lib.py: Library for inverse kinematics calculations
- Power on the hexapod - Connect batteries and turn on
- Connect to WiFi - Join the hexapod's WiFi network:
- SSID:
hexapod(default) - Password:
hexapod_1234(default) - The hexapod creates its own Access Point
- SSID:
- Default IP:
192.168.4.1(for both ESP32 and Pico) - UDP Port:
1234
The hexapod accepts motion commands via UDP packets on port 1234. Commands must be wrapped with : delimiters (e.g., :walk0:).
Available Commands:
:standby:- Stop and hold position:walk0:- Walk forward:walk180:- Walk backward:walkr45:/:walkr90:/:walkr135:- Walk right at 45°/90°/135°:walkl45:/:walkl90:/:walkl135:- Walk left at 45°/90°/135°:turnleft:/:turnright:- Rotate in place:fastforward:/:fastbackward:- Fast walking:climbforward:/:climbbackward:- Climbing gait:rotatex:/:rotatey:/:rotatez:- Body rotation (pitch/roll/yaw):twist:- Body twist motion
Example (Python):
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.sendto(b":walk0:", ("192.168.4.1", 1234))Boot Behavior: The robot automatically performs a boot sequence (stands up) when a client connects to its WiFi network.
Both ESP32 and Pico support wireless firmware updates:
- Power on the robot and connect to its WiFi network
- In Arduino IDE, go to Tools → Port → Network Ports
- Select the hexapod from network ports
- Click Upload as normal
Important Notes:
- For ESP32: OTA is disabled after the first motion command. Reboot the robot to re-enable OTA.
- For Pico: Ensure Flash Size includes "FS: 1MB" in board settings for OTA to work.
Upload fails:
- Check USB cable (must support data transfer)
- Try different USB port
- Ensure correct board and port selected
- For ESP32: Hold BOOT button during upload
Servos not responding:
- Verify battery voltage (should be 7.4V nominal for 2S Li-ion setup)
- Check all servo connections match the wiring diagram
- For ESP32: Verify PCA9685 I2C addresses (default: 0x40 left, 0x41 right)
- For ESP32: Check enable pins (GPIO 19 for left, GPIO 26 for right)
- Test individual servos using
posture_calibration()function - Confirm servo pin mappings in
config.hmatch your wiring
WiFi connection issues:
- Verify SSID and password in
config.h(default: hexapod/hexapod_1234) - The hexapod creates an Access Point - connect to it, don't look for it on your router
- Ensure your device supports 2.4GHz WiFi (5GHz not supported)
- Default IP is always
192.168.4.1when connected to the hexapod's AP
OTA not working:
- For ESP32: OTA only works before the first motion command - reboot to re-enable
- Ensure you're connected to the hexapod's WiFi network
- Check firewall settings on your computer
- For Pico: Verify Flash Size setting includes "FS: 1MB"
Control your hexapod directly from your Android smartphone:
The app provides an intuitive interface to:
- Connect to your hexapod's WiFi network
- Control movement with on-screen buttons
- Execute all available motion commands
- Monitor connection status
Requirements: Android device with WiFi capability
Work in progress - Check repository for updates
Proper calibration is critical for smooth walking. Take your time with this step!
All servos should be at 90° (neutral position) when the legs are in the reference positions shown below.
The hexapod now includes a web-based calibration interface that makes the calibration process much easier - no need to repeatedly edit code and re-upload firmware!
- Upload Firmware: Flash the code to your controller with default offset values
- Power On: Connect batteries and turn on the hexapod
- Connect to WiFi: Join the hexapod's WiFi network (default SSID:
hexapod) - Open Browser: Navigate to
http://192.168.4.1
-
Click the "Enter Calibration Mode" button
- The hexapod will stop motion execution
- All current offset values will be loaded
- A grid showing all 6 legs (18 servos) will appear
-
Check Leg Positions: Compare each leg with the reference images below
- Coxa (hip) joint: Should be perpendicular to body
- Femur (thigh) joint: Should be horizontal
- Tibia (shin) joint: Should form 90° angle with femur
For each misaligned servo:
-
Locate the servo in the web interface:
- Left column: Left Leg 1, 2, 3
- Right column: Right Leg 1, 2, 3
- Each leg has 3 joints: Joint 1 (coxa), Joint 2 (femur), Joint 3 (tibia)
-
Adjust the offset value:
- Use + and - buttons for fine adjustment (±1 tick per click)
- Or type a value directly in the input field
- Changes apply immediately to the servo
- 1 tick ≈ 0.44° for most servos
-
Observe the movement and continue adjusting until the servo reaches the correct position
-
Once all servos are properly aligned, click "Save Offsets"
- Offset values are saved to EEPROM (persistent storage)
- Values are also printed to Serial Monitor as backup
- The hexapod will remember these values even after power cycles
-
Now tighten the servo horn screws - With each servo in its correct neutral position, firmly tighten the small screws on each servo horn to secure them in place
-
Click "Exit Calibration Mode" to resume normal operation
Send a walking command to verify smooth motion. If adjustments are needed, simply re-enter calibration mode and fine-tune.
Front View
Top View
- Use the web interface: Much faster than editing code and re-uploading
- Start with one leg: Calibrate completely before moving to the next
- Make small adjustments: Use the +/- buttons for precise control (±1 tick per click)
- Real-time feedback: Servos respond immediately as you adjust values
- Save your work: Don't forget to click "Save Offsets" when done!
- Check screw tightness: Loose servo horns will affect calibration
- Servo horn position: If offsets exceed ±25 ticks, consider repositioning the servo horn physically

































