We will start with the Bluetooth communication, and for that purpose we need two HC-05 Bluetooth modules which need to be configured as master and slave devices.

We can easily do that by using AT commands, and I set the joystick to be a master and the Arduino robot car to be a slave. Here’s the complete circuit schematic for this example:
📷
You can get the components needed for this example from the links below:
*Please note: These are affiliate links. I may make a commission if you buy the components through these links. I would appreciate your support in this way!
Source Code
We will use the same code from the previous tutorial, where we control the Arduino robot car directly using the joystick, and we will make some modifications to it.
HC-05 Master code:
/*
Arduino Robot Car Wireless Control using the HC-05 Bluetooth
== MASTER DEVICE - Joystick ==
by Dejan Nedelkovski, www.HowToMechatronics.com
*/
int xAxis, yAxis;
void setup() {
Serial.begin(38400); // Default communication rate of the Bluetooth module
}
void loop() {
xAxis = analogRead(A0); // Read Joysticks X-axis
yAxis = analogRead(A1); // Read Joysticks Y-axis
// Send the values via the serial port to the slave HC-05 Bluetooth device
Serial.write(xAxis/4); // Dividing by 4 for converting from 0 - 1023 to 0 - 256, (1 byte) range
Serial.write(yAxis/4);
delay(20);
}
The code at the master device, or the joystick is quite simple. We just need to read the X and Y values of the joystick, which actually regulate the speed of the motors, and send them via the serial port to the slave HC-05 Bluetooth device. We can note here that the analog values of joystick from 0 to 1023 are converted into a values from 0 to 255 by diving them by 4.
We do this because that range, from 0 to 255, can be sent, over the Bluetooth device, as 1 byte which is easier to be accepted on the other side, or at the Arduino robot car.
So here, if the serial has received the 2 bytes, the X and Y values, using the Serial.read() function we will read both of them.
// Code from the Arduino Robot Car
// Read the incoming data from the Joystick, or the master Bluetooth device
while (Serial.available() >= 2) {
x = Serial.read();
delay(10);
y = Serial.read();
}
Now we just have to convert the values back to the range from 0 to 1023, suitable for the motor control code below, which we already explained how it works in the previous video.
// Code from the Arduino Robot Car
// Convert back the 0 - 255 range to 0 - 1023, suitable for motor control code below
xAxis = x*4;
yAxis = y*4;
Just a quick note that when uploading the code, we need to disconnect the RX and TX pins of the Arduino board.
Complete HC-05 Slave code:
/*
Arduino Robot Car Wireless Control using the HC-05 Bluetooth
== SLAVE DEVICE - Arduino robot car ==
by Dejan Nedelkovski, www.HowToMechatronics.com
*/
#define enA 9
#define in1 4
#define in2 5
#define enB 10
#define in3 6
#define in4 7
int xAxis, yAxis;
unsigned int x = 0;
unsigned int y = 0;
int motorSpeedA = 0;
int motorSpeedB = 0;
void setup() {
pinMode(enA, OUTPUT);
pinMode(enB, OUTPUT);
pinMode(in1, OUTPUT);
pinMode(in2, OUTPUT);
pinMode(in3, OUTPUT);
pinMode(in4, OUTPUT);
Serial.begin(38400); // Default communication rate of the Bluetooth module
}
void loop() {
// Default value - no movement when the Joystick stays in the center
x = 510 / 4;
y = 510 / 4;
// Read the incoming data from the Joystick, or the master Bluetooth device
while (Serial.available() >= 2) {
x = Serial.read();
delay(10);
y = Serial.read();
}
delay(10);
// Convert back the 0 - 255 range to 0 - 1023, suitable for motor control code below
xAxis = x*4;
yAxis = y*4;
// Y-axis used for forward and backward control
if (yAxis < 470) {
// Set Motor A backward
digitalWrite(in1, HIGH);
digitalWrite(in2, LOW);
// Set Motor B backward
digitalWrite(in3, HIGH);
digitalWrite(in4, LOW);
// Convert the declining Y-axis readings for going backward from 470 to 0 into 0 to 255 value for the PWM signal for increasing the motor speed
motorSpeedA = map(yAxis, 470, 0, 0, 255);
motorSpeedB = map(yAxis, 470, 0, 0, 255);
}
else if (yAxis > 550) {
// Set Motor A forward
digitalWrite(in1, LOW);
digitalWrite(in2, HIGH);
// Set Motor B forward
digitalWrite(in3, LOW);
digitalWrite(in4, HIGH);
// Convert the increasing Y-axis readings for going forward from 550 to 1023 into 0 to 255 value for the PWM signal for increasing the motor speed
motorSpeedA = map(yAxis, 550, 1023, 0, 255);
motorSpeedB = map(yAxis, 550, 1023, 0, 255);
}
// If joystick stays in middle the motors are not moving
else {
motorSpeedA = 0;
motorSpeedB = 0;
}
// X-axis used for left and right control
if (xAxis < 470) {
// Convert the declining X-axis readings from 470 to 0 into increasing 0 to 255 value
int xMapped = map(xAxis, 470, 0, 0, 255);
// Move to left - decrease left motor speed, increase right motor speed
motorSpeedA = motorSpeedA - xMapped;
motorSpeedB = motorSpeedB + xMapped;
// Confine the range from 0 to 255
if (motorSpeedA < 0) {
motorSpeedA = 0;
}
if (motorSpeedB > 255) {
motorSpeedB = 255;
}
}
if (xAxis > 550) {
// Convert the increasing X-axis readings from 550 to 1023 into 0 to 255 value
int xMapped = map(xAxis, 550, 1023, 0, 255);
// Move right - decrease right motor speed, increase left motor speed
motorSpeedA = motorSpeedA + xMapped;
motorSpeedB = motorSpeedB - xMapped;
// Confine the range from 0 to 255
if (motorSpeedA > 255) {
motorSpeedA = 255;
}
if (motorSpeedB < 0) {
motorSpeedB = 0;
}
}
// Prevent buzzing at low speeds (Adjust according to your motors. My motors couldn't start moving if PWM value was below value of 70)
if (motorSpeedA < 70) {
motorSpeedA = 0;
}
if (motorSpeedB < 70) {
motorSpeedB = 0;
}
analogWrite(enA, motorSpeedA); // Send PWM signal to motor A
analogWrite(enB, motorSpeedB); // Send PWM signal to motor B
}
Arduino Robot Car Control Using a Smartphone and a Custom-build Android App
Next, let’s see how we can control our Arduino robot car using a custom-build Android app. The circuit schematic of the robot car is exactly the same as the previous example, with the HC-05 Bluetooth mode set as a slave device.
📷
On the other hand, using the MIT App Inventor online application we will build our own Android app, and here’s how it looks.
So basically the app simulates a joystick, which appearance is made out of two images, or image sprites.
📷
If we take a look at the blocks of this app, we can see that when the joystick sprite is dragged, the image of the joystick ball is moved to the current location of our finger, and at the same time we send the X and Y values over the Bluetooth to the Arduino car.📷
These values are accepted by the Arduino in the same way as in the previous example, using the Serial.read function.
// Read the incoming data from the Smartphone Android App
while (Serial.available() >= 2) {
x = Serial.read();
delay(10);
y = Serial.read();
}
What we need to do additionally here is to convert the received X and Y values from the smartphone into the 0 to 1023 range, suitable for the motor control code below. These values depend of the canvas size, and the X and Y values I was getting from my app were from 60 to 220, which using the map() function I easily converted them.
// Makes sure we receive corrent values
if (x > 60 & x < 220) {
xAxis = map(x, 220, 60, 1023, 0); // Convert the smartphone X and Y values to 0 - 1023 range, suitable motor for the motor control code below
}
if (y > 60 & y < 220) {
yAxis = map(y, 220, 60, 0, 1023);
}
At the application blocks, we can also see that when the image sprite is touched up the joystick ball moves back to the center of the canvas and appropriate values are sent to the car in order stop moving. You can find and download this app on the website article, as well as, the two images of the joystick so you can build your own or modify this app.
Your can download the Android App below, as well as the two images for the joystick:
📷Arduino_Robot_Car_Joystick_App.apk 1.62 MBDownload📷Arduino_Robot_Car_Joystick_App_aia_file 171.20 KBDownload📷Joystick App Images 44.36 KBDownload
Complete Arduino code:
/*
Arduino Robot Car Wireless Control using the HC-05 Bluetooth and custom-build Android app
== SLAVE DEVICE - Arduino robot car ==
by Dejan Nedelkovski, www.HowToMechatronics.com
*/
#define enA 9
#define in1 4
#define in2 5
#define enB 10
#define in3 6
#define in4 7
int xAxis, yAxis;
int x = 0;
int y = 0;
int motorSpeedA = 0;
int motorSpeedB = 0;
void setup() {
pinMode(enA, OUTPUT);
pinMode(enB, OUTPUT);
pinMode(in1, OUTPUT);
pinMode(in2, OUTPUT);
pinMode(in3, OUTPUT);
pinMode(in4, OUTPUT);
Serial.begin(38400); // Default communication rate of the Bluetooth module
}
void loop() {
// Default value - no movement when the Joystick stays in the center
xAxis = 510;
yAxis = 510;
// Read the incoming data from the Smartphone Android App
while (Serial.available() >= 2) {
x = Serial.read();
delay(10);
y = Serial.read();
}
delay(10);
// Makes sure we receive corrent values
if (x > 60 & x < 220) {
xAxis = map(x, 220, 60, 1023, 0); // Convert the smartphone X and Y values to 0 - 1023 range, suitable motor for the motor control code below
}
if (y > 60 & y < 220) {
yAxis = map(y, 220, 60, 0, 1023);
}
// Y-axis used for forward and backward control
if (yAxis < 470) {
// Set Motor A backward
digitalWrite(in1, HIGH);
digitalWrite(in2, LOW);
// Set Motor B backward
digitalWrite(in3, HIGH);
digitalWrite(in4, LOW);
// Convert the declining Y-axis readings for going backward from 470 to 0 into 0 to 255 value for the PWM signal for increasing the motor speed
motorSpeedA = map(yAxis, 470, 0, 0, 255);
motorSpeedB = map(yAxis, 470, 0, 0, 255);
}
else if (yAxis > 550) {
// Set Motor A forward
digitalWrite(in1, LOW);
digitalWrite(in2, HIGH);
// Set Motor B forward
digitalWrite(in3, LOW);
digitalWrite(in4, HIGH);
// Convert the increasing Y-axis readings for going forward from 550 to 1023 into 0 to 255 value for the PWM signal for increasing the motor speed
motorSpeedA = map(yAxis, 550, 1023, 0, 255);
motorSpeedB = map(yAxis, 550, 1023, 0, 255);
}
// If joystick stays in middle the motors are not moving
else {
motorSpeedA = 0;
motorSpeedB = 0;
}
// X-axis used for left and right control
if (xAxis < 470) {
// Convert the declining X-axis readings from 470 to 0 into increasing 0 to 255 value
int xMapped = map(xAxis, 470, 0, 0, 255);
// Move to left - decrease left motor speed, increase right motor speed
motorSpeedA = motorSpeedA - xMapped;
motorSpeedB = motorSpeedB + xMapped;
// Confine the range from 0 to 255
if (motorSpeedA < 0) {
motorSpeedA = 0;
}
if (motorSpeedB > 255) {
motorSpeedB = 255;
}
}
if (xAxis > 550) {
// Convert the increasing X-axis readings from 550 to 1023 into 0 to 255 value
int xMapped = map(xAxis, 550, 1023, 0, 255);
// Move right - decrease right motor speed, increase left motor speed
motorSpeedA = motorSpeedA + xMapped;
motorSpeedB = motorSpeedB - xMapped;
// Confine the range from 0 to 255
if (motorSpeedA > 255) {
motorSpeedA = 255;
}
if (motorSpeedB < 0) {
motorSpeedB = 0;
}
}
// Prevent buzzing at low speeds (Adjust according to your motors. My motors couldn't start moving if PWM value was below value of 70)
if (motorSpeedA < 70) {
motorSpeedA = 0;
}
if (motorSpeedB < 70) {
motorSpeedB = 0;
}
analogWrite(enA, motorSpeedA); // Send PWM signal to motor A
analogWrite(enB, motorSpeedB); // Send PWM signal to motor B
}
Arduino Robot Car Wireless Control Using NRF24L01 Transceiver Module
Now we can move on to the next method, wireless control of the Arduino robot car using the NRF24L01 transceiver modules.
📷
Here’s the circuit schematic. We can note that these modules use the SPI communication, so compared to the previous example, I had the move the Enable A and Enable B pins of the L298N driver to the pins number 2 and 3 of the Arduino board.📷You can get the NRF24L01 module on the following Amazon link.
Source Code
For this example we need to install the RF24 library. In a similar way to the previous example, after defining some pins and setting up the module as a transmitter, we read the X and Y values of the joystick and send them to the other NRF24L01 module at the Arduino robot car.
First we can note that analog readings are Strings, which using the string.toCharArray() function are put into a character array. Then using the radio.write() function we send that character array data to the other module.
Transmitter code:
/*
Arduino Robot Car Wireless Control using the NRF24L01 Transceiver module
== Transmitter - Joystick ==
by Dejan Nedelkovski, www.HowToMechatronics.com
Library: TMRh20/RF24, https://github.com/tmrh20/RF24/
*/
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(8, 9); // CE, CSN
const byte address[6] = "00001";
char xyData[32] = "";
String xAxis, yAxis;
void setup() {
Serial.begin(9600);
radio.begin();
radio.openWritingPipe(address);
radio.setPALevel(RF24_PA_MIN);
radio.stopListening();
}
void loop() {
xAxis = analogRead(A0); // Read Joysticks X-axis
yAxis = analogRead(A1); // Read Joysticks Y-axis
// X value
xAxis.toCharArray(xyData, 5); // Put the String (X Value) into a character array
radio.write(&xyData, sizeof(xyData)); // Send the array data (X value) to the other NRF24L01 modile
// Y value
yAxis.toCharArray(xyData, 5);
radio.write(&xyData, sizeof(xyData));
delay(20);
}
On the other side. at the Arduino robot car, after defining the module as receiver, we accept data using the radio.read() function. Then using the atoi() function we convert the received data, or the X and Y values from the joystick, into integer values, which are suitable for the motor control code below.
// Code from the Arduino Robot Car - NRF24L01 example
if (radio.available()) { // If the NRF240L01 module received data
radio.read(&receivedData, sizeof(receivedData)); // Read the data and put it into character array
xAxis = atoi(&receivedData[0]); // Convert the data from the character array (received X value) into integer
delay(10);
radio.read(&receivedData, sizeof(receivedData));
yAxis = atoi(&receivedData[0]);
delay(10);
}
It’s that simple, but of course as I already said, if you need more details how to connect and setup the modules, you can always check my particular tutorial for it.
Receiver code:
/*
Arduino Robot Car Wireless Control using the NRF24L01 Transceiver module
== Receiver - Arduino robot car ==
by Dejan Nedelkovski, www.HowToMechatronics.com
Library: TMRh20/RF24, https://github.com/tmrh20/RF24/
*/
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#define enA 2 // Note: Pin 9 in previous video ( pin 10 is used for the SPI communication of the NRF24L01)
#define in1 4
#define in2 5
#define enB 3 // Note: Pin 10 in previous video
#define in3 6
#define in4 7
RF24 radio(8, 9); // CE, CSN
const byte address[6] = "00001";
char receivedData[32] = "";
int xAxis, yAxis;
int motorSpeedA = 0;
int motorSpeedB = 0;
void setup() {
pinMode(enA, OUTPUT);
pinMode(enB, OUTPUT);
pinMode(in1, OUTPUT);
pinMode(in2, OUTPUT);
pinMode(in3, OUTPUT);
pinMode(in4, OUTPUT);
Serial.begin(9600);
radio.begin();
radio.openReadingPipe(0, address);
radio.setPALevel(RF24_PA_MIN);
radio.startListening();
}
void loop() {
if (radio.available()) { // If the NRF240L01 module received data
radio.read(&receivedData, sizeof(receivedData)); // Read the data and put it into character array
xAxis = atoi(&receivedData[0]); // Convert the data from the character array (received X value) into integer
delay(10);
radio.read(&receivedData, sizeof(receivedData));
yAxis = atoi(&receivedData[0]);
delay(10);
}
// Y-axis used for forward and backward control
if (yAxis < 470) {
// Set Motor A backward
digitalWrite(in1, HIGH);
digitalWrite(in2, LOW);
// Set Motor B backward
digitalWrite(in3, HIGH);
digitalWrite(in4, LOW);
// Convert the declining Y-axis readings for going backward from 470 to 0 into 0 to 255 value for the PWM signal for increasing the motor speed
motorSpeedA = map(yAxis, 470, 0, 0, 255);
motorSpeedB = map(yAxis, 470, 0, 0, 255);
}
else if (yAxis > 550) {
// Set Motor A forward
digitalWrite(in1, LOW);
digitalWrite(in2, HIGH);
// Set Motor B forward
digitalWrite(in3, LOW);
digitalWrite(in4, HIGH);
// Convert the increasing Y-axis readings for going forward from 550 to 1023 into 0 to 255 value for the PWM signal for increasing the motor speed
motorSpeedA = map(yAxis, 550, 1023, 0, 255);
motorSpeedB = map(yAxis, 550, 1023, 0, 255);
}
// If joystick stays in middle the motors are not moving
else {
motorSpeedA = 0;
motorSpeedB = 0;
}
// X-axis used for left and right control
if (xAxis < 470) {
// Convert the declining X-axis readings from 470 to 0 into increasing 0 to 255 value
int xMapped = map(xAxis, 470, 0, 0, 255);
// Move to left - decrease left motor speed, increase right motor speed
motorSpeedA = motorSpeedA - xMapped;
motorSpeedB = motorSpeedB + xMapped;
// Confine the range from 0 to 255
if (motorSpeedA < 0) {
motorSpeedA = 0;
}
if (motorSpeedB > 255) {
motorSpeedB = 255;
}
}
if (xAxis > 550) {
// Convert the increasing X-axis readings from 550 to 1023 into 0 to 255 value
int xMapped = map(xAxis, 550, 1023, 0, 255);
// Move right - decrease right motor speed, increase left motor speed
motorSpeedA = motorSpeedA + xMapped;
motorSpeedB = motorSpeedB - xMapped;
// Confine the range from 0 to 255
if (motorSpeedA > 255) {
motorSpeedA = 255;
}
if (motorSpeedB < 0) {
motorSpeedB = 0;
}
}
// Prevent buzzing at low speeds (Adjust according to your motors. My motors couldn't start moving if PWM value was below value of 70)
if (motorSpeedA < 70) {
motorSpeedA = 0;
}
if (motorSpeedB < 70) {
motorSpeedB = 0;
}
analogWrite(enA, motorSpeedA); // Send PWM signal to motor A
analogWrite(enB, motorSpeedB); // Send PWM signal to motor B
}
Arduino Robot Car Wireless Control Using HC-12 Long Range Transceiver
For the last method of wireless control of the Arduino robot car, we will use the HC-12 long range transceiver modules. These modules can communication to each other with distances up to 1.8 km.
The circuit schematic for this example is almost the same as the one for the HC-05 Bluetooth modules, as they are using the same method for communication with the Arduino, via the serial port.
📷
You can get the HC-12 Transceiver module on the following Amazon link.
Source Code
The Joystick code is exactly the same as the one for the Bluetooth communication. We just read the analog values of the joystick and send them to the other module using the Serial.write() function.
Transmitter code:
/*
Arduino Robot Car Wireless Control using the HC-12 long range wireless module
== Transmitter - Joystick ==
by Dejan Nedelkovski, www.HowToMechatronics.com
*/
int xAxis, yAxis;
void setup() {
Serial.begin(9600); // Default communication rate of the Bluetooth module
}
void loop() {
xAxis = analogRead(A0); // Read Joysticks X-axis
yAxis = analogRead(A1); // Read Joysticks Y-axis
// Send the values via the serial port to the slave HC-05 Bluetooth device
Serial.write(xAxis/4); // Dividing by 4 for converting from 0 - 1023 to 0 - 256, (1 byte) range
Serial.write(yAxis/4);
delay(20);
}
On the other side, with the while() loop we wait until the data arrive, then read it using Serial.read() function and convert it back into the 0 to 1023 range, suitable for the motor control code below.
Receiver code:
/*
Arduino Robot Car Wireless Control using the HC-12 long range wireless module
== Receiver - Arduino robot car ==
by Dejan Nedelkovski, www.HowToMechatronics.com
*/
#define enA 9
#define in1 4
#define in2 5
#define enB 10
#define in3 6
#define in4 7
int xAxis, yAxis;
int x = 0;
int y = 0;
int motorSpeedA = 0;
int motorSpeedB = 0;
void setup() {
pinMode(enA, OUTPUT);
pinMode(enB, OUTPUT);
pinMode(in1, OUTPUT);
pinMode(in2, OUTPUT);
pinMode(in3, OUTPUT);
pinMode(in4, OUTPUT);
Serial.begin(9600); // Default communication rate of the Bluetooth module
}
void loop() {
// Default value - no movement when the Joystick stays in the center
xAxis = 510;
yAxis = 510;
// Read the incoming data from the
while (Serial.available() == 0) {}
x = Serial.read();
delay(10);
y = Serial.read();
delay(10);
// Convert back the 0 - 255 range to 0 - 1023, suitable for motor control code below
xAxis = x * 4;
yAxis = y * 4;
// Y-axis used for forward and backward control
if (yAxis < 470) {
// Set Motor A backward
digitalWrite(in1, HIGH);
digitalWrite(in2, LOW);
// Set Motor B backward
digitalWrite(in3, HIGH);
digitalWrite(in4, LOW);
// Convert the declining Y-axis readings for going backward from 470 to 0 into 0 to 255 value for the PWM signal for increasing the motor speed
motorSpeedA = map(yAxis, 470, 0, 0, 255);
motorSpeedB = map(yAxis, 470, 0, 0, 255);
}
else if (yAxis > 550) {
// Set Motor A forward
digitalWrite(in1, LOW);
digitalWrite(in2, HIGH);
// Set Motor B forward
digitalWrite(in3, LOW);
digitalWrite(in4, HIGH);
// Convert the increasing Y-axis readings for going forward from 550 to 1023 into 0 to 255 value for the PWM signal for increasing the motor speed
motorSpeedA = map(yAxis, 550, 1023, 0, 255);
motorSpeedB = map(yAxis, 550, 1023, 0, 255);
}
// If joystick stays in middle the motors are not moving
else {
motorSpeedA = 0;
motorSpeedB = 0;
}
// X-axis used for left and right control
if (xAxis < 470) {
// Convert the declining X-axis readings from 470 to 0 into increasing 0 to 255 value
int xMapped = map(xAxis, 470, 0, 0, 255);
// Move to left - decrease left motor speed, increase right motor speed
motorSpeedA = motorSpeedA - xMapped;
motorSpeedB = motorSpeedB + xMapped;
// Confine the range from 0 to 255
if (motorSpeedA < 0) {
motorSpeedA = 0;
}
if (motorSpeedB > 255) {
motorSpeedB = 255;
}
}
if (xAxis > 550) {
// Convert the increasing X-axis readings from 550 to 1023 into 0 to 255 value
int xMapped = map(xAxis, 550, 1023, 0, 255);
// Move right - decrease right motor speed, increase left motor speed
motorSpeedA = motorSpeedA + xMapped;
motorSpeedB = motorSpeedB - xMapped;
// Confine the range from 0 to 255
if (motorSpeedA > 255) {
motorSpeedA = 255;
}
if (motorSpeedB < 0) {
motorSpeedB = 0;
}
}
// Prevent buzzing at low speeds (Adjust according to your motors. My motors couldn't start moving if PWM value was below value of 70)
if (motorSpeedA < 70) {
motorSpeedA = 0;
}
if (motorSpeedB < 70) {
motorSpeedB = 0;
}
analogWrite(enA, motorSpeedA); // Send PWM signal to motor A
analogWrite(enB, motorSpeedB); // Send PWM signal to motor B
}
So that’s pretty much everything for this tutorial. Feel free to ask any question in the comments section below.
Opmerkingen