In this tutorial, we will guide you on building an advanced autonomous and Bluetooth-controlled car with Arduino Mega, HC-05 Bluetooth module, multiple ultrasonic sensors, and the Adafruit Motor Shield. This project covers everything from assembling the car’s chassis to programming the Arduino and developing a control app for your smartphone. By the end of this guide, you will have a fully functional robot car that can navigate autonomously and be controlled wirelessly using your Android device.
This project is an extension of our previous project “Building a Bluetooth-Controlled Robot Car with Arduino, HC-05, and Adafruit Motor Shield.” It adds more sophisticated features such as autonomous navigation using ultrasonic sensors. For more details on the basics of DC motor control with a motor shield, you can refer to this blog and for ultrasonic sensor integration, check out this blog.
Components Needed:
- Plexiglas sheet (for the chassis)
- 4 DC motors with gearboxes
- Adafruit Motor Shield V1.2
- Arduino Uno
- HC-05 Bluetooth Module
- 4 Ultrasonic sensors (HC-SR04)
- 3D-printed frame, motor mounts and Arduino holder
- Jumper wires
- Battery
- Smartphone with MIT App Inventor installed
Step 1: Building the Chassis for Your Car
To start building your Bluetooth-controlled car, we’ll create the chassis using a Plexiglas sheet. This will serve as the base to mount all the components.
- Cut the Plexiglas: Measure and cut the Plexiglas sheet to your desired dimensions for the chassis.
- 3D Print the frame and Motor Mounts: Design and print the frame and motor mounts to securely attach the DC motors to the chassis.
- 3D Print Arduino Holder: Design and print a holder to securely mount the Arduino Uno on the chassis.
Step 2: Mounting the Motors
Next, we’ll mount the DC motors as part of our Bluetooth-controlled car project.
- Attach the Motors: Use screws and nuts to secure the DC motors to the 3D-printed motor mounts.
- Mount the Motors on the Chassis: Attach the motor mounts to the Plexiglas chassis using screws and nuts.
Step 3: Mounting the Arduino and Motor Shield
Secure the Arduino Uno and the Adafruit Motor Shield as we progress in our Bluetooth-controlled car tutorial.
- Attach the Arduino Holder: Secure the 3D-printed Arduino holder to the chassis.
- Mount the Arduino: Place the Arduino Mega in the holder and secure it with screws.
- Attach the Motor Shield: Place the Adafruit Motor Shield onto the Arduino Mega, ensuring all pins are properly aligned.
Step 4: Wiring the Components
Wiring the components correctly is crucial in this Bluetooth-controlled car project.
- Connect the Motors to the Shield:
– Connect the left motors to terminals M1 and M2 on the motor shield.
– Connect the right motors to terminals M3 and M4 on the motor shield. - Connect the HC-05 Bluetooth Module:
– VCC to 5V on the Arduino.
– GND to GND on the Arduino.
– TXD to RX (Pin 0) on the Arduino.
– RXD to TX (Pin 1) on the Arduino. Connect the Ultrasonic Sensorrs:
Ultrasonic Sensor_F: Echo to pin 22, Trig to pin 23
Ultrasonic Sensor_B: Echo to pin 24, Trig to pin 25
Ultrasonic Sensor_L: Echo to pin 26, Trig to pin 27
Ultrasonic Sensor_R: Echo to pin 28, Trig to pin 29Connect the Battery Pack:
Connect the positive and negative terminals of the battery pack to the power terminals on the motor shield.
Ensure the ground is connected properly.
Step 5: Programming the Arduino for Autonomous and Bluetooth Control
Here’s the Arduino code to control the robot car using Bluetooth commands from your smartphone and autonomously using ultrasonic sensors
/** * Author: Omar Draidrya * Date: 2024/07/20 * This code controls the forward and backward movement of a motor using an H-bridge. */ #include <AFMotor.h> // Motor setup AF_DCMotor motor1(1); AF_DCMotor motor2(2); AF_DCMotor motor3(3); AF_DCMotor motor4(4); // Ultrasonic sensor pins const int trigF = 23; const int echoF = 22; const int trigL = 27; const int echoL = 26; const int trigR = 29; const int echoR = 28; const int trigB = 25; const int echoB = 24; char command; bool autonomousModeEnabled = false; // Variable to track autonomous mode // Function prototypes void handleCommand(char command); void forward(int speed = 160); void backward(int speed = 160); void turnLeft(int speed = 160); void turnRight(int speed = 160); void stop(); void autonomousMode(); int getDistance(int trigPin, int echoPin); void setup() { Serial.begin(9600); pinMode(trigF, OUTPUT); pinMode(echoF, INPUT); pinMode(trigL, OUTPUT); pinMode(echoL, INPUT); pinMode(trigR, OUTPUT); pinMode(echoR, INPUT); pinMode(trigB, OUTPUT); pinMode(echoB, INPUT); } void loop() { if (Serial.available() > 0) { command = Serial.read(); handleCommand(command); } if (autonomousModeEnabled) { autonomousMode(); } } void handleCommand(char command) { if (command == 'F') { forward(); autonomousModeEnabled = false; // Disable autonomous mode } else if (command == 'B') { backward(); autonomousModeEnabled = false; // Disable autonomous mode } else if (command == 'L') { turnLeft(); autonomousModeEnabled = false; // Disable autonomous mode } else if (command == 'R') { turnRight(); autonomousModeEnabled = false; // Disable autonomous mode } else if (command == 'S') { stop(); autonomousModeEnabled = false; // Disable autonomous mode } else if (command == 'A') { autonomousModeEnabled = true; // Enable autonomous mode } } void forward(int speed) { motor1.setSpeed(speed); motor2.setSpeed(speed); motor3.setSpeed(speed); motor4.setSpeed(speed); motor1.run(FORWARD); motor2.run(FORWARD); motor3.run(FORWARD); motor4.run(FORWARD); } void backward(int speed) { motor1.setSpeed(speed); motor2.setSpeed(speed); motor3.setSpeed(speed); motor4.setSpeed(speed); motor1.run(BACKWARD); motor2.run(BACKWARD); motor3.run(BACKWARD); motor4.run(BACKWARD); } void turnLeft(int speed) { motor1.setSpeed(speed); motor2.setSpeed(speed); motor3.setSpeed(speed); motor4.setSpeed(speed); motor1.run(BACKWARD); motor2.run(BACKWARD); motor3.run(FORWARD); motor4.run(FORWARD); } void turnRight(int speed) { motor1.setSpeed(speed); motor2.setSpeed(speed); motor3.setSpeed(speed); motor4.setSpeed(speed); motor1.run(FORWARD); motor2.run(FORWARD); motor3.run(BACKWARD); motor4.run(BACKWARD); } void stop() { motor1.run(RELEASE); motor2.run(RELEASE); motor3.run(RELEASE); motor4.run(RELEASE); } void autonomousMode() { int distanceF = getDistance(trigF, echoF); int distanceL = getDistance(trigL, echoL); int distanceR = getDistance(trigR, echoR); int distanceB = getDistance(trigB, echoB); // Prüfen, ob ein Hindernis vorne ist if (distanceF < 20) { stop(); delay(100); // Verzögerung, um sicherzustellen, dass der Roboter angehalten hat // Hindernisvermeidung if (distanceR > distanceL && distanceR > 20) { turnRight(180); delay(300); } else if (distanceL > distanceR && distanceL > 20) { turnLeft(180); delay(300); } else if (distanceB > 20) { backward(160); while (distanceB > 20) { distanceB = getDistance(trigB, echoB); distanceL = getDistance(trigL, echoL); distanceR = getDistance(trigR, echoR); if (distanceR > 20 || distanceL > 20) { stop(); delay(100); if (distanceR > distanceL) { turnRight(180); } else { turnLeft(180); } delay(300); break; } delay(100); } stop(); } else { stop(); } } else { adjustDirection(distanceL, distanceR); forward(map(distanceF, 20, 160, 64, 160)); } } void adjustDirection(int distanceL, int distanceR) { if (distanceL < 20) { turnRight(180); delay(100); forward(160); } else if (distanceR < 20) { turnLeft(180); delay(100); forward(160); } } int getDistance(int trigPin, int echoPin) { digitalWrite(trigPin, LOW); delayMicroseconds(2); digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); long duration = pulseIn(echoPin, HIGH); int distance = duration * 0.034 / 2; return distance; }
Description:
This code controls a robot with four DC motors using serial Bluetooth communication. The Arduino receives commands from a smartphone and executes corresponding movements:
- Motor Initialization: The motors are configured using the Adafruit Motor Shield library (<AFMotor.h>) with connectors M1 to M4. Each motor is initially set to full speed.
- Serial Communication: The Arduino waits for serial data from the smartphone. When a command is received, it is read and stored in the variable command.
- Command Execution: Depending on the received command (F for forward, B for backward, L for left, R for right, S for stop), the corresponding function is called to control the motors.
- Movement Functions:
forward(): All motors move forward.
backward(): All motors move backward.
turnLeft(): Left motors move backward, right motors move forward.
turnRight(): Left motors move forward, right motors move backward.
stop(): All motors stop.
Step 6: Developing the Android App for Bluetooth Control
We’ll use MIT App Inventor to create an app that will send commands to the robot via Bluetooth. To understand the basics of Arduino programming, refer to our Basics of Arduino Programming tutorial.
- Register and Log In:
Go to MIT App Inventor and log in with your Google account. - Create a New Project:
Click on “Start New Project” and name it “RobotCarControl”. - Design the User Interface:
Add a ListPicker and set the text to “Select Bluetooth Device”.
Add a BluetoothClient component from the Connectivity palette (non-visible component).
Add four buttons for control: Forward, Backward, Left, Right, and set their colors accordingly. Add a switch to toggle between manual and autonomous modes.
- Program the Blocks:
Add the following blocks to manage Bluetooth connection and send control commands.
when ListPicker1.BeforePicking set ListPicker1.Elements to BluetoothClient1.AddressesAndNames when ListPicker1.AfterPicking if call BluetoothClient1.Connect address ListPicker1.Selection then set Label1.Text to "Connected" else set Label1.Text to "Not Connected" when ButtonForward.TouchDown if BluetoothClient1.IsConnected call BluetoothClient1.SendText text "F" when ButtonBackward.TouchDown if BluetoothClient1.IsConnected call BluetoothClient1.SendText text "B" when ButtonLeft.TouchDown if BluetoothClient1.IsConnected call BluetoothClient1 .SendText text "L" when ButtonRight.TouchDown if BluetoothClient1.IsConnected call BluetoothClient1.SendText text "R" when ButtonForward.TouchUp if BluetoothClient1.IsConnected call BluetoothClient1.SendText text "S" when ButtonBackward.TouchUp if BluetoothClient1.IsConnected call BluetoothClient1.SendText text "S" when ButtonLeft.TouchUp if BluetoothClient1.IsConnected call BluetoothClient1.SendText text "S" when ButtonRight.TouchUp if BluetoothClient1.IsConnected call BluetoothClient1.SendText text "S" when ModeSwitch.Changed if ModeSwitch.On call BluetoothClient1.SendText text "A" else call BluetoothClient1.SendText text "M"
Step 7: Connecting and Testing the Robot
- Pair the Bluetooth Device:
Turn on Bluetooth on your smartphone and pair with the HC-05 module (default password is 1234). - Connect via App:
Use the app to connect to the Bluetooth module. - Use the Directional Buttons to Control the Robot:
Test the manual control by using the directional buttons. Toggle the switch to test the autonomous mode.
Conclusion
Building an advanced autonomous and Bluetooth-controlled robot car is an exciting project that combines various aspects of robotics, including motor control, ultrasonic sensors, Bluetooth communication, and mobile app development. By following this comprehensive guide, you can create a fully functional robot car that navigates autonomously and responds to commands from your smartphone. This project not only enhances your understanding of Arduino and Bluetooth modules but also provides a solid foundation for more advanced robotics projects.
Feel free to ask any questions in the comments section below and check out my other Arduino projects for more inspiration.