Instructables

Simple RC car for beginners (Android control over Bluetooth)

Featured
Picture of Simple RC car for beginners (Android control over Bluetooth)
This is a simple project of Android Bluetooth Car with Bluetooth control. Arduino controller is used

To control the car used Android-device with a built-in accelerometer. Tilt forward - car goes forward, tilt to the left - car turns to the left, tilt back - car goes back. Speed of movement or rotation depends on how much you tilt the device. Sensitivity and value of the tilt set in the configuration Android-apps. Also are provided a normal way to control: the buttons on the screen. In addition to all I implemented the touch control. Total 3 ways to control the RC Car.

Capabilities of the device you can see on the video above
 
Remove these adsRemove these ads by Signing Up

Step 1: Android device

Picture of Android device
Parts needed

1. Android device

The most important part - Android device with accelerometer and Bluetooth: tablet, smartphone and other... As an Android device, I used a cheap Chinese tablet "Ainol Aurora" with an external USB-Bluetooth module (because its not have own), connected via USB Host.

Step 2: DIY Car Chassis

Picture of DIY Car Chassis
arduino_car.jpg
2. DIY Car Chassis

We also need any chassis with 2 or 4 DC motors. You can use an old RC toy car. As a platform I used a small RC DIY platform, bought on eBay for $ 25. To control described in this project is most suitable track chassis.

Step 3: Controller (MCU)

Picture of Controller (MCU)
3. Controller (MCU)

You need Arduino-compatible controller

Controller must support 2 PWM and UART.

Step 4: Bluetooth module

Picture of Bluetooth module
4. Bluetooth module

As a Bluetooth module uses cheap Chinese module HC-06 (6-8$ on eBay). Instructions guide on connecting bluetooth module to Arduino is here.
You can use HC-05, HC-07 and other serial Bluetooth modules

Step 5: Motor Driver

Picture of Motor Driver
5. Motor Driver

I used L298N Dual Bridge DC stepper Motor Driver module. It cost 4-5$ on eBay.

Step 7: Theory

Picture of Theory
Theory

All calculations are performed in the Android-application, and immediately calculate the values 2‹2‹of the PWM for the left and right motor. Application has flexible settings, such as the range of the PWM, the sensitivity of tilt, the minimum threshold for the PWM and other. Example commands transmitted by Bluetooth:
L-255\rR-120\r
L - the command to the left engine, R - for the right
A dash means the motor rotation to move back
255 - PWM value (for Arduino is the maximum speed of rotation)
\r - end of command.
On this command RC car will move forward and slightly rotated to the right, as right engine rotates slowly left.

L255\rR-255\r
On this command the left engine will rotate back and forward right, forcing a car to rotate around its axis counterclockwise.

H1\r
Command is an additional channel to which you can connect for example lights, sound, etc.

Symbols command L, R and H can be defined in the settings of Android-applications.

In the MCU control program provides a timer that shuts off the engine if the last command was received more than n-seconds ago. The data are stored in the EEPROM memory of the controller and can be changed from Android device. The range of this setting is from 0.1 seconds to 99.9 seconds. This setting can be disabled. To work with EEPROM provides commands: Fr - reading values 2‹2‹and Fw - record values.

Electronics

Block diagram see on picture above

Step 8: Android Application

Picture of Android Application
10.png
11.png
As we can see, the Arduino connects to Bluetooth module and a motor driver with two or four connected motors.

Android Application

The application for Android was written in Eclipse IDE. All sources of the project and the project for Eclipse, you can download below. Android version on your device must be > 3.0.

The application contains several activity. Main activity is a home screen with buttons running different operating modes and settings

There are 3 control modes Bluetooth-car: from accelerometer, screen buttons and touch-control.

Android application settings

Screenshot of settings CxemCar Android application version 1.0

MAC address

