Arduino Bluetooth Car using HC05 Master-Slave Transmitter Receiver

In this lesson we are going to make Arduino Bluetooth Car using HC05 Master Slave Transmitter Receiver. We will pair 2 HC05 modules in Master Slave configuration to transmit and receive data, we have created Remote Control with 2 joysticks to send car control commands. Car has throttle and steering control.

below are the components required for the project

Components - Transmitter:
✅ Arduino Nano https://amzn.to/3i24wfZ ✅ HC05 Module https://amzn.to/3NUSjbM ✅ 2 Analog Joysticks ✅ 7-12 V DC battery (In our case lipo 2s battery) https://amzn.to/3q4SjLN ✅ Breadboard https://amzn.to/3KH7sL6 ✅ Double sided tape ✅ Jumper wires https://amzn.to/3I8fZVG 👉 Components - Receiver:
✅ 4WD car kit https://amzn.to/3i1PdDW ✅ Arduino Nano https://amzn.to/3i24wfZ ✅ HC05 Module https://amzn.to/3NUSjbM ✅ L298N motor driver module https://amzn.to/3J98zTJ ✅ 7-12 V DC battery (we will use lipo 3s battery) https://amzn.to/37gJWpQ ✅ Breadboard https://amzn.to/3KH7sL6 ✅ Jumper wires https://amzn.to/3I8fZVG

Below is the circuit for Configuring the Bluetooth module from Master to Slave and Code

#include <SoftwareSerial.h>
SoftwareSerial btSerial(2, 3); // RX | TX
 
void setup() 
{
    Serial.begin(9600);

    btSerial.begin(38400);      
    Serial.println("btSerial started at 38400");
}
 
void loop()
{
  // Keep reading from Arduino Serial Monitor and send to HC-05
  if (Serial.available())
  {
    btSerial.write(Serial.read()); 
  }
  
  // Keep reading from HC-05 and send to Arduino Serial Monitor
  if (btSerial.available())
  {  
    Serial.write(btSerial.read());
  }
}
With this command you will set one of the Bluetooth to Slave Mode
/*
Slave Command:
AT
AT+RMAAD
AT+ROLE=0
AT+UART=38400,0,0
AT+ADDR

With this command, you will set the other  Bluetooth to Master Mode
Master Commands:
AT
AT+RMAAD
AT+ROLE=1
AT+UART=38400,0,0
AT+CMODE=0
AT+BIND=98D3:61:F613EA  (This should be your HC05 Slave address)
*/


Below is the circuit of the Receiver and The Code

#include<SoftwareSerial.h>

SoftwareSerial btSerial(2, 3); // RX | TX

struct PacketData 
{
  byte lxAxisValue;
  byte lyAxisValue;
  byte rxAxisValue;
  byte ryAxisValue;
};
PacketData data;

//Right motor
int enableRightMotor=5; 
int rightMotorPin1=7;
int rightMotorPin2=8;

//Left motor
int enableLeftMotor=6;
int leftMotorPin1=9;
int leftMotorPin2=10;

unsigned long lastRecvTime = 0;

void setup()
{
  pinMode(enableRightMotor,OUTPUT);
  pinMode(rightMotorPin1,OUTPUT);
  pinMode(rightMotorPin2,OUTPUT);
  
  pinMode(enableLeftMotor,OUTPUT);
  pinMode(leftMotorPin1,OUTPUT);
  pinMode(leftMotorPin2,OUTPUT);

  rotateMotor(0, 0);
  
  btSerial.begin(38400);  
}

