Can i use bluetooth and joystick together?

I'm trying to make a Bluetooth car, but the car also has a joystick. so that if you don't use Bluetooth, the car can move using the joystick. If the code is only Bluetooth the car can run normally, if the code is only the joystick then the car can move normally, but if the code is combined then the Bluetooth controller cannot move the car, it only makes a clicking sound. What is wrong ?

tools : Arduino Uno, 2pcs 18650 batteries, L298N, 4 wheels, Bluetooth and joystick. VCC on Bluetooth and joystick are combined and plugged into VCC on Arduino.

Hello dhani2882

Welcome to the best Arduino Forum ever :slight_smile:

Post the current sketch and schematic to see how we can help.

char data; // Variable to store received data
int joyXpin = A0;
int joyYpin = A1;
int xVal;
int yVal;

void setup() {
    Serial.begin(9600); // Start serial communication at 9600 baud rate

    // Set motor control pins as output
    pinMode(7, OUTPUT); 
    pinMode(6, OUTPUT);
    pinMode(5, OUTPUT);
    pinMode(4, OUTPUT);
    
    pinMode(joyXpin, INPUT);
    pinMode(joyYpin, INPUT);
}

void loop() {
    // Cek data dari Bluetooth terlebih dahulu
    if (Serial.available() > 0) {
        data = Serial.read(); // Read received data
        Serial.println(data);  // Debugging: Print received data

        // Kontrol motor berdasarkan perintah dari Bluetooth
        switch (data) {
            case 'F': // Move Forward
                digitalWrite(7, HIGH);
                digitalWrite(6, LOW);
                digitalWrite(5, HIGH);
                digitalWrite(4, LOW);
                return; // Keluar dari loop
            case 'B': // Move Backward
                digitalWrite(7, LOW);
                digitalWrite(6, HIGH);
                digitalWrite(5, LOW);
                digitalWrite(4, HIGH);
                return; // Keluar dari loop
            case 'R': // Turn Left
                digitalWrite(7, LOW);
                digitalWrite(6, HIGH);
                digitalWrite(5, HIGH);
                digitalWrite(4, LOW);
                return; // Keluar dari loop
            case 'L': // Turn Right
                digitalWrite(7, HIGH);
                digitalWrite(6, LOW);
                digitalWrite(5, LOW);
                digitalWrite(4, HIGH);
                return; // Keluar dari loop
            case 'S': // Stop
                digitalWrite(7, LOW);
                digitalWrite(6, LOW);
                digitalWrite(5, LOW);
                digitalWrite(4, LOW);
                return; // Keluar dari loop
        }
    } else 
    
    {
    // Jika tidak ada data dari Bluetooth, kontrol motor berdasarkan joystick
    xVal = analogRead(joyXpin);
    yVal = analogRead(joyYpin);

    // Normalisasi nilai joystick
    int threshold = 100; // Batas untuk mengabaikan gerakan kecil
    int speed = map(yVal, 0, 1023, -255, 255); // Peta nilai Y untuk kecepatan
    int turn = map(xVal, 0, 1023, -255, 255); // Peta nilai X untuk belok

    // Kontrol motor berdasarkan joystick
    if (abs(speed) > threshold) {
        if (speed > 0) { // Maju
            digitalWrite(5, LOW);   // Motor B maju
            digitalWrite(4, HIGH);
            digitalWrite(7, HIGH);  // Motor A maju
            digitalWrite(6, LOW);
        } else { // Mundur
            digitalWrite(5, HIGH);   // Motor B mundur
            digitalWrite(4, LOW);
            digitalWrite(7, HIGH);  // Motor A maju
            digitalWrite(6, LOW);
        }
    } else { // Stop jika tidak ada gerakan
        digitalWrite(7, LOW);
        digitalWrite(6, LOW);
        digitalWrite(5, LOW);
        digitalWrite(4, LOW);
    }

    if (abs(turn) > threshold) {
        if (turn > 0) { // Belok kiri
            digitalWrite(5, HIGH);  // Motor B maju
            digitalWrite(4, LOW);
            digitalWrite(7, LOW);    // Motor A mundur
            digitalWrite(6, HIGH);
        } else { // Belok kanan
            digitalWrite(5, LOW);   // Motor B mundur
            digitalWrite(4, HIGH);
            digitalWrite(7, HIGH);  // Motor A maju
            digitalWrite(6, LOW);
        }
    } 
    }
}

