mapping correctly joystick for tank steering.

Good day,

I have found a sketch online that I am trying to change for my needs. Unfortunately I am stuck in a situation which I need help.

The idea is 1 joystick to move wirelessly a small tank vehicle. I am able to have motors A&B go forward when X is pushed forward and motors going backward when joystick is pushed backward.

I have tried to add extra lines to have motor A go forward and motor B go backward when joystick is pushed left and have reverse action done when pushed right but I seem to not be able to do so accurately.

What I am doing wrong?

Thank You

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#define enA 6
#define in1 7
#define in2 5
#define enB 3
#define in3 4
#define in4 2

RF24 radio(8, 9); // CE, CSN
const byte address[6] = "00001";
char receivedData[32] = "";
int  xAxis, yAxis;
int motorSpeedA = 0;
int motorSpeedB = 0;
int joystick[2];

void setup() {
  pinMode(enA, OUTPUT);
  pinMode(enB, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);
  Serial.begin(9600);
  radio.begin();
  radio.openReadingPipe(0, address);
  radio.setPALevel(RF24_PA_MAX);
  radio.startListening();

  digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);
  digitalWrite(in3, HIGH);
  digitalWrite(in4, LOW);
}
void loop() {

  if (radio.available()) {   // If the NRF240L01 module received data

    radio.read( joystick, sizeof(joystick) );

    radio.read(&receivedData, sizeof(receivedData));
    yAxis = joystick[0];
    xAxis = joystick[1];

    Serial.println(yAxis);
    Serial.println(xAxis);

  }

  if (yAxis < 470) {
    //forward
    digitalWrite(in1, HIGH);
    digitalWrite(in2, LOW);

    digitalWrite(in3, HIGH);
    digitalWrite(in4, LOW);

    motorSpeedA = map(yAxis, 470, 0, 0, 255);
    motorSpeedB = map(yAxis, 470, 0, 0, 255);
  }
  //backward
  else if (yAxis > 550) {

    digitalWrite(in1, LOW);
    digitalWrite(in2, HIGH);

    digitalWrite(in3, LOW);
    digitalWrite(in4, HIGH);

    motorSpeedA = map(yAxis, 550, 1023, 0, 255);
    motorSpeedB = map(yAxis, 550, 1023, 0, 255);
  }

  else {
    motorSpeedA = 0;
    motorSpeedB = 0;
  }

  if (xAxis < 470) {
    //THIS IS LEFT
    // Set Motor A backward

    digitalWrite(in1, LOW);
    digitalWrite(in2, HIGH);

    // Set Motor B forward

    digitalWrite(in3, HIGH);
    digitalWrite(in4, LOW);

    motorSpeedA = motorSpeedA - 470;
    motorSpeedB = motorSpeedB * -1;

    motorSpeedA = map(xAxis, 0, 470, 0, 255);
    motorSpeedB = map(xAxis, 0, 470, 0, 255);


    // Confine the range from 0 to 255
    if (motorSpeedA < 0) {
      motorSpeedA = 0;
    }
    if (motorSpeedB > 255) {
      motorSpeedB = 255;
    }
  }
  if (xAxis > 550) {
    //THIS IS RIGHT

    // Set Motor A forward

    digitalWrite(in1, HIGH);
    digitalWrite(in2, LOW);

    // Set Motor B backward

    digitalWrite(in3, LOW);
    digitalWrite(in4, HIGH);

    motorSpeedA = motorSpeedA - 550;
    motorSpeedB = motorSpeedB * 1;

    motorSpeedA = map(xAxis, 0, 550, 0, 255);
    motorSpeedB = map(xAxis, 0, 550, 0, 255);



    if (motorSpeedA > 255) {
      motorSpeedA = 255;
    }
    if (motorSpeedB < 0) {
      motorSpeedB = 0;
    }
  }

  if (motorSpeedA < 70) {
    motorSpeedA = 0;
  }
  if (motorSpeedB < 70) {
    motorSpeedB = 0;
  }
  analogWrite(enA, motorSpeedA); // Send PWM signal to motor A
  analogWrite(enB, motorSpeedB); // Send PWM signal to motor B
}

Fabiolus:
I have tried to add extra lines to have motor A go forward and motor B go backward when joystick is pushed left and have reverse action done when pushed right but I seem to not be able to do so accurately.

What does "have reverse action done" mean?

In your Right and Left routines shouldn't you be reading something into motorSpeedA and B BEFORE you start adding and subtracting values from them?

Steve

Steve,

Sorry for the confusion.

"have reverse action done". I meant that I wanted the below behavior.

Joystick pushed forward = both motors going forward.
Joystick pushed backward = both motors going backward.
joystick pushed left = left motor going forward and right motor going backward
joystick pushed right = left motor going backward and right motor going forward.

I will look into your advice, I have been stuck on this for a while :frowning:

thank you

Good day,

