Proper Coding for Bluetooth Car Control with Arduino

Controlling a car with your smartphone via Bluetooth is a fascinating project for hobbyists and Arduino enthusiasts. This guide will walk you through the essential Arduino code for setting up Bluetooth control for your car, ensuring smooth and responsive operation. We’ll break down the code and also touch upon troubleshooting common issues, like unexpected beeping sounds from your motor driver.

Understanding the Arduino Code for Bluetooth Car Control

The provided Arduino code is designed to interface with a Bluetooth module, receive commands from a smartphone app, and control a car using an L298N motor driver. Let’s dissect the code section by section:

#define in1 4  // L298n Motor Driver pins
#define in2 5
#define in3 6
#define in4 7
#define LED 13
int command;      // Int to store app command state
int Speed = 204;  // 0 - 255
int Speedsec;
int buttonState = 0;
int lastButtonState = 0;
int Turnradius = 0; // Set the radius of a turn, 0 - 255
                     // Note: the robot will malfunction if this is higher than int Speed.
int brakeTime = 45;
int brkonoff = 1;   // 1 for the electronic braking system, 0 for normal.

void setup() {
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);
  pinMode(LED, OUTPUT);    // Set the LED pin.
  Serial.begin(9600);      // Set the baud rate to your Bluetooth module.
}

void loop() {
  if (Serial.available() > 0) {
    command = Serial.read();
    Stop(); // Initialize with motors stopped.
    switch (command) {
      case 'F':
        forward();
        break;
      case 'B':
        back();
        break;
      case 'L':
        left();
        break;
      case 'R':
        right();
        break;
      case 'G':
        forwardleft();
        break;
      case 'I':
        forwardright();
        break;
      case 'H':
        backleft();
        break;
      case 'J':
        backright();
        break;
      case '0':
        Speed = 100;
        break;
      case '1':
        Speed = 140;
        break;
      case '2':
        Speed = 153;
        break;
      case '3':
        Speed = 165;
        break;
      case '4':
        Speed = 178;
        break;
      case '5':
        Speed = 191;
        break;
      case '6':
        Speed = 204;
        break;
      case '7':
        Speed = 216;
        break;
      case '8':
        Speed = 229;
        break;
      case '9':
        Speed = 242;
        break;
      case 'q':
        Speed = 255;
        break;
    }
    Speedsec = Turnradius;
    if (brkonoff == 1) {
      brakeOn();
    } else {
      brakeOff();
    }
  }
}

void forward() {
  analogWrite(in1, Speed);
  analogWrite(in3, Speed);
}

void back() {
  analogWrite(in2, Speed);
  analogWrite(in4, Speed);
}

void left() {
  analogWrite(in3, Speed);
  analogWrite(in2, Speed);
}

void right() {
  analogWrite(in4, Speed);
  analogWrite(in1, Speed);
}

void forwardleft() {
  analogWrite(in1, Speedsec);
  analogWrite(in3, Speed);
}

void forwardright() {
  analogWrite(in1, Speed);
  analogWrite(in3, Speedsec);
}

void backright() {
  analogWrite(in2, Speed);
  analogWrite(in4, Speedsec);
}

void backleft() {
  analogWrite(in2, Speedsec);
  analogWrite(in4, Speed);
}

void Stop() {
  analogWrite(in1, 0);
  analogWrite(in2, 0);
  analogWrite(in3, 0);
  analogWrite(in4, 0);
}

void brakeOn() {
  // Here's the future use: an electronic braking system!
  // read the pushbutton input pin:
  buttonState = command;
  // compare the buttonState to its previous state
  if (buttonState != lastButtonState) {
    // if the state has changed, increment the counter
    if (buttonState == 'S') {
      if (lastButtonState != buttonState) {
        digitalWrite(in1, HIGH);
        digitalWrite(in2, HIGH);
        digitalWrite(in3, HIGH);
        digitalWrite(in4, HIGH);
        delay(brakeTime);
        Stop();
      }
    }
    // save the current state as the last state,
    // for next time through the loop
    lastButtonState = buttonState;
  }
}

void brakeOff() {}

