Issue with joystick controlled independent DC motors' direction

Hi all,
as my first real project with Arduino I am putting together a radio controlled two wheeled car.

Remote controller: Arduino Uno board, 1 nRF24L01, 2 joysticks

Controlled car: Arduino Uno board, 1 nRF24L01, 2 DC motor wheels

The values from the joysticks pass from the remote to the car through the antennas smoothly, but the DC motors only turn according to the code when engaged separately. If both joysticks are used at the same time, the motors will turn in different directions, not according to the code (push forward, move clockwise and vice versa).

I've attached the codes from Transmitter and Receiver, and the serial monitors too.

I believe there's a better way to program the DCs, what do you think?

Thanks,
Joe

Transmitter

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

RF24 radio(9, 8);  // CE, CSN
const byte address[6] = "00001";
int value;

int left = 0;
int right = 0;

int mapleft = 0;
int mapright = 0;

void setup(){
radio.begin();
radio.openWritingPipe(address);
radio.stopListening();

pinMode(A0,INPUT);
pinMode(A1,INPUT);

Serial.begin(9600);
}

void loop(){

left = analogRead(A0);
right = analogRead(A1);

mapleft = map(left, 0, 1023, -255, 255);
mapright = map(right, 0, 1023, -255, 255);

Serial.print("TX   ");Serial.print("value[0] ");Serial.print(mapleft);Serial.print("   ");Serial.print("value[1] ");Serial.print(mapright);Serial.print("     ");Serial.print("anlg left - ");Serial.print(left);Serial.print("   ");Serial.print("anlg right - ");Serial.println(right);

int value[4] = {0,0,0,0};
value[0] = mapleft;
value[1] = mapright;
value[2] = left;
value[3] = right;

radio.write(&value, sizeof(value));
}

Receiver

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(9, 8);  // CE, CSN
const byte address[6] = "00001";
int value;
int array[4];

int speedleft = 5;
int dir1 = 4;
int dir2 = 2;

int speedright = 6;
int dir3 = 7;
int dir4 = 3;

void setup(){ 
radio.begin();
radio.openReadingPipe(0, address);
radio.startListening();

pinMode(speedleft,OUTPUT);
pinMode(dir1,OUTPUT);
pinMode(dir2,OUTPUT);

pinMode(speedright,OUTPUT);
pinMode(dir3,OUTPUT);
pinMode(dir4,OUTPUT);

Serial.begin(9600);
}

void loop(){
if (radio.available())
 { 
 char text[32] = " ";
 int value[4] = {0,0,0,0};
 radio.read(&value, sizeof(value));

 Serial.print("RX   ");Serial.print("val[0] ");Serial.print(value[0]);Serial.print("  ");Serial.print("val[1] ");Serial.print(value[1]);Serial.print("     ");Serial.print("anlg left - ");Serial.print(value[2]);Serial.print("   ");Serial.print("anlg right - ");Serial.println(value[3]);

 if(value[2],value[3] > 500){  
  digitalWrite(dir1,HIGH);
  digitalWrite(dir2,LOW);
  analogWrite(speedleft,value[0]);
  
  digitalWrite(dir3,HIGH);
  digitalWrite(dir4,LOW);
  analogWrite(speedright,value[1]);  
  }
 if(value[2],value[3] <= 500){
  digitalWrite(dir1,LOW);
  digitalWrite(dir2,HIGH);
  analogWrite(speedleft,abs(value[0]));

  digitalWrite(dir3,LOW);
  digitalWrite(dir4,HIGH);
  analogWrite(speedright,abs(value[1]));  
  }
 if(value[2]>500, value[3]<=500){
  digitalWrite(dir1,HIGH);
  digitalWrite(dir2,LOW);
  analogWrite(speedleft,abs(value[0]));
 
  digitalWrite(dir3,LOW);
  digitalWrite(dir4,HIGH);
  analogWrite(speedright,abs(value[1]));  
  }
 if(value[2]<=500, value[3]>500){
  digitalWrite(dir1,LOW);
  digitalWrite(dir2,HIGH);
  analogWrite(speedleft,abs(value[0]));
  
  digitalWrite(dir3,HIGH);
  digitalWrite(dir4,LOW);
  analogWrite(speedright,abs(value[1]));  
  }
 } 
}

Thank you all in advance,
I'll upload a video tomorrow

What is this supposed to do?

I would just send 'left' and 'right' and do the mapping in the receiver.

true that, didn't think about it

if the two analog value from the joystick are between 500 and 1023 (pushed forward), the two DC motors should run clockwise

If motors are pointing out to the left and right, turning both in the same direction will cause one to roll forward and the other to roll backward, spinning the vehicle. Are you SURE both motors should turn clockwise?

Try this receiver. If one wheel goes backward when you push its stick forward, swap the motor wires on that side.

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(9, 8);  // CE, CSN
const byte address[6] = "00001";

int LeftPWMPin = 5;
int LeftForwardPin = 4;
int LeftReversePin = 2;

int RightPWMPin = 6;
int RightForwardPin = 7;
int RightReversePin = 3;

const int DEADZONE = 10;  // Values on either side of 0 where the joystick is considered centered

void setup()
{
  radio.begin();
  radio.openReadingPipe(0, address);
  radio.startListening();

  pinMode(LeftPWMPin, OUTPUT);
  pinMode(LeftForwardPin, OUTPUT);
  pinMode(LeftReversePin, OUTPUT);

  pinMode(RightPWMPin, OUTPUT);
  pinMode(RightForwardPin, OUTPUT);
  pinMode(RightReversePin, OUTPUT);

  Serial.begin(9600);
}

void loop()
{
  if (radio.available())
  {
    int value[4] = {0, 0, 0, 0};
    radio.read(&value, sizeof(value));

    // Let's ignore the "mapped" values and just use the left and right analog values

    int leftThrottle = value[2];
    int rightThrottle = value[3];

    Serial.print("RX  Left Throttle = ");
    Serial.print(" ");
    Serial.print(leftThrottle);
    Serial.print(", Right Throttle = ");
    Serial.println(rightThrottle);

    //Map the raw throttle values to the range -255 to +255
    int mappedLeft = map(leftThrottle, 0, 1023, -255, +255);
    int mappedRight =  map(rightThrottle, 0, 1023, -255, +255);

    // Set the direction and speed for the left motor
    if (mappedLeft > DEADZONE)
    {
      // Left Forward
      digitalWrite(LeftForwardPin, HIGH);
      digitalWrite(LeftReversePin, LOW);
      analogWrite(LeftPWMPin, mappedLeft);
    }
    else if (mappedLeft < -DEADZONE)
    {
      // Left Reverse
      digitalWrite(LeftForwardPin, LOW);
      digitalWrite(LeftReversePin, HIGH);
      analogWrite(LeftPWMPin, -mappedLeft);
    }
    else // Left Stopped
    {
      digitalWrite(LeftForwardPin, LOW);
      digitalWrite(LeftReversePin, LOW);
      analogWrite(LeftPWMPin, 0);
    }

    // Set the direction and speed for the left motor
    if (mappedRight > DEADZONE)
    {
      // Right Forward
      digitalWrite(RightForwardPin, HIGH);
      digitalWrite(RightReversePin, LOW);
      analogWrite(RightPWMPin, mappedRight);
    }
    else if (mappedRight < -DEADZONE)
    {
      // Right Reverse
      digitalWrite(RightForwardPin, LOW);
      digitalWrite(RightReversePin, HIGH);
      analogWrite(RightPWMPin, -mappedRight);
    }
    else // Right Stopped
    {
      digitalWrite(RightForwardPin, LOW);
      digitalWrite(RightReversePin, LOW);
      analogWrite(RightPWMPin, 0);
    }
  }
}

