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.

The Hardware You’ll Need

The Wiring: Taming the Spaghetti

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).

  1. Power: Connect the 18650 battery pack to the 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.
  2. I2C: Connect the PCA9685 SCL to Arduino A5, and SDA to A4.
  3. Logic Power: Connect the PCA9685 VCC to the Arduino 5V, and GND to Arduino GND.
  4. Servos: Plug your 18 servos into the numbered headers on the PCA9685 (you’ll need to chain a second PCA9685 board to get all 18 channels, bridging the address solder pads on the second board to give it a unique address like 0x41).

The Code: Inverse Kinematics (Simplified)

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)!