Consider what happens

  1. You send a letter over Bluetooth (e.g. 'F'). This gets executed in if (Serial.available() > 0)
  2. There is no further data, so the code will now react on the joystick (the first else).
    Whatever the joystick indicates will now happen. E.g. if your joystick is in the centre position, your car will stop (I assume).

Late edit
I think the can be solved.

You can try the below framework; you need to implement the todo's

char data;  // Variable to store received data
int joyXpin = A0;
int joyYpin = A1;
int xVal;
int yVal;

void setup()
{
  Serial.begin(9600);  // Start serial communication at 9600 baud rate

  // Set motor control pins as output
  pinMode(7, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(4, OUTPUT);

  pinMode(joyXpin, INPUT);
  pinMode(joyYpin, INPUT);
}

void loop()
{
  // Always read the joystick
  xVal = analogRead(joyXpin);
  yVal = analogRead(joyYpin);

  // Normalize joystick values
  int threshold = 100;                        // Limits to ignoring small movements
  int speed = map(yVal, 0, 1023, -255, 255);  // Y value map for speed
  int turn = map(xVal, 0, 1023, -255, 255);   // Map X values ​​for turns

  if (Serial.available() > 0)
  {
    data = Serial.read();  // Read received data

    // if the joystick is in the centre
    if (speed == 0 && turn == 0)
    {
      // process the serial data
      switch(data)
      {
        // to do
      }
    }
  }
  else
  {
    // use the joystick values
    //todo
  }
}

Note:
Don't use magic numbers (4, 5, 6, 7) for your pin numbers in the pinMode() and digitalWrite() statements; if you ever need to make a change, you have to modify it everywhere and run the risk that you make a mistake somewhere.

So there is nothing wrong with schematic?
5v Vcc is devides for bluetooth and joystick, is that ok?

If your car works with Bluetooth code or with the joystick code, the hardware is OK in my opinion. The fact that the combination does not work is a logic error in your code (as I tried to point out).

Question (if I may)
What is your native language? I threw some of your sentences from the code in google translate and it detected all kinds of different languages.

You are right, i am using google. I am sorry for my bad english. My first language is bahasa.
The code still not working, no respond at all when i use bluetooth car app. When i disable if (speed ==0 && turn==0), there is a sound on gearbox but the wheel not moving

But the joystick is working normally, only bluetooth not working

Show your latest version of the code. I might have made a mistake.

What are the values for speed and turn in the neutral position of the joystick?

char data; // Variable to store received data
int joyXpin = A0;
int joyYpin = A1;
int xVal;
int yVal;

void setup() {
    Serial.begin(9600); // Start serial communication at 9600 baud rate

    // Set motor control pins as output
    pinMode(7, OUTPUT); 
    pinMode(6, OUTPUT);
    pinMode(5, OUTPUT);
    pinMode(4, OUTPUT);
    
    pinMode(joyXpin, INPUT);
    pinMode(joyYpin, INPUT);
}

void loop() {

  // Jika tidak ada data dari Bluetooth, kontrol motor berdasarkan joystick
    xVal = analogRead(joyXpin);
    yVal = analogRead(joyYpin);

    // Normalisasi nilai joystick
    int threshold = 100; // Batas untuk mengabaikan gerakan kecil
    int speed = map(yVal, 0, 1023, -255, 255); // Peta nilai Y untuk kecepatan
    int turn = map(xVal, 0, 1023, -255, 255); // Peta nilai X untuk belok

    // Cek data dari Bluetooth terlebih dahulu
    if (Serial.available() > 0) {
        data = Serial.read(); // Read received data
        Serial.println(data);  // Debugging: Print received data

        if (speed == 0 && turn == 0) {
        // Kontrol motor berdasarkan perintah dari Bluetooth
        switch (data) {
            case 'F': // Move Forward
                digitalWrite(7, HIGH);
                digitalWrite(6, LOW);
                digitalWrite(5, HIGH);
                digitalWrite(4, LOW);
                return; // Keluar dari loop
            case 'B': // Move Backward
                digitalWrite(7, LOW);
                digitalWrite(6, HIGH);
                digitalWrite(5, LOW);
                digitalWrite(4, HIGH);
                return; // Keluar dari loop
            case 'R': // Turn Left
                digitalWrite(7, LOW);
                digitalWrite(6, HIGH);
                digitalWrite(5, HIGH);
                digitalWrite(4, LOW);
                return; // Keluar dari loop
            case 'L': // Turn Right
                digitalWrite(7, HIGH);
                digitalWrite(6, LOW);
                digitalWrite(5, LOW);
                digitalWrite(4, HIGH);
                return; // Keluar dari loop
            case 'S': // Stop
                digitalWrite(7, LOW);
                digitalWrite(6, LOW);
                digitalWrite(5, LOW);
                digitalWrite(4, LOW);
                return; // Keluar dari loop
        }
    } 
    
    }  else 
    
    {
    
    // Kontrol motor berdasarkan joystick
    if (abs(speed) > threshold) {
        if (speed > 0) { // Maju
            digitalWrite(5, LOW);   // Motor B maju
            digitalWrite(4, HIGH);
            digitalWrite(7, HIGH);  // Motor A maju
            digitalWrite(6, LOW);
        } else { // Mundur
            digitalWrite(5, HIGH);   // Motor B mundur
            digitalWrite(4, LOW);
            digitalWrite(7, HIGH);  // Motor A maju
            digitalWrite(6, LOW);
        }
    } else { // Stop jika tidak ada gerakan
        digitalWrite(7, LOW);
        digitalWrite(6, LOW);
        digitalWrite(5, LOW);
        digitalWrite(4, LOW);
    }

    if (abs(turn) > threshold) {
        if (turn > 0) { // Belok kiri
            digitalWrite(5, HIGH);  // Motor B maju
            digitalWrite(4, LOW);
            digitalWrite(7, LOW);    // Motor A mundur
            digitalWrite(6, HIGH);
        } else { // Belok kanan
            digitalWrite(5, LOW);   // Motor B mundur
            digitalWrite(4, HIGH);
            digitalWrite(7, HIGH);  // Motor A maju
            digitalWrite(6, LOW);
        }
    } 
    }
}

I think that I made the same mistake as you did. There was supposed to be a condition inside the else but I forgot about that. Let me think about it.

Yes that correct, i think all i have to do is add condition if bluetooth is connected

The program presented below makes the assumption that the Bluetooth can not be used while the joystick is not in the centre position. The joystick will override the Bluetooth.

loop() consists of three functional blocks. I have used some static variables in loop() to remember what is happening.

I have used an enum that has two values to indicate if the program is in Bluetooth mode or in joystick mode.

enum MODE
{
  BLUETOOTH,
  JOYSTICK
};

void loop()
{
  // we start in joystic mode
  static MODE mode = JOYSTICK;
  
  ...
  ...
}

To be able to detect changes in the joystick we keep track of the old values for speed and turn.

{
  // we start in joystick mode
  static MODE mode = JOYSTICK;

  // we keep track of the old speed and turn value
  static int oldSpeed;
  static int oldTurn;  

  ...
  ...
}

The first functional block reads the joystick and maps them.

  // Jika tidak ada data dari Bluetooth, kontrol motor berdasarkan joystick
  xVal = analogRead(joyXpin);
  yVal = analogRead(joyYpin);

  // Normalisasi nilai joystick
  int speed = map(yVal, 0, 1023, -255, 255);  // Peta nilai Y untuk kecepatan
  int turn = map(xVal, 0, 1023, -255, 255);   // Peta nilai X untuk belok

  if (abs(speed) < zeroVal)
  {
    speed = 0;
  }
  if (abs(turn) < zeroVal)
  {
    turn = 0;
  }

The two if statements are needed because it is difficult to get exactly zero with the potentiometers that I have. zeroVal has the value 50 and any speed value or turn value between -50 and 50 will become 0. Next we can check if the joystick changed and if so, set the mode accordingly.

  // if the joystick changed
  if (abs(speed - oldSpeed) > deltaVal || (abs(turn - oldTurn) > deltaVal))
  {
    Serial.print(F("speed = "));
    Serial.print(speed);
    Serial.print(F(", oldSpeed = "));
    Serial.println(oldSpeed);

    Serial.print(F("turn = "));
    Serial.print(turn);
    Serial.print(F(", oldTurn = "));
    Serial.println(oldTurn);

    // switch to joystick mode
    Serial.println(F("Switching to joystick"));
    mode = JOYSTICK;
    oldSpeed = speed;
    oldTurn = turn;
  }

That completes the first block

The second functional block handles the reading of the Bluetooth.

  if (Serial.available() > 0)
  {
    data = Serial.read();  // Read received data
    Serial.println(data);  // Debugging: Print received data

    // debug
    Serial.print(F("speed = "));
    Serial.println(speed);
    Serial.print(F("turn = "));
    Serial.println(turn);

    // if the joystick is in the centre
    if (speed == 0 && turn == 0)
    {
      // switch to bluetooth mode
      Serial.println(F("Switching to bluetooth"));
      mode = BLUETOOTH;
    }
  }

The code always reads available data (as in my earlier reply); it will only switch to Bluetooth mode if the joystick is in the centre position.

And the last functional block handles the "selected" mode.

  if (mode == BLUETOOTH)
  {
    handleBluetooth(data);
  }
  else
  {
    handleJoystick(speed, turn);
  }

This calls one of two functions depending on the mode.

The complete code

char data;  // Variable to store received data
int joyXpin = A0;
int joyYpin = A1;
int xVal;
int yVal;

// potentiometers are 0 between -50 and 50
const int zeroVal = 50;
// only react on changes of 50 or more
const int deltaVal = 50;

void setup()
{
  Serial.begin(9600);  // Start serial communication at 9600 baud rate

  // Set motor control pins as output
  pinMode(7, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(4, OUTPUT);

  pinMode(joyXpin, INPUT);
  pinMode(joyYpin, INPUT);
}

enum MODE
{
  BLUETOOTH,
  JOYSTICK
};

void loop()
{
  // we start in joystick mode
  static MODE mode = JOYSTICK;
  // we keep track of the old speed and tunr value
  static int oldSpeed;
  static int oldTurn;

  // Jika tidak ada data dari Bluetooth, kontrol motor berdasarkan joystick
  xVal = analogRead(joyXpin);
  yVal = analogRead(joyYpin);

  // Normalisasi nilai joystick
  int speed = map(yVal, 0, 1023, -255, 255);  // Peta nilai Y untuk kecepatan
  int turn = map(xVal, 0, 1023, -255, 255);   // Peta nilai X untuk belok

  if (abs(speed) < zeroVal)
  {
    speed = 0;
  }
  if (abs(turn) < zeroVal)
  {
    turn = 0;
  }

  // only one potentiometer
  //turn = 0;

  // if the joystick changed
  if (abs(speed - oldSpeed) > deltaVal || (abs(turn - oldTurn) > deltaVal))
  {
    Serial.print(F("speed = "));
    Serial.print(speed);
    Serial.print(F(", oldSpeed = "));
    Serial.println(oldSpeed);

    Serial.print(F("turn = "));
    Serial.print(turn);
    Serial.print(F(", oldTurn = "));
    Serial.println(oldTurn);

    // switch to joystick mode
    Serial.println(F("Switching to joystick"));
    mode = JOYSTICK;
    oldSpeed = speed;
    oldTurn = turn;
  }


  if (Serial.available() > 0)
  {
    data = Serial.read();  // Read received data
    Serial.println(data);  // Debugging: Print received data

    // debug
    Serial.print(F("speed = "));
    Serial.println(speed);
    Serial.print(F("turn = "));
    Serial.println(turn);

    // if the joystick is in the centre
    if (speed == 0 && turn == 0)
    {
      // switch to bluetooth mode
      Serial.println(F("Switching to bluetooth"));
      mode = BLUETOOTH;
    }
  }

  if (mode == BLUETOOTH)
  {
    handleBluetooth(data);
  }
  else
  {
    handleJoystick(speed, turn);
  }
}

/*
Handle Bluetooth commands
In:
  received character
*/
void handleBluetooth(char ch)
{
  // Kontrol motor berdasarkan perintah dari Bluetooth
  switch (ch)
  {
    case 'F':  // Move Forward
      Serial.println(F("Forward"));
      digitalWrite(7, HIGH);
      digitalWrite(6, LOW);
      digitalWrite(5, HIGH);
      digitalWrite(4, LOW);
      return;  // Keluar dari loop
    case 'B':  // Move Backward
      Serial.println(F("Backward"));
      digitalWrite(7, LOW);
      digitalWrite(6, HIGH);
      digitalWrite(5, LOW);
      digitalWrite(4, HIGH);
      return;  // Keluar dari loop
    case 'R':  // Turn Left
      Serial.println(F("Left"));
      digitalWrite(7, LOW);
      digitalWrite(6, HIGH);
      digitalWrite(5, HIGH);
      digitalWrite(4, LOW);
      return;  // Keluar dari loop
    case 'L':  // Turn Right
      Serial.println(F("Right"));
      digitalWrite(7, HIGH);
      digitalWrite(6, LOW);
      digitalWrite(5, LOW);
      digitalWrite(4, HIGH);
      return;  // Keluar dari loop
    case 'S':  // Stop
      Serial.println(F("Stop"));
      digitalWrite(7, LOW);
      digitalWrite(6, LOW);
      digitalWrite(5, LOW);
      digitalWrite(4, LOW);
      return;  // Keluar dari loop
  }
}

/*
Handle joystick values
In:
  speed
  turn
*/
void handleJoystick(int speed, int turn)
{
  // Batas untuk mengabaikan gerakan kecil
  int threshold = 100;

  // Kontrol motor berdasarkan joystick
  if (abs(speed) > threshold)
  {
    if (speed > 0)
    {                        // Maju
      digitalWrite(5, LOW);  // Motor B maju
      digitalWrite(4, HIGH);
      digitalWrite(7, HIGH);  // Motor A maju
      digitalWrite(6, LOW);
    }
    else
    {                         // Mundur
      digitalWrite(5, HIGH);  // Motor B mundur
      digitalWrite(4, LOW);
      digitalWrite(7, HIGH);  // Motor A maju
      digitalWrite(6, LOW);
    }
  }
  else
  {  // Stop jika tidak ada gerakan
    digitalWrite(7, LOW);
    digitalWrite(6, LOW);
    digitalWrite(5, LOW);
    digitalWrite(4, LOW);
  }

  if (abs(turn) > threshold)
  {
    if (turn > 0)
    {                         // Belok kiri
      digitalWrite(5, HIGH);  // Motor B maju
      digitalWrite(4, LOW);
      digitalWrite(7, LOW);  // Motor A mundur
      digitalWrite(6, HIGH);
    }
    else
    {                        // Belok kanan
      digitalWrite(5, LOW);  // Motor B mundur
      digitalWrite(4, HIGH);
      digitalWrite(7, HIGH);  // Motor A maju
      digitalWrite(6, LOW);
    }
  }
}

This was tested relying on the the serial outputs with only one potentiometer (I don't have a joystick).