I took a different approach and have somewhat better result even though it would had been cool using the other method

In the end it turned out I had to be careful when troubleshooting, I launched serial monitor to see pot values and behavior and noticed that I did a mistake in the pot value for left/right.

Now the results are great, maybe I will tweak better the map() for the joystick for better response. I am learning more and more.

Thank You

Thank You

remote:

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(8,9); // CE, CSN
const byte address[6] = "00001";
char xyData[32] = "";
int joystick[2];
void setup() {
  Serial.begin(9600);
  radio.begin();
  radio.openWritingPipe(address);
  radio.setPALevel(RF24_PA_MAX);
  radio.stopListening();
}
void loop() {

  joystick[0] = analogRead(A4);
  joystick[1] = analogRead(A3);

  
  radio.write( joystick, sizeof(joystick) );
}

receiver:

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#define enA 6
#define in1 7
#define in2 5
#define enB 3
#define in3 4
#define in4 2

RF24 radio(8, 9); // CE, CSN
const byte address[6] = "00001";
char receivedData[32] = "";
int  xAxis, yAxis;
int motorSpeedA = 0;
int motorSpeedB = 0;
int joystick[2];

void setup() {
 pinMode(enA, OUTPUT);
 pinMode(enB, OUTPUT);
 pinMode(in1, OUTPUT);
 pinMode(in2, OUTPUT);
 pinMode(in3, OUTPUT);
 pinMode(in4, OUTPUT);
 Serial.begin(9600);
 radio.begin();
 radio.openReadingPipe(0, address);
 radio.setPALevel(RF24_PA_MAX);
 radio.startListening();

 digitalWrite(in1, LOW);
 digitalWrite(in2, LOW);
 digitalWrite(in3, LOW);
 digitalWrite(in4, LOW);
}
void loop() {

 if (radio.available()) {   // If the NRF240L01 module received data

   radio.read( joystick, sizeof(joystick) );

   radio.read(&receivedData, sizeof(receivedData));
   xAxis = joystick[0];
   yAxis = joystick[1];

  // Serial.println(yAxis);
   //Serial.println(xAxis);

 }

 if (xAxis < 500) {
   //Backward
   digitalWrite(in1, HIGH);
   digitalWrite(in2, LOW);

   digitalWrite(in3, HIGH);
   digitalWrite(in4, LOW);

   motorSpeedA = map(xAxis, 500, 0, 0, 255);
   motorSpeedB = map(xAxis, 500, 0, 0, 255);
 }
 //Forward
 else if (xAxis > 500) {

   digitalWrite(in1, LOW);
   digitalWrite(in2, HIGH);

   digitalWrite(in3, LOW);
   digitalWrite(in4, HIGH);

   motorSpeedA = map(xAxis, 500, 1023, 0, 255);
   motorSpeedB = map(xAxis, 500, 1023, 0, 255);
 }

 else {
   motorSpeedA = 0;
   motorSpeedB = 0;
 }

 if (yAxis < 500) {
   //THIS IS LEFT

   // Set Motor A backward
   digitalWrite(in1, LOW);
   digitalWrite(in2, HIGH);

   // Set Motor B forward

   digitalWrite(in3, HIGH);
   digitalWrite(in4, LOW);


   motorSpeedA = map(yAxis, 500, 0, 0, 255); 
   motorSpeedB = map(yAxis, 500, 0, 0, 255);  

   //  Confine the range from 0 to 255
   if (motorSpeedA < 0) {
     motorSpeedA = 0;
   }
   if (motorSpeedB > 255) {
     motorSpeedB = 255;
   }
 }

 if (yAxis > 515) {
   //THIS IS RIGHT

   // Set Motor A forward
   digitalWrite(in1, HIGH);
   digitalWrite(in2, LOW);

   // Set Motor B backward

   digitalWrite(in3, LOW);
   digitalWrite(in4, HIGH);

   motorSpeedA = map(yAxis, 515, 1023, 0, 255);
   motorSpeedB = map(yAxis, 515, 1023, 0, 255);


   if (motorSpeedA > 255) {
     motorSpeedA = 255;
   }
   if (motorSpeedB < 0) {
     motorSpeedB = 0;
   }
 }

//prevent noise
 if (motorSpeedA < 70) {
   motorSpeedA = 0;
 }
 if (motorSpeedB < 70) {
   motorSpeedB = 0;
 }


 analogWrite(enA, motorSpeedA); // Send PWM signal to motor A
 analogWrite(enB, motorSpeedB); // Send PWM signal to motor B
}

Or you could do this:

leftmotor = lX + lY - 90;
rightmotor = lX - lY + 90;

lX and lY are the x and y axis if the joystick. The value my joystick outputs is 0 to 180. If your joystick output is different, you need to change the value of 90 to half the value of your joystick, if that makes any sense :slight_smile:

Here is a link to upgraded code

:slight_smile:

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.