Project – Bluetooth Blynk Car

Project – Bluetooth Blynk Car

Hi! In this tutorial you’ll learn how to control an Arduino car using Blynk and Bluetooth module! Control the car with your Smartphone!

What do you need?

How it Works?

We will control the car with the Blynk app thanks to Bluetooth connection.

First of all we will configure Blynk’s widgets and then we will create the Arduino Sketch.

We will use the joystick widget from Blynk to send values to Arduino and control the car.

Let’s see how to configure the Blynk app!

Blynk App configuration

Create a new Blynk Project.

Choose a name, select your Arduino Board, and Select Bluetooth as connection type.

New Blynk Project

Then add Bluetooth and Joystick widget.

Blynk app

Configure the Joystick Widget as follows.

Joystick Blynk configuration

Schematics

Then use these schematics for the car:

Thanks to https://howtomechatronics.com for the schematic

Once the circuit is done, we have to upload the sketch on the Arduino board.

Sketch

Let’s see how is done the code:

First of all we include the needed libraries, then put your Auth Token in ” “.

You will get the Auth Token when you create a new project in Blynk. If you don’t know how to use Blynk, we have a lot of article about it. I suggest you to read this article -> Use an LED with Blynk.

Then we declare some variables that we will use later.

#include <BlynkSimpleSerialBLE.h>
#include <SoftwareSerial.h>

#define BLYNK_USE_DIRECT_CONNECT

#define BLYNK_PRINT DebugSerial

SoftwareSerial DebugSerial(2, 3); //RX, TX


char auth[] = "Put Here Your Auth Token";
//You will get the Auth Token when you create a new project on Blynk

#define enA 9
#define in1 4
#define in2 5
#define enB 10
#define in3 6
#define in4 7

int motorSpeedA = 0;
int motorSpeedB = 0;

int xAxis;
int yAxis;

Now we have to write the setup.

Here we begin the Bluetooth connection and we set as OUTPUT some pins used for the motor driver.

void setup()
{
  // Debug console
  DebugSerial.begin(9600);

  DebugSerial.println("Waiting for connections...");

  Serial.begin(9600);
  Blynk.begin(Serial, auth);

  pinMode(enA, OUTPUT);
  pinMode(enB, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);
}

The Void section is really simple:

void loop()
{
  Blynk.run();
}

Then we create a function to control the motors:

You can read the comments to understand the code. This function is used in the next step!