To establish a connection with the RC Car's Bluetooth module, you must set MAC-address in the application settings. But first, you must configure the pair the devices on Android-device: open Settings -> Bluetooth and click "Search for devices". When the phone finds our Bluetooth-module, click them and enter password for pairing (usually "1234")

To know Bluetooth module MAC-address possible from any application, such as Bluetooth Terminal. To do this, click "Connect a device - Secure" and in the resulting window, click the button "Scan for devices". Software will be scans the Bluetooth devices and displays them MAC-address.

Step 9: Arduino RC car wiring

Wiring diagram for Arduino controller

In the circuit I used a jumper (in the scheme Jmp1), because with a connected Bluetooth module is impossible be load sketch to the Arduino.

I soldered a Bluetooth-module to the Arduino and led status light. For communication between Arduino and Bluetooth, read this article: Arduino and Bluetooth. Module HC-06 placed in heat-shrink tube 10mm. Bluetooth-state LED with current limiting resistor (calculator) were also placed in heat-shrink tube.

In the breadboard platform, I drilled a hole and secure motor driver L298N. Arduino board attached with double-sided tape

Between the car platform and breadboard I placed 3 Li-Po battery 3.7V 1100 mAh. Power to the controller and motors separately: Arduino powered by a 3.7 V battery, and the motors and driver L298N from two 3.7V batteries connected in series. There are two 2-position power switch - one position is the power from the batteries to consumers, in the other position to charging terminals.

Beetween BT pin RX (2) and Arduino pin TX may require level shifter. For this, you can use voltage divider: calculator 5V to 3.3V

Step 10: Software

Picture of Software
The program was written in Arduino IDE 1.01.

#include "EEPROM.h"

#define D1 2          // direction of motor rotation 1
#define M1 3          // PWM left motor
#define D2 4          // direction of motor rotation 2
#define M2 5          // PWM right motor
#define HORN 13       // additional channel 1
//#define autoOFF 2500  // milliseconds after which the robot stops when the connection

#define cmdL 'L'      // UART-command for left motor
#define cmdR 'R'      // UART-command for right motor
#define cmdH 'H'      // UART-command for additional channel (for example Horn)
#define cmdF 'F'      // UART-command for EEPROM operation
#define cmdr 'r'      // UART-command for EEPROM operation (read)
#define cmdw 'w'      // UART-command for EEPROM operation (write)

char incomingByte;    // incoming data

char L_Data[4];       // array data for left motor
byte L_index = 0;     // index of array L
char R_Data[4];       // array data for right motor
byte R_index = 0;     // index of array R
char H_Data[1];       // array data for additional channel
byte H_index = 0;     // index of array H
char F_Data[8];       // array data for  EEPROM
byte F_index = 0;     // index of array F
char command;         // command

unsigned long currentTime, lastTimeCommand, autoOFF;

void setup() {
  Serial.begin(9600);       // initialization UART
  pinMode(HORN, OUTPUT);    // additional channel
  pinMode(D1, OUTPUT);      // output for motor rotation
  pinMode(D2, OUTPUT);      // output for motor rotation
  /*EEPROM.write(0,255);
  EEPROM.write(1,255);
  EEPROM.write(2,255);
  EEPROM.write(3,255);*/
  timer_init();             // initialization software timer
}

void timer_init() {
  uint8_t sw_autoOFF = EEPROM.read(0);   // read EEPROM "is activated or not stopping the car when losing connection"
  if(sw_autoOFF == '1'){                 // if activated
    char var_Data[3];
    var_Data[0] = EEPROM.read(1);
    var_Data[1] = EEPROM.read(2);
    var_Data[2] = EEPROM.read(3);
    autoOFF = atoi(var_Data)*100;        // variable autoOFF ms
  }
  else if(sw_autoOFF == '0'){        
    autoOFF = 999999;
  }
  else if(sw_autoOFF == 255){
    autoOFF = 2500;                      // if the EEPROM is blank, dafault value is 2.5 sec
  }
  currentTime = millis();                // read the time elapsed since application start
}
 
