Issues with RC car motor control reliability [Video included]

Hello!

This is the first project that I’m trying to do somewhat on my own - a wifi RC car. And the main issue I’ve been dealing with is the cheap motors, though the problem most likely is in the code. When I push the thumbstick, sometimes it does what I’ve intended and drives both wheels, sometimes just one. And when I release the stick, the wheels sometimes don’t stop moving, sometimes only one stops, and sometimes, rarely, both stop. Sometimes nothing happens when I push the stick and so on - feels very random.

The video

It would be lovely if someone could check out the code and see if they notice something. I know that the last lines, where I apply the speed, are most likely also wrong, but I’ve tried multiple iterations and none seem to work right.

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

RF24 myRadio (7, 8);
byte addresses[][6] = {"0"};

struct package
{
  int X = 512;
  int Y = 512;
};

//Wheels
const int L_SWITCH1 = 22;
const int L_SWITCH2 = 24;
const int L_MOTOR = 3;
const int R_SWITCH1 = 26;
const int R_SWITCH2 = 28;
const int R_MOTOR = 4;
int speed_L = 0;
int speed_R = 0;


typedef struct package Package;
Package data;

void setup()
{
  Serial.begin(115200);
  delay(1000);

  myRadio.begin();
  myRadio.setChannel(115);
  myRadio.setPALevel(RF24_PA_MAX);
  myRadio.setDataRate( RF24_250KBPS ) ;
  myRadio.openReadingPipe(1, addresses[0]);
  myRadio.startListening();

  pinMode(L_SWITCH1, OUTPUT);
  pinMode(L_SWITCH2, OUTPUT);
  pinMode(L_MOTOR, OUTPUT);
  pinMode(R_SWITCH1, OUTPUT);
  pinMode(R_SWITCH2, OUTPUT);
  pinMode(R_MOTOR, OUTPUT);

}


void loop()
{
  if ( myRadio.available())
  {
    while (myRadio.available())
    {
      myRadio.read( &data, sizeof(data) );
    }
    Serial.print("X:");
    Serial.print(data.X);
    Serial.print("      Y:");
    Serial.println(data.Y);


    if ( data.Y > 550 )                 // Go forward
    {
      digitalWrite(L_SWITCH1, LOW);
      digitalWrite(L_SWITCH2, HIGH);
      digitalWrite(R_SWITCH1, LOW);
      digitalWrite(R_SWITCH2, HIGH);
      speed_R = map(data.Y, 550, 1023, 0, 255);
      speed_L = map(data.Y, 550, 1023, 0, 255);
    }

    else if ( data.Y < 480 )            // Go backward
    {
      digitalWrite(L_SWITCH1, HIGH);
      digitalWrite(L_SWITCH2, LOW);
      digitalWrite(R_SWITCH1, HIGH);
      digitalWrite(R_SWITCH2, LOW);
      speed_R = map(data.Y, 480, 0, 0, 255);
      speed_L = map(data.Y, 480, 0, 0, 255);

    }

    if ( data.X > 550 )                  // Turn right
    {
      int mapX = map(data.X, 550, 1023, 0, 255);
      speed_L = speed_L + mapX;
      speed_R = speed_R - mapX;

      if (speed_L > 250) {
        speed_L = 250;
      }
      if (speed_R < 0) {
        speed_R = 0;
      }
    }

    else if ( data.X < 480 )              // Turn left
    {
      int mapX = map(data.X, 480, 0, 0, 255);
      speed_R = speed_R + mapX;
      speed_L = speed_L - mapX;

      if (speed_R > 250) {
        speed_R = 250;
      }
      if (speed_L < 0) {
        speed_L = 0;
      }
    }


    if (speed_L < 50) {   //To prevent buzzing
      speed_L = 0;
    }
    if (speed_R < 50) {
      speed_R = 0;
    }

    if ( (data.Y > 550) || (data.Y < 480) || (data.X > 550) || (data.X < 480)) {
      analogWrite(L_MOTOR, speed_L);
      analogWrite(R_MOTOR, speed_R);
    }
    else {
      digitalWrite(speed_L, LOW);
      digitalWrite(speed_R, LOW);
    }

    Serial.print("speed_L:");
    Serial.print(speed_L);
    Serial.print("      speed_R:");
    Serial.println(speed_R);

    delay(10);
  }
}

Thank you!

You face some strange malfunctioning. They could be symptoms of a system weakness.
You need, as I Think, to verify the integrety of the communication.
I worked with controlling 8 ton electric fork lift trucks. They mainly consisted of the central Control unit, 2 Power stages handling the drive motor and the hydraulic pump motor and the "fly by wire" stearing controller.
We used CAN as the Communication line. That means that every command to a motor was valid for a few 100 milliseconds. In order to run for long time the motor command had to be repeated Before the previous command got invalid.
The stearing controler had to report "All okey" very often, else the emergency brakes would be applied.

Do You get something from this?

Most likely I don't, since I'm just using a basic nrf24l01 wifi module and the example library. But I could get behind the idea of some kind of a control confirmation, will look. Maybe just even increasing the delay could help.

Loss of data is common in all communication. That needs to be cared for. Wireless is naturally more easily disturbed but even communication via copper wires can get corrupted now and then.
Do Your best to create that malfuncioning and debug, check, debug…..

maksiss:
This is the first project that I'm trying to do somewhat on my own - a wifi RC car

nRF24 wireless is very good for what you are doing but it is not WiFi

You need to post the Transmitter program as well as the Receiver program.

If the receiver is not correctly getting the data that is being sent then that is the first thing that needs to be fixed.

...R
Simple nRF24L01+ Tutorial

What happens if you comment out the serial prints…??

Robin2:
nRF24 wireless is very good for what you are doing but it is not WiFi

You need to post the Transmitter program as well as the Receiver program.

If the receiver is not correctly getting the data that is being sent then that is the first thing that needs to be fixed.

I’ve looked at both device serial windows, and the values go through very well

bluejets:
What happens if you comment out the serial prints…??

Nothing changes much. Although increasing the delay a bit removed the randomness, but the biggest issue left is that the wheels don’t stop when I stop moving the stick.

Hi,
Welcome to the forum.

Can you please post a copy of BOTH your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?
Not a Fritzy...

How are you powering your projects?

Thanks Tom... :slight_smile: