3.Bluetooth modules and Arduino code

The Bluetooth module I bought was Spark Fun's Bluetooth Mate Silver. It costs around $40 bucks. It is decent but does not always connect to the Android application successfully with either 9600 or 115200 bps. It has a transfer range of 2400-115200bps. I bought it because it was the only one I could find. It has two LEDs to indicate connection status. This module might be better for an application that needs a lot of bandwidth.

BluetoothMateSilver

http://www.sparkfun.com/products/10393

After the project was done, I tumbled upon this $14 Bluetooth module by MDFLY electronics. It has a range of up to 30ft, a 9600 baud rate, and connectors. I tested it and it performed just as well as the Bluetooth Mate. It has a slightly smaller range, specially because of wall. But unlike the Bluetooth Mate, this module always connected to the Android application. I can tell you that for this project, the MDFLY module does the job perfectly.

MDFLY

http://www.mdfly.com/index.php?main_page=product_info&cPath=&products_id=769&zenid=d7vpt46igk3b54fin3rid873c1


The Arduino Code:

NOTE:

Before uploading the program onto the Arduino, make sure the Bluetooth module is not connected to the Arduino. This may cause a sync issue. Just disconnect the wires connecting  the Arduino and module's RX and TX pins.

Be aware that these two programs makes use of a library. It makes the program much cleaner. Once you download the folder with the program, you will find a folder named "MotorShieldR3". This folder needs to be placed in the Arduino's "libraries" folder. The "libraries" folder can be found in the same directory as the Arduino executable file. 

Since the application now allows you to choose between a continuous or on change data stream, there are two different versions of the Arduino code. They are not very different from one another. 

RC_Motor_Shield_Continuous.ino

The first program makes use of the continuous data stream to detect, and stop the car when it has lost connection to the phone. Because of this continuous stream of characters, it also needs to filter repeated characters. The program is called "RC_Motor_Shield_Continuous.ino". It uses the "millis()" function which returns the number of milliseconds since the Arduino's execution started. This function lets the Arduino know when 500 milliseconds have elapsed since the last command was received. Once 500 milliseconds have gone by without receiving a command, the Arduino stops the car and turns it front and back lights off:

/*
  Front Motor (Steering) => Channel A
  Back Motor => Channel B
 
  Since the motor shield hijacks 6 pins for the motors'
  control, they are declared in the MotorShieldR3 library.
*/
#include <MotorShieldR3.h>
MotorShieldR3 yellowCar;
#define pinfrontLights    7    //Pin that activates the Front lights.
#define pinbackLights     4    //Pin that activates the Back lights.  
char command = 'S';
char prevCommand = 'A';
int velocity = 0;  
unsigned long timer0 = 2000;  //Stores the time (in millis since execution started)
unsigned long timer1 = 0;  //Stores the time when the last command was received from the phone

void setup()
{      
  Serial.begin(9600);  //Set the baud rate to that of your Bluetooth module.
  pinMode(pinfrontLights , OUTPUT);
  pinMode(pinbackLights , OUTPUT);
}

void loop(){
  if(Serial.available() > 0){
    timer1 = millis();  
    prevCommand = command;
    command = Serial.read();
    //Change pin mode only if new command is different from previous.  
    if(command!=prevCommand){
      //Serial.println(command);
      switch(command){
      case 'F': 
        yellowCar.Forward_4W(velocity);
        break;
      case 'B': 
        yellowCar.Back_4W(velocity);
        break;
      case 'L': 
        yellowCar.Left_4W();
        break;
      case 'R':
        yellowCar.Right_4W(); 
        break;
      case 'S': 
        yellowCar.Stopped_4W();
        break;
      case 'I':  //FR 
        yellowCar.ForwardRight_4W(velocity);
        break;
      case 'J':  //BR 
        yellowCar.BackRight_4W(velocity);
        break;       
      case 'G':  //FL 
        yellowCar.ForwardLeft_4W(velocity);
        break;
      case 'H':  //BL
        yellowCar.BackLeft_4W(velocity);
        break;
      case 'W':  //Font ON
        digitalWrite(pinfrontLights, HIGH);
        break;
      case 'w':  //Font OFF
        digitalWrite(pinfrontLights, LOW);
        break;
      case 'U':  //Back ON
        digitalWrite(pinbackLights, HIGH);
        break;
      case 'u':  //Back OFF
        digitalWrite(pinbackLights, LOW);
        break;
      case 'D':  //Everything OFF
        digitalWrite(pinfrontLights, LOW);
        digitalWrite(pinbackLights, LOW);
        yellowCar.Stopped_4W();
        break;        
      default:  //Get velocity
        if(command=='q'){
          velocity = 255;  //Full velocity
          yellowCar.SetSpeed_4W(velocity);
        }
        else{
          //Chars '0' - '9' have an integer equivalence of 48 - 57, accordingly.
          if((command >= 48) && (command <= 57)){
            //Subtracting 48 changes the range from 48-57 to 0-9.
            //Multiplying by 25 changes the range from 0-9 to 0-225.
            velocity = (command - 48)*25;      
            yellowCar.SetSpeed_4W(velocity);
          }
        }
      }
    }
  }
  else{
    timer0 = millis();  //Get the current time (millis since execution started).
    //Check if it has been 500ms since we received last command.
    if((timer0 - timer1)>500){ 
      //More tan 500ms have passed since last command received, car is out of range.
      //Therefore stop the car and turn lights off.
      digitalWrite(pinfrontLights, LOW);
      digitalWrite(pinbackLights, LOW);
      yellowCar.Stopped_4W();
    }
  } 
}


