Robotics: Differential Steering Using An Analog Joystick With The Arduino - Redux
Posted on 2013-09-14 @ 11:04:27 by r00t - Read the parent: How To Use An Analog Joystick With The Arduino

A couple of years ago, I wrote an article on how to use an analog joystick (like those found in Playstation controllers) with the Arduino. I presented some code to steer a tank-like vehicle, aka "differential steering". Not too long ago, I posted how to do the same on the Arduino forum, in an updated manner...

A user on the forum was needing an example of how to do the same exact thing; I was going to point him to the original article I wrote, but after looking over the code, and thinking about it, I thought I could offer a better algorithm - here's the text:
I'm going to try to explain something - and once I do, it will 
either get your brain running again - or it just might be a "doh!" 

You have two axes on the joystick - an x-axis and a y-axis, right? 
So - let's imagine you have the potentiometers of each axis connected 
to an analog input on the Arduino. So - what happens then if you push 
the joystick all the way up into the upper-left hand corner?

That's right - your Arduino is going to read "0" for the x-axis, and 
"0" for the y-axis (note: I am ignoring any possibility that calibration 
of the joystick will be needed - in reality, this is most likely - I 
don't know if you are old enough or not to remember old DOS games, and 
how you had to calibrate the analog joystick before playing a game - the 
routine was a part of the game itself).

Now - what happens if you then push the joystick to the lower-right 

Yes - your Arduino will read "1023" for the x-axis, and "1023" for the 

So - what does this mean? Well - here are the values (more or less):

0,0     511,0   1023,0
  \       |       /
   \      |      /
    \     |     /
     \    |    /
      \   |   /
       \  |  /
        \ | /
        / | \        
       /  |  \
      /   |   \
     /    |    \
    /     |     \
   /      |      \
  /       |       \
0,1023 511,1023 1023,1023

Now - if you subtract 511 from each axis - that'll "center-up" the 
values - which means that the upper-left will be "-511,-511", the center 
will be "0,0", and the lower-right will be "512, 512"...and the other 
values will change similarly - understand?

Now - given that - what can you do?

Well - what if you said "my x-axis value will drive my left wheel" and 
"my y-axis value will drive my right wheel" - and then you scaled the 
values for the PWM, and based on the sign of the value, switched the 
PWM from one side or the other of the h-bridge...

So - let's suppose positive values mean "forward" and negative values 
mean "reverse". So now, at rest - the joystick (auto-centered) would 
read "0,0" - and a PWM values of "0" would be sent to each motor, and 
they would remain "off".

Then, when you pushed the joystick to the bottom-right corner, you are 
reading "512,512", then after scaling and sign checking - you apply 
PWM values of "255,255" to both motors - you're now going forward!

If you pushed the joystick to the upper-left corner, you are reading 
"-511, -511", then scaled and sign checked to mean "apply PWM values of
255,255 to the other pin of the h-bridge" to drive both motors in the 
opposite direction - and you're going backward!

So what happens if you push the joystick to the *upper-right* side? 
Well, you would then read "512, -511" - and after scaling and 
sign-checking - hey look! One motor turning one way, and the other the 
opposite! Turning in place, so to speak. For the "lower-left" side, you 
would read "-511, 512" - wow! Spinning in the opposite direction.

Take a look at the other ordinal points - and notice what they do: That's
right, you can turn one motor off, and have the other spinning - that is,
one wheel moving, and the other stationary - so instead of turning on the
center-point of the "axle" between the wheels, you are now rotating around
the center of one of the wheels.

All fine and well - for the most part - but! Everything is on a diagonal - 
how can I use my joystick this way (you're asking yourself)? Simple:

Rotate the joystick 135 degrees counter-clockwise - so that the normally 
"bottom-right" corner of the joystick faces "up"...

Note that this isn't a perfect solution; it has it's bugs - but maybe you 
(or someone else) can make use of it. I hope it helps, or at least gives 
you some ideas. It's an example of thinking outside of the box (the main 
part being to not look at the joystick as needing to be explicitly 
oriented in an X/Y position as given by the potentiometers).

Good luck with your project!

Now - I'll leave it to you to implement the code - or you can go to the thread on the Arduino forum and look at the code the original poster created from my description above: Supposedly it works great, though it wasn't implemented in full - some bits were left out, because it wasn't needed by the OP's application. Maybe you could expand on it?
Enjoy...and again, good luck with your projects!

Share This Article


Questions or Comments?

If you have any questions or comments about this article, please contact me...

0 comment(s) posted
Post New Thread