Part 2: Walking Wildlife

ESP32-Controlled Robotic Elephant

Andy Clark

Issue 28, November 2019

This article includes additional downloadable resources.
Please log in to access.

Log in

Build your own walking 3D printed elephant and control it wirelessly from your computer or smartphone.


In part 1 (Issue 26), we designed the 3D printed parts for our elephant, built a breakout board to power the four servos, and a test rig to experiment with the walking movements. Now we’ll undertake the full assembly, coding, and get it walking!


The ESP-32-Controlled walking elephant has been modified since Part 1 was presented, largely because we had to re-engineer the design. Notably, the range of very small fasteners that were used on the original design was proving difficult to source locally, so the legs were redesigned. In addition, Andy has continued to develop and improve the design between writing parts 1 and 2.

We printed our prototype based on what filament we had available at the time, which was partly white PLA, and partly an aluminium-finish PLA. We then painted our model with automotive plastic primer and flat grey. We had a plain grey PLA from Aurarum for our final build, but never got the time to use it before going to print.

We’re going to discuss some of the design changes, introduce the electronics used, build, code and finally test the elephant.



We have improved some of the parts over those we presented in part 1, as development continued. The new print files are available for download from our website. If you have already printed your parts, you just need to reprint the chassis [A], lower body [E], upper legs [M], and pawl [J]. Experience showed these to need some work to improve the overall motion of the build.

The chassis had an error where the holes for the rear leg armature wires were too close to the servo. This meant that the rear legs bent differently to the front. To fix this inconsistency, the chassis has been redesigned to allow the hole to be placed in the correct location, further back. To fit the new chassis, the lower body also needed adjusting, but the middle and upper bodies were kept the same to reduce the amount of reprinting.

The pawl proved to be too light to fall under its own weight, and was modified to mount around the rib on the leg, so that an M2 bolt could be used without nuts. M2 bolts are available from Jaycar (HP0390) to suit the thread in slide switches, and hence the nuts are not available. No other widespread retail supplier for M2 nuts or bolts was found in Australia, although they can be found piecemeal at some hobby shops and a few specialised stores. You can also use 2mm wire or metal rod. The weight comes from a fishing sinker glued to the back.


The battery needed to be capable of supplying at least 300mA to power the circuitry and four servos. Initially, lithium batteries were investigated. However, we settled on a 3 × AA holder for alkaline batteries instead. The ESP32 is a module that runs on 3.3V, and has a stated maximum of 3.6V. A lithium-ion battery has a voltage range of 4.2V fully charged to 3V fully discharged. This is too low to use the onboard voltage regulator and too high to use directly on the 3.3V input pin as it will certainly destroy the microcontroller. While the ESP-32 will run, it won’t for anywhere near its intended life before damage is done.

The ESP32 is built into modules by various manufacturers, and the one we used does have an onboard regulator for running from USB, but on some modules, this is not connected to the power supply pins, only the USB port. On others, there is a pin for 5V supply. Ours was rather ambiguous, with labels and datasheets confusing the issue of whether our board had an input for a 5V supply or not. Seeing as we needed a 3.3V option in our design to suit other brands of module anyway, we went the safest option.

In addition to this, the servos need 5V, so a step-up SMPS was required. We chose to go with a combination of 3.3V SMPS for the ESP-32, and a separate SMPS to give the 5V for the servos. Powering both of these Switch Mode Power Supply (SMPS) regulators from 3 × AA batteries keeps costs down and solves charging hassles, but there is plenty of scope for using a LiPo if you wish.

The Main Build:

Walking Elephant Robot

Parts Required:Jaycar
1 × Servo Breakout Board (DIYODE Issue 26)-
1 × ESP32 BoardXC3800
4 × 180° 9G Servo MotorsYM2758
1 × 5V PowerBoost Switch Mode Power Supply (SMPS)-
1 × Switch Mode Power Supply (SMPS)-
1 × 3 × AA Battery Holder with Switch-
1 × DPDT Sub Miniature Slide SwitchSS0852
1m × Mains 20A Twin & Earth Cable (Or White Tie Wire)WB1568
4 × M3 Brass Or Glassfibre Rods (For Wheel Axles)-
4 × M2 × 8mm Bolts *, Or 2mm RodHP0390
4 × 4G × 12mm Self-Tapping Screws *HP0554

* Quantity shown, may be sold in packs.


Before assembling the elephant, you will need to know the positions of the servos. We did this with a simple sketch that set all the servo positions to 90°. We have included this sketch in our web resources. You could also do this with the servo tester project from Issue 24.

Fit the servos into the chassis, so that the spindles are closest to the ends. Take care to ensure the cables don’t get crushed, and that they all exit from the top. Screw the servos in place using the screws they are supplied with. You may need to drill the holes on the 3D print, as screw sizes vary. We recommend labelling the servo cables at this point.

These are 180° servos, and we used the servo tester to set each servo to 50%, which corresponds to 90°. You may also wish to use a marker to put a dot that touches both the spindle and the case. This way, if anything gets moved during assembly, you will be able to see that this has happened.


