Skip to content
Savage Makers
  • Projects
  • Blog
Tank Drive

Joystick to Differential Drive (Arduino)

When you are building robots, one of the most common chassis you find are the ones that use Differential Drive. This means they have a motor per wheel, might be threaded, two wheels and a caster, 4 wheels, etc.

differential drive details
differential drive details

One way of driving this differential drive robots is sending PWM signals to each motor. But how do you convert for example the signals from a Joystick, (or any Cartesian pair of coordinates, like a direction vector) to the specific order for each wheel?

That is where this function is required. It receives a pair of cartesian x, and y coordinates, and calculates the differential drive output (right and left wheel commands) you will need to send to the motors.

This function will generate an output as can be seen in the following image:

Cartesian to Differencial Drive
Cartesian to Differencial Drive

LeftMotorOutput and RightMotorOutput will hold the values you should send to the right and left motors.

You can also configure the limits of x, y, and right and left motors by using the 4 constants defined on top of the code, this is handy to adapt the function to your specific scenario.

#define DDRIVE_MIN -100 //The minimum value x or y can be.
#define DDRIVE_MAX 100  //The maximum value x or y can be.
#define MOTOR_MIN_PWM -255 //The minimum value the motor output can be.
#define MOTOR_MAX_PWM 255 //The maximum value the motor output can be.

int LeftMotorOutput; //will hold the calculated output for the left motor
int RightMotorOutput; //will hold the calculated output for the right motor



void DifferentialDriveService::CalculateTankDrive(float x, float y)
{
 float rawLeft;
 float rawRight;
 float RawLeft;
 float RawRight;


 // first Compute the angle in deg
 // First hypotenuse
 float z = sqrt(x * x + y * y);

// angle in radians
 float rad = acos(abs(x) / z);

// Cataer for NaN values
 if (isnan(rad) == true) {
 rad = 0;
 }

// and in degrees
 float angle = rad * 180 / PI;

// Now angle indicates the measure of turn
 // Along a straight line, with an angle o, the turn co-efficient is same
 // this applies for angles between 0-90, with angle 0 the co-eff is -1
 // with angle 45, the co-efficient is 0 and with angle 90, it is 1

float tcoeff = -1 + (angle / 90) * 2;
 float turn = tcoeff * abs(abs(y) - abs(x));
 turn = round(turn * 100) / 100;

// And max of y or x is the movement
 float mov = max(abs(y), abs(x));

// First and third quadrant
 if ((x >= 0 && y >= 0) || (x < 0 && y < 0))
 {
 rawLeft = mov; rawRight = turn;
 }
 else
 {
 rawRight = mov; rawLeft = turn;
 }

// Reverse polarity
 if (y < 0) {
 rawLeft = 0 - rawLeft;
 rawRight = 0 - rawRight;
 }

// Update the values
 RawLeft = rawLeft;
 RawRight = rawRight;

// Map the values onto the defined rang
 LeftMotorOutput = map(rawLeft, DDRIVE_MIN, DDRIVE_MAX, MOTOR_MIN_PWM, MOTOR_MAX_PWM);
 RightMotorOutput = map(rawRight, DDRIVE_MIN, DDRIVE_MAX, MOTOR_MIN_PWM, MOTOR_MAX_PWM);
}

 

If you find this code snippet useful, need help to make it work, or to understand it, please leave a comment and we can talk about it!

Share this:

  • Click to share on Twitter (Opens in new window)
  • Click to share on Facebook (Opens in new window)
Arduino Robot – Service Oriented Architecture
Arduino C++ Robotics Source Code

Related articles

Radio Controlled Minnie Mouse Quad
Modular Rover Tracks
Self-contained rover tracks
3D Printable Rover
Shell – Switch
Shell - Blank
Shell – Blank
InnerTrackFrame - DCMotor
InnerTrackFrame – DCMotor
3D Printable Rover Architecture
Raspberry Pi Zero W based robot
Aum2 – “Raspberry Pi Zero…
Raspberry Pi Zero W based robot
Joystick to Differential Drive (Python)
HC-SR04
HC-SR04 Distance Sensor Service
L298N Motor Driver Module
L298N Motor Driver Service

Recent Posts

  • Radio Controlled Minnie Mouse Quad
  • Self-contained rover tracks
  • Shell – Switch
  • Shell – Blank
  • InnerTrackFrame – DCMotor

Archives

  • April 2018
  • February 2018
  • September 2017
  • April 2017
  • December 2016
  • September 2009
Theme by Colorlib Powered by WordPress
 

Loading Comments...