RC Anything!

by jasonwinfilednz in Circuits > Remote Control

2604 Views, 32 Favorites, 0 Comments

RC Anything!

How to make a controller for rc car

We have all (probably) used a game controller to race cars on a Playstation or x-box. The controllers are very natural to use. The joysticks and triggers make it easy to control the car on the screen at speed. With these learned controls, it would be easy to translate this to the real world with a RC car.

In this guide, I will show you how to (with a few components) control an RC car using a PS3 controller. The PS3 controller has more buttons than you would need for an RC car so the options are endless for anything else you would like to control. Camera rig, crane, tank anything that needs remote control.

For this project, I will be using an old RC truck that lost its controller many moons ago. I will be bringing it back to life!

This truck is just a little toy truck with quite small motors so I will use a smaller motor controller. If you would like to use a high-power motor search around the internet for something a bit beefier.

The TB6612FNG motor controller is good up to 1.5 amps or a 3.2A burst. Some brushless motors draw up to 70 times this current so it would quickly let the magic smoke out of used in that application.

For this truck the motor controller is ideal.

Supplies

1 x ESP32

1 x PS3 Controller

1 x TB6612FNG Motor controller

1 x Donor RC car

Collect Required Hardware

motor.jpg
driver.jpg
esp32.png

For the recommended controller try and find a donor vehicle with motors like that pictured. These are pretty common low-power motors found in most cheap RC cars. Any RC car sub $20 will almost certainly have motors like this. The ESP32 and TB6612FNG driver are super common components found anywhere that sell electronic parts. The PS3 controller I used was a knock-off version so a genuine PS3 controller is not required.

Hook Up Hardware

espdriver2.png
esppdriver.PNG
unnamed.png

The TB6612FNG motor driver has the ideal pin out for the ESP32 where the control pins can be soldered directly to the GPIO of the ESP32 or maybe add a header to the TB6612FNG so you can remove the ESP32 for other projects in the future.

Hookup up the motors and driver board as shown in the diagram. Note for these cheaper RC cars they usually just have another DC motor that forces the steering in either direction. You could probably easily adapt your code to accommodate a servo.

The power from the battery should go directly to the VM of the power source. The VCC is up to 5.5V so you may need voltage regulation if your batteries exceed this voltage.


Configure Controller

sixaxis.png

The controller likes to peer to a PS3, we don't have one here so we have to convince the controller there is one by using a special program called sixaxispeertool. I don't have a link for this app as there doesn't seem to be a home page for the program. Just search for sixaxispeertool and you should get several locations you can gather the tool.

Plug your PS3 controller into the USB of your PC and run the sixaxispeertool The tool will present you with the controller's current MAC address. You can either update to another valid MAC or keep the one shown. Keep a note of this MAC address as we will need this later.

Flash the ESP32

I used the ESP32-PS3 library. It hasn't been updated for a while but it works perfectly.

https://github.com/jvpernis/esp32-ps3

If you have the controller setup the same as I have the following should work for you. Just update the MAC address as mentioned in step 3.

As the steering is not analog I used the D-pad buttons for steering. The analog triggers will provide variable speed output.

#include <Ps3Controller.h>
#include <analogWrite.h>

//Define the Pins

//Motor 1
int pinAIN1 = 26; //Direction
int pinAIN2 = 25; //Direction
int pinPWMA = 33; //Speed

//Motor 2
int pinBIN1 = 14; //Direction
int pinBIN2 = 12; //Direction
int pinPWMB = 13; //Speed

//Standby
int pinSTBY = 27;
int speed1 = 0;
//Constants to help remember the parameters
static boolean turnCW = 0;  //for motorDrive function
static boolean turnCCW = 1; //for motorDrive function
static boolean motor1 = 0;  //for motorDrive, motorStop, motorBrake functions
static boolean motor2 = 1;  //for motorDrive, motorStop, motorBrake functions

