Help with joystick controlled arduino car

I've been trying to create a remote controlled arduino car by following a youtube video. All the wiring is connected connected correctly, but the code that came with the video is wrong. It causes two of the wheels to spin while not receiving any commands from the joystick.
I'm completely clueless when it comes to coding, so I was really hoping if someone from this forum could possibly help me fix the code? It would be greatly appreciated.

According to a commenter who managed to fix the code. It has something to do with the x and y axis being swapped?

Receiver:

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#define enA 2  
#define in1 3
#define in2 4
#define enB 7   
#define in3 5
#define in4 6
RF24 radio(8, 9); // CE, CSN
const byte address[6] = "00001";
char receivedData[32] = "";
int  xAxis, yAxis;
int motorSpeedA = 0;
int motorSpeedB = 0;
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_MIN);
  radio.startListening();
}
void loop() {
  if (radio.available()) {   // If the NRF240L01 module received data
    radio.read(&receivedData, sizeof(receivedData)); // Read the data and put it into character array
    xAxis = atoi(&receivedData[0]); // Convert the data from the character array (received X value) into integer
    delay(10);
    radio.read(&receivedData, sizeof(receivedData));
    yAxis = atoi(&receivedData[0]);
    delay(10);
  }
  
  // Y-axis used for forward and backward control
  if (yAxis < 470) {
    // Set Motor A backward
    digitalWrite(in1, HIGH);
    digitalWrite(in2, LOW);
    // Set Motor B backward
    digitalWrite(in3, HIGH);
    digitalWrite(in4, LOW);
    // Convert the declining Y-axis readings for going backward from 470 to 0 into 0 to 255 value for the PWM signal for increasing the motor speed
    motorSpeedA = map(yAxis, 470, 0, 0, 255);
    motorSpeedB = map(yAxis, 470, 0, 0, 255);
  }
  else if (yAxis > 550) {
    // Set Motor A forward
    digitalWrite(in1, LOW);
    digitalWrite(in2, HIGH);
    // Set Motor B forward
    digitalWrite(in3, LOW);
    digitalWrite(in4, HIGH);
    // Convert the increasing Y-axis readings for going forward from 550 to 1023 into 0 to 255 value for the PWM signal for increasing the motor speed
    motorSpeedA = map(yAxis, 550, 1023, 0, 255);
    motorSpeedB = map(yAxis, 550, 1023, 0, 255);
  }
  // If joystick stays in middle the motors are not moving
  else {
    motorSpeedA = 0;
    motorSpeedB = 0;
  }
  // X-axis used for left and right control
  if (xAxis < 470) {
    // Convert the declining X-axis readings from 470 to 0 into increasing 0 to 255 value
    int xMapped = map(xAxis, 470, 0, 0, 255);
    // Move to left - decrease left motor speed, increase right motor speed
    motorSpeedA = motorSpeedA + xMapped;
    motorSpeedB = motorSpeedB - xMapped;
    // Confine the range from 0 to 255
    if (motorSpeedA < 0) {
      motorSpeedA = 0;
    }
    if (motorSpeedB > 255) {
      motorSpeedB = 255;
    }
  }
  if (xAxis > 550) {
    // Convert the increasing X-axis readings from 550 to 1023 into 0 to 255 value
    int xMapped = map(xAxis, 550, 1023, 0, 255);
    // Move right - decrease right motor speed, increase left motor speed
    motorSpeedA = motorSpeedA - xMapped;
    motorSpeedB = motorSpeedB + xMapped;
    // Confine the range from 0 to 255
    if (motorSpeedA > 255) {
      motorSpeedA = 255;
    }
    if (motorSpeedB < 0) {
      motorSpeedB = 0;
    }
  }
  // Prevent buzzing at low speeds (Adjust according to your motors. My motors couldn't start moving if PWM value was below value of 70)
  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
}

Transmitter:

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(8,9); // CE, CSN
const byte address[6] = "00001";
char xyData[32] = "";
String xAxis, yAxis;
void setup() {
  Serial.begin(9600);
  radio.begin();
  radio.openWritingPipe(address);
  radio.setPALevel(RF24_PA_MIN);
  radio.stopListening();
}
void loop() {
  
  xAxis = analogRead(A1); // Read Joysticks X-axis
  yAxis = analogRead(A0); // Read Joysticks Y-axis
  // X value
  xAxis.toCharArray(xyData, 5); // Put the String (X Value) into a character array
  radio.write(&xyData, sizeof(xyData)); // Send the array data (X value) to the other NRF24L01 modile
  // Y value
  yAxis.toCharArray(xyData, 5);
  radio.write(&xyData, sizeof(xyData));
  delay(20);
}

You'll need to include a wiring schematic too.

Yes, it's BS.

You will find better examples here in the forum.

Oh, right. My mistake. Here are the two schematics.

I could only include one image in the first post oops.

Fantastic, but we'll need to see one for the receiver and how it's connected to the car as well.

the code looks fine at first glance

God damn it, the second image was supposed to be the receiver. Here it is for real this time.

Neither D2 nor D7 are PWM pins

how do you insure that the 1st read value is x and not y?

since it looks like ascii strings are being sent, why not send one msg with the x & y values separated by a comma?

i don't think having one motor forward and the other reversed is necessary for turning. wouldn't it make more sense to simple reduce the speed of the motors on one side to effect the turn?

How would you ensure that there even is a second packet?

consider following - less code to read/debug
you can test using serial monitor

see ternary operator, shorthand or if/else
and combines turn and speed (xAxis and yAxis) to compute a speed for each side

you need to add your own getXy() to read values across the radio channel. values are comma separate

#define enA 2
#define in1 3
#define in2 4

#define enB 7
#define in3 5
#define in4 6

int xAxis;
int yAxis;

char buf [80];
char s   [80];

// -----------------------------------------------------------------------------
int
getXy (void)
{
    if (Serial.available ()) {
        int n = Serial.readBytesUntil ('\n', buf, sizeof (buf)-1);
        buf [n] = '\0';

        char *pX = strtok (buf,  ",");
        char *pY = strtok (NULL, ",");

        if (NULL == pY)  {
            Serial.println (" invalid msg - no 2nd field");
            return 0;
        }

        xAxis = atoi (pX);
        yAxis = atoi (pY);
        return 1;
    }

    return 0;
}

// -----------------------------------------------------------------------------
// determine from left and right values limited to -255 - 255
#define sgn(x)    (0 > x ? -1 : 1)

void
setSpeed (
    int   spdLeft,
    int   spdRight )
{
    sprintf (s, "%s:  %d %d", __func__, spdLeft, spdRight);
    Serial.println (s);

    spdLeft  = 255 <= abs(spdLeft)  ? 255 : sgn(spdLeft)  * abs(spdLeft);
    spdRight = 255 <= abs(spdRight) ? 255 : sgn(spdRight) * abs(spdRight);

    digitalWrite (in1, 0 > spdLeft  ? LOW  : HIGH);
    digitalWrite (in2, 0 > spdLeft  ? HIGH : LOW);
        
    digitalWrite (in3, 0 > spdRight ? LOW  : HIGH);
    digitalWrite (in4, 0 > spdRight ? HIGH : LOW);

    analogWrite (enA, abs(spdLeft));
    analogWrite (enB, abs(spdRight));

    sprintf (s, " %s: %d %d", __func__, spdLeft, spdRight);
    Serial.println (s);
}

// -----------------------------------------------------------------------------
void
loop ()
{
    if (0 == getXy ())
        return;

    sprintf (s, " %s: x %4d, y %4d", __func__, xAxis, yAxis);
    Serial.println (s);

    int spd  = map (xAxis, 0, 1024, -255, 255);
    int turn = map (yAxis, 0, 1024, -100, 100);

    setSpeed (spd + turn, spd - turn);
}

// -----------------------------------------------------------------------------
void setup ()
{
    Serial.begin (9600);

    pinMode (enA, OUTPUT);
    pinMode (enB, OUTPUT);
    pinMode (in1, OUTPUT);
    pinMode (in2, OUTPUT);
    pinMode (in3, OUTPUT);
    pinMode (in4, OUTPUT);
}

Please consider language :face_with_symbols_over_mouth:

Do any changes need to be made to the transmitter code as well?

How do I determine what my getXy() is?

Additionally, I'll post the link to the video of where I got the initial code and build design from, in case it helps.
video

yes. send a single c-string with both values separated by a comma

void loop() {
    int x = analogRead(A1); // Read Joysticks X-axis
    int y = analogRead(A0); // Read Joysticks Y-axis

    char xyData [32];
    sprintf (xyData, "%d,%d", x, y);
    radio.write (xyData, strlen (xyData)+1);

    delay(20);
}

not write, xAxis is a String?
[quote="mossv2, post:1, topic:1024045"]

String xAxis, yAxis;

 xAxis = analogRead(A1); // Read Joysticks X-axis
[/quote]

sorry i confused this with another post

I’m just going to say this again, one more time and I’m leaving this thread

