ESP32 Mini-Bot

A small proof-of-concept ESP32 Bot

Public Chat
Similar projects worth following
A club I've been involved with for a while at my university wanted to upgrade one of our projects to utilize the ESP32 to expand its capabilities. I decided to build a prototype proof-of-concept model to work out the basic circuitry and programming for the project. This design is almost fully 3D printed (not including the #6 screws) and is relatively easy to build and reproduce.

A simple WiFi controlled robot prototype for a club at my university. Uses the ESP32 dev board, a L293 dual H-Bridge, and is mostly 3D printed. 

esp32 mini-bot joystick

HTML Web-page served by the bot

Zip Archive - 897.00 bytes - 02/22/2019 at 20:24


Adobe Portable Document Format - 31.22 kB - 02/21/2019 at 21:30



STL Files of ESP32 Mini-Bot

Zip Archive - 111.08 kB - 02/21/2019 at 21:29


Arduino Sketch Files

Zip Archive - 2.74 kB - 02/21/2019 at 21:27


Tank Mech Build.FCStd

Master FreeCAD Model

fcstd - 2.48 MB - 02/21/2019 at 21:26


View all 8 components

  • Software Part 2: Motor Control

    Matthew James Bellafaire02/22/2019 at 00:56 0 comments

    Finally we're here at the end; time to talk about how this thing actually moves. The original bots that my club utilized were remote control tanks, ideally this bot would move and turn just like a tank. I can't manage to find two matching rubber bands to string across the wheels but that was the intention. In order to make this bot move properly the program must be capable of varying the amount of power to each motor, interpreting the relative power to each motor based on input, and be continuous and predictable (it shouldn't immediately turn left if the user is 1 degree off forward). 

    Varying the speed is simple, since this project uses a L293 all that the program needs to do is send a PWM signal to the EN pins on the channel controlling each motor. In Arduino this is easy, for the ESP32 its more involved but still way less than pure AVR C. using the ledc library we can assign two PWM channels to two separate pins and assign outputs: 

      pinMode(O4A, OUTPUT);
      pinMode(O3A, OUTPUT);
      pinMode(O2A, OUTPUT);
      pinMode(O1A, OUTPUT);
      //PWM Setup
      ledcSetup(pwmRightChannel, pwmFreq, pwmRes);
      ledcSetup(pwmLeftChannel, pwmFreq, pwmRes);
      ledcAttachPin(EN34, pwmLeftChannel);
      ledcAttachPin(EN12, pwmRightChannel);

    Each pin is labeled in accordance with what it's connected to on the L293. The PWM channel can be written to utilizing the function: 

    ledcWrite(pwmChannel, val);

    Its also worth noting that the resolution is definable with the ESP32, in the case of this sketch its set to a resolution of 8-bits so 0-255. 

    Now there's fine control of each of the motors, what about direction? That's where the setMotors() function comes in: 

    void setMotors(int _right, int _left) {
      int rightVal = abs(_right) ;
      int leftVal = abs(_left);
      Serial.print("Right ");
      Serial.print(" Left ");
      if (_right > 0) {
        ledcWrite(pwmRightChannel, map(rightVal, 0, 100, 0, 245));
        digitalWrite(O2A, HIGH);
        digitalWrite(O1A, LOW);
      } else if (_right < 0) {
        ledcWrite(pwmRightChannel, map(rightVal, 0, 100, 0, 245));
        digitalWrite(O2A, LOW);
        digitalWrite(O1A, HIGH);
      } else {
        ledcWrite(pwmRightChannel, map(rightVal, 0, 100, 0, 245)); //it'll only get here if its zero anyway
        digitalWrite(O2A, LOW);
        digitalWrite(O1A, LOW);
      if (_left > 0) {
        ledcWrite(pwmLeftChannel, map(leftVal, 0, 100, 0, 245));
        digitalWrite(O4A, LOW);
        digitalWrite(O3A, HIGH);
      } else if (_left < 0) {
        ledcWrite(pwmLeftChannel, map(leftVal, 0, 100, 0, 245));
        digitalWrite(O4A, HIGH);
        digitalWrite(O3A, LOW);
      else {
        ledcWrite(pwmLeftChannel, map(leftVal, 0, 100, 0, 245));
        digitalWrite(O3A, LOW);
        digitalWrite(O4A, LOW);

    for the right motor, we can set the direction of the motor by changing the values on the 2A and 1A pins of the L293, 2A high and 1A low makes the right motor move forward. Changing the pin values to 2A low and 1A high will make the right motor go in reverse. Toggling the EN pin high will enable the right motor and toggling it low will disable the right motor. The PWM signal is fed into the EN pin, since using this method only one pin has to be modified rather than modifying both the inputs on the L293. 

    Now the bot has XY coordinates coming in and a way to vary the speed and direction of each motor, the program still needs to be able to interpret these values. There's a lot of ways to manage this here's the method I used: 

    void setMotorsXY(int x, int y) {
      //lets move things to polar, it will make the motor setting much easier since we really only have to look at theta
      double theta = PI / 2; //default to forward
      double rightSpeed = 0;
      double leftSpeed = 0;
      if (x != 0) {  //just some exception handling here
        if (y > 0) {
          theta =  PI - atan2(y, x * (-1));
        } else if (y < 0) {
          theta = 2 * PI + atan2(y, x);
      } else {
        if (y > 0) {
          theta = PI / 2;
        } else {
          theta = 3 * PI / 2;
      double r = sqrt(x * x + y * y) / 100; //we want this value to be...
    Read more »

  • Software Part 1: WiFi Control

    Matthew James Bellafaire02/21/2019 at 21:25 0 comments

    Before this project I had limited experience with the ESP32 and for the most part I followed this tutorial to get the project up and running in the beginning and modified from it. That tutorial got me started, however, since the software for this project is probably the most likely reused part of it, there were not a lot of compromises and I had a few goals: 

    • Quick and responsive communication
    • accurate speed/direction control
    • simple and intuitive interface 

    So lets start with the web page the ESP32 serves every time a user connects: 

    <html><head><meta charset="utf-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
    <script src = ""></script>
    <script src=""></script>
    body {overflow    : hidden;background-color: #BBB;}
    #container {width: 100%;height: 100%;overflow: hidden;padding:0;margin:0;-webkit-user-select:none;-moz-user-select:none;}
    </style><title> ESP32 Bot Control Site </title></head><body>
    <div id="container"><h1>ESP32 Bot Control</h1></div><div id="info"><span id="result"></span></div> <script>
    console.log("touchscreen is", VirtualJoystick.touchScreenAvailable() ? "available" : "not available");
    var joystick    = new VirtualJoystick({
    container    : document.getElementById('container'),
    mouseSupport    : true,
    limitStickTravel : true,
    stickRadius : 100
    joystick.addEventListener('touchStart', function(){
    joystick.addEventListener('touchEnd', function(){
    var message = "/?M/?X"+Math.round(joystick.deltaX())+"/X/?Y"+Math.round(joystick.deltaY())+"/Y/M";$.get(message);var outputEl    = document.getElementById('result');}, 50);

    which looks like: 

    I can't embed the web-page directly into this log, but the full HTML file is posted on the main page of this project. 

    The blue circles you see in the image above are actually a joystick. I didn't create this joystick, the credit for that goes to jeromeetienne on github. The virtualjoystick.js github page can be found here

    Now, as I said in the first log this project write up is for someone who wants to do something similar to this project. The web interface specifically took the majority of the time I spent on this project and I really want someone else who does this to have an easier time. there are two very important parts in this website that make the whole thing work as intended, first loading the javascript externally:

    <script src = ""></script>

    Notice the script tag is pulling the .js file from somewhere that's not the ESP32, github will not let you load a file directly with one of their raw URL's, additionally the javascript file is too big to be sent by the ESP32 (it can do it but you're adding 40ms to the transmission time). The solution to this is to use to offer up the JavaScript file to any computer that loads the web-page. This offloads the burden from the ESP32 to the device connected to it. 

    second sending the information to the ESP32:

    var message = "/?M/?X"+Math.round(joystick.deltaX())+"/X/?Y"+Math.round(joystick.deltaY())+"/Y/M";
    , 50);

    (which is all on the same line in the code posted above)

    The bottom part of the code simply composes a string with the x and y coordinates of the joystick, formats it, then requests it as a URL from the ESP32 every 50ms. The ESP32 receives this then processes it, for the longest time this code would not work because the ESP32 would become backlogged with requests. The longer it spent running, the more behind it was with the requests. Eventually the bot was impossible to control,...

    Read more »

  • Time to give it a body

    Matthew James Bellafaire02/21/2019 at 20:20 0 comments

    Let me just say, FreeCAD is a great tool. Coming from google sketchup for my personal projects this has been a breath of fresh air and just simplified the entire process. If you're looking for a good open-source (and more importantly free) CAD program then give FreeCAD a shot.

    The body design for this project was fairly simple. the design had to fit the populated perf-board, hold a lithium ion battery, and support the wheel and motors. Here's what I came up with: 

    without the cover:

    Note: I never modeled the lithium ion battery into the design, it fits in the area below the board stand in. 

    The model for this project went through a few redesigns. Originally, before the motors even arrived, the drive wheels were placed directly onto the motors. As a result that design never went anywhere quick and would frequently be a general pain to play with. Using the FreeCad plugin FCGears the rear wheels and motor mount were redesigned to have some reduction. This improved the performance of the bot considerably but not as much as intended. 

    adding the geared wheels also required the wheels themselves to be moved down and back slightly. This resulted in the ridges seen on the bottom of the model. These ridges are far from ideal for a 3D printer and required the entire model to be printed with support material, adding another hour to the print time.

    The wheels came out well, each wheel had as much material removed as possible in CAD to save on print time. On each of the wheels there is a groove intended for a rubber band to improve traction on the plastic surface which works well. 

    Overall this design is alright, in hindsight i should have spent some time looking for better motors for all the trouble these ones have caused me. 

    The STL files and FreeCAD project file are available for download on the main page of this project!

  • Hardware

    Matthew James Bellafaire02/21/2019 at 19:59 0 comments

    The goal here is to build a proof of concept, so I went a little cheap on the motors and found whatever came in at the lowest price on amazon. That doesn't affect the hardware too much, since the intention is still to make a cheap-proof of concept that can use more powerful motors. However, it does come into play in the design of the body and this is the best place to mention it. The hardware is simple and to the point: 

    The upper-left corner contains all the power circuitry, power comes in from the battery through the lithium ion battery module then gets fed into a boost converter. The output of the boost converter, is then fed into both a LM7805 and the L239 motor driver. While it would be possible to connect the ESP32 Board directly to the 12V output through the EXT_5V pin, it's not ideal. Pins 12, 14, 25, 26, 27, and 33 on the ESP32 are connected directly to the L293. The outputs of the L293 then connect to the motors with proper diode protection as shown in the IC's datasheet. 

    This circuit was assembled on perf-board and works properly. Utilizing the boost converter and lithium ion battery modules saved a great deal of time soldering.

  • Design Considerations

    Matthew James Bellafaire02/21/2019 at 19:19 0 comments

    I've already completed this project, however, since a lot of work has gone into each part of this project i'm going to split up the logs for better readability. I hope that someone looking to create a similar project finds this project and can use it as a jumping off point, there were no shortage of hurdles to overcome over the course of this project for me. With that said, what were the goals for creating this project: 

    1. Be simple and easy to upgrade/modify: this bot really is designed to be a proto-type proof of concept so when we design a new one the majority of components and circuity can stay as is. Therefore, the control board should be able to work with a small or medium sized motor depending on the requirements we decide later. 
    2. Have a web-interface for control: The best reason to use the ESP32 in this project is for it's wifi capabilities, ideally it will be able to communicate with a central computer for the purposes of the game the bots will play. (basically battle bots playing laser-tag). 
    3. operate predictably and responsively to user input: no sense in controlling a small robot if all your commands are going to be delayed. 

    With that said lets get into it starting with the hardware!

View all 5 project logs

Enjoy this project?



Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates