Project 12 Bluetooth Control Smart Car

1.Description

There is a DX-BT24 5.1 Bluetooth module in this kit. This Bluetooth module comes with 256Kb space and complies with V5.1 BLE Bluetooth specification, which supports AT commands. Users can change parameters such as the baud rate and device name of the serial port as required.
Furthermore, it supports UART interface and Bluetooth serial port transparent transmission, which also contains the advantages of low cost, small size, low power consumption and high sensitivity for sending and receiving. Notably, it solely needs a few peripheral components to realize its powerful functions.
In this project, we will use the BT24 Bluetooth module to combine all modules of the car in one code, which contains all functions except IR remote control mentioned in the previous projects. We plan to use mobile APP to connect Bluetooth module, so as to control various functions, which is distinctly simple and convenient.
We will work to read the control characters sent by each button through the Bluetooth connection of the APP.
2.Parameters
Bluetooth protocol: Bluetooth Specification V5.1 BLE
Working frequency:2.4GHz ISM band
Communication interface: UART
Power supply:5V/3.3V
Communication distance: 40m
Dimension:27(L)mm x 13 (W)mm x 2(H) mm
Bluetooth name:BT24
Serial port parameters:9600、eight data bits, one stop bit, no check, no flow control
Working temperature: MIN:-40℃- MAX:+85℃
The DX-BT24 module also supports the BT5.1 BLE protocol, which can be directly connected to iOS devices with BLE Bluetooth function, and supports resident running of background programs. It is mainly used in the field of short-distance data wireless transmission. It enables to avoid cumbersome cable connections and can directly replace serial cables. Successful application areas of BT24 modules:

※ Bluetooth wireless data transmission;
※ Mobile phone, computer peripheral equipment;
※ Handheld POS equipment;
※ Wireless data transmission of medical equipment;
※ Smart home control;
※ Bluetooth printer;
※ Bluetooth remote control toys;
※ Shared bicycles;
Ports
①STATE: Status pin
②RX: Receiving pin
③TX: sending pin
④GND:GND
⑤VCC: Power
⑥EN: Enable pin
Connect the BT module to the development board.
Uno |
BT24 |
|---|---|
TX |
RX |
RX |
TX |
VCC |
5V |
GND |
GND |
3.APP
Please download the app here.

4.Test Code
void setup()
{
Serial.begin(9600);//Start the serial monitor and set the baud rate to 9600
}
void loop()
{
if (Serial.available())//If the receiving area is not empty
{
char ble_val = Serial.read();//Read the data of the bluetooth
Serial.println(ble_val);//The serial monitor prints the read data
}
}
5.Test Result
After uploading the code, plug in the Bluetooth, be careful not to plug it upside down. Connect the Bluetooth module and turn on the serial monitor.
Aim at the Bluetooth module and press the APP button of the mobile phone. We can see the corresponding control characters of the APP button, as shown below.

6.Code Explanation
Serial1.begin(9600); //Set the baud rate of the Bluetooth serial port to 9600. (Serial port 0 corresponds to Serial1, serial port 1 corresponds to Serial2 ).
Serial1.available(); //If Bluetooth data is received, this value is not 0.
char ble_val = Serial1.read(); //Read Bluetooth serial port data and define a variable of type char to save.
Serial.println(ble_val);
Serial1.println(ble_val);
// Upper : output to serial monitor;Lower: output data to Bluetoot module.
Serial1.readStringUntil('#'); //Read the Bluetooth strings, stop reading if "#" appears, note that we use two consecutive such statements, because when we adjust speed, sending strings such as V# 50#, we first read is "V" (#,then stop), the second read is"50", read here is string instead of an integer value.
String(speed_str).toInt(); // Convert the numeric string read to an integer value.
map(speed_Upper_L, 0, 100, 0, 255); //Since the speed value we send on our APP is 0~100, we have to map it to 0~ 255.
speed_Upper_L
speed_Lower_L
speed_Upper_R
speed_Lower_R //Represents the speed values of the four motors.Range is 0~255
7.Comprehensive Project APP Control Smart Car
#include "MecanumCar_v2.h"
#include <Adafruit_NeoPixel.h>
#include "Servo.h"
mecanumCar mecanumCar(3, 2); //sda-->D3,scl-->D2
//Creat a class called rgb_2812 to control rgb,there are four LEDs and the pins are connected to D10
Adafruit_NeoPixel rgb_2812 = Adafruit_NeoPixel(4, 10, NEO_GRB + NEO_KHZ800);
Servo myservo;
/*******Ultrasonic Sensor interface*****/
#define EchoPin 13 //ECHO to D13
#define TrigPin 12 //TRIG to D12
/********Define the pin of line tracking sensor**********/
#define SensorLeft A0 //input pin of left sensor
#define SensorMiddle A1 //input pin of middle sensor
#define SensorRight A2 //input pin of right sensor
String speed_str1 = "0";
String speed_str2 = "0";
int color_num = 0;
char ble_val;
void setup() {
Serial.begin(9600); //Set the Bluetooth string baud rate to 9600
pinMode(EchoPin, INPUT); //The ECHO pin is set to input mode
pinMode(TrigPin, OUTPUT); //The TRIG pin is set to output mode
/****All interfaces of the line tracking sensor are set to input mode***/
pinMode(SensorLeft, INPUT);
pinMode(SensorMiddle, INPUT);
pinMode(SensorRight, INPUT);
myservo.attach(9); // attaches the servo on D9 to the servo object
myservo.write(90);
delay(500);
rgb_2812.begin(); //Start rgb2818
rgb_2812.setBrightness(255); //Initialize the brightness(0~255)
rgb_2812.show(); //Initializing a refresh
mecanumCar.Init(); //Initialize the seven-color LED and motor drive
}
void loop() {
if (Serial.available())//If the receiving area is not empty
{
ble_val = Serial.read();//Read the data of the bluetooth
Serial.println(ble_val);//The serial monitor prints the read data
switch (ble_val)
{
/*********************The car driving************************/
case 's': mecanumCar.Stop(); break; //Stop
case 'a': mecanumCar.Advance(); break; //Go ahead
case 'c': mecanumCar.Back(); break; //Move back
case 'b': mecanumCar.Turn_Left(); break; //Turn left
case 'd': mecanumCar.Turn_Right(); break; //Turn right
case 'k': mecanumCar.L_Move(); break; //Left shift
case 'h': mecanumCar.R_Move(); break; //Right shift
case 'l': mecanumCar.LU_Move(); break; //Upper left move
case 'j': mecanumCar.LD_Move(); break; //lower left move
case 'g': mecanumCar.RU_Move(); break; //Upper right move
case 'i': mecanumCar.RD_Move(); break; //lower right move
case 'e': mecanumCar.drift_left(); break; //Drift
case 'f': mecanumCar.drift_right(); break; //Drift
case 'p': Line_Tracking(); break; //Tracking
case 'q': ult_following(); break; //Follow
case 'r': ult_avoiding(); break; //Obstacle Avoidance
/*********************The light of the car*************************/
case 't': mecanumCar.right_led(1); mecanumCar.left_led(1); break; //Open the 7-color LED
case 'u': mecanumCar.right_led(0); mecanumCar.left_led(0); break; //Close the 7-color LED
case 'm': color_num++; showColor(); break; //Switching the color of 2812 LED
case 'o': rgb_2812.clear(); rgb_2812.show(); break; //Close the 2812 LED
case 'n': color_num--; showColor(); break; //Switching the color of 2812 LED
/*********************The car changes speed**************************/
case 'v': /*Read left front motor M2 speed*/
speed_str1=Serial.readStringUntil('#'); //Save the speed data read for the first time
speed_str2 = Serial.readStringUntil('#'); //Save the speed data read for the second time
speed_Upper_L = String(speed_str2).toInt(); //The speed value is a string and needs to be converted to an integer
speed_Upper_L = map(speed_Upper_L, 0, 100, 0, 255); //Mapping from 0 to 100 to 0 to 255
//Serial.println(speed_Upper_L); //Serial debugging
break;
case 'w': /*Read left rear M3 motor speed*/
speed_str1=Serial.readStringUntil('#');
speed_str2 = Serial.readStringUntil('#');
speed_Lower_L = String(speed_str2).toInt();
speed_Lower_L = map(speed_Lower_L, 0, 100, 0, 255);
//Serial.println(speed_Lower_L);
break;
case 'x': /*Read right front M1 motor speed*/
speed_str1=Serial.readStringUntil('#');
speed_str2 = Serial.readStringUntil('#');
speed_Upper_R = String(speed_str2).toInt();
speed_Upper_R = map(speed_Upper_R, 0, 100, 0, 255);
//Serial.println(speed_Upper_R);
break;
case 'y': /*Read right rear M4 motor speed*/
speed_str1=Serial.readStringUntil('#');
speed_str2 = Serial.readStringUntil('#');
speed_Lower_R = String(speed_str2).toInt();
speed_Lower_R = map(speed_Lower_R, 0, 100, 0, 255);
//Serial.println(speed_Lower_R);
break;
default: break;
}
}
}
/*********************RGB2812 display*******************************/
void showColor() {
// Serial.print("color num:"); //Serial debugging
// Serial.println(color_num);
// There are only 7 colors, you can add them yourself
if (color_num > 6)color_num = 0;
if (color_num < 0)color_num = 6;
switch (color_num) {
case 0:
for (int i = 0; i < 4; i++) {
rgb_2812.setPixelColor(i, 255, 0, 0); //The iLED is red
}
break;
case 1:
for (int i = 0; i < 4; i++) {
rgb_2812.setPixelColor(i, 255, 80, 0); //The iLED is orange
}
break;
case 2:
for (int i = 0; i < 4; i++) {
rgb_2812.setPixelColor(i, 255, 255, 0); //The iLED is yellow
}
break;
case 3:
for (int i = 0; i < 4; i++) {
rgb_2812.setPixelColor(i, 0, 255, 0); //The iLED is green
}
break;
case 4:
for (int i = 0; i < 4; i++) {
rgb_2812.setPixelColor(i, 0, 0, 255); //he iLED is blue
}
break;
case 5:
for (int i = 0; i < 4; i++) {
rgb_2812.setPixelColor(i, 0, 255, 255); //The iLED is indigo
}
break;
case 6:
for (int i = 0; i < 4; i++) {
rgb_2812.setPixelColor(i, 160, 32, 240);//The iLED is purple
}
break;
default : break;
}
rgb_2812.show(); //Refresh display
}
/*********************Line Tracking*******************************/
void Line_Tracking(void) { //Tracking black line
while (1)
{
uint8_t SL = digitalRead(SensorLeft); //Read the value of the left line tracking sensor
uint8_t SM = digitalRead(SensorMiddle); //Read the value of the middle line tracking sensor
uint8_t SR = digitalRead(SensorRight); //Read the value of the right line tracking sensor
if (SM == HIGH) {
if (SL == LOW && SR == HIGH) { // black on right, white on left, turn right
mecanumCar.Turn_Right();
}
else if (SR == LOW && SL == HIGH) { // black on left, white on right, turn left
mecanumCar.Turn_Left();
}
else { // white on both sides, going forward
mecanumCar.Advance();
}
}
else {
if (SL == LOW && SR == HIGH) { // black on right, white on left, turn right
mecanumCar.Turn_Right();
}
else if (SR == LOW && SL == HIGH) { // white on right, black on left, turn left
mecanumCar.Turn_Left();
}
else { // all white, stop
mecanumCar.Stop();
}
}
if (Serial.available())//If the receiving area is not empty
{
ble_val = Serial.read();//Read Bluetooth data
if (ble_val == 's') {
mecanumCar.Stop();
break;
}
}
}
}
/*********************Ultrasonic Following*******************************/
void ult_following(void)
{
while (1)
{
int distance = get_distance(); //Get the distance and save in the distance variable
//Serial.println(distance);
if (distance <= 15) //The range of moving back
{
mecanumCar.Back();
}
else if (distance <= 25) //The range of stop
{
mecanumCar.Stop();
}
else if (distance <= 45) //The range of advance
{
mecanumCar.Advance();
}
else //Other cases stop
{
mecanumCar.Stop();
}
if (Serial.available())//If the receiving area is not empty
{
ble_val = Serial.read();//Read Bluetooth data
if (ble_val == 's') {
mecanumCar.Stop();
break;
}
}
}
}
/*********************Ultrasonic obstacle avoidance*******************************/
void ult_avoiding(void)
{
int distance_M, distance_L, distance_R;
while (1)
{
distance_M = get_distance(); //Get the distance and save in the distance variable
if (distance_M < 20) {//When the distance in front is less than 20cm
mecanumCar.Stop(); //Robot stops
delay(500); //Delay in 500ms
myservo.write(180); //Ultrasonic cradle head turns left
delay(500); //Delay in 500ms
distance_L = get_distance(); //Assign the left ultrasonic distance to variable a1
delay(100); //Read values when stable
myservo.write(0); //Ultrasonic cradle head turns right
delay(500); //Delay in 500ms
distance_R = get_distance(); //Assign the right ultrasonic distance to variable a2
delay(100); //Read values when stable
myservo.write(90); //Return to the 90 degree position
delay(500);
if (distance_L > distance_R) { //When the distance on the left is greater than right
mecanumCar.Turn_Left(); //Robot turns left
delay(300); //Turn left 700ms
} else {
mecanumCar.Turn_Right(); //Robot turns right
delay(300);
}
}
else { //If the distance in front is >=20cm, the robot will advance
mecanumCar.Advance(); //Advance
}
if (Serial.available())//If the receiving area is not empty
{
ble_val = Serial.read();//Read Bluetooth data
if (ble_val == 's') {
mecanumCar.Stop();
break;
}
}
}
}
/**********************Ultrasonic detects the distance*******************************/
int get_distance(void) { //Ultrasonic detects the distance
int dis;
digitalWrite(TrigPin, LOW);
delayMicroseconds(2);
digitalWrite(TrigPin, HIGH); //Give the TRIG a high level at least 10 µ s to trigger
delayMicroseconds(10);
digitalWrite(TrigPin, LOW);
dis = pulseIn(EchoPin, HIGH) / 58.2; //Work out the distance
delay(30);
return dis;
}
After uploading the code successfully, turn the DIP switch to the ON end and powerup, plug in the bluetooth, then connect it to BT24. We can do the following operations:
Click
to open the 7-color LED, click it again the LED will be turned off.
Click
to enter tracking mode, click it again will exit the mode.
Click
to enter follow mode, click it again will exit the mode.
Click
to enter obstacle avoidance mode, click it again will exit the mode.
Pulling these two strips will change the speed of the two motors on the left and the same operation on the right.
These buttons are used to switch the color of the four 2812 LEDs under the base board, and the middle button is used to close the function.
The rest of the buttons are all used to drive the car, but unlike the other buttons, they drive when we press them and stop when we release them.