Code Breakdown:

  • Pin Definitions: #define statements assign digital pins on the Arduino to control the L298N motor driver (in1, in2, in3, in4) and an optional LED.
  • Variables:
    • command: Stores the command received via Bluetooth from the app.
    • Speed: Sets the base speed of the motors (0-255), with 204 as the default.
    • Speedsec, Turnradius: Likely intended for controlling turning radius by adjusting speed, although Turnradius is not used in the movement functions.
    • brakeTime, brkonoff: Variables related to an electronic braking system, which is partially implemented but not fully utilized in the provided code.
  • setup() function:
    • pinMode(): Configures the defined pins as OUTPUT to control the motor driver and LED.
    • Serial.begin(9600): Initializes serial communication at 9600 baud rate, which should match the baud rate of your Bluetooth module for proper communication.
  • loop() function:
    • Serial.available() > 0: Checks if there is incoming data from the Bluetooth module.
    • command = Serial.read(): Reads the incoming byte (command) from the Bluetooth module.
    • Stop(): Immediately stops the motors before processing the new command, ensuring smooth transitions.
    • switch(command): A series of case statements to execute different movement functions based on the received command characters (‘F’, ‘B’, ‘L’, ‘R’, ‘G’, ‘I’, ‘H’, ‘J’ for movements, and ‘0’ to ‘9’, ‘q’ for speed control).
    • Speedsec = Turnradius;: Assigns Turnradius to Speedsec, but Turnradius is always 0 in the provided code, so Speedsec will also be 0 unless Turnradius is changed elsewhere.
    • brakeOn()/brakeOff(): Calls the braking functions based on the brkonoff variable.
  • Movement Functions (forward(), back(), left(), right(), forwardleft(), forwardright(), backleft(), backright(), Stop()): These functions control the motor driver pins using analogWrite() to set motor speed (PWM) or digitalWrite() for braking. Notice that turning functions (forwardleft, forwardright, etc.) use Speedsec which is currently set to Turnradius (0), effectively making one side of the motors stop during turns in the current code configuration.
  • brakeOn() and brakeOff(): brakeOn() attempts to implement an electronic brake by briefly setting all motor driver inputs HIGH, then stopping. However, it’s triggered by the ‘S’ command which is not included in the main command switch case, and its logic within the if (buttonState != lastButtonState) and nested if (lastButtonState != buttonState) could be simplified. brakeOff() is empty, indicating braking is intended to be an on/off feature.

Troubleshooting Beeping Sounds from the L298N Motor Driver

The user reported a beeping sound from the L298N motor driver when using this code and powering the Arduino from a laptop via USB. This beeping sound is a strong indicator of insufficient power.

Reasons and Solutions:

  1. Insufficient Current from USB: Laptop USB ports typically provide limited current (often around 500mA). Motor drivers and motors, especially when starting or under load, can demand significantly more current. When the current draw exceeds what the USB port can supply, the voltage can drop, leading to erratic behavior in the motor driver and potentially causing beeping sounds.

    • Solution: Use an external power supply with sufficient voltage and current capabilities for your motors and L298N driver. A 7.4V or 12V battery pack with a capacity of 1A or more is generally recommended for small robot cars. Connect this external power supply directly to the motor driver’s power input pins, ensuring correct polarity. Do not power the motors directly from the Arduino’s 5V or Vin pins, as these are also limited by the USB power or the Arduino’s onboard voltage regulator.
  2. Voltage Drop: Even with an external power supply, if the voltage is too low for the motors or if the wiring is thin and causing voltage drop, it can lead to similar issues.

    • Solution:
      • Check Motor Voltage Requirements: Ensure your power supply voltage is within the recommended operating voltage range of your motors and L298N driver.
      • Use Thicker Wires: Thin wires can cause significant voltage drop, especially with higher currents. Use thicker gauge wires for power connections to minimize resistance and voltage loss.
      • Shorten Wires: Longer wires also increase resistance. Keep power wires as short as practically possible.
  3. Motor Driver Overload/Fault: In rare cases, beeping could indicate a problem with the motor driver itself, such as overheating or internal fault.

    • Solution:
      • Check Motor Driver Specifications: Ensure your motors are within the current and voltage limits of the L298N driver.
      • Cooling: If the driver is getting very hot, consider adding a heatsink to improve cooling.
      • Replace Driver: If you suspect a driver fault and other power issues are ruled out, try replacing the L298N driver.

In summary, the beeping sound from your L298N motor driver is almost certainly due to a power supply issue, most likely insufficient current from the laptop’s USB port. Switching to an appropriate external power supply is the most crucial step to resolve this problem and ensure proper operation of your Bluetooth-controlled car.

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

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