Welcome to Project 43. At some point in every maker’s journey, you look at a blinking LED and think, “This is great, but what if it had six legs, eighteen motors, and crawled across the floor like a caffeinated tarantula to terrify my cat?”
Congratulations. You have officially reached the mad scientist phase of Arduino prototyping.
Today, we are building an Arduino Hexapod. This project is a rite of passage. It involves a glorious spaghetti monster of jumper wires, the very real threat of releasing the magic blue smoke if you accidentally plug 18 servos directly into the Arduino’s 5V pin (spoiler: don’t do that), and learning how to multiplex PWM signals.
To pull this off without frying our microcontroller, we’ll be using the I2C-controlled PCA9685 16-channel servo driver. It allows us to control a massive array of motors using just two pins on the Arduino. Let’s get building.
If you remember our Lesson 126: Moving Things - Introduction to Servo Motors, you know that a servo requires a PWM (Pulse Width Modulation) signal to set its angle. The Arduino Uno only has 6 hardware PWM pins. Our robot has 18 joints. Do the math.
This is where the PCA9685 shines. It communicates via the I2C protocol (which we covered in Lesson 127: Displaying Data - Introduction to I2C LCD Displays).
V+ and GND screw terminals on the PCA9685. DO NOT power the servos from the Arduino’s 5V pin, or you will experience a catastrophic brown-out.SCL to Arduino A5, and SDA to A4.VCC to the Arduino 5V, and GND to Arduino GND.0x41).Walking isn’t just moving servos randomly. You have to calculate Inverse Kinematics—the math that figures out what angle each joint needs to be at to place the foot at a specific XYZ coordinate.
Here is a basic initialization snippet using the Adafruit PWM Servo Driver library to get your robot standing up:
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
// Initialize two PCA9685 boards with different I2C addresses
Adafruit_PWMServoDriver pwm1 = Adafruit_PWMServoDriver(0x40);
Adafruit_PWMServoDriver pwm2 = Adafruit_PWMServoDriver(0x41);
#define SERVOMIN 150 // This is the 'minimum' pulse length count (out of 4096)
#define SERVOMAX 600 // This is the 'maximum' pulse length count (out of 4096)
void setup() {
Serial.begin(9600);
Serial.println("Hexapod Booting... Brace Yourself.");
pwm1.begin();
pwm1.setPWMFreq(60); // Analog servos run at ~60 Hz updates
pwm2.begin();
pwm2.setPWMFreq(60);
delay(10);
}
void loop() {
// Stand up sequence (Centering the servos)
for (uint8_t servonum = 0; servonum < 16; servonum++) {
pwm1.setPWM(servonum, 0, 375); // Set to middle position
}
delay(1000);
}
Once you have it standing, the real fun begins: coding the tripod gait. Good luck, and may your code be bug-free (even if your robot isn’t)!