void setup()
{
  //Set the PIN Modes
  pinMode(pinPWMA, OUTPUT);
  pinMode(pinAIN1, OUTPUT);
  pinMode(pinAIN2, OUTPUT);
  pinMode(pinPWMB, OUTPUT);
  pinMode(pinBIN1, OUTPUT);
  pinMode(pinBIN2, OUTPUT);
  pinMode(pinSTBY, OUTPUT);
    Serial.begin(115200);
  Ps3.begin("e0:e2:e6:d1:39:2a");  //<----------------Replace with your controller MAC
    Serial.println("Ready.");
}

void loop()
{
    if(Ps3.isConnected()){

 if( abs(Ps3.event.analog_changed.button.l2) ){
       Serial.print("Pressing the left trigger button: ");
       motorDrive(motor1, turnCW, Ps3.data.analog.button.l2);
        Serial.println(Ps3.data.analog.button.l2, DEC);
   }


   if( abs(Ps3.event.analog_changed.button.r2) ){
       Serial.print("Pressing the right trigger button: ");
       motorDrive(motor1, turnCCW, Ps3.data.analog.button.r2);
        Serial.println(Ps3.data.analog.button.r2, DEC);       
   }


    if( Ps3.event.button_down.right )
        {
        Serial.println("Started pressing the right button");
        motorDrive(motor2, turnCW, 255);
        }
            
    if( Ps3.event.button_up.right )
        {
        Serial.println("Released the right button");
        motorStop(motor2);
        }
    
     
    if( Ps3.event.button_down.left )
     {    
        Serial.println("Started pressing the left button");
        motorDrive(motor2, turnCCW, 255);
     }
     
    if( Ps3.event.button_up.left )
     {
        Serial.println("Released the left button");
        motorStop(motor2);
     }
       
}
}


void motorDrive(boolean motorNumber, boolean motorDirection, int motorSpeed)
{
  /*
  This Drives a specified motor, in a specific direction, at a specified speed:
    - motorNumber: motor1 or motor2 ---> Motor 1 or Motor 2
    - motorDirection: turnCW or turnCCW ---> clockwise or counter-clockwise
    - motorSpeed: 0 to 255 ---> 0 = stop / 255 = fast
  */
boolean pinIn1;  //Relates to AIN1 or BIN1 (depending on the motor number specified)

//Specify the Direction to turn the motor
  //Clockwise: AIN1/BIN1 = HIGH and AIN2/BIN2 = LOW
  //Counter-Clockwise: AIN1/BIN1 = LOW and AIN2/BIN2 = HIGH
  if (motorDirection == turnCW)
    pinIn1 = HIGH;
  else
    pinIn1 = LOW;

//Select the motor to turn, and set the direction and the speed
  if(motorNumber == motor1)
  {
    digitalWrite(pinAIN1, pinIn1);
    digitalWrite(pinAIN2, !pinIn1);  //This is the opposite of the AIN1
    analogWrite(pinPWMA, motorSpeed);
  }
  else
  {
    digitalWrite(pinBIN1, pinIn1);
    digitalWrite(pinBIN2, !pinIn1);  //This is the opposite of the BIN1
    analogWrite(pinPWMB, motorSpeed);
  }


//Finally , make sure STBY is disabled - pull it HIGH
  digitalWrite(pinSTBY, HIGH);
}
void motorBrake(boolean motorNumber)
{
/*
This "Short Brake"s the specified motor, by setting speed to zero
*/
  if (motorNumber == motor1)
    analogWrite(pinPWMA, 0);
  else
    analogWrite(pinPWMB, 0);
}
void motorStop(boolean motorNumber)
{
  /*
  This stops the specified motor by setting both IN pins to LOW
  */
  if (motorNumber == motor1) {
    digitalWrite(pinAIN1, LOW);
    digitalWrite(pinAIN2, LOW);
  }
  else
  {
    digitalWrite(pinBIN1, LOW);
    digitalWrite(pinBIN2, LOW);
  } 
}
void motorsStandby()
{
  /*
  This puts the motors into Standby Mode
  */
  digitalWrite(pinSTBY, LOW);
  }

Conclusion

Controll rc car with phone

All the buttons can be mapped somehow in the controller using the esp32-ps3 library so it would be possible to control anything within the 10M Bluetooth range.

If you don't have a PS3 controller, no problem. Check out my video using a phone as a controller.