In arduino nano pins 2 and 7 CANNOT OUTPUT PWM! This idiot guy from the video made a mistake and likely rectified it but did not show you. here is the code from video

He is using 2 and 9, ONE OF WHICH IS PWM PIN! I’m sure he figured out later why only one motor changes speed and the other goes full blast and changed it too. Anyway, keep on improving your code and pay no attention to the wrong pins, caio!

1 Like

Alright. I attempted to apply the code that you sent, along with some help that I received from another person. But it still does not work. So I must have done something wrong again.

This is the code that I have written up for the receiver and transmitter right now.

Transmitter:

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio (9, 10); // CE, CSN
const byte address[6] = "00001";
char xyData[32] = "";
String xAxis, yAxis;
void setup() {
  Serial.begin(9600);
  radio.begin();
  radio.openWritingPipe(address);
  radio.setPALevel(RF24_PA_MIN);
  radio.stopListening();
}
void loop() {
    int x = analogRead(A1); // Read Joysticks X-axis
    int y = analogRead(A0); // Read Joysticks Y-axis

    char xyData [32];
    sprintf (xyData, "%d,%d", x, y);
    radio.write (xyData, strlen (xyData)+1);

    delay(20);
}

Receiver:

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

#define in1 3 // D3 arduino to IN1 of L298N
#define in2 4 // D4 arduino to IN2 of L298N
#define enA 5 // D5 arduino to ENA of L298N
#define enB 6 // D6 arduino to ENB of L298N
#define in3 7 // D7 arduino to IN3 of L298N
#define in4 8 // D8 arduino to IN4 of L298N

RF24 radio (9, 10); // CE, CSN
const byte address[6] = "00001";
char receivedData[32] = "";

int xAxis;
int yAxis;

char buf [80];
char s   [80];

// -----------------------------------------------------------------------------
int
getXy (void)
{
    if (Serial.available ()) {
        int n = Serial.readBytesUntil ('\n', buf, sizeof (buf)-1);
        buf [n] = '\0';

        char *pX = strtok (buf,  ",");
        char *pY = strtok (NULL, ",");

        if (NULL == pY)  {
            Serial.println (" invalid msg - no 2nd field");
            return 0;
        }

        xAxis = atoi (pX);
        yAxis = atoi (pY);
        return 1;
    }

    return 0;
}

// -----------------------------------------------------------------------------
// determine from left and right values limited to -255 - 255
#define sgn(x)    (0 > x ? -1 : 1)

void
setSpeed (
    int   spdLeft,
    int   spdRight )
{
    sprintf (s, "%s:  %d %d", __func__, spdLeft, spdRight);
    Serial.println (s);

    spdLeft  = 255 <= abs(spdLeft)  ? 255 : sgn(spdLeft)  * abs(spdLeft);
    spdRight = 255 <= abs(spdRight) ? 255 : sgn(spdRight) * abs(spdRight);

    digitalWrite (in1, 0 > spdLeft  ? LOW  : HIGH);
    digitalWrite (in2, 0 > spdLeft  ? HIGH : LOW);
        
    digitalWrite (in3, 0 > spdRight ? LOW  : HIGH);
    digitalWrite (in4, 0 > spdRight ? HIGH : LOW);

    analogWrite (enA, abs(spdLeft));
    analogWrite (enB, abs(spdRight));

    sprintf (s, " %s: %d %d", __func__, spdLeft, spdRight);
    Serial.println (s);
}

// -----------------------------------------------------------------------------
void
loop ()
{
    if (0 == getXy ())
        return;

    sprintf (s, " %s: x %4d, y %4d", __func__, xAxis, yAxis);
    Serial.println (s);

    int spd  = map (xAxis, 0, 1024, -255, 255);
    int turn = map (yAxis, 0, 1024, -100, 100);

    setSpeed (spd + turn, spd - turn);
}

// -----------------------------------------------------------------------------
void setup ()
{
    Serial.begin (9600);

    pinMode (enA, OUTPUT);
    pinMode (enB, OUTPUT);
    pinMode (in1, OUTPUT);
    pinMode (in2, OUTPUT);
    pinMode (in3, OUTPUT);
    pinMode (in4, OUTPUT);
radio.begin();
  radio.openReadingPipe(0, address);
  radio.setPALevel(RF24_PA_MIN);
  radio.startListening(); 
}

i confused things with my getXy(). you need something like above.

i would expect receivedData to more than large enough to read the received string and the read() will return the # of bytes received.

but you should start with using Serial.println() to display the string being transmitted as well as the raw string received.

No.

read is void.

But without changing the defaults, all packets are 32 bytes.