Fastest RC Car using Arduino

Programming, Tutorial, Coding, New Design, and/or any project for your Arduino and Raspberry Pi can post your topic /suggestion here.
User avatar
Dohangout
Admin
Admin
Contact:
Location: Philippines
Posts: 198
Joined: Sat Apr 23, 2016 10:32 pm

Fastest RC Car using Arduino

Mon Apr 06, 2020 5:44 am

In this project, we will build a totally different type of RC car using Arduino, the main objective is to achieve maximum speed, so I decided to try out the coreless DC motor for an RC car. These motors are normally used in drones and rated 39000 RPM which should be more than enough to quench our speed thirst. The car will be powered with a small lithium battery and can be controlled remotely using the nRF24L01 RF module.

Just look for 8520 Magnetic Micro Coreless Motor and you will find these. First let's provide a very low starting torque for our RC car and should be lightweight as possible. That is why I decided to build the entire car on top of a PCB using SMD components and reduces the board size as much as possible. The second problem is its high speed, 39000 RPM (RPM of the shaft) is hard to handle, so we need a speed control circuit on the Arduino side, so we are going to use MOSFET. The third is these motors will be powered by a single lithium-polymer battery with an operating voltage between 3.6V to 4.2V, so we have to design our circuit to operate at 3.3V. In that we need a 3.3V Arduino Pro mini as the brain of the RC car. Now the problems is sorted out, let’s look for materials required.

Components:
- 3.3V Arduino Pro Mini
- Arduino Nano
- NRF24L01 (2pcs)
- Joystick Module
- SI2302 MOSFET
- 1N5819 Diode
- Coreless BLDC Motors
- AMS1117-3.3V
- Lithium Polymer battery
- Resistors, Capacitors,
- Connecting wires

The RC car will be controlled remotely using an RF Joystick. This Joystick will use Arduino along with an nRF24L01 RF module, we also need the Joystick module to control the RC in the required direction. To build your Arduino RF Remote Joystick you can follow the below Circuit Diagram.
Arduino-RC-Car-Circuit-Diagram.png
Arduino-RC-Car-Circuit-Diagram.png (97.12 KiB) Viewed 1411 times
The RF Joystick circuit can be powered using the USB port of the nano board. The nRF24L01 module operates only on 3.3V, we can able to use the 3.3V pin on Arduino.

The Arduino Code for RF Joystick circuit is pretty simple, we have to read the X value and Y value from our Joystick and send it to the RC car through the nRF24L01. The complete program for this circuit can be found at the bottom of this page.

The complete circuit diagram for our Remote controlled Arduino Car is shown below.
Arduino-RC-Car-using-nRF24L01-Circuit-Diagram.png
The RC car will be powered by the Lipo Battery connected to terminal P1. The AMS117-3.3V is used to regulate 3.3V for our nRF24L01 and our pro-mini-board. We can also power the Arduino board directly on the raw pin but the on-board 3.3V voltage regulator on pro mini will not be able to supply enough current to our RF modules, hence we have used an external voltage regulator.

To drive our two BLDC motor, we have used two SI2302 MOSFETs. It is important to make sure that these MOSFETS can be driven by 3.3V.

The motors can consume peak current as high as 7A (continuous was tested to be 3A with load), MOSFET drain current should be 7A or more and it should turn on completely at 3.3V. The MOSFET that we selected can provide 10A even at 2.25V so it’s an ideal choice.

The fun part with the building this project was the PCB Development. The PCB’s here not only forms the circuit but also acts as a Chassis for our Car, so we planned a car looking shape for it with options to easily mount our motors. You can also try designing your own PCB using the circuit above or you can use the PCB design which you can download below,
Arduino-RC-Car-gerber-file.zip
(127.17 KiB) Downloaded 29 times
If you have used our PCB Gerber file shared above, then you might as well use a 3D model of the wheel, which can also download below,
motor+wheel+and+mount.zip
(227.4 KiB) Downloaded 23 times
The Code:

Code: Select all

// RF Remote Joystick
/*
   Code to transmit RF values to Arduino 
   Pin Conections
   CE - 7
    MISO - 12
    MOSI - 11
    SCK - 13
    CS - 8
    A0 - JoyX
    A1 - JoyY
*/
#include <SPI.h>  
#include "RF24.h"
RF24 myRadio (7, 8);
struct package
{
  int msg = 0;
};
byte addresses[][6] = {"0"};
typedef struct package Package;
Package data;
void setup()
{
  Serial.begin(9600);
  myRadio.begin();  
  myRadio.setChannel(115);  //115 band above WIFI signals
  myRadio.setPALevel(RF24_PA_MAX); //MAX power long rage
  myRadio.setDataRate( RF24_250KBPS ) ;  //Minimum speed
  delay(500);
  Serial.print("Remote Initialized");
}
  int forward; 
  int reverse; 
  int left; 
  int right; 
