Final Project¶

Inspiration¶
I really liked the boston dynamics robot dog and I ever the genius think I can make a smaller verison of it. I also have a really fast dog and I want to understand why she is so fast.
For an overall base of what Im going to build this robot off I found this pervious Fab Final Project which was of a more spiderlike robot
Sketch¶
This week I worked on defining my final project idea and started to getting used to the documentation process. My final project is based off my dog on the front page. She is very fast. So fast that I cant keep up with her, but I wanted to see if I could build something to compete with her. The idea for the project is a robot similar to the boston dynamics dog that uses servos to move its limbs.
This is a rough draft of what I think it will look like
This is just an AI generated design to give a better perscpetive becuase I not a good artist
Midterm Review¶
As a part of the midterm, I planed out the rest of the stuff I needed to do for the final and put together my bill of materials for it.
Bill of Materials¶
Bill of Materials (BOM)¶
| Item # | Component | Description | Quantity | Where to Buy |
|---|---|---|---|---|
| 1 | Single-Sided Copper PCB | FR-1 board for custom circuit milling | 1 | Adafruit |
| 2 | MG90S Metal Gear Servo | 9g metal gear servos (2 per leg, total 8) | 8 | Amazon |
| 3 | Seeed Studio XIAO ESP32C6 | Main microcontroller for control and Wi-Fi | 1 | Seeed Studio |
| 4 | PCA9685 Servo Driver Shield | 16-channel servo controller compatible with ESP32 | 1 | Amazon |
| 5 | PLA Filament (Bambu PLA) | 3D printing material for body and leg components | 1 spool | Bambu Lab |
| 6 | Jumper Wires & Headers | Connection cables and pin headers for PCB setup | 1 set | Amazon |
Estimated Total Cost: ≈ $46.00 USD
Breakdown:
- MG90S Servos (8 total): $25
- ESP32C6: $6
- PCA9685 Servo Shield: $11
- Single-Sided PCB Material: $3
- Misc. Wiring/Headers: $3
- PLA Filament (portion used): $4
Gantt Chart¶

Planing¶
For this to project to work I went through several design options, the first idea was to make it a remote control dog using a web server as the controller the next was to try and put ai in it to act like a dog you could interact with through a touch sensor, what I landed on though was making simple versions of both that could be swapped out. This way I could do both versions of the dog I wanted to do, without having to make two models. To acomplish this, I used an esp32s3 for the autonoumus/controlable mode where the only thing the person would need to do is upload a diffrent code to swithc between modes. Once I had this idea in mind, I figured out what my biggest issues were. These issues summed up into one category was legs. This included making them, moving them and probably the biggest challenge balance.
Rebuilding my Project¶
Files¶
Case and Leg¶
PCB Files¶
Final Code¶
Overview¶
The day before I was to present my project, it shatered. To clairfy, while trying to force a leg onto a servo, I pressed to hard and the base of the print broke. I saw this as a sign, my project was subpar, it was large and janky. I accepted I was not going to pass the next day and began to plan.
New Electronics¶
Servo Shield:¶
Something I foolishly ignored last time was to use a servo shield. It would have allowed for a safer and stronger servo connection to my microcontroller but I had forgotten the suggestion that Mr. Dubik had given me a few weeks prior and made a board without one. For my new design I built my robot around the sheild
Here is the servo shield I used:

New Board¶
For my new board, its main purpos was to connect to the servo shield so it became simple to design, all I needed to do was connect the esp32c6 to the servo shield via my sda, scl, vcc, oed, gnd, and v+ pins. The sda and scl were the digital pins 4 and 5 and the rest was to send power to the chip in the board and to share logic between the sheild and the esp32c6. Here is the pinout sheet of the esp32c6 that I used for reference when figuring out how to use the servo shield:

Here is the schematic and pcb view of the final board:


Milling and Soldering¶
Milling has always been a big part of my fab journey. It has been good and bad, so when it came time to mill I knew it could go either way. Thankfully though, I ran into no issues while milling and was able to get a clean looking board after my first attempt at milling it. Afterwards I soldered on the female pinheaders and it came out looking like this:

Here it is in the bot

