Remote controlled tank/car (via WiFi), chassis with tracks, L298 module with NodeMCU

How to build a robot on a NodeMCU, L298 and two motors? Here is a short mini-project - part one. We are running a remote controlled "tank" with two tracks. By the way, we will see how to connect the L298 to the motors, how to operate it with PlatformIO/Arduino and how it can be controlled via WiFi. The method shown here, however, will also be able to work just as well for the typical 2wd robot chassis available to buy online....

I will show the whole thing step by step so that a beginner can follow what I was running and how. In addition, I will try to simplify so that the project is not too demanding and complicated. The project will be divided into at least several parts, where I will gradually present the progress, solutions and problems encountered.
At this stage, I'm assuming that this is a toy that is, to put it jokingly, 'not going out' or 'home' - that is, it will work with our WiFi and will pair with it via WiFiManager. At a later stage I may change this assumption too.
NodeMCU .
NodeMCU is such an "Arduino of the new times" for me. Cheap, useful, convenient, supported by many libraries. The NodeMCU is based on the ESP8266 and offers, among other things, connectivity via WiFi.

In addition, there is a USB to UART converter on board to facilitate easy wired programming (although you can also change the batch over WiFi) and a 3.3V LDO regulator to ensure a stable 3.3V for the ESP with 5V from USB.
I program the whole thing in PlatformIO, this has already been discussed:
Clock on ESP12 and MAX7219 display - tutorial - part 1, ArduinoOTA, basics .
WiFi Manager in PlatformIO - convenient WiFi configuration for ESP8266 and ESP32 - tutorial
Chassis module .
I bought the chassis module in China. I'm not sure if it has a model name by which it can be found, but basically the whole tutorial can be done on any module with tracks, or even with regular wheels. It's just important to choose the right module to control the motors - you need to respect the maximum operating voltage and current.

My module has space for 4 AA batteries on the bottom:


These batteries are nominally 1.5V, so 4*1.5V = 6V, but in practice as they discharge the voltage will drop. This is something to watch out for, because if we power a NodeMCU from them with an LDO AMS1117-3.3V regulator on board, the voltage at its input must be at least around 4.6V (according to the datasheet note) to get a stable output....
L298N module .
I bought the module with the L298N from an importer in our country for a dozen zlotys, although it can be imported cheaper.
The L298N is a dual motor controller operating at up to 46V and up to 4A current. Two motors can be connected to it, each motor being controlled independently.

There are 3 control pins per motor, one enable pin and two in. In addition, two supply voltages are applied separately to L298N, one for the motors (up to 46V) and the other up to 7V (logic):

To control the motor we need to:
- connect the PWM to EN - this will determine the speed of the motor, although at lower PWM settings the motor will not start, it will only "buzz"
- connect the logic pins to IN1 and IN2; manipulation of these pins will allow us to change the direction of the motor or activate braking
The specific settings are shown in the truth table:
IN1 | IN2 | . Result | |
high | low | motor on (speed is determined by PWM on EN) | |
low | high | motor on -. reversing (speed is determined by PWM on EN) | |
low | low | fast braking of motors (when high state on EN) | |
high | high | fast braking of motors (when low on EN) | |
high | high | free braking of the motors (when there is a high state on the EN) |
Two PWM and four digital pins are therefore required for two motors.
The commercially available L298 module is essentially L298 + 5V stabiliser. In this situation, we can specify with a jumper whether we want to give, for example, 9V inputs of our own and draw current from the 5V, or whether the stabiliser can be switched off. This is determined by the schematic:

There are two potential pitfalls here, however:
- The 7805 has slightly lower maximum input voltages than the L298N, plus it heats up at higher voltages, so in such situations consider using, for example, an external step-down converter
- if we give 5V to the input, the 7805 will not switch on (at least when I tested it, it gave 0.5V at the output...) so then you can power both sides, the motors and the logic one with 5V
First connection .
In the end, I opted for absolute minimalism. I connect the batteries directly to the L298 module and additionally on Vin from the NodeMCU, as their voltage is within the operating range of the AMS1117-3.3V present on this board. The 7805 on L298 is omitted, with power being routed to both sides from Vin.
In addition, as a test, I put the whole thing on a spool from the solder joint so that the tracks do not touch the ground, so the vehicle will not run away while I am writing the programme.