void loop()
{
 int xValue = analogRead(A0); //Read JoyX value
 int yValue = analogRead(A1); //Read JoyY Value 
 //Serial.print(xValue); Serial.print(" , "); Serial.println(yValue);
 if (xValue>560 && xValue<1000) // Filter JoyX for up 
 {
 forward = map (xValue, 560, 1000, 1, 10); //Convert Joyx-up to 0-10
 //Serial.print("F="); Serial.println(forward);
 data.msg = forward; WriteData(); delay(50);
 }
 if (xValue<500 && xValue > 10) // Filter JoyX for break 
 {
 reverse = map (xValue, 10, 500, 20, 11); //Convert JoyX-down to 11-20
 //Serial.print("B="); Serial.println(reverse);
 data.msg = reverse; WriteData(); delay(50);
 }
 else if (yValue>600 && yValue<1000) // Filter JoyY for right  
 {
 right = map (yValue, 600, 1000, 21, 30); //Convert JoyY-right to 21-30
 //Serial.print("R="); Serial.println(right);
 data.msg = right; WriteData(); delay(50);
 }
 else if (yValue<450 && yValue > 10) // Filter JoyY for left 
 {
 left = map (yValue, 10, 450, 40, 31); //Convert JoyY-left to 31-40
 //Serial.print("L="); Serial.println(left);
 data.msg = left; WriteData(); delay(50);
 }
/* else
 {
  Serial.println("Rest");
  data.msg = 0; WriteData(); delay(50);
 }
*/
}
void WriteData()
{
  myRadio.stopListening();  //Stop Receiving and start transminitng 
  myRadio.openWritingPipe( 0xF0F0F0F0AA); //Sends data on this 40-bit address
  myRadio.write(&data, sizeof(data)); 
  //Serial.print("\nSent:");
  //Serial.println(data.msg);
  delay(50);
}
void ReadData()
{ 
myRadio.openReadingPipe(1, 0xF0F0F0F066); // Which pipe to read, 40 bit Address
  myRadio.startListening(); //Stop Transminting and start Reveicing 
  if ( myRadio.available()) 
  {
    while (myRadio.available())
    {
      myRadio.read( &data, sizeof(data) );
    }
    Serial.print("\nReceived:");
    Serial.println(data.msg);
  }
}

// BLDC Motor

/*
CE - 7
MISO - 12
MOSI - 11
SCK - 13
CS - 8
Recently tested with nano
*/
/*PIN DEFINITIONS*/
#define R_IR 3
#define L_IR 4
#define L_MR 5
#define R_MR 6
#define min_speed 200
#define max_speed 800
#include <SPI.h>  
#include "RF24.h" 
RF24 myRadio (7, 8); 
struct package
{
  int msg;
};
typedef struct package Package;
Package data;
byte addresses[][6] = {"0"}; 
void setup() { 
  pinMode(R_IR, INPUT);
  pinMode(L_IR, INPUT);
  pinMode(L_MR, OUTPUT);
  pinMode(R_MR, OUTPUT);
  Serial.begin (9600);
  myRadio.begin(); 
  myRadio.setChannel(115);  //115 band above WIFI signals
  myRadio.setPALevel(RF24_PA_MIN); //MIN power low rage
  myRadio.setDataRate( RF24_250KBPS ) ;  //Minimum speed
}
int received; 
void loop() {
ReadData();
}
void Control_Car()
{
  if (received>=1 && received <=10) // Move Forward
  {
    int PWM_Value =  map (received, 1, 10, min_speed, max_speed);
    analogWrite(R_MR,PWM_Value);
    analogWrite(L_MR,PWM_Value);
  }
    if (received>=11 && received <=20) // Break
  {
    int PWM_Value =  map (received, 11, 20, min_speed, max_speed);
    analogWrite(R_MR,0);
    analogWrite(L_MR,0);
  }
    if (received>=21 && received <=30) // Turn Right 
  {
    int PWM_Value =  map (received, 21, 30, min_speed, max_speed);
    analogWrite(R_MR,PWM_Value);
    analogWrite(L_MR,0);
  }
      if (received>=31 && received <=40) // Turn Right 
  {
    int PWM_Value =  map (received, 31, 40, min_speed, max_speed);
    analogWrite(R_MR,0);
    analogWrite(L_MR,PWM_Value);
  }
}
void ReadData()
{
  myRadio.openReadingPipe(1, 0xF0F0F0F0AA); //Which pipe to read, 40 bit Address
  myRadio.startListening(); //Stop Transmitting and start Receiving 
  if ( myRadio.available()) 
  {
    while (myRadio.available())
    {
      myRadio.read( &data, sizeof(data) );
    }
    Serial.print("\nReceived:");
    Serial.println(data.msg);
    received = data.msg;
    Control_Car();
  }
  else  //If not data from RF
  {
  //analogWrite(R_MR,0);
  //analogWrite(L_MR,0);
  }
}
void WriteData()
{
  myRadio.stopListening(); //Stop Receiving and start transminitng 
  myRadio.openWritingPipe(0xF0F0F0F066);//Sends data on this 40-bit address
  myRadio.write(&data, sizeof(data)); 
  Serial.print("\nSent:");
  Serial.println(data.msg);
  delay(300);
}
If you found this Tutorial helpful please consider sharing this article or you send us some heart of donation to help us to develop more projects for you.

Thank you


Return to “ARDUINO AND RASPBERRY PI”

Links