void loop() {
  if (Serial.available() > 0) {          // if received UART data
    incomingByte = Serial.read();        // raed byte
    if(incomingByte == cmdL) {           // if received data for left motor L
      command = cmdL;                    // current command
      memset(L_Data,0,sizeof(L_Data));   // clear array
      L_index = 0;                       // resetting array index
    }
    else if(incomingByte == cmdR) {      // if received data for left motor R
      command = cmdR;
      memset(R_Data,0,sizeof(R_Data));
      R_index = 0;
    }
    else if(incomingByte == cmdH) {      // if received data for additional channel
      command = cmdH;
      memset(H_Data,0,sizeof(H_Data));
      H_index = 0;
    }   
    else if(incomingByte == cmdF) {      // if received data for EEPROM op
      command = cmdF;
      memset(F_Data,0,sizeof(F_Data));
      F_index = 0;
    }
    else if(incomingByte == '\r') command = 'e';   // end of line
    else if(incomingByte == '\t') command = 't';   // end of line for EEPROM op
    
    if(command == cmdL && incomingByte != cmdL){
      L_Data[L_index] = incomingByte;              // store each byte in the array
      L_index++;                                   // increment array index
    }
    else if(command == cmdR && incomingByte != cmdR){
      R_Data[R_index] = incomingByte;
      R_index++;
    }
    else if(command == cmdH && incomingByte != cmdH){
      H_Data[H_index] = incomingByte;
      H_index++;
    }   
    else if(command == cmdF && incomingByte != cmdF){
      F_Data[F_index] = incomingByte;
      F_index++;
    }   
    else if(command == 'e'){                       // if we take the line end
      Control4WD(atoi(L_Data),atoi(R_Data),atoi(H_Data));
      delay(10);
    }
    else if(command == 't'){                       // if we take the EEPROM line end
      Flash_Op(F_Data[0],F_Data[1],F_Data[2],F_Data[3],F_Data[4]);
    }
    lastTimeCommand = millis();                    // read the time elapsed since application start
  }
  if(millis() >= (lastTimeCommand + autoOFF)){     // compare the current timer with variable lastTimeCommand + autoOFF
    Control4WD(0,0,0);                             // stop the car
  }
}

void Control4WD(int mLeft, int mRight, uint8_t Horn){

  bool directionL, directionR;      // direction of motor rotation L298N
  byte valueL, valueR;              // PWM M1, M2 (0-255)
  
  if(mLeft > 0){
    valueL = mLeft;
    directionL = 0;
  }
  else if(mLeft < 0){
    valueL = 255 - abs(mLeft);
    directionL = 1;
  }
  else {
    directionL = 0;
    valueL = 0;
  }
 
  if(mRight > 0){
    valueR = mRight;
    directionR = 0;
  }
  else if(mRight < 0){
    valueR = 255 - abs(mRight);
    directionR = 1;
  }
  else {
    directionR = 0;
    valueR = 0;
  }
   
  analogWrite(M1, valueL);            // set speed for left motor
  analogWrite(M2, valueR);            // set speed for right motor
  digitalWrite(D1, directionL);       // set direction of left motor rotation
  digitalWrite(D2, directionR);       // set direction of right motor rotation
  
  digitalWrite(HORN, Horn);           // additional channel
}

void Flash_Op(char FCMD, uint8_t z1, uint8_t z2, uint8_t z3, uint8_t z4){

  if(FCMD == cmdr){           // if EEPROM data read command
    Serial.print("FData:");       // send EEPROM data
    Serial.write(EEPROM.read(0));     // read value from the memory with 0 address and print it to UART
    Serial.write(EEPROM.read(1));
    Serial.write(EEPROM.read(2));
    Serial.write(EEPROM.read(3));
    Serial.print("\r\n");         // mark the end of the transmission of data EEPROM
  }
  else if(FCMD == cmdw){          // if EEPROM data write command
    EEPROM.write(0,z1);               // z1 record to a memory with 0 address
    EEPROM.write(1,z2);
    EEPROM.write(2,z3);
    EEPROM.write(3,z4);
    timer_init();             // reinitialize the timer
    Serial.print("FWOK\r\n");         // send a message that the data is successfully written to EEPROM
  }
The code uses a library to work with EEPROM AVR-memory. Arduino board by USART from the Bluetooth module receives data ready for the left and right engine. All basic calculations are performed in the Android application.

The project structure in Eclipse you can see on the screenshot above.

You can download the source code for the Arduino, and the project for Eclipse
Download APK application for Android-device

The latest software version can be found on this page

Video of demonstration the virtual steering wheel mode (1.2 version and above):


P.S. Sorry for my bad english
P.S.S. Soon to be the same project for STM32
abencomo1 month ago

Nice work! We built a similar project. However, we installed the
Android device onto a RC car and used an IOIO board to control it
autonomously. Here is the preliminary result:

SHARQ1 month ago

Hi everyone..

I did this as my project as my FYP. I did my own L298N motor driver referring to this link, http://www.instructables.com/id/Dual-H-Bridge-L298-Breakout-Board-Homemade/ . I had set up all as per instructed above. But, I'm finding some issues on my project which is only 1 motor operates and only forward is functional while other buttons are malfunctioned.. Can anyone help me to complete my project by giving advises or suggestions? I'm in a desperate situation here because my submission due next week. Please help me. Thank you.

SHARQ3 months ago

Hi tolik777.. is it possible for me to use bluetooth dongle instead of bluetooth module?? Thank you..

jomet SHARQ1 month ago

I don't think so that you can blueetoth dongle

SHARQ jomet1 month ago

Thanks jomet for your reply

hsumaria3 months ago
can arduino uno be used instead of this ??
tolik777 (author)  hsumaria3 months ago
Yes, surely. You can use any arduino
rovilo tolik7771 month ago

But Does Uno use the same coding as the Nano?

fs42 months ago

Hi Guys... loved the tutorial:) I am very new to this. I'm finding difficult to buy the parts. Can somebody please guide me with links to buy these in India.

So far below are the links i found. But I'm not sure whether these are the right components. Please guide me

http://www.ebay.in/itm/PWM-Motor-Speed-Controller-for-PIC-Atmel-Atmega-Arduino-Raspberry-Pi-/291061633181?pt=LH_DefaultDomain_203&hash=item43c4a0109d&_uhb=1#ht_1562wt_1139

http://probots.co.in/index.php?main_page=product_info&cPath=22&products_id=427

http://probots.co.in/index.php?main_page=advanced_search_result&search_in_description=1&keyword=motor+driver

jomet fs41 month ago
jomet jomet1 month ago
nezzmuk2 months ago

I have everything put together. But when I tried to use it all I get is a socket error. I used Bluetooth Terminal to connect and get the MAC for the android app. Any idea what else I should try?

ddidiano2 months ago

I'm wondering if you can use an arduino UNO rather than the leonardo model.

pranjaltables2 months ago

can i use another version of arduino like arduino duemilanove atmega328?

pranjaltables3 months ago

can i use another version of motor driver?