And here is a video of the legs moving while the electonrics are connected to the pcb:
The one thing to note is that I was ubale to get the bot to be powered independently yet. I hope to countinue to work on this project and eventually get it powered portably.
Fusion360¶
Inspiration¶
When designing my legs and case in my first go around with this project, I had been using the boston dynaimcs dog as reference. I know now that this was not the best choice as it is a much larger and complex piece of machineray then what I was trying to make. To rectify this I started looking at smaller scale projects and came across Nymmble. It is a small scale cat robot that has many similarities to the boston dynamic dog. I looked deeply into it for inspieration and came to the conclusion I would use 2 servos per leg and would also screw the servos in this time for extra security.
Legs¶
For the legs I looked at how the geniuses at Nymble had made the legs and I noticed how they used two servos for each leg to give it a more realistic motion. I designed my lower part of the legs with a slot for the servo and then a middle piece to hold both servos gears. The other servo would be mounted to the case that would hold the electronices. Heres what the lower piece looks like:

Heres what the middle joint part looks like:

Heres a picture of them together with the servos attached to them:

Case¶
I was not able to start designing the case until I had a general idea of how large the electronics were going to be. After finishing the design of the shield board combination, I was able to start. First I designed the right and left side of the case. I took the mesurment of the width of the sheild and then added room for the servos to be pressed in. After taking all these mesurments I came up with a good design and added tabs for press fit. It came out looking like this in fusion:

For the front and back of the case I similarly took mesumrents of the sheild and servos and added a place for the tabs to the bottom and a place for the tabs on the side of the left and right pieces. Heres what it looks like in fusion:

Finally I made the top and bottom pieces of the case. These were similar to the front/back piece as they had space for the tabs. They are near idential except the bottom piece has an open middle area to activate power and easy access to the wires. Heres what they both look like:


Finally heres what all the pieces look like printed and assembled together:

