Many hobbyists try to directly use some projects on how to build a robot car available on the internet and eventually face issues. There are various reasons why the project fails because there are differences in setup and components. A common approach to steer a robotic car to the right or left is by using a shield which uses four DC motors. The method is good for toys but not enough mature or robust. We are publishing a series of articles so that you can use part of other projects to create your robot car.
Building a robot car is quite an advanced project and you’ll require continuous improvement. But the basic principle to create a robot car starts with mastering two types of projects:
- You have to learn to control a servo motor over WiFi (via web GUI)
- You have to learn to control PWM over WiFi (via web GUI), that is just controlling a LED via PWM over WiFi
The first set will help you to steer the robotic car, the second thing will help you to control two or four DC motors via some shield or IC. In earlier guides, we have discussed servo motors, for example, Arduino Servo Motor Control With Pushbutton.
---
For a robot car project, you can not directly use pushbuttons connected with wires simply because the car is not a static thing. So the basic option to connect is via WiFi. I have forked the below sketch from Elktros’s gist on GitHub (https://gist.github.com/elktros). In this case, you are attaching the servo’s pin to GPIO number 16 on ESP32. The other two wires of the Servo will be connected to the 3.3v pin and GND pin of ESP32.
You already know how to control a LED over WiFi via PWM:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | // Import required libraries #include <WiFi.h> #include <AsyncTCP.h> #include <ESPAsyncWebServer.h> // Replace with your network credentials const char* ssid = "Your WIFI SSID"; const char* password = "Your WIFI Password"; const int output = 2;// Connected to D2 Pin of ESP32 String sliderValue = "0";//initial Slider value // setting PWM properties const int freq = 5000; const int ledChannel = 0; const int resolution = 8; const char* PARAM_INPUT = "value"; // Create AsyncWebServer object on port 80 AsyncWebServer server(80); const char index_html[] PROGMEM = R"rawliteral( <!DOCTYPE HTML><html> <head> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>ESP32 Web Server</title> <style> html {font-family: Arial; display: inline-block; text-align: center;} h2 {font-size: 2.3rem;} p {font-size: 1.9rem;} body {max-width: 400px; margin:0px auto; padding-bottom: 25px;} .slider { -webkit-appearance: none; margin: 14px; width: 360px; height: 25px; background: #FFD65C; outline: none; -webkit-transition: .2s; transition: opacity .2s;} .slider::-webkit-slider-thumb {-webkit-appearance: none; appearance: none; width: 35px; height: 35px; background: #003249; cursor: pointer;} .slider::-moz-range-thumb { width: 35px; height: 35px; background: #003249; cursor: pointer; } </style> </head> <body> <h2><u>ESP32 Web Server</u></h2> <p>PWM VALUE = <span id="textSliderValue">%SLIDERVALUE%</span></p> <p><input type="range" onchange="updateSliderPWM(this)" id="pwmSlider" min="0" max="255" value="%SLIDERVALUE%" step="1" class="slider"></p> <script> function updateSliderPWM(element) { var sliderValue = document.getElementById("pwmSlider").value; document.getElementById("textSliderValue").innerHTML = sliderValue; console.log(sliderValue); var xhr = new XMLHttpRequest(); xhr.open("GET", "/slider?value="+sliderValue, true); xhr.send(); } </script> </body> </html> )rawliteral"; // Replaces placeholder with button section in your web page String processor(const String& var) { //Serial.println(var); if (var == "SLIDERVALUE") { return sliderValue; } return String(); } void setup() { // Serial port for debugging purposes Serial.begin(115200); // configure LED PWM functionalitites ledcSetup(ledChannel, freq, resolution); // attach the channel to the GPIO to be controlled ledcAttachPin(output, ledChannel); ledcWrite(ledChannel, sliderValue.toInt()); // Connect to Wi-Fi WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.println("Connecting to WiFi.."); } // Print ESP Local IP Address Serial.println(WiFi.localIP()); // Route for root / web page server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){ request->send_P(200, "text/html", index_html, processor); }); // Send a GET request to <ESP_IP>/slider?value=<inputMessage> server.on("/slider", HTTP_GET, [] (AsyncWebServerRequest *request) { String inputMessage; // GET input1 value on <ESP_IP>/slider?value=<inputMessage> if (request->hasParam(PARAM_INPUT)) { inputMessage = request->getParam(PARAM_INPUT)->value(); sliderValue = inputMessage; ledcWrite(ledChannel, sliderValue.toInt()); } else { inputMessage = "No message was sent"; } Serial.println(inputMessage); request->send(200, "text/plain", "OK"); }); // Start the server server.begin(); } void loop() { } |
If you combine these two sketches, you’ll get the control on the servo, as well as the DC motors. This is too primitive to create a WiFi-controlled robot car but, as I have pointed out the intention of this article – this approach is fail-proof.
Buy this model of servo motor:
Initially I used the costlier version with metal gears. That is super unreliable.