Source: Rohm, Author: Jan Gromes
https://techclass.rohm.com.cn/knowledge/tech-info/how-tos/arduino/how-to-arduino-hexapod-part-1-mechanics-and-wiring
This article is a translation from the English website DevicePlus.com.
The hexapod robot is one of the coolest robots, but they are often expensive. One reason is that they consist of multiple components and use 18 servos, all of which need to be powered and driven by certain microcontrollers. In this tutorial, I will show you how to build your own Arduino hexapod robot, or Ardupod for short, by using 3D printing for all parts and only 12 servos. Are you ready? Let’s get started!
-
• Arduino UNO (or other compatible Arduino development boards)
-
• Adafruit 16-channel PWM expansion board (or module; however, this expansion board is strongly recommended due to its small prototype area)
-
• 12 micro servos with metal gears (MG90S or other equivalent products)
-
• 4.8V or 6V battery (NiMH, Li-ion, etc.)
-
• 60 M3 bolts + 120 nuts and washers (only for the body; you will need to add more for other parts)
-
• 6 identical ballpoint pen springs
-
• HC-SR04 ultrasonic distance measuring module (optional)
-
-
• SolidWorks or other 3D modeling software
-
• Github (https://github.com/Gipsonek/ArduPod) – Here you can find all the Arduino source code and 3D models for printing
-
-
• It is highly recommended to use other tools such as multimeter, soldering iron, and electric drill
Design
As mentioned above, the designed hexapod robot only requires 12 servos to move its six legs. This means that each leg is equipped with only two servos, providing two degrees of freedom (DOF). This approach has several advantages compared to the usual three servos per leg. We will need less power and less processing time to drive the servos. However, removing one servo also means sacrificing one degree of freedom, making programming the robot for stable crawling more challenging.
To compensate for the lack of a servo, all legs have a mechanical system that converts the angular motion of the servo into linear motion of the legs.
This mechanism includes a spring. The role of the spring is to compensate for all errors caused during printing. Additionally, the spring provides stronger support, helping achieve more natural crawling motion. You can obtain springs from anywhere. For example, the small springs in ballpoint pens can be used here, but you may need to trim them slightly. Ensure that the springs you obtain can compress and are strong enough to support the weight of the robot. Also, before starting to print the parts, make sure the springs are suitable for the printed parts leg_1 and leg_1_seg_1 (see details on Github: https://github.com/jgromes/ArduPod).
Assembly
Next, welcome to the most challenging part of this article: assembling the legs. This is a relatively advanced project in both construction and programming. We will assume that the person intending to build this robot has basic skills in using tools such as electric drills and soldering irons.
Figure 1: Overview of leg assembly
Figure 2: Details of leg assembly

When assembling the legs, always remember to place a washer between every two plastic parts that need to move up and down. You may need to adjust the size of the holes with an electric drill to ensure that the bolts can rotate freely. Also, note that each bolt requires two nuts.
Figure 4: Connecting leg joints: plastic parts (black) and metal parts (light gray)
This is crucial for the proper functioning of the entire support system. When assembling the legs, ensure that the bottom nuts are not tightened too much, allowing the plastic parts to move freely. Then, the top nuts should be tightened as much as possible. The bottom nuts ensure the free movement of all parts, while the top nuts secure the connection of all parts. If your nuts are too loose, the legs will become very unstable; if too tight, they will place unnecessary load on the servos. Adjusting the legs may require several attempts. This is the most important part of this tutorial, so make sure to complete this step correctly.
The servos are fixed in place by a small “triangle arm” that is commonly used to connect the servo gear shaft to any object you want to move. However, in this case, the position of the triangle arm will be fixed so that when the servo operates, it will also move, thus moving the legs.
Ensure that you are using metal gear servos, not plastic gear servos! Using plastic gears in this application will not only result in lower strength than metal, but the gears may also wear out quickly.
Figure 5: Details of servo attachment. Ensure the triangle arm is fixed in the correct position.
The servo bracket is divided into three parts for easier printing. Assuming the parts are printed with ABS, acetone can be used to slightly dissolve the ABS, then glue these three parts together and let them dry. Alternatively, if you have access to a higher quality 3D printer, you can print the entire part in one go.
Figure 6: Details of servo bracket assembly
The remaining parts of the hexapod robot are not that complicated: the body is made up of two plates on which we can install all the required electronics, batteries, and sensors. You can set the holes for installing the electronics before printing or drill them afterward. All parts and printing instructions can be found on Github.

Figure 7: Assembled body: “A” is the top plate, “B” is the bottom plate. You can also see the ultrasonic sensor mounted on the servo.
Success! At this point, you have completed the assembly of the robot, finishing the most challenging part of this tutorial. If something goes wrong, don’t worry, try again. If necessary, try fine-tuning the printed parts and see if it works.
Wiring
So far, this is the easiest part, as we will use the Adafruit PWM expansion board to do most of the work. We connect the expansion board to the Arduino and then connect the servos to the expansion board. If the module you are using cannot be directly connected to the Arduino, simply connect SDA, SCL, and V+ to the corresponding pins on the Arduino (see the diagram below for details).
You may have noticed that there is a place for a capacitor, but there is no capacitor. Don’t worry, this is intentional! When many servos operate simultaneously, the current peaks can reach several amps. The capacitor will be used to eliminate these spikes. You may need this capacitor to ensure stable power for all servos. For this purpose, using an electrolytic capacitor is most suitable, but the choice of capacitor value is more based on guesswork than exact scientific calculation. Generally, the larger the capacitor value, the better. The capacitor voltage should be slightly higher than the battery voltage, so if you are using a 6V battery to power all the servos, then 6.3V 4700µF should suffice.
On the expansion board, you will also notice a separate power terminal. This is because the Arduino itself cannot provide enough current to operate more than one or two servos at a time; you need to connect the battery to this terminal as well as to the Arduino power input (VIN and GND pins).
That’s it, the basic wiring is done! If needed, you can also add more modules and sensors, such as ultrasonic distance meters.

Figure 9: Wiring details: it is advisable to tie together the cables of all servos connected to the same leg. This way, you will know which cable leads to which servo. Moreover, this will look better than a tangle of wires.
Figure 10: Wiring diagram with HC-SR04 ultrasonic sensor
In this tutorial, I will add an ultrasonic sensor to allow the robot to move in the presence of obstacles. I chose the HC-SR04 because they are very cheap and easy to use with Arduino. Also, the shape of this specific sensor resembles an eye, which you can use to identify what the robot is looking at!
I will mount the sensor on an additional servo (for installation details, see Figure 7). Wiring this sensor is also very simple, just be careful not to connect the VCC pin directly to the battery! If you are using a 6V battery, such a connection may damage the sensor. Connect the VCC pin to the Arduino 5V output and GND to GND. You can connect the TRIG and ECHO pins to any remaining digital pins, but remember to set them appropriately in the code. I will connect them to pin 3 (TRIG) and pin 2 (ECHO) because I want to keep pins 0 and 1 free for serial port use.
Conclusion
Now you should have completed the assembly of all hardware. It is strongly recommended that you test and confirm each connection you have made before powering up.
I hope you haven’t encountered any tricky issues so far. If you have any suggestions for improvements to this design, please reach out to me on Github! Stay tuned for the second part of this project, where we will delve into the next stage, further exploring inverse kinematics and programming this amazing Arduino hexapod robot (or Ardupod).
Next, you will see the ArduPod extend all its legs at once!
Part Two: Programming
In the second part of this project, we will continue with the relatively easy part of the project—programming. Programming the hexapod robot usually has two different approaches. The first is simply figuring out the series of servo operations for the robot to walk forward. Obviously, this is a challenging yet rarely effective task—your designed code cannot be directly applied to another hexapod robot. Thus, the second approach, known as inverse kinematics, comes into play. But first, we need to upgrade the onboard microcontroller.
Hardware
-
-
• Adafruit 16-channel PWM expansion board (or module; however, this expansion board is strongly recommended due to its small prototype area)
-
• 12 micro servos with metal gears (MG90S or other equivalent products)
-
• 4.8V or 6V battery (NiMH, Li-ion, etc.)
-
• 60 M3 bolts + 120 nuts and washers (only for the body; you will need to add more for other parts)
-
• 6 identical ballpoint pen springs
-
• HC-SR04 ultrasonic distance measuring module (optional)
Software
-
-
• Github (https://github.com/jgromes/ArduPod) – Here you can find all the Arduino source code and 3D models for printing
UNO -> Mega
In the previous article, we recommended using Arduino UNO for this project. However, I encountered a problem when using UNO: it does not have enough SRAM memory for all the calculations required for the inverse kinematics model to run properly. Most of these calculations are done using floating point numbers. Each number will occupy 4 bytes of memory when used, which is twice that of integers. Although it seems like a small amount, the UNO has only 2kB of RAM, some of which will be occupied by global variables. If we reserve 0.5kB for all global and other local variables, then there will be 1.5kB of usable memory left, which can only accommodate 384 floating point numbers. 384 may seem like a lot, but it is insufficient for the amount of data generated by a 1K model (see the “Algorithm” section below for related reasons). Therefore, we must find a way to obtain larger memory.
The simplest way to achieve this is to change UNO to MEGA. MEGA and UNO are compatible, so the schematic does not need modifications. Moreover, using MEGA not only provides four times the RAM for calculations but also means there will be more than eight times the flash memory available for our program storage. We are unlikely to use all of it, but having a larger reserve is always better. Below is the improved Fritzing schematic; if you are using the latest version of Arduino MEGA (Rev 3), the replacement process is simple—just disconnect the UNO and connect the MEGA. The diagram below is for reference.
Figure 1: Improved schematic of the PWM expansion board
Figure 2: Improved schematic of the PWM module and HC-SR04 ultrasonic sensor
Now, let’s explore some physical principles, the large amount of mathematics involved, and a bit of code.
Introduction to Inverse Kinematics
Some of you may remember that in high school, there was a section of physics class called “kinematics”. Simply put, it is a description of the motion of a target object (or a point) in the field of mechanics. This means that in kinematics, you will use mathematical formulas and models to analyze the known motion of a single point. As the name suggests, inverse kinematics (IK) is the opposite: it uses a series of mathematical formulas to backtrack and create motion.
In the field of robotics, algorithms commonly used can only calculate the motion of all joints based on the corresponding endpoint motion. Now, you can clearly see the advantages of inverse kinematics in the servo motion programming part—it is universal. Theoretically, a single algorithm can handle any motion performed by the robot. From the user’s perspective, it is very easy to use— you only need to tell the robot to turn left 90° and then move straight for 1 meter without worrying about the position of each servo.
Model
In the above paragraphs, one word keeps appearing: a (mathematical) model. While it sounds complicated, the model for this hexapod robot project is quite simple: any position that the robot can mechanically reach can be defined by a set of seven points. One for the body and six for the legs. If you check the AP_Utils library (available on GitHub https://github.com/jgromes/ArduPod), especially the AP_Utils.h inside, you will see the definitions of these points (among other things):
struct body {float x;float y;float z;float facing;};struct leg {uint8_t number;bool move;float phi;float z;};
You can see that they are declared as private structures in the AP_Utils class.
There are two reasons for making these structures private:
-
Users should not have the authority to arbitrarily modify these values. The existence of these structures is to track the current position of the robot, so these structures will only change when the robot actually generates motion. If the user wants to change the current origin’s z coordinate, it will lead to unpredictable changes in the IK model—this is obviously undesirable.
-
Generally, keeping the number of public functions and variables in a class to a minimum is a good programming practice (especially in C++). Therefore, doing so can enhance security and facilitate the easy implementation of APIs.
If needed, we can visualize these points. Now, our entire robot is represented by seven points (Figure 3).
Figure 3: Graphical representation of the IK model. In short, this is how the hexapod robot “thinks” it looks. The red point is the body, and the blue points are the legs.
These structures are used to track the positions of all legs and the robot itself. You may have noticed that the position of the legs is defined by only two coordinates: phi and z. This is because each leg has only two degrees of freedom, so it can only move along two axes. Now, all positions can be defined by the body’s x, y, and z coordinates. The range of each leg’s phi and z coordinates is -1 to 1 and only determines the position of the leg relative to the body. Although this complexity may seem unnecessary at first glance, it is much easier than calculating each leg’s x, y, and z coordinates after every movement. The phi coordinate represents horizontal movement, while z represents vertical movement.
Figure 4: Leg details with phi and z axes
Algorithm
Now that we have a sufficiently simple mathematical expression for the robot, we haven’t done anything with it yet. The next step is to explore how to convert input as a set of point coordinates into servo operations.
Another issue arises at this point, and this time, simply replacing it with another Arduino won’t solve it. When activating the servos, we may need to operate most of the servos simultaneously. However, Arduino (and all related AVRs) can only perform one task at a time. This means that if we want to operate the servos smoothly, we need to activate them one by one. If we simply move the servos from one end to the other, the entire process will be very unstable.
One way to solve this problem is to pre-calculate the positions of all servos, then iterate through this data and set all servos. Since the Arduino MEGA has a clock frequency of 16MHz, although all servos operate in discrete increments during the actual process, the overall performance appears as a continuous and smooth operation. Even though they are just a collection of static images, this is consistent with the effect of continuous motion produced in a video. The human brain cannot process visual information quickly. If we add a 50-millisecond delay after each position change, it will be evident that the servo operation is actually composed of small increments.
This is also why we must change the Arduino. If we want to operate every servo, we need a lot of memory to store the coordinates we just calculated. If we operate all servos, we will need 600 floating point numbers to store the motion coordinates because each servo requires at least 50 positions to produce a smooth continuous operation effect. 600 floating point numbers take up about 2.3 kB of RAM—this already exceeds the capacity of the UNO.
In the AP_Utils library, the functions that convert positions into servo operation statuses are traceLeg() and setLegs(). The traceLeg() function only performs calculations: when provided with the target endpoint’s phi and z coordinates, it will create a path in the form of a coordinate array. The path can take various shapes; currently, linear (a simple straight line from one point to another), arc, and elliptical arc are supported. The latter two paths can make walking easier. The second function setLegs() will move all specified legs based on the results of traceLeg, but all of this is hidden from the regular user. The focus of the entire scheme is to make it as convenient as possible for the user. The end user will not need to directly set setLegs(), but only call functions directly related to walking.
Now we begin the last step of IK programming, which is actual walking. We have completed all the basics: we have created a model to track everything, we can operate multiple servos, and we can make the operation of the servos relatively smooth and continuous. In the following content, the numbering of the legs corresponds to the numbers in the diagram below:
This numbering system is consistent with the code you will find in the library.
We start with a simple operation: turning in place. Typically, when setting a new position for the legs, you must ensure that three legs are on the ground. The reason behind this is obvious—unless you can move the legs very quickly, the robot will lose stability and fall. We can turn the robot in several steps:
1. Move legs 0, 2, and 4 to the maximum phi coordinate (maximum horizontal angle).
Figure 6: Turning step 1 (legs 0, 2, and 4)
2. Repeat the same operation for legs 1, 3, and 5.
Figure 7: Turning step 2 (legs 1, 3, and 5)
3. The body turns. This step is accomplished by running all horizontal servos in the opposite direction to steps 1-3. Since all legs are on the ground and cannot move, only the body can move.
By repeating these steps, the robot can turn 80°. Of course, as long as the maximum phi coordinate is not maintained throughout the process, turning at angles less than this can be achieved. Thanks to the clever algorithm behind traceLeg(), we do not need to calculate the z coordinate values of the legs—these calculations will be done automatically, forming a circle or ellipse shape. You can observe this process in the video below.
The final step is walking. Specifically, we want it to walk forward at least. There are many walking algorithms for hexapod robots, but most of them are based on legs with three degrees of freedom. Our legs only have two degrees of freedom, so we must design something ourselves. The method I propose, while not achieving the expected speed, is the easiest to program and allows for observation of phenomena during the process.
1. First, legs 0 and 3 move forward
Figure 9: Walking step 1 (legs 0 and 3)
2. Then, legs 2 and 5 move in the same direction
Figure 10: Walking step 2 (legs 2 and 5)
3. Repeat the same operation for legs 1 and 4
Figure 11: Walking step 4 (legs 1 and 4)
4. Now, the body moves forward, starting to repeat the entire process.
Figure 12: Walking step 4
Basic Obstacle Avoidance Function
You may have noticed that there is a part in the library specifically for the SR04 ultrasonic distance meter. This is to obtain some information about the environment where the robot is located. Of course, a stationary sensor is not enough, so in the previous article, we also installed a sensor on an additional servo.
I believe most people trying to build hexapod robots have a certain understanding of how ultrasonic distance meters work. For interfacing with this sensor, I recommend using the AP_Utils::sr04_median function. It can provide the most accurate results of all SR04 functions in the library. You can even output the unit of the data; currently, it supports millimeters, centimeters, and meters!
Important Note: Please note that you need the Adafruit PWM driver library to make AP_Utils work. You can click here (https://github.com/adafruit/Adafruit-PWM-Servo-Driver-Library) to download it. After downloading, install it like any other Arduino library.
Below is a very simple example of an “autonomous” mode that uses all the content we have discussed so far: walking, turning, and reading distances from the SR04. If you have read this article carefully, you should be able to fully understand the most important parts of the following code. For more details on all functions, please refer to the README.md file in the library folder or on GitHub (https://github.com/jgromes/ArduPod/blob/master/arduino/AP_Utils/README.md).
#include <AP_Utils.h>//define the pins that the SR04 is connected to#define TRIG 3#define ECHO 2//create an instance of AP_Utils classAP_Utils ardupod;//you will have to supply your own offsets here//see examples/calibration.ino for detailsint offsets[16] = {5, 0, 0, -7, 10, -3, 6, -4, 3, -5, 10, -3, 0, 0, 0, 0};void setup() { //reset the robot ardupod.begin(offsets);}void loop() { //take one step directly forward ardupod.walk(0, 1); //if an obstacle is closer than 20 cm, we have to turn if(sr04_median(TRIG, ECHO, CM, 100, 500) < 20.0) { //turn 90 degrees to the right ardupod.turn(90); }}
Conclusion
Congratulations on completing one of the most challenging projects! Well done! Before trying to make your own ArduPod walk, please ensure to run the calibration.ino and servo_test.ino files in the example folder simultaneously. This is crucial for correctly setting all servos so that they are not damaged! In the next article, we may conduct one final exploration of this project to improve some poorly performing mechanical points and, more importantly, add some enhanced features, such as remote control.

Part Three: Remote Control
In the third and final part of this series, we will add the last component to the robot: the remote control. Additionally, we will make some minor improvements to the legs to ensure they are more stable on any type of base surface. First, we will introduce the slightly modified leg mechanism, then connect the HC-05 Bluetooth module to the Arduino for wireless control. Finally, we will write a Processing application so that we do not have to use written instructions for every movement of the ArduPod.
Hardware
-
• The hexapod robot obtained from Part One
-
-
• 1 kΩ resistor and 1.8 kΩ (or 2.2 kΩ) resistor
Software
-
-
-
• GitHub – Contains the latest source code
-
• Release 1.0.0 – Alternatively, you can download the source code for v1.0.0 here. If there are significant API-breaking updates in the code on GitHub, this code will still run as described in this article.
Tools
Improving the Legs
When I made my hexapod robot, the biggest challenge I faced was the instability of the legs on smooth surfaces. Usually, adding some non-slip material on the legs can easily solve this problem. However, the contact area between the legs and the ground was too small. Increasing the contact area between the legs and the ground greatly helps with non-slip effects and improves the overall stability of the legs.

Figure 1: Old legs (left) and new legs (right)
In the above image, you can see that a supporting part has been added to the bottom of the legs. Like other parts, this part is also made from black ABS material using a 3D printer. You can find models of other parts on my GitHub.

Figure 2: New part added to the legs. Note the deep green non-slip layer at the bottom
Now we can add a non-slip layer to the feet. I used a green gel pad. This material will not slip even under very light loads. If you cannot obtain this material, there are very few other options (like rubber). You can try which material works best for your robot. Then cut six circles from the material and glue these circles onto the feet, and this step is complete!
The next improvement I want to make is a bit more complex than the feet. In the current system, the servos are only connected to the legs at one point. This creates a weak point in the structure that will bear most of the load, which may lead to a break at some point. In Figure 3, you can see the current attachment system and the new attachment system next to it.

Figure 3: Old attachment system (left) and new attachment system (right)
We noticed that the newly added part allows the servos to connect in two positions: on the axle (the previous connection point) and on the opposite side of the servo. Gluing a small pad with a knob to the servo can provide extra support for the servo. Now, the servos are connected at two points, distributing the load between these two points. This allows for better motion control.
Wireless Arduino
Now that we have solved the leg issues, we can connect the HC-05 Bluetooth module, which allows for wireless control of the robot. Since all controls are managed by Arduino, our main task is to send instructions to it.
The methods for wireless communication between Arduino and the PC mainly include the following:
-
1.RF modules – This is the most basic (and also the cheapest) wireless communication method. Typically, they operate in a single radio frequency band (433, 868, or 915 MHz) and require some setup on the user side. The main advantage of RF modules is the long communication distance (up to several hundred meters) and relatively low power consumption.
-
2.LoRa – LoRa modules are similar to the above RF modules but use special modulation methods to achieve longer-range communication (up to several kilometers) at the same power consumption. Of course, the trade-off is a very slow transmission speed, with a maximum transmission speed of only a few hundred bits per second.
-
3.WiFi – WiFi modules provide a fast and easy way for Arduino to connect to the network, but the range is usually quite limited. Additionally, the power consumption of this module can be high.
-
4.GSM – This is the technology that allows your phone to work. The GSM module has a significant advantage over other options: as long as there is a signal, communication can be achieved, even if the Arduino and the target PC are hundreds of kilometers apart. The biggest drawback of GSM is that it requires a lot of power—in some cases, the current consumption can rise to several amps, making it difficult to power solely with batteries.
-
5.ZigBee technology – XBee modules are usually more expensive than other modules mentioned here, but they easily interact with Arduino. These modules were developed as an alternative to Bluetooth, and generally, the communication distance can reach up to 75 meters.
-
6.Bluetooth – This is the module I ultimately decided to use in this project. Bluetooth is very easy to use, and in this project, limited range is not a big issue: we do not intend for the ArduPod to run off on a large adventure several meters away from the computer. Moreover, most smartphones have Bluetooth functionality, so if you plan to write a smartphone application, this module makes it easy.
Therefore, we will use the Bluetooth module in this project. I used the HC-05 Bluetooth module mainly because it is the cheapest and most common module. Since this module acts like a serial COM port, connecting the HC-05 to Arduino is straightforward, as shown in the Fritzing diagram below:

Figure 4: Wiring diagram of HC-05 Bluetooth module and Arduino Mega

Figure 5: Connecting HC-05 Bluetooth module to Arduino Mega
The module is powered by Arduino. The TX pin of the HC-05 connects directly to the RX1 pin on the Arduino. However, since the HC-05 operates at a logic level of 3.3V while the Arduino runs at 5V, there must be a simple voltage divider on the RX pin of the HC-05 to reduce the voltage. The value of R1 should be 1 kΩ, and the value of R2 can be 1.8 kΩ or 2.2 kΩ. I used a 2.2 kΩ resistor because I could not find a resistor with a value of 1.8 kΩ, but either of these two resistor values will work fine for this module.
At this point, Arduino still does not know that it is communicating via the Bluetooth module. From Arduino’s perspective, this is exactly the same as connecting via a cable. This is why we do not need to make any settings on the Arduino; the module handles everything itself—at least in the most common scenarios.
The next step is to set up the HC-05 Bluetooth module. The PC I am using does not have a built-in Bluetooth interface, so I must use a USB Bluetooth adapter.
First, we must pair the PC with the Bluetooth module.
-
• Connect the adapter to the PC and, after installing the drivers, find the