Coding¶
One Leg¶
To start, I took the general code for the servo shield and modified it to get one servo to move how I want to easily. This allowed me then to add a second group of variables for how I could move the leg. This was needed as I was using two servos per leg now. To create the gait cycle that makes the dog walk, I had the hip servo swing small amounts and the knee servo do most the moving this is because it is how everything else walks in the world and why mess with what works. After a few tries I got this code:
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
// Servo calibration (tweak if needed)
#define HIP_MIN 340 // Hip back position
#define HIP_MAX 380 // Hip forward position
#define KNEE_MIN 300 // Knee straight (leg extended)
#define KNEE_MAX 480 // Knee bent (paw lowered)
#define SERVO_FREQ 50
// Servo channel assignments
#define HIP_SERVO 0
#define KNEE_SERVO 1
void setup() {
Serial.begin(9600);
pwm.begin();
pwm.setOscillatorFrequency(27000000);
pwm.setPWMFreq(SERVO_FREQ);
delay(10);
Serial.println("Front leg gait initialized");
}
void loop() {
// 🦿 Step 1: starting stance — hip back, knee straight
pwm.setPWM(HIP_SERVO, 0, HIP_MIN);
pwm.setPWM(KNEE_SERVO, 0, KNEE_MIN);
delay(300);
// 🦿 Step 2: hip swings forward, knee stays straight
for (uint16_t pos = HIP_MIN; pos <= HIP_MAX; pos++) {
pwm.setPWM(HIP_SERVO, 0, pos);
delay(10);
}
// 🦿 Step 3: hip holds forward, knee bends (paw lowers)
for (uint16_t pos = KNEE_MIN; pos <= KNEE_MAX; pos++) {
pwm.setPWM(KNEE_SERVO, 0, pos);
delay(10);
}
// 🦿 Step 4: hip moves back to starting position, knee stays bent
for (uint16_t pos = HIP_MAX; pos >= HIP_MIN; pos--) {
pwm.setPWM(HIP_SERVO, 0, pos);
delay(10);
}
// 🦿 Reset knee back to straight
for (uint16_t pos = KNEE_MAX; pos >= KNEE_MIN; pos--) {
pwm.setPWM(KNEE_SERVO, 0, pos);
delay(10);
}
delay(300);
}
and heres a video of one leg working:
Two Legs¶
From getting that to work, I added in a second leg on the same side so that I could alternate the two legs in walking to get an idea on how it would look. Heres what that code looks like:
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
// =======================
// === Servo Settings ===
// =======================
#define HIP_MIN 340 // Hip back position
#define HIP_MAX 380 // Hip forward position
#define KNEE_MIN 300 // Knee straight (leg extended)
#define KNEE_MAX 480 // Knee bent (paw lowered)
#define SERVO_FREQ 50 // PWM frequency (Hz)
// =======================
// === Servo Channels ====
// =======================
#define FRONT_HIP 0
#define FRONT_KNEE 1
#define BACK_HIP 2
#define BACK_KNEE 3
void setup() {
Serial.begin(9600);
pwm.begin();
pwm.setOscillatorFrequency(27000000);
pwm.setPWMFreq(SERVO_FREQ);
delay(10);
Serial.println("Two-leg alternating gait initialized");
}
void loop() {
// ===================================================
// === FRONT LEG CYCLE ===
// ===================================================
// Step 1: Front leg back, knee straight
pwm.setPWM(FRONT_HIP, 0, HIP_MIN);
pwm.setPWM(FRONT_KNEE, 0, KNEE_MIN);
// Step 1 (back leg does opposite): hip forward, knee bent
pwm.setPWM(BACK_HIP, 0, HIP_MAX);
pwm.setPWM(BACK_KNEE, 0, KNEE_MAX);
delay(300);
// Step 2: Front hip forward, knee stays straight
// Back hip moves back, knee stays bent
for (uint16_t i = 0; i <= 100; i++) {
uint16_t frontHip = HIP_MIN + (HIP_MAX - HIP_MIN) * i / 100;
uint16_t backHip = HIP_MAX - (HIP_MAX - HIP_MIN) * i / 100;
pwm.setPWM(FRONT_HIP, 0, frontHip);
pwm.setPWM(BACK_HIP, 0, backHip);
delay(10);
}
// Step 3: Front knee bends (paw lowers)
for (uint16_t pos = KNEE_MIN; pos <= KNEE_MAX; pos++) {
pwm.setPWM(FRONT_KNEE, 0, pos);
delay(10);
}
// Step 3 (back knee straightens as paw lifts)
for (uint16_t pos = KNEE_MAX; pos >= KNEE_MIN; pos--) {
pwm.setPWM(BACK_KNEE, 0, pos);
delay(10);
}
// Step 4: Front hip moves back, knee stays bent
// Back hip moves forward, knee stays straight
for (uint16_t i = 0; i <= 100; i++) {
uint16_t frontHip = HIP_MAX - (HIP_MAX - HIP_MIN) * i / 100;
uint16_t backHip = HIP_MIN + (HIP_MAX - HIP_MIN) * i / 100;
pwm.setPWM(FRONT_HIP, 0, frontHip);
pwm.setPWM(BACK_HIP, 0, backHip);
delay(10);
}
// Step 5: Reset knees
pwm.setPWM(FRONT_KNEE, 0, KNEE_MIN); // straighten front leg
pwm.setPWM(BACK_KNEE, 0, KNEE_MAX); // bend back leg
delay(300);
}
And heres a video of both legs moving:
All Four Legs¶
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
// =======================
// === Servo Settings ====
// =======================
#define HIP_MIN 340
#define HIP_MAX 380
#define KNEE_MIN 300
#define KNEE_MAX 480
#define SERVO_FREQ 50
// =======================
// === Servo Channels ====
// =======================
#define FRONT_RIGHT_HIP 0
#define FRONT_RIGHT_KNEE 1
#define BACK_RIGHT_HIP 2
#define BACK_RIGHT_KNEE 3
#define FRONT_LEFT_HIP 4
#define FRONT_LEFT_KNEE 5
#define BACK_LEFT_HIP 6
#define BACK_LEFT_KNEE 7
// Speed control: reduce step delay by 50% (faster)
#define STEP_DELAY 5 // original was 10
// =======================
// === Helper Functions ===
// =======================
void moveServo(uint8_t servo, uint16_t start, uint16_t end, uint8_t stepDelay = STEP_DELAY) {
if (start < end) {
for (uint16_t pos = start; pos <= end; pos++) {
pwm.setPWM(servo, 0, pos);
delay(stepDelay);
}
} else {
for (uint16_t pos = start; pos >= end; pos--) {
pwm.setPWM(servo, 0, pos);
delay(stepDelay);
}
}
}
void setNeutral(uint8_t hip, uint8_t knee) {
pwm.setPWM(hip, 0, HIP_MIN);
pwm.setPWM(knee, 0, KNEE_MIN);
}
// =======================
// === Gait Functions =====
// =======================
void frontLegCycle(uint8_t hip, uint8_t knee) {
moveServo(hip, HIP_MIN, HIP_MAX);
moveServo(knee, KNEE_MIN, KNEE_MAX);
moveServo(hip, HIP_MAX, HIP_MIN);
moveServo(knee, KNEE_MAX, KNEE_MIN);
}
void backLegCycle(uint8_t hip, uint8_t knee) {
moveServo(hip, HIP_MIN, HIP_MAX);
moveServo(knee, KNEE_MIN, KNEE_MAX);
moveServo(hip, HIP_MAX, HIP_MIN);
moveServo(knee, KNEE_MAX, KNEE_MIN);
}
// =======================
// === Setup =============
// =======================
void setup() {
Serial.begin(9600);
pwm.begin();
pwm.setOscillatorFrequency(27000000);
pwm.setPWMFreq(SERVO_FREQ);
delay(10);
Serial.println("Quadruped alternating walk initialized");
setNeutral(FRONT_RIGHT_HIP, FRONT_RIGHT_KNEE);
setNeutral(BACK_RIGHT_HIP, BACK_RIGHT_KNEE);
setNeutral(FRONT_LEFT_HIP, FRONT_LEFT_KNEE);
setNeutral(BACK_LEFT_HIP, BACK_LEFT_KNEE);
}
// =======================
// === Main Loop =========
// =======================
void loop() {
// Phase 1: Front Right + Back Left
frontLegCycle(FRONT_RIGHT_HIP, FRONT_RIGHT_KNEE);
backLegCycle(BACK_LEFT_HIP, BACK_LEFT_KNEE);
// Reset to neutral
setNeutral(FRONT_RIGHT_HIP, FRONT_RIGHT_KNEE);
setNeutral(BACK_LEFT_HIP, BACK_LEFT_KNEE);
delay(50); // shorter wait for faster gait
// Phase 2: Front Left + Back Right
frontLegCycle(FRONT_LEFT_HIP, FRONT_LEFT_KNEE);
backLegCycle(BACK_RIGHT_HIP, BACK_RIGHT_KNEE);
// Reset to neutral
setNeutral(FRONT_LEFT_HIP, FRONT_LEFT_KNEE);
setNeutral(BACK_RIGHT_HIP, BACK_RIGHT_KNEE);
delay(50); // shorter wait for faster gait
}
And heres a video of all 4 moving:
Web Server¶
Now that I had two legs, I wanted to get it to work on a web server so that I eventually could remotly control it.
For it, I have a start and stop button that begins the gait cycle and ends it. Additonally I have a sit button and a dance button to give the dog a bit more to do. Heres what that code looks like without giving away my home wifi:
#include <Wire.h>
#include <WiFi.h>
#include <Adafruit_PWMServoDriver.h>
// ======================
// ==== WiFi Settings ====
// ======================
const char* ssid = "yourSSID";
const char* password = "yourPASSWORD";
WiFiServer server(80);
// ============================
// ==== Servo Driver Setup ====
// ============================
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
#define SERVO_FREQ 50 // Hz
// === Servo Channels ===
// Front Left: 0–1
// Front Right: 2–3
// Back Left: 4–5
// Back Right: 6–7
#define FL_HIP 0
#define FL_KNEE 1
#define FR_HIP 2
#define FR_KNEE 3
#define BL_HIP 4
#define BL_KNEE 5
#define BR_HIP 6
#define BR_KNEE 7
// === Servo Pulse Ranges ===
#define HIP_MIN 340
#define HIP_MAX 380
#define KNEE_MIN 300
#define KNEE_MAX 480
// === Control ===
volatile bool stopAll = false;
int command = 0;
// =======================
// ==== Helper Functions ====
// =======================
void moveServo(uint8_t servo, uint16_t start, uint16_t end, uint8_t stepDelay = 5) {
if (stopAll) return;
if (start < end) {
for (uint16_t pos = start; pos <= end; pos++) {
if (stopAll) return;
pwm.setPWM(servo, 0, pos);
delay(stepDelay);
}
} else {
for (uint16_t pos = start; pos >= end; pos--) {
if (stopAll) return;
pwm.setPWM(servo, 0, pos);
delay(stepDelay);
}
}
}
void homeLeg(uint8_t hip, uint8_t knee) {
pwm.setPWM(hip, 0, HIP_MIN);
pwm.setPWM(knee, 0, KNEE_MIN);
}
void homeAll() {
stopAll = true; // stop everything immediately
delay(50);
stopAll = false;
homeLeg(FL_HIP, FL_KNEE);
homeLeg(FR_HIP, FR_KNEE);
homeLeg(BL_HIP, BL_KNEE);
homeLeg(BR_HIP, BR_KNEE);
}
// =======================
// ==== Motion Patterns ====
// =======================
// Faster walk cycle (50% speed increase)
void walkForward() {
stopAll = false;
// Step 1: Front Left + Back Right
moveServo(FL_HIP, HIP_MIN, HIP_MAX, 3);
moveServo(FL_KNEE, KNEE_MIN, KNEE_MAX, 3);
moveServo(BR_HIP, HIP_MIN, HIP_MAX, 3);
moveServo(BR_KNEE, KNEE_MIN, KNEE_MAX, 3);
moveServo(FL_HIP, HIP_MAX, HIP_MIN, 3);
moveServo(FL_KNEE, KNEE_MAX, KNEE_MIN, 3);
moveServo(BR_HIP, HIP_MAX, HIP_MIN, 3);
moveServo(BR_KNEE, KNEE_MAX, KNEE_MIN, 3);
// Step 2: Front Right + Back Left
moveServo(FR_HIP, HIP_MIN, HIP_MAX, 3);
moveServo(FR_KNEE, KNEE_MIN, KNEE_MAX, 3);
moveServo(BL_HIP, HIP_MIN, HIP_MAX, 3);
moveServo(BL_KNEE, KNEE_MIN, KNEE_MAX, 3);
moveServo(FR_HIP, HIP_MAX, HIP_MIN, 3);
moveServo(FR_KNEE, KNEE_MAX, KNEE_MIN, 3);
moveServo(BL_HIP, HIP_MAX, HIP_MIN, 3);
moveServo(BL_KNEE, KNEE_MAX, KNEE_MIN, 3);
}
// Sit: fold knees, lower hips
void sitPose() {
stopAll = false;
moveServo(FL_KNEE, KNEE_MIN, KNEE_MAX, 5);
moveServo(FR_KNEE, KNEE_MIN, KNEE_MAX, 5);
moveServo(BL_KNEE, KNEE_MIN, KNEE_MAX, 5);
moveServo(BR_KNEE, KNEE_MIN, KNEE_MAX, 5);
moveServo(FL_HIP, HIP_MIN, HIP_MAX, 5);
moveServo(FR_HIP, HIP_MIN, HIP_MAX, 5);
moveServo(BL_HIP, HIP_MIN, HIP_MAX, 5);
moveServo(BR_HIP, HIP_MIN, HIP_MAX, 5);
}
// Dance: 5 seconds of movement
void danceMove() {
stopAll = false;
unsigned long startTime = millis();
while (millis() - startTime < 5000 && !stopAll) {
moveServo(FL_HIP, HIP_MIN, HIP_MAX, 3);
moveServo(FR_HIP, HIP_MAX, HIP_MIN, 3);
moveServo(BL_HIP, HIP_MIN, HIP_MAX, 3);
moveServo(BR_HIP, HIP_MAX, HIP_MIN, 3);
moveServo(FL_KNEE, KNEE_MIN, KNEE_MAX, 3);
moveServo(FR_KNEE, KNEE_MAX, KNEE_MIN, 3);
moveServo(BL_KNEE, KNEE_MIN, KNEE_MAX, 3);
moveServo(BR_KNEE, KNEE_MAX, KNEE_MIN, 3);
}
}
// =======================
// ==== Setup ====
// =======================
void setup() {
Serial.begin(115200);
pwm.begin();
pwm.setOscillatorFrequency(27000000);
pwm.setPWMFreq(SERVO_FREQ);
homeAll();
WiFi.begin(ssid, password);
Serial.print("Connecting to WiFi");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nConnected!");
Serial.println(WiFi.localIP());
server.begin();
}
// =======================
// ==== Web Server ====
// =======================
void handleClient() {
WiFiClient client = server.available();
if (!client) return;
String request = client.readStringUntil('\r');
client.flush();
if (request.indexOf("/FORWARD") != -1) command = 1;
else if (request.indexOf("/SIT") != -1) command = 2;
else if (request.indexOf("/DANCE") != -1) command = 3;
else if (request.indexOf("/HOME") != -1) command = 4;
String html = R"rawliteral(
<!DOCTYPE html>
<html>
<head><title>Robot Dog Control</title></head>
<body style="background-color:#111; color:white; font-family:sans-serif; text-align:center;">
<h2>ESP32 Robot Dog</h2>
<button onclick="location.href='/FORWARD'" style="width:200px; height:60px; margin:10px; background-color:#0077ff;">Forward</button><br>
<button onclick="location.href='/SIT'" style="width:200px; height:60px; margin:10px; background-color:#ffaa00;">Sit</button><br>
<button onclick="location.href='/DANCE'" style="width:200px; height:60px; margin:10px; background-color:#aa00ff;">Dance</button><br>
<button onclick="location.href='/HOME'" style="width:200px; height:60px; margin:10px; background-color:#00cc00;">Home</button>
</body>
</html>
)rawliteral";
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connection: close");
client.println();
client.print(html);
}
// =======================
// ==== Main Loop ====
// =======================
void loop() {
handleClient();
switch (command) {
case 1: walkForward(); break;
case 2: sitPose(); break;
case 3: danceMove(); break;
case 4: homeAll(); break;
}
command = 0;
}
Here are videos of each command being used:
Forward:
Dance:
Sit:
Fully Assembled¶