Hi John, I just filmed a video to give a clearer picture of what's happening. Left and right only stand for left wheel and right wheel.
Note the left wheel only rolls forward even if joystick is backwards.
BTW I transferred the mapping to the receiver, new code below.

video here (youtube)

TX

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

RF24 radio(9, 8);  // CE, CSN
const byte address[6] = "00001";
int value;

int left = 0;
int right = 0;

void setup(){
radio.begin();
radio.openWritingPipe(address);
radio.stopListening();

pinMode(A0,INPUT);
pinMode(A1,INPUT);

Serial.begin(9600);
}

void loop(){

left = analogRead(A0);
right = analogRead(A1);

Serial.print("TX   ");Serial.print("anlg left - ");Serial.print(left);Serial.print("   ");Serial.print("anlg right - ");Serial.println(right);

int value[2] = {0,0};
value[0] = left;
value[1] = right;

radio.write(&value, sizeof(value));
}

RX

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(9, 8);  // CE, CSN
const byte address[6] = "00001";
int value;
int array[2];

int speedleft = 5;
int dir1 = 4;
int dir2 = 2;

int speedright = 6;
int dir3 = 7;
int dir4 = 3;

int mapleft = 0;
int mapright = 0;

void setup(){ 
radio.begin();
radio.openReadingPipe(0, address);
radio.startListening();

pinMode(speedleft,OUTPUT);
pinMode(dir1,OUTPUT);
pinMode(dir2,OUTPUT);

pinMode(speedright,OUTPUT);
pinMode(dir3,OUTPUT);
pinMode(dir4,OUTPUT);

Serial.begin(9600);
}

