Introduction
Having two motors to drive on a bot, how can one make it turn left? Or right? The premisse is quite simple:
- To turn right while going forward, the left motor should drive faster than the right one.
- To turn left while going forward, the right motor should drive faster than the left one.
The inverse happens when the bot is driving backwards and the same can be acheived, just in a different perspective, by driving one motor slower than the other.
The most basic approach to the premisse exposed above would be to, when aiming to turn the bot, drive one motor and stop the other one. In pseudo code would be something like:
The above idea could somehow work, but it would be extremely unlikely to produce any satisfatory outcome. The driving wouldn’t be smooth and it would highly depend on the time the bot has configured to turn.
Smoother driving
To achieve a smoother driving, the bot would have to be able to turn slowly or quickly, depending on the controller’s input.
From now on, let’s use a scale of 0 to 100 to materialize the velocity of the motors, where 0 is when a motor is not spinning and 100 is when it’s spinning at maximum speed.
Changing just the speed of each motor, it could be possible to take the last pseudo code example and tweak it a bit:
Instead of turning off the motor, it could remain powered, but spinning less than the other. However, this would result in the same conclusion as in the previous section.
Using a 2 dimensions axis direction
Ideally, one would want to be able to change the speed of motor_left
and motor_right
based on a input. Conceptually speaking, a two axis controller, such a joystick, would fit within the requirements. Both axis, X and Y could be used to tweak the spinning speed of each motor.
Let’s take a look at the 2D X and Y axis:
Following what has been said, the small circle in red should lead to a slow forward right turn and the circle in blue should lead to a faster forward right turn.
Essentially, the one in red could have the left motor at full speed and the right one at slightly less speed.
By contrast, the blue example would still have the left motor at full speed, but the right one would be slower. This results in a quicker turn to the right.
Slow down
The goal has always been to slow down one of the motors, but where should the speed be set from?
By looking at the 2 axis scenario, when the right motor speed decreases, so does the value of Y. Essentially, the speed of the right motor, can be based on something that relies on the axis Y.
Both arrows, the red and blue, materialize the maximum speed of the left motor and can be interpreted as hypotenuses. When one of the hypotenuses has a angle of 90 degress, both motors spin at the same speed. Therefore, the speed of the right motor should be based on the opposite side of a triangle:
The desired opposite side Y value can be measured by:
Info
The double variable z is in radians, not degrees.
This ensures the bot has a smoother turn and its behaviour is based on a Joystick controller, the direction of the bot is pretty much figured out. However, this is not enough — there is something missing.
Same direction, different speed
Instead of focusing only on one motor, the focus should be on both. The direction is set: the bot will turn left or right based on a turn angle. But, what if the same turn needs to performed quicker? Or slower?
There is a need for one more Joystick – one which only controllers how fast a angle based turn should be done.
The speed should be based on this newly added joystick, while the direction (how the bot turns) should be managed by the second joystick.
Building a bot controller
With all that being said, I jumped into turning all this theory into reality by building a bot controller (e.g. “RC”) with two joysticks.
Hardware
The controller is battery (LiPo) powered and uses the ESPNow wireless protocol as its communication protocol. Here is the list of components:
- A ESP32 dev board; The dev kit uses a ESP32-WROOM-32 module.
- Two joystick modules. They are not the best, however, the calibration can be done through software.
- One TP4096 based charging module, capable of charging 3.7V LiPo batteries.
- A 3.7V LiPo battery with 1200mAh capacity. One with a different capacity also fits.
- A rocker switch to turn ON/OFF the controller.
Software
As stated previously, the joysticks are not the best. Their read analog voltage, from both axis, differs from one to another. To mitigate the diference, I’ve introduced a CALIBRATION_DELTA
.
I’ve also mapped the read analog voltage from 0 until 4096 to -100 until 100. The mapped values help materialize the value of each read value into a 2 axis (X and Y) graph, but they are not necessarly mandatory for the end goal.
Design
The enclosure to glue everything together is a 12cm x 9cm PLA printed design with a border radius of 2cm.
In case you are interested in the project, please check the project’s repository and feel free to build your own controller!
That’s all folks! Have safe drives ;)