Beginning program - ArduinoOTA and WiFiManager .
I write my ESP programs in PlatformIO (an environment based on Visual Code) and I highly recommend its use. I usually start my adventures the same way - my initial program includes two useful libraries that I have already discussed:
- WiFi Manager - for pairing with WiFi
- ArduinoOTA - to update the batch remotely
The program basically contains only the basic integration of these two libraries enriched additionally with a flashing diode which is on the WiFi module itself. During configuration (blocking call from WiFiManager) the diode does not flash, only during normal operation.
Code: C / C++
Add a server (to receive commands) .
Let's start with communication. The easiest way is to add a simple HTTP server. Admittedly, TCP is connection-intensive and can introduce minor delays when a packet retransmission occurs, but that is negligible here.
The creation of the server comes down to the use of the ESP8266WebServer class, or more precisely to the creation of an object of this class, where the only argument of the constructor is the port we are listening on. Then, using the "on" function, we set the functions that handle the given resource from the server, in my case there is only one, the "hello world" page. Then we start the server (function begin):
Code: C / C++
Result:

Add a simple control via HTTP .
The control will come in handy smoothly, in addition to having to take into account both directions of the motor. For this reason I decided to use a slider from HTML. You can easily set a range for it - say from -100 to 100. 0 is no movement, -100 is counterclockwise and 100 is clockwise, all the way forward.
Additionally, as a simplification, instead of pasting my code over and over into PlatformIO, I just ran it on the computer.... .
This simplifies the process of testing and creating the page.
So, the current code:
Code: HTML, XML
Result:

In addition, you still need to send the slider value to the NodeMCU. All you need for this is a short script - addEventListener, input event:
Code: HTML, XML
The fetch function sends a GET request to /steer whose argument is a value with a value from the slider. This now needs to be received and handled.
I have introduced endpoint in the project:
Code: C / C++
And then in it I added control handling:
Code: C / C++
I use hasArg to check if an argument is available, and retrieve it with the arg function. Then I do what was mentioned for L298 - I set the direction pins and the PWM value (two digital pins - digitalWrite and one PWM - analogWrite). I decode the negative value to the direction and then write it already without a sign so that I can send it to the PWM.
The rest of the code:
Code: C / C++
Video of the track movement:
Class of tracks .
There are two caterpillars, so it is tempting to separate their code into a separate class. This will allow more convenient development and maintenance of the project.
I packed the whole thing into the Track class. This class stores the pins for controlling one motor, its enable pin and two directional pins.
Code: C / C++
The rest of the code:
Code: C / C++
It is now convenient to create two extinguishers:
Code: C / C++
As a test, I do not yet separate the values sent by the web page, I simply enter it into both crawlers:
Code: C / C++
Separating the tracks .
I didn't want to complicate things, so I essentially copied the slider so that there are now two. One each for the tracks.
Code: HTML, XML
The result:

I organised the script in turn so that the data is sent together - there is one change event handler for both sliders and it sends one common GET request:
Code: HTML, XML
Now on the ESP, in handleSteer, I can separately access each of the arguments:
Code: C / C++
In this way, we can remotely control each track separately.
First drives .
At this stage, you can already drive. Let's see how the tank performs.
The chassis works, but rides rather sluggishly in places. I measured the current consumption, first of one motor and then of the whole (NodeMCU + 2 motors) when powered by USB:


In addition, I saw that even with the USB wired power supply the voltage drop is noticeable - with one motor it is able to drop to almost 4V, and with both even lower.
I tested the option with a powerbank for this reason:

It is better - with both motors at full power it drops to 4.2V:

The ride is better:
I'm staying with the powerbank for the moment.
Summary .
This was the first step of work on our car. Here we managed to run a comfortable working environment based on NodeMCU programmed remotely (OTA, via WiFi) in PlatformIO and then drive the motors from it via a module from L298. The power supply was finally realised using a powerbank, which nevertheless holds its own and can be driven in comfort. I rejected the idea of AA batteries, as they heat up, the voltage drops (more so than with the powerbank) and it's a shame to use them up..
On the programming side it was just as simple as on the hardware side - there is one PWM per motor and two digital pins, this allows it to be controlled both ways. We separated the motor operation into a separate class so that we could have two motors (or tracks) and then controlled them in the simplest way via an HTTP server - GET request arguments.
The project works but leaves a lot to be desired, even the control is clumsy.
For this reason, I will introduce a virtual joypad in the next section:

All in all, I am planning at least several parts, where with each part improvements, modifications and problems encountered will be presented.
It went exceptionally smoothly at this point - I was expecting trouble with the ESP power supply, but it didn't reset once for me. The biggest hassle was battery power, but I just skipped that - the powerbank fit just fine.
Feel free to comment - maybe you have some ideas on what to implement next? I already have a bit of sensors lined up myself, as well as a 3D printer ready to help improve the build of the car, and the ESP32-cam module will also be somewhere... .
PS: Attached the same code in as in the post, but together in one file. Final version.
Comments
Leaving such a driving platform with a camera and charging station at home is a nice idea for video monitoring of the house when we are on a trip. In a more advanced version, such a platform could make... [Read more]
Last year I was thinking of redoing the cleaning robot, maybe replacing its 'brain' with a Raspberry, and I already had two robots set aside.... but unfortunately they both drowned in the flood and all... [Read more]
Perhaps a contactless charging station? Less problems with positioning. [Read more]
A remote control with 2 potentiometers, so called analogue console pads, would suit this project perfectly. Print out a casing with a place for a phone (to view the image from the camera) and we would... [Read more]
Very cool ideas, thanks for your comments. @techekspert I was thinking about this option, although I haven't delved into it yet. I've seen that interesting ready-made modules can be imported from China.... [Read more]
Qi chargers are quite cheap, you can test them: https://pl.aliexpress.com/item/1005008107671736.html https://pl.aliexpress.com/item/1005006386722006.html https://pl.aliexpress.com/item/1005005716095383.html https://pl.aliexpress.com/item/1005008072369885.html https://pl.aliexpress.com/item/1005007361163095.html https://pl.aliexpress.com/item/1005008239169084.html Only... [Read more]
At low speeds the engines squeal and the vehicle does not run. You could try using a 'group regulator'. We usually use it with alternating current, but it should work well here too. The idea is to apply... [Read more]
. Maybe just a lower PWM frequency for lower motor speeds would work better. The motor beeping indicates that the frequency is quite high. [Read more]
Or closed-loop control, where we observe the rpm of the track drive and adjust the PWM to obtain the set rpm. [Read more]
With feedback, it would already be full control. Something like ABS / ASR. [Read more]
It looks like you are right about this PWM - the right setting of analogWriteFreq helps, only now you have to choose the best value. In the meantime, I'm upgrading the virtual touch pad and I have... [Read more]
The design of the tank even came out rather interestingly for you. I hope someday you will print a "Royal Tiger" that will patrol your domain when you are outside. [Read more]
@sheriff3 Intrigued by the subject of this tank, I've been browsing the listings on Ali. There's a powerful model that two kids can ride comfortably. So that it's not such a long way to patrol your domain... [Read more]
I have seen that people are printing tracks on a 3D printer. Practically the whole thing is printed, only some common cheap parts are used for this. [Read more]
I've had a printout of flexible filament in my hand. It behaves like hard rubber. The fact that it costs several times more expensive than PLA for example. So it probably wouldn't be much of a problem... [Read more]
. Necessarily equipped with such armament on the turret: https://www.elektroda.pl/rtvforum/topic1021421.html ;-) [Read more]
I buy SUNLU PLA filaments at 65PLN per kilo, ABS, at 89PLN per kilo, while Plexiwire TPU filament, at 130PLN per 900g, so some very expensive is not. However, I have to admit that it is amazing. It is... [Read more]
The camera and control option in one can be possessed with the ESP32 CAM, or if that's not enough, the ESP32-S3-Cam. Control can be transferred to the drive module via I2C. There are also laser distance... [Read more]
See this wonder. https://obrazki.elektroda.pl/7209575600_1741885691_thumb.jpg . [Read more]