void moveControl(int x, int y)
{
  //Y axis used for forward and backward control
  if (y < 300)
  {
    //Set Motor A forward
    digitalWrite(in1, LOW);
    digitalWrite(in2, HIGH);
    //Set Motor B forward
    digitalWrite(in3, LOW);
    digitalWrite(in4, HIGH);

    //The map function is used to rescale the range of values read from the joystick from 0 to 1023 to 100 to 255
    motorSpeedA = map(y, 0, 1023, 100, 255);
    motorSpeedB = map(y, 0, 1023, 100, 255);
  }
  else if (y > 800)
  {
    //Set Motor A backward
    digitalWrite(in1, HIGH);
    digitalWrite(in2, LOW);
    //Set Motor B backward
    digitalWrite(in3, HIGH);
    digitalWrite(in4, LOW);

    //The map function is used to rescale the range of values read from the joystick from 0 to 1023 to 100 to 255
    motorSpeedA = map(y, 0, 1023, 100, 255);
    motorSpeedB = map(y, 0, 1023, 100, 255);
  }
  //If joystick stays in middle the motors dont't move
  else 
  {
    motorSpeedA = 0;
    motorSpeedB = 0;
  }
  //X axis is used for left and right control
  if (x < 300)
  {
    //Set Motor A backward
    digitalWrite(in1, HIGH);
    digitalWrite(in2, LOW);
    //Set Motor B backward
    digitalWrite(in3, HIGH);
    digitalWrite(in4, LOW);
    
    //The map function is used to rescale the range of values read from the joystick from 0 to 1023 to 100 to 255
    int xMapped = map(x, 0, 1023, 100, 255);
    
    //Move to left - decrease left motor speed, increase right motor speed
    motorSpeedA = motorSpeedA + xMapped;
    motorSpeedB = motorSpeedB - xMapped;

    /*
    motorSpeedA = motorSpeedA - xMapped;    //If your motors go in the wrong way try to comment
    motorSpeedB = motorSpeedB + xMapped;    //the previous two line and use this two
     */
    
    //We don't want that the motors could start moving if there are values under 0 or higher then 255
    if (motorSpeedA < 0)
    {
      motorSpeedA = 0;
    }
    if (motorSpeedB > 255)
    {
      motorSpeedB = 255;
    }
  }
  if (x > 800)
  {
    //Set Motor A backward
    digitalWrite(in1, HIGH);
    digitalWrite(in2, LOW);
    //Set Motor B backward
    digitalWrite(in3, HIGH);
    digitalWrite(in4, LOW);
    
    //The map function is used to rescale the range of values read from the joystick from 0 to 1023 to 100 to 255
    int xMapped = map(x, 0, 1023, 100, 255);
    
    // Move right - decrease right motor speed, increase left motor speed
    motorSpeedA = motorSpeedA - xMapped;
    motorSpeedB = motorSpeedB + xMapped;
    
    /*
    motorSpeedA = motorSpeedA + xMapped;    //If your motors go in the wrong way try to comment
    motorSpeedB = motorSpeedB - xMapped;    //the previous two line and use this two
    */
    
    //We don't want that the motors could start moving if there are values under 0 or higher then 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
}

Last Step:

Read the values for xAxis and yAxis from the Blynk Joystick.

BLYNK_WRITE(V1)
{
    xAxis = param[0].asInt();
    yAxis = param[1].asInt();
    moveControl(xAxis,yAxis);
}

Complete Sketch for the Bluetooth Blynk Car

#define BLYNK_USE_DIRECT_CONNECT

// You could use a spare Hardware Serial on boards that have it (like Mega)
#include <SoftwareSerial.h>
SoftwareSerial DebugSerial(2, 3); // RX, TX

#define BLYNK_PRINT DebugSerial
#include <BlynkSimpleSerialBLE.h>

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "3CyaH1x5sz42cYTDW4mQX6w1ItVc10Om";


#define enA 9
#define in1 4
#define in2 5
#define enB 10
#define in3 6
#define in4 7

int motorSpeedA = 0;
int motorSpeedB = 0;

int xAxis;
int yAxis;



void setup()
{
  // Debug console
  DebugSerial.begin(9600);

  DebugSerial.println("Waiting for connections...");

  // Blynk will work through Serial
  // 9600 is for HC-06. For HC-05 default speed is 38400
  // Do not read or write this serial manually in your sketch
  Serial.begin(9600);
  Blynk.begin(Serial, auth);

  pinMode(enA, OUTPUT);
  pinMode(enB, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);
}


void loop()
{
    Blynk.run();
}

void moveControl(int x, int y)
{
  //Y axis used for forward and backward control
  if (y < 300)
  {
    //Set Motor A forward
    digitalWrite(in1, LOW);
    digitalWrite(in2, HIGH);
    //Set Motor B forward
    digitalWrite(in3, LOW);
    digitalWrite(in4, HIGH);

    //The map function is used to rescale the range of values read from the joystick from 0 to 1023 to 100 to 255
    motorSpeedA = map(y, 0, 1023, 100, 255);
    motorSpeedB = map(y, 0, 1023, 100, 255);
  }
  else if (y > 800)
  {
    //Set Motor A backward
    digitalWrite(in1, HIGH);
    digitalWrite(in2, LOW);
    //Set Motor B backward
    digitalWrite(in3, HIGH);
    digitalWrite(in4, LOW);

    //The map function is used to rescale the range of values read from the joystick from 0 to 1023 to 100 to 255
    motorSpeedA = map(y, 0, 1023, 100, 255);
    motorSpeedB = map(y, 0, 1023, 100, 255);
  }
  //If joystick stays in middle the motors dont't move
  else 
  {
    motorSpeedA = 0;
    motorSpeedB = 0;
  }
  //X axis is used for left and right control
  if (x < 300)
  {
    //Set Motor A backward
    digitalWrite(in1, HIGH);
    digitalWrite(in2, LOW);
    //Set Motor B backward
    digitalWrite(in3, HIGH);
    digitalWrite(in4, LOW);
    
    //The map function is used to rescale the range of values read from the joystick from 0 to 1023 to 100 to 255
    int xMapped = map(x, 0, 1023, 100, 255);
    
    //Move to left - decrease left motor speed, increase right motor speed
    motorSpeedA = motorSpeedA + xMapped;
    motorSpeedB = motorSpeedB - xMapped;

    /*
    motorSpeedA = motorSpeedA - xMapped;    //If your motors go in the wrong way try to comment
    motorSpeedB = motorSpeedB + xMapped;    //the previous two line and use this two
     */
    
    //We don't want that the motors could start moving if there are values under 0 or higher then 255
    if (motorSpeedA < 0)
    {
      motorSpeedA = 0;
    }
    if (motorSpeedB > 255)
    {
      motorSpeedB = 255;
    }
  }
  if (x > 800)
  {
    //Set Motor A backward
    digitalWrite(in1, HIGH);
    digitalWrite(in2, LOW);
    //Set Motor B backward
    digitalWrite(in3, HIGH);
    digitalWrite(in4, LOW);
    
    //The map function is used to rescale the range of values read from the joystick from 0 to 1023 to 100 to 255
    int xMapped = map(x, 0, 1023, 100, 255);
    
    // Move right - decrease right motor speed, increase left motor speed
    motorSpeedA = motorSpeedA - xMapped;
    motorSpeedB = motorSpeedB + xMapped;
    
    /*
    motorSpeedA = motorSpeedA + xMapped;    //If your motors go in the wrong way try to comment
    motorSpeedB = motorSpeedB - xMapped;    //the previous two line and use this two
    */
    
    //We don't want that the motors could start moving if there are values under 0 or higher then 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
}

BLYNK_WRITE(V1)
{
    xAxis = param[0].asInt();
    yAxis = param[1].asInt();
    Blynk.virtualWrite(V3,xAxis);
    moveControl(xAxis,yAxis);
}

Davide Busco

Davide Busco is an engineering student at Federico II University of Naples. He uses his passion and studies to create his projects. He loves be a maker and spread his knowledge. Moreover he has gained the second place in a national makers-tournament between Italian's Universities.

Leave a Reply

Your email address will not be published. Required fields are marked *