void loop()
{
  String dataString;
  if (btSerial.available())
  {
    dataString = btSerial.readStringUntil('\n');
    sscanf(dataString.c_str(), "%d,%d,%d,%d", &data.lxAxisValue, &data.lyAxisValue, &data.rxAxisValue, &data.ryAxisValue);
    int throttle = map(data.lyAxisValue, 254, 0, -255, 255); //Left stick  - y axis - forward/backward car movement
    int steering = map(data.rxAxisValue, 0, 254, -255, 255); //Right stick - x axis - left/right car movement 
    int motorDirection = 1;
    
    if (throttle < 0)       //Move car backward
    {
      motorDirection = -1;    
    }
  
    int rightMotorSpeed, leftMotorSpeed;
    rightMotorSpeed =  abs(throttle) - steering;
    leftMotorSpeed =  abs(throttle) + steering;
    rightMotorSpeed = constrain(rightMotorSpeed, 0, 255);
    leftMotorSpeed = constrain(leftMotorSpeed, 0, 255);
  
    rotateMotor(rightMotorSpeed * motorDirection, leftMotorSpeed * motorDirection);
    lastRecvTime = millis();      
  }
  else
  {
    unsigned long now = millis();
    if ( now - lastRecvTime > 1000 )       //Signal lost after 1 second. Reset the motor to stop
    {
      rotateMotor(0, 0);   
   }
 }      
}

void rotateMotor(int rightMotorSpeed, int leftMotorSpeed)
{
  if (rightMotorSpeed < 0)
  {
    digitalWrite(rightMotorPin1,LOW);
    digitalWrite(rightMotorPin2,HIGH);    
  }
  else if (rightMotorSpeed > 0)
  {
    digitalWrite(rightMotorPin1,HIGH);
    digitalWrite(rightMotorPin2,LOW);      
  }
  else
  {
    digitalWrite(rightMotorPin1,LOW);
    digitalWrite(rightMotorPin2,LOW);      
  }
  
  if (leftMotorSpeed < 0)
  {
    digitalWrite(leftMotorPin1,LOW);
    digitalWrite(leftMotorPin2,HIGH);    
  }
  else if (leftMotorSpeed > 0)
  {
    digitalWrite(leftMotorPin1,HIGH);
    digitalWrite(leftMotorPin2,LOW);      
  }
  else
  {
    digitalWrite(leftMotorPin1,LOW);
    digitalWrite(leftMotorPin2,LOW);      
  }  

  analogWrite(enableRightMotor, abs(rightMotorSpeed));
  analogWrite(enableLeftMotor, abs(leftMotorSpeed));    
}



Below is the circuit of the Transmitter and The Code

#include<SoftwareSerial.h>

SoftwareSerial btSerial(2, 3); // RX | TX

struct PacketData 
{
  byte lxAxisValue;
  byte lyAxisValue;
  byte rxAxisValue;
  byte ryAxisValue;
};
PacketData data;

void setup()
{
  btSerial.begin(38400);   
}

//This function is used to map 0-1023 joystick value to 0-254. hence 127 is the center value which we send.
//It also adjust the deadband in joystick.
//Jotstick values range from 0-1023. But its center value is not always 511. It is little different.
//So we need to add some deadband to center value. in our case 500-530. Any value in this deadband range is mapped to center 127.
int mapAndAdjustJoystickDeadBandValues(int value, bool reverse)
{
  if (value >= 530)
  {
    value = map(value, 530, 1023, 127, 254);
  }
  else if (value <= 500)
  {
    value = map(value, 500, 0, 127, 0);  
  }
  else
  {
    value = 127;
  }

  if (reverse)
  {
    value = 254 - value;
  }
  return value;
}

void loop()
{
  data.lxAxisValue    = mapAndAdjustJoystickDeadBandValues(analogRead(A0), false);
  data.lyAxisValue    = mapAndAdjustJoystickDeadBandValues(analogRead(A1), false);
  data.rxAxisValue    = mapAndAdjustJoystickDeadBandValues(analogRead(A2), false);
  data.ryAxisValue    = mapAndAdjustJoystickDeadBandValues(analogRead(A3), false);

  String dataString;
  dataString = dataString 
               + data.lxAxisValue + "," 
               + data.lyAxisValue + ","  
               + data.rxAxisValue + ","  
               + data.ryAxisValue + "\n";
  
  btSerial.print(dataString);
  delay(10);
}


It is Recommended that you use a Rechargeable battery.
See you in our next lesson, Thank you
You can Download Zip Here


Share:

1 comment:

Anonymous said...

Nice one sir, please I need a robotic circuit using AT89C52 micro controller, thank you