tolik777 (author)  pranjaltables3 months ago
Yes
sketch_dec25a:173: error: expected `}' at end of input

please help!

Serial.print("FWOK\r\n"); // send a message that the data is successfully written to EEPROM

}

}

IT SHOULD BE ENDING WITH ANOTHER " } " SAME LIKE ABOVE

meanbean1 year ago
Can you recommend a quad bridge dc motor driver? I'm thinking about starting a project that would involve 4 motors, i'm just a little hesitant about where to start. Thanks!
tolik777 (author)  meanbean1 year ago
Do you want control 4 motors independently? Each separately?
Two or four control motor channel?
If you need 2 motors, you can connect them in parallel. For this you can use L298
Yes, I too want to use 4 motors for my toy car wheel... can you helpme out how to to with L298N motor drive and arduino...

I am beginner here... Your help would highly appreciated...
srauniyar3 months ago
Hello Everyone... can anyone please tell me how to connect 4 motor for toy car wheel with L298N motor drive and arduino mega... when I am using only two wheel then its running ok for few second but after few second its not working.... Your help would highly appreciated...
adi-sreyaj6 months ago
here's mine version of this.........................works perfectly and i got a range of over 100 mtr
DSC_0093.jpgDSC_0094.jpg
hey adi ....i hv some queries abt the same
will u plz suggest abt the parts n their configurations,
will u plz post them with details,n also the program.
vkadnor vkadnor4 months ago
grt job dude
tolik777 (author)  adi-sreyaj6 months ago
Perfect work!
vkadnor4 months ago
L298N Dual Bridge DC stepper Motor Driver.....is this wireless
tnburrow4 months ago
I cant seem to figure out how to install the program on my android. I pulled the apk file and tried to install it but it said there was a problem with the parsing. How did you guys get it to work?
dbridges44 months ago
Hi. I built this project with an old RC truck. There is a front motor that turns the front wheels left and right and back motor that is supposed to go forward and backward.. The car doesn't drive properly on carpet. Weak motors? or not enough voltage getting to the motors. When it does drive forward it turns left and when it drives backwards it turns right. It doesn't go straight forward or straight back. Any suggestions.
ArtBotHack6 months ago
hello
i use android 4.04 and i have 'Socket failed' error message every time .
I test the bluetooth connection with the Bluetooth Terminal and it's ok
what can i do ??
thanks you for this wonderful tuto
adi-sreyaj6 months ago
HELLO ANYBODY ...............................

PLS HELP ME ..............................
I MADE THE CAR, BUT WHEN I ACCELERATE THE FULL VOLTAGE IS NOT GETTING DELIVERED TO THE MOTOR.........I PROVIDED 12V SUPPLY TO THE MOTOR DRIVER BUT AT THE MOTOR TERMINAL ONLY 2V IS APPEARING............PLS SUGGEST ME A THE SOLUTION
the ground........
adi-sreyaj6 months ago
(removed by author or community request)
So as far as you shorting your connection, make sure all grounds are tight, and also make sure that the arduino or whatever microcontroller you used is not sitting directly on metal. However I am not sure how well you soldered any connections, or if they are soldered at all.. Shoot me a reply with your problem and step-by-step what you have done to get to this point.
bergbrock7 months ago
This was an amazing DIY Guide! I don't think I can thank enough the people who made this project possible. I used an adafruit V1 motorshield, and had to completely revamp the code. If anyone is interested in looking at that code please email me, bbrock@pdx.edu

Also am looking at getting this working with autonomy; my idea is that I would like to use an ultrasonic sensor to detect objects in our way, and autonomously take control over to avoid said objects, then return control to bluetooth
I am very close to doing so, there are minor nuances in the code.

Anyways I hope everyone has as much fun as I did following this project; and if there are any questions you feel are unanswered, shoot me an email and I will try to clear them up for you!

Brock
Portland State University Computer Science Student
jams41 year ago
This is great! Thank you for the fantastic tutorial. Could the Arduino (uno) be controlled with an iPhone as well?
tolik777 (author)  jams41 year ago
Sorry, I don't know. I havn't iPhone
Iphone doesn t have bluetooth connection, but u can try to control the RC with an wireless conection. U will need a wireless bee for arduino
are you retarted?! Of course iPhones have Bluetooth
I dont think this follows the "be nice" rules....
Pro

Get More Out of Instructables

Already have an Account?

close

PDF Downloads
As a Pro member, you will gain access to download any Instructable in the PDF format. You also have the ability to customize your PDF download.

Upgrade to Pro today!