To begin, you'll need to check over your prints and make sure each piece is clean and ready for build. Before assembling the legs, ensure all the parts are deburred and cleaned, paying particular attention to the holes for screws and spindles. It is worth checking that the wheels slide in and out of the lower legs and that the two parts of the leg slide easily on their joint. These parts may need sanding.

Glue the lower and middle body sections with the flat sides together. We found gelled superglue works well for this, but you may have your own preferences. This leaves the upper body to clip on and off for access to the electronics.

Glue the ears to the head, then the head to the neck. Carefully attach the head to the upper body. Consider supporting this part while the adhesive sets if you are not using cyanoacrylate glue. The tail can also be attached now. It goes at the back of the upper body.

Assemble all four legs the same way, noting that the lower halves of the left and right legs are different. Start by inserting the 4Gx12mm screw through the knee joint, then locate it into the pilot hole in the lower leg.

The wheel slots into the bottom of the leg. Check that this is oriented the right way, with the saw-tooth pattern aligned so the ratchet catches on it. Insert the axle and check for clean rotation of the wheel. Drill or file the hole if needed. Slide in a piece of 3mm shaft. We used an M3 bolt.

Attach the pawl into the lower hole in the lower leg, using an M2 bolt glued so that the pawl moves freely. Glue the sinker to the back of the pawl.

Connect the legs onto the servos, facing forwards. The front of the chassis is the end with no hole, and where the servos are closest to the edge. Attach the legs by press-fitting the hole in the leg over the servo spindle, and securing with the screws supplied with the servos which normally secure the servo horn.

You will need 1 to 2mm diameter wire for this step. We used white (galvanised) 1.25mm tie wire for this. Cut a length 65mm long and bend it into a dog leg 15mm from each end, to match the template. Note that the angles are not 90°.

Fit the wire between the upper hole in the back of the legs, and the chassis. Bend the ends to fix them in place. When set up, the wire should hold the leg straight. If it is too long, you can bend a slight kink in it to reduce its length.

Considering the front right leg as 0, the rear right as 1, the rear left as 2, and the front left as 3, (you may wish to number with a marker), feed the servo cables through the holes in the lower body. Push-fit the lower body onto the servo chassis.

Connect the battery pack, both Switch Mode Power Supply (SMPS) boards, ESP32 board, and servo breakout board as shown in the photo and schematic. Double check polarity of all connections. Some soldering is required. Add the data connections between the ESP32 and servo breakout board. Note that the pins are under the board. It is depicted from the component side in the schematic.

The board we used, and possibly others, had an incorrect label on the board, with two IO23 pins marked and no IO33.

Always check the connection diagram on the data sheet for your brand of module.

Attach wires to the switch that are long enough for it to reach from the ESP32 to the cut-out in the back of the chassis.

Mount the switch into the area at the rear of the chassis where the leg armatures mount, orienting it to your preference so you know which direction is ‘enable’ and which is ‘disable’. Glue it in place with hot melt glue, then set to ‘disable’.

Move the servo cables to the side and arrange the battery pack and circuit boards inside the middle body. Plug the servo connectors in, taking care to check polarity and order.

Slide the upper body over the recess on the middle body to cover the electronics. Turn your elephant upside down, and move the switch to ‘enable’.


The controller for our elephant robot is an ESP32 board. This is the newer version of the ESP2866 which comes with a faster dual-core processor and the usual WiFi connectivity. We picked a variant of the board that can be easily programmed using the Arduino IDE. However, there are a few steps necessary to set up your machine for this to work.

To configure your computer for developing with the ESP32, you may need to install a virtual com port driver for the USB to serial chip. This will be either a CH340 or CP2102 depending on where you bought your board from:

With the driver installed, you should find that the board appears as a comm port when you plug it into your computer.

You’ll also need to configure the Arduino IDE to talk to this board. From the Arduino IDE, select the File menu, then Preferences. In the “Additional Boards Manager URLs:” box type, add the following:

Then from the Boards Manager, install “ESP32 by Espressif Systems”.

The ESP32 can produce the PWM signals for the servos on any of the available pins. It can support up to 16 channels at once. It does need a different library instead of the default servo library.

To install the library, choose the library manager, and search for ESP32Servo.

The elephant communicates to your phone or computer via a web page. The name resolution is done using a technology called mDNS or ZeroConfig. This allows us to access our board as ESP32.Local rather than having to know its IP address. For this to work, you may need to install some software.

LINUX: Install Avahi.

WINDOWS: Install Bonjour.

MAC OSX AND IOS: Support is built in through Bonjour.


For the final code, we simplified the servo motion so that forward and backward movement travels at the same speed. To turn the elephant, we reduce the stride length on the side it turns towards. The user interface uses a simple web app and AJAX calls to activate the functionality of the Elephant.

See our Fundamentals article from Issue 19 for more details on how to get started with Web Apps.

The code is available for download from the resources section of our website. It includes the libraries we need to connect to the WiFi, resolve the name, run the webserver and move the servos.