Reflection¶
This project was not an easy one but over the course of this year, I have learned alot. I ran into some difficulites with the walking cylce and web server at points since they were both thingsn I had never tried before but in the end, a majoirty of the things I did went well and I think I can account that to my time spent learning from videos and weekly projects how to do the many things that make up my project.
Final Project Documentation¶
What does it do?¶
This project is a quadruped robot that walks using eight servos, two per leg, controlled through a web server interface. The interface allows remote control of the robot’s movements over Wi-Fi, letting users adjust direction and motion in real time. The system combines electronics, mechanical design, and programming to demonstrate coordinated robotic locomotion.
Who’s done what beforehand?¶
This Fab Final Project by Karam Khrais is similar in spirit, though his design took a more spider-like approach.
Additionally, I drew inspiration from Petoi Nybble, a commercial open-source quadruped robot, studying its servo layout and gait logic to inform my own system’s design.
What did you design?¶
I designed a custom PCB to connect the Xiao ESP32C6 to a servo shield, allowing the control of eight servos powering the robot’s four legs.
I also designed the mechanical structure, including the leg attachments and body that house all electronics and wiring.
The PCB was created in KiCad, and the robot body and legs were modeled in Fusion 360 and fabricated using 3D printing.
What sources did you use?¶
- Fab Academy archives for reference on PCB design, embedded networking, and milling workflows.
- Petoi Nybble documentation for gait pattern research and servo placement.
- Adafruit and Espressif documentation for ESP32C6 hardware and web server examples.
- My own prototype testing data from single- and dual-leg setups to refine movement sequences.
What materials and components were used?¶
- Bambu PLA filament for 3D-printed body and leg structures
- Single sided copper board for the milled PCB
- Xiao ESP32C6 microcontroller
- PCA9685 Servo Shield for multi-servo control
- Eight micro servos (SG90/MG90S)
- Jumper wires, pin headers, and connectors
Where did they come from?¶
- PLA sourced from the Bambu Lab website
- Servos and servo shield purchased from Amazon
- ESP32C6 and electronic components provided through the Fab Lab
How much did they cost?¶
The total project cost is approximately $46.44 USD, covering the ESP32C6, servos, servo shield, PCB materials, and power supply components.
The PLA filament used for printing was lab-provided and therefore excluded from the total cost calculation.
What parts and systems were made?¶
I fabricated and assembled:
- A custom-milled PCB for signal routing and testing
- 3D-printed body and leg assemblies
- A servo control system using the PCA9685 shield
- A web server interface for wireless robot control
- The software handling gait logic, network communication, and motion synchronization
What processes were used?¶
- PCB milling for custom circuit fabrication
- 3D modeling and additive manufacturing for the mechanical design
- Embedded programming on the ESP32C6 using Arduino
- Networking for Wi-Fi-based web control
- System integration to bring together mechanical, electrical, and software systems
What questions were answered?¶
The main design question was how to coordinate eight servos to mimic a natural, stable walking gait.
The answer was to sequence movements diagonally and incrementally, ensuring that balance was maintained while transitioning between steps.
What worked? What didn’t?¶
The servo shield worked extremely well for controlling all eight servos simultaneously and simplified power distribution.
Initially, attempting to run multiple servos directly from the ESP32C6 caused instability and inconsistent power delivery, which was solved after integrating the shield and optimizing the control code.
The web server interface also worked smoothly after refining the non-blocking control logic.
How was it evaluated?¶
Evaluation was done through real-time motion testing. The robot’s gait cycle, servo timing, and response to web-based input were observed and adjusted until smooth, balanced walking was achieved.
Performance was measured by how consistently the robot could walk forward and turn without losing stability or servo alignment.
What are the implications?¶
This project demonstrates how digital fabrication, embedded electronics, and networked control can merge to create fully interactive robotic systems.
It serves as a foundation for future development in legged robotics, web-based control systems, and educational robotics, showing how accessible components can be used to design complex, functional machines.