RC_Motor_Shield_OnChange

The program seen bellow is a copy of the one above. The one differences you'll notice have to do with the lines of code that check for disconnection, and repeated commands. Everything else is identical:

/*
  Front Motor (Steering) => Channel A
 Back Motor => Channel B
 
 Since the motor shield hijacks 6 pins for the motors'
 control, they are declared in the MotorShieldR3 library.
 */
#include <MotorShieldR3.h>
MotorShieldR3 yellowCar;
#define pinfrontLights    7    //Pin that activates the Front lights.
#define pinbackLights     4    //Pin that activates the Back lights.  
char command = 'S';
int velocity = 0;  

void setup()
{      
  Serial.begin(115200);  //Set the baud rate to that of your Bluetooth module.
  pinMode(pinfrontLights , OUTPUT);
  pinMode(pinbackLights , OUTPUT);
}

void loop(){
  if(Serial.available() > 0){
    command = Serial.read();
    //Change pin mode only if new command is different from previous.  
    //Serial.println(command);
    switch(command){
    case 'F': 
      yellowCar.Forward_4W(velocity);
      break;
    case 'B': 
      yellowCar.Back_4W(velocity);
      break;
    case 'L': 
      yellowCar.Left_4W();
      break;
    case 'R':
      yellowCar.Right_4W(); 
      break;
    case 'S': 
      yellowCar.Stopped_4W();
      break;
    case 'I':  //FR 
      yellowCar.ForwardRight_4W(velocity);
      break;
    case 'J':  //BR 
      yellowCar.BackRight_4W(velocity);
      break;       
    case 'G':  //FL 
      yellowCar.ForwardLeft_4W(velocity);
      break;
    case 'H':  //BL
      yellowCar.BackLeft_4W(velocity);
      break;
    case 'W':  //Font ON
      digitalWrite(pinfrontLights, HIGH);
      break;
    case 'w':  //Font OFF
      digitalWrite(pinfrontLights, LOW);
      break;
    case 'U':  //Back ON
      digitalWrite(pinbackLights, HIGH);
      break;
    case 'u':  //Back OFF
      digitalWrite(pinbackLights, LOW);
      break;
    case 'D':  //Everything OFF
      digitalWrite(pinfrontLights, LOW);
      digitalWrite(pinbackLights, LOW);
      yellowCar.Stopped_4W();
      break;        
    default:  //Get velocity
      if(command=='q'){
        velocity = 255;  //Full velocity
        yellowCar.SetSpeed_4W(velocity);
      }
      else{
        //Chars '0' - '9' have an integer equivalence of 48 - 57, accordingly.
        if((command >= 48) && (command <= 57)){
          //Subtracting 48 changes the range from 48-57 to 0-9.
          //Multiplying by 25 changes the range from 0-9 to 0-225.
          velocity = (command - 48)*25;      
          yellowCar.SetSpeed_4W(velocity);
        }
      }
    }
  }
}


Remember that these programs only works for an RC car with two DC motors. In case your car uses a servo, you need to make modifications to it or use the joystick application..



1.Parts needed and the Arduino motor shield
2.The Front and Back LEDs
3.Bluetooth modules and Arduino code
4.Putting it all together and the Android Application
5.A More Complex Circuit
6.Joystick Control
ċ
RC_Motor_Shield_Continuous.zip
(6k)
Bluetooth Rc,
Aug 4, 2014, 5:40 PM
ċ
RC_Motor_Shield_OnChange.zip
(5k)
Bluetooth Rc,
Aug 4, 2014, 5:40 PM
Comments