#include <ESP32Servo.h>
#include <WiFi.h>
#include <WiFiClient.h>
#include <WebServer.h>
#include <ESPmDNS.h>
#include "Secrets.h"

This is followed by some special constant. These “SECRET” constants work with the Secrets.h file and if you use the webIDE these will be kept securely. For the desktop Arduino IDE, you have to remember not to copy the secrets file to your source control system.

const char *ssid = SECRET_SSID;
const char *password = SECRET_PASS;

The next constant is the definition of the main page shown by the webserver. This has been minified and converted to a string using the following two online resources:

It presents to the users some buttons, which when pressed, make REST calls back to the webserver with the commands, left, right, forward or stop. This variable is stored in program memory using the PROGMEM keyword.

The webserver is declared and defined to run on the standard port 80.

We also declare the array containing our four servos and define some variable which will be used to control the motion of the legs.

const char PROGMEM *webpage = "
<!DOCTYPE html>
<meta charset="UTF-8">
<title>Elephant Control Panel</title>
move(dir){document.getElementById("response").innerHTML=dir; var xhr=new
XMLHttpRequest(); xhr.timeout=500; xhr.ontimeout=function
(e){document.getElementById("response").innerHTML="Elephant not responding";};
(this.readyState==4){document.getElementById("response").innerHTML=this.responseText;}};"POST", "/" + dir, true); xhr.send();}</script>
<p><button type="button" onclick="move(‘left’)"><</button> 
<button type="button"
<button type="button"
<p><button type="button"
<p id="response"></p></body></html>";
WebServer server(80);
Servo myservo[4];
int strideLeft;
int strideRight;
const int strideShort = 20;
const int strideLong = 45;
const int strideStopped = 0;
const int middlePosition = 90;


The setup code is too long to list here. In the setup, the first tasks are to connect to the WiFi and define the name in MDNS as “esp32”. We then define what happens when the user requests different web pages. After starting the webserver we configure the servos to connect to the different pins of the ESP32 board. The servos are moved to their starting positions.


In the main loop, we handle the requests for the webserver and the motion of the legs.


It is best to test the servos and chassis before mounting the elephant’s body. Although the construction steps above involve mounting the lower body first, you can temporarily connect the circuitry for testing. This will allow you to see that the links are working correctly.

Don’t be tempted to move the servos by hand while they are plugged in, as this can generate both noise and power when and where it is not wanted. The servo tester or a simplified code could help here, although be aware that once the armature wire is fitted, the servos only have about 45° movement. The servo should rotate the upper leg forward and up, and the link wire should hold the lower leg vertical, causing the knee joint to bend. If this motion is not smooth, then disassemble and smooth the curved surfaces of the leg joints with sandpaper.

You may find your elephant skates on smooth surfaces, so find a rougher surface such as wood or stone. Note that a long carpet will tangle in the wheels, and so should be avoided. Check that the wheels are free moving when rolling forward and stopped by the ratchet in reverse.

If you can’t find the board with your web browser on http://esp.local, then check your router. It should show you the IP address that has been assigned. The serial monitor should also show this address, although we found our board was not writing to the debug serial port. An alternative would be to configure some other pins as a serial port and use a USB to TTL adapter to monitor those.


You’ll need to configure your secrets file to your WiFi credentials, compile the code and upload it to the board. When the ESP32 boots it will connect to the WiFi and start a web server. Enable the servo power by sliding the switch. Your elephant should stand straight.

Point your web browser to http://esp32.local and you should see the control buttons. Pressing these should cause the elephant to move.


The design of the elephant is quite modular so you could swap out the head and tail to form other animals. You could perhaps wire up a fifth servo and have a moving trunk on your model. Using the REST API of the elephant you could remote control the elephant programmatically. If you don’t fancy an animal, then perhaps combine your four servos and control circuit into a different vehicle or a robot arm.

3D Printing: Trials and Tribulations

3D printing the parts for this project was not without dramas, and not all of them were solved before going to print. One of these was the pawl. The original design was too light, and the first revision was designed with an extension that would press on the back of the leg in the resting state, and flex when the pawl indexed, applying pressure. This was intended to be printed with flexible filament. However, flexible filament is actually quite hard to work with. For many readers, this was a no-go, hence the redesign to feature the fishing sinker.

The next issue revolved around orientation. Something went wrong between design, and the files arriving at the DIYODE office. Not one of them sat flat on the print bed. While some slicing programs deal with this, either automatically or at the click of a button, others do not. We found that Windows 3D Builder solves the orientation problem, with the “Settle” command.

We had some trouble with warping, which has not been an issue in the past. This could be due to a range of part design factors. It could have been a lack of glue on our recently-acquired Flashforge Finder’s build plate, or even a cold draft. Whatever the cause, it was a new problem for us.

Finally, we encountered scale issues between prints. Parts which were nominally the same size, printed out of scale by a small factor. These parts were printed on the Flashforge Guider and Finder, and similar problems have been encountered by one of the DIYODE team who has a Guider. So far, this problem appears to lay in the Flashprint software, and not the printer. Our next step is to use another slicer to explore, but again, we ran out of time.