In the natural world, many organisms possess an instinct for “approaching benefits and avoiding harm.” When a threat appears in their environment, they often respond with rapid avoidance through sensing, decision-making, and immediate action.
This project aims to simulate such biological behavior by building a quadruped robot prototype that can detect human approach direction → quickly evade → trigger light warning, through embedded system-level integration.
This is not only a technical integration exercise but also an exploration of how biologically inspired intelligent behaviors can be reproduced in robotic systems. The project integrates perceptual input (sensors), motion output (servos), emotional expression (RGB lighting), and decision-making control (microcontroller programming) to create an embedded system that can react to environmental changes and be applicable in real-world scenarios.
This system integrates multiple sensors and actuators to build a responsive robotic system with quadruped mobility, human proximity perception, and visual status feedback. Specific goals include:
┌────────────────────┐ │ System Initialization │ └────────────┬────────────┘ ↓ ┌────────────────────────────┐ │ Initialize Servos and RGB Ring │ └────────────┬────────────────┘ ↓ ┌────────────────────────────┐ │ Set RGB Ring to Blue Breathing │ └────────────┬────────────────┘ ↓ ┌──────────────────────┐ │ Read Left and Right PIR Sensors │◄────────────┐ └────────────┬─────────┘ │ ↓ │ ┌──────────────┐ No Person Detected │ Evaluate Sensor Input │─────────────┘ └─────┬──────────┬──────┘ │ │ Left Triggered Right Triggered ↓ ↓ ┌────────────┐ ┌────────────┐ │ Move Right │ │ Move Left │ └─────┬──────┘ └─────┬──────┘ ↓ ↓ ┌────────────────────────────┐ │ Switch RGB Ring to Red Flashing │ └────────────┬──────────────────┘ ↓ ┌──────────────────────────────┐ │ Stop Movement, Return to Sensor Check │→→→→ (Loop) └──────────────────────────────┘
The overall system structure is illustrated as follows:
┌────────────┐ │ Left PIR Sensor │ └──────┬──────┘ ↓ ┌──────────────────────┐ │ XIAO ESP32S3 Microcontroller │ └────┬────┬────┬────────────┘ │ │ │ ┌──────┘ │ └──────────────┐ ↓ ↓ ↓ Right PIR Servo Control RGB LED Ring (WS2812) (Digital In) (PWM D1~D8) (Data Out D10)
Project Highlight | Description |
---|---|
Biological Behavior Simulation | Simulates animal-like logic of "threat perception → escape", enabling autonomous reactive behavior. |
Multi-Module Integration | Integrates PIR sensors, SG90 servos, RGB LED ring, and microcontroller into a tightly coordinated system. |
Dynamic Visual Expression | Uses RGB lighting effects to express “calm vs alert” states, enhancing human-robot interaction. |
Expandable Structure | Allows easy replacement or upgrade to other sensors like cameras or ultrasonic modules for extended perception. |
This system is based on the XIAO ESP32S3 development board and integrates multiple input/output modules to detect human proximity and trigger corresponding robot movements. Each module has a clear function and collaborates in real time to form a complete interactive smart system. The main hardware components are described in detail below:
However, during assembly testing, I encountered a serious issue: the dimensional tolerance of the FDM prints was too large, especially the servo mounting holes. The connection plates for the claws could either not fit at all or were too loose in the horizontal and vertical directions.
I tried the following adjustments:
Despite these attempts, the print precision still failed to meet the requirements of the mechanical structure.
Eventually, I switched all mechanical claw components—i.e., parts requiring high-precision fit with servos—to SLA resin printing. Details are as follows:
The results were very satisfying: extremely high print accuracy, perfect snap-fit, smooth surface with no layer lines, and tight, seamless assembly.
I completed the assembly of all parts and ensured the following:
After completing the structural assembly and standing stability test, I moved on to the second phase of the quadruped robot project: making the structure move and implementing basic motion logic through automated control.
For this phase, I chose the following setup:
Microbit_Motor1
control library support)Reasons for selection:
servo(Sn, angle)
command for servo control, making the logic easier to implement.The servo numbering scheme was defined during the structural design phase. The details are as follows (referencing the top-down structural diagram):
Servo ID | Controlled Part | Function |
---|---|---|
S1 | Left front knee | Leg lift |
S2 | Left front hip | Forward swing |
S3 | Right front knee | Leg lift |
S4 | Right front hip | Forward swing |
S5 | Left rear knee | Leg lift |
S6 | Left rear hip | Forward swing |
S7 | Right rear knee | Leg lift |
S8 | Right rear hip | Forward swing |
I adopted a layout in which even-numbered servos control knee joints (vertical lift) and odd-numbered servos control hip joints (horizontal swing). This mapping makes it easier to organize and program motion sequences.
I began by creating the following function structure:
DF_Initial_state()
: Set all servos to 90° neutral positionDF_Standing()
: Set legs into a crouched standing pose (preparation for gait)DF_Lying_down()
: Simulate a lying/squatting postureDF_Move_forward_action_X()
: Define four-frame forward walking sequence: A ~ DThese motion functions control each servo individually using esp.servo(Sn, angle)
.
Referring to diagonal gait patterns in real quadrupeds, I defined a full cycle as:
A → B → C → D → (loop)
Frame | Core Motion Description |
---|---|
A | Lift left front + right rear leg → swing |
B | Legs land and push forward |
C | Lift right front + left rear leg → swing |
D | Legs land and complete forward propulsion |
DF_Initial_state()
: Servo Initializationvoid DF_Initial_state() {
esp.servo(S1, 90); // Left front knee
esp.servo(S2, 90); // Left front hip
esp.servo(S3, 90); // Right front knee
esp.servo(S4, 90); // Right front hip
esp.servo(S5, 90); // Left rear knee
esp.servo(S6, 90); // Left rear hip
esp.servo(S7, 90); // Right rear knee
esp.servo(S8, 90); // Right rear hip
}
Used for zeroing servo positions after power-on to avoid erratic behavior or self-triggering.
DF_Standing()
: Ready Postureesp.servo(S1, 135);
esp.servo(S2, 135);
esp.servo(S3, 45);
esp.servo(S4, 45);
Forms a balanced, crouched stance for starting the next leg movement.
DF_Lying_down()
: Crouch Simulationesp.servo(S1, 90);
esp.servo(S2, 135);
Used to demonstrate controlled resting action and test servo angle limits.
[A] Lift left front + right rear → swing
esp.servo(S1, 105);
esp.servo(S2, 165);
esp.servo(S7, 15);
esp.servo(S8, 165);
[B] Legs land → push forward
esp.servo(S1, 135);
esp.servo(S2, 105);
esp.servo(S7, 45);
esp.servo(S8, 105);
[C] Lift right front + left rear → swing
esp.servo(S3, 15);
esp.servo(S4, 15);
esp.servo(S5, 105);
esp.servo(S6, 15);
[D] Legs land → push forward
esp.servo(S3, 45);
esp.servo(S4, 45);
esp.servo(S5, 135);
esp.servo(S6, 75);
void setup() {
DF_Initial_state();
delay(2000);
DF_Standing();
delay(300);
DF_Lying_down();
delay(300);
DF_Standing();
delay(300);
for (int index = 0; index < 5; index++) {
DF_Move_forward_action_A();
delay(300);
DF_Move_forward_action_B();
delay(300);
DF_Move_forward_action_C();
delay(300);
DF_Move_forward_action_D();
delay(300);
}
}
Execution logic:
Initialize → Stand → Lie down → Stand again → Perform 5 full gait cycles → Stop
This sequence demonstrates the robot's full functional flow from power-on to movement, useful for both testing and presentation.
After completing the program logic design and structural assembly, I conducted multiple rounds of debugging. The main goals were:
I recorded and resolved multiple real issues through a layered diagnosis approach:
Symptoms: S7 and S8 showed no movement during Action A.
Troubleshooting:
Solutions: Changed slot, reconnected firmly, labeled channels
Symptoms: Robot leaned forward and deviated to the left
Troubleshooting:
Solutions: Symmetrical angle table, replaced parts with SLA, reinforced servo mounting
Symptoms: S2/S8 heated up and buzzed after 2 minutes
Troubleshooting:
Solutions: Limit angles, add buffer frames, use MG90S in future, extend delay()
Symptoms: Frames switched before motion completion
Troubleshooting:
Solutions: Increased delay to 350ms, added intermediate angles, suggest using millis()
Symptoms: Random desynchronization or jitter, restored after reboot
Troubleshooting:
Solutions: Separate power supplies, added 1000uF capacitor, recommend independent DC supply
I developed a reliable debugging workflow:
Ultimately, I realized that a stable robotic motion system is built on precise mechanics, reliable power delivery, and synchronized timing—not just correct code.