void loop(){
if (radio.available())
 { 
 char text[32] = " ";
 int value[2] = {0,0};
 radio.read(&value, sizeof(value));

 mapleft = map(value[0], 0, 1023, -255, 255);
 mapright = map(value[1], 0, 1023, -255, 255);

 Serial.print("RX   ");Serial.print("mapleft ");Serial.print(mapleft);Serial.print("  ");Serial.print("mapright");Serial.print(mapright);Serial.print("     ");Serial.print("anlg left - ");Serial.print(value[0]);Serial.print("   ");Serial.print("anlg right - ");Serial.println(value[1]);

 if(value[0],value[1] > 500){  
  digitalWrite(dir1,HIGH);
  digitalWrite(dir2,LOW);
  analogWrite(speedleft,abs(mapleft));
  
  digitalWrite(dir3,HIGH);
  digitalWrite(dir4,LOW);
  analogWrite(speedright,abs(mapright));  
  }
 if(value[0],value[1] <= 500){
  digitalWrite(dir1,LOW);
  digitalWrite(dir2,HIGH);
  analogWrite(speedleft,abs(mapleft));

  digitalWrite(dir3,LOW);
  digitalWrite(dir4,HIGH);
  analogWrite(speedright,abs(mapright));  
  }
 if(value[0]>500, value[1]<=500){
  digitalWrite(dir1,HIGH);
  digitalWrite(dir2,LOW);
  analogWrite(speedleft,abs(mapleft));
 
  digitalWrite(dir3,LOW);
  digitalWrite(dir4,HIGH);
  analogWrite(speedright,abs(mapright));  
  }
 if(value[0]<=500, value[1]>500){
  digitalWrite(dir1,LOW);
  digitalWrite(dir2,HIGH);
  analogWrite(speedleft,abs(mapleft));
  
  digitalWrite(dir3,HIGH);
  digitalWrite(dir4,LOW);
  analogWrite(speedright,abs(mapright));  
  }
 } 
}```

Many thanks :)

You still have this mistake in your sketch. It is likely causing your problem. Did you want "if both value[0] and value[1] are greater than 500" or did you want "if either value[0] or value[1] is greater than 500"? I can't tell from your code.

I think what you have now means "if value[0] is not equal to zero".

By that I mean 'if both values are above 500'. In that case both motors would run in the same direction, at the speed of each mapped value.
So I figured out what I was doing wrong, I had to use the && function (new codes below).

And here a video of the final product :slight_smile: https://youtu.be/nFTnSiKkvqc

Receiver:

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(9, 8);  // CE, CSN
const byte address[6] = "00001";
int value;
int array[2];

int speedleft = 5;
int dir1 = 4;
int dir2 = 2;

int speedright = 6;
int dir3 = 7;
int dir4 = 3;

int mapleft = 0;
int mapright = 0;

int connectionled = 0;
int noconnectionled = 1;

void setup(){ 
radio.begin();
radio.openReadingPipe(0, address);
radio.startListening();

pinMode(speedleft,OUTPUT);
pinMode(dir1,OUTPUT);
pinMode(dir2,OUTPUT);

pinMode(speedright,OUTPUT);
pinMode(dir3,OUTPUT);
pinMode(dir4,OUTPUT);

pinMode(connectionled,OUTPUT);

Serial.begin(9600);
}

void loop(){
if (radio.available())
 { 
digitalWrite(connectionled,HIGH);
digitalWrite(noconnectionled,LOW);
  
 char text[32] = " ";
 int value[2] = {0,0};
 radio.read(&value, sizeof(value));

 mapleft = map(value[0], 0, 1023, -255, 255);
 mapright = map(value[1], 0, 1023, -255, 255);

 Serial.print("RX   ");Serial.print("mapleft ");Serial.print(mapleft);Serial.print("  ");Serial.print("mapright");Serial.print(mapright);Serial.print("     ");Serial.print("anlg left - ");Serial.print(value[0]);Serial.print("   ");Serial.print("anlg right - ");Serial.println(value[1]);

 if(value[0] > 500 && value[1] > 500){  
  digitalWrite(dir1,HIGH);
  digitalWrite(dir2,LOW);
  analogWrite(speedleft,abs(mapleft));
  
  digitalWrite(dir3,HIGH);
  digitalWrite(dir4,LOW);
  analogWrite(speedright,abs(mapright));  
  }
 if(value[0] <= 500 && value[1] <= 500){
  digitalWrite(dir1,LOW);
  digitalWrite(dir2,HIGH);
  analogWrite(speedleft,abs(mapleft));

  digitalWrite(dir3,LOW);
  digitalWrite(dir4,HIGH);
  analogWrite(speedright,abs(mapright));  
  }
 if(value[0]>500 && value[1]<=500){
  digitalWrite(dir1,HIGH);
  digitalWrite(dir2,LOW);
  analogWrite(speedleft,abs(mapleft));
 
  digitalWrite(dir3,LOW);
  digitalWrite(dir4,HIGH);
  analogWrite(speedright,abs(mapright));  
  }
 if(value[0]<=500 && value[1]>500){
  digitalWrite(dir1,LOW);
  digitalWrite(dir2,HIGH);
  analogWrite(speedleft,abs(mapleft));
  
  digitalWrite(dir3,HIGH);
  digitalWrite(dir4,LOW);
  analogWrite(speedright,abs(mapright));  
  }
 }
 else{
 digitalWrite(connectionled,LOW);
 digitalWrite(noconnectionled,HIGH);
 }
}

Transmitter

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

RF24 radio(9, 8);  // CE, CSN
const byte address[6] = "00001";
int value;

int left = 0;
int right = 0;

void setup(){
radio.begin();
radio.openWritingPipe(address);
radio.stopListening();

pinMode(A0,INPUT);
pinMode(A1,INPUT);

Serial.begin(9600);
}

void loop(){

left = analogRead(A0);
right = analogRead(A1);

Serial.print("TX   ");Serial.print("anlg left - ");Serial.print(left);Serial.print("   ");Serial.print("anlg right - ");Serial.println(right);

int value[2] = {0,0};
value[0] = left;
value[1] = right;

radio.write(&value, sizeof(value));
}

Thank you John for the help!

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