Bluetooth RC car with BTS7960 Problems

Hi all,
I have been struggling with this project for a couple of weeks now, and one after another problems keep showing up. I have this car that I have built from scratch, and it can be controlled by a Bluetooth app made in MIT App Inventor. The 4 TT geared motors are controlled by 2 BTS7960 motor drivers. The problem is that when I try and control the car from the app, the motors only work when I give them full power from the Android app over BT. It has worked before, but now that I added some more features (a controllable servo) it has seemed to only work at full speed. Here are some images for an idea of what's going on:





I can provide more images if necessary.

Here is the code I have used for the Arduino. I apologize for the messy code, but it has been edited many, many times.

#include <Servo.h>

Servo camera;


int state = 0;

long distanceFront = 1188;
long distanceRight = 1188;
long distanceLeft  = 1188;
int varSpd = 90;//Default motor speeds
//Motor Driver 1:

int motorPin1 = A0;
int motorPin2 = A1;
int EN1 = 9;

//Motor driver 2:
int motorPin3 = A2;
int motorPin4 = A3;
int EN2 = 10;

long duration, distance;

int trigPinFront = 2;
int echoPinFront = 3;

int trigPinRight = 4;
int echoPinRight = 5;

int trigPinLeft = 7;
int echoPinLeft = 8;



bool status = false;

int pos = 90;


String data;

void setup()
{
  camera.attach(6);
  camera.write(pos);
  pinMode(trigPinFront, OUTPUT);
  pinMode(echoPinFront, INPUT);

  pinMode(trigPinRight, OUTPUT);
  pinMode(echoPinRight, INPUT);

  pinMode(trigPinLeft, OUTPUT);
  pinMode(echoPinLeft, INPUT);

  pinMode(A4, INPUT_PULLUP);

  pinMode(13, OUTPUT);

  pinMode(motorPin1, OUTPUT);
  pinMode(motorPin2, OUTPUT);

  pinMode(motorPin3, OUTPUT);
  pinMode(motorPin4, OUTPUT);

  pinMode(EN1, OUTPUT);
  pinMode(EN2, OUTPUT);

  Serial.begin(9600);

  delay(1000);


  Serial.println("started.");


}

void loop() {
  if (digitalRead(A4) == LOW) {
    if (status == false) {
      status = true;
    } else {
      status = false;
      stopAll();
    }
    delay(300);
  }



  if (status == 1) {

    if (Serial.available() > 0) { // Checks whether data is coming from the serial port
      state = Serial.read(); // Reads the data from the serial port
      if (state > 50) {

        varSpd = state;
      }



    }


    sonar();
    if (distanceFront < 30) {
      if (distanceRight > distanceLeft) {
        while (distanceRight > distanceLeft) {

          right();
          sonar();
        }
      } else if (distanceLeft > distanceRight) {
        while (distanceLeft > distanceRight) {

          left();
          sonar();
        }
      }
    } else {
      if (distanceRight < 25) {
        while (distanceRight < 25) {

          left();
          sonar();
        }
      } else if (distanceLeft < 25) {
        while (distanceLeft < 25) {

          right();
          sonar();

        }
      } else {

        forward();

      }

    }

  }



  //Read the data if available in buffer
  if (status == 0) {

    if (Serial.available() > 0) { // Checks whether data is comming from the serial port
      state = Serial.read(); // Reads the data from the serial port

      // Serial.println(state);
      if (state == 0) {
        //Serial.println("stop");
        digitalWrite(13, LOW); // Turn LED OFF
        stopAll();
      }
      else if (state == 1) {

        digitalWrite(13, HIGH);
        forward();
      }
      else if (state == 2) {

        digitalWrite(13, HIGH);
        backward();
      }
      else if (state == 3) {

        digitalWrite(13, HIGH);
        left();
      }
      else if (state == 4) {

        digitalWrite(13, HIGH);
        right();
      } else  if (state > 10) {
        //Serial.println("Setting speed!");
        varSpd = state;


      } else if (state == '5') {
        //servo left
        digitalWrite(13, HIGH);
        while (state != '7') {
          if (Serial.available() > 0) {
            state = Serial.read();
          }
          if (pos > 179) {
            pos = 179;
          } else {
            pos++;
            camera.write(pos);
            delay(35);
          }
        }
        digitalWrite(13, LOW);

      } else if (state == '6') {
        //servo right;
        digitalWrite(13, HIGH);
        while (state != '7') {
          if (Serial.available() > 0) {
            state = Serial.read();
          }
          if (pos < 1) {
            pos = 1;
          } else {
            pos--;
            camera.write(pos);
            delay(35);
          }

        }
        digitalWrite(13, LOW);
      } else {
        stopAll();
        digitalWrite(13, LOW);
    

      }
    }
  }
}












void SonarSensor(int trigPin, int echoPin)
{
  digitalWrite(trigPin, LOW);
  delay(.2);
  digitalWrite(trigPin, HIGH);
  delay(.10);
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  distance = (duration / 2) / 29.1;

}


void backward() {
  // Serial.print("backward. Speed: ");
  //Serial.println(varSpd);
  analogWrite(EN1, varSpd);
  analogWrite(EN2, varSpd);
  digitalWrite(motorPin1, 1);
  digitalWrite(motorPin2, 0);
  digitalWrite(motorPin3, 0);
  digitalWrite(motorPin4, 1);
}
void forward() {
  //  Serial.print("forward. Speed: ");
  //Serial.println(varSpd);
  analogWrite(EN1, varSpd);
  analogWrite(EN2, varSpd);
  digitalWrite(motorPin1, 0);
  digitalWrite(motorPin2, 1);
  digitalWrite(motorPin3, 1);
  digitalWrite(motorPin4, 0);
}

void left() {
  //  Serial.print("left. Speed: ");
  //Serial.println(varSpd);
  analogWrite(EN1, varSpd);
  analogWrite(EN2, varSpd);
  digitalWrite(motorPin1, 1);
  digitalWrite(motorPin2, 0);
  digitalWrite(motorPin3, 1);
  digitalWrite(motorPin4, 0);
}

void right() {
  //  Serial.print("right. Speed: ");
  //Serial.println(varSpd);
  analogWrite(EN1, varSpd);
  analogWrite(EN2, varSpd);
  digitalWrite(motorPin1, 0);
  digitalWrite(motorPin2, 1);
  digitalWrite(motorPin3, 0);
  digitalWrite(motorPin4, 1);
}

void stopAll() {
  analogWrite(EN1, 0);
  analogWrite(EN2, 0);
  digitalWrite(motorPin1, LOW);
  digitalWrite(motorPin2, LOW);
  digitalWrite(motorPin3, LOW);
  digitalWrite(motorPin4, LOW);
}

void sonar() {
  SonarSensor(trigPinFront, echoPinFront);
  distanceFront = distance;
  SonarSensor(trigPinRight, echoPinRight);
  distanceRight = distance;
  SonarSensor(trigPinLeft, echoPinLeft);
  distanceLeft = distance;
  //Serial.print(distanceFront);Serial.print(" "); Serial.print(distanceRight);Serial.print(" "); Serial.print(distanceLeft); Serial.println(" ");

}

I'm not sure if you will need this, but I will provide an image of the code I am using in MIT App Inventor:

I know this is a strange and possibly pretty confusing question, but if you need any more detail or wiring diagrams, just let me know!

Thanks in advance,
transistor_man

Go back to that version, make sure it works, and add the features again, one by one. Test each addition as you go, and save your work frequently under new names.

Yes. I have been trying that. I have tried to get back to my first operational version, but even early versions seem to have new problems that weren't there before. I wish I had more information to provide, but I'm really stumped with this one.

Thanks,
transistor_man

Sounds like a wire has come loose. Check all connections for validity and continuity.

Write simple test programs that individually exercise and test each functionality (motor control, sensors, etc.).

I have checked all the wires now, and none of them seem to have any problems. I made a new test sketch to see if the motor drivers work and if they can be used with PWM to control the speed but still, if I set the speed integer to anything less than 255, none of the motors will spin at all. I think it might be a wiring issue. I am using 2 BTS7960s, and neither of them work unless given full speed. The fact that they both don't work, makes me think it could be a problem in the code, or I wired the drivers up incorrectly. When I look up some tutorials on the BTS7960, the three links that show up have different wiring configurations for the driver. I am confused on what the correct wiring and/or control code would be for them.

Thanks,
transistor_man

You need PWM (analogWrite) to control the motor speed and that appears only on certain pins, depending on which Arduino you have. Please state the type of Arduino.

Look up the Arduino analogWrite reference page to make sure of your motor speed wiring. I know nothing of the motor driver.

Thanks for the quick reply. I am using an Arduino UNO, and I am using analogWrite() to control the speed of the motors on PWM pins 9 and 10. I am PWMing the L_EN and R_EN pins on the driver, and use logic control on pins A0-A3 on the Arduino for the direction of the motors. The logic pins on the BTS7960 are L_PWM and R_PWM in my case, but I believe you can also reverse this and PWM the L_PWM and R_PWM pins on the driver, and control direction by setting the EN pins to high/low. I am currently unaware if there is a correct wiring configuration for the driver, but I believe the current wiring is supposed to work.

Thanks,
transistor_man

It is easy enough to do experiments. Just make sure that the power is off before changing wiring, and that all the grounds are connected.

I have now checked all the wires and did many experiments on the motor drivers. I can only get one driver to spin the motors properly, while the other one does nothing. I have traced the problem down to the 2 PWM pins used for controlling the non operational driver. I then uploaded a simple fade sketch, and connected an LED to the "broken" PWM pins, and they work just fine. I uploaded the motor code again, and tried swapping the wires to the motor drivers and now the second driver works just fine, but the first one doesn't work at all. If I'm correct, I think it may have something to do with my code. I have been staring at this for way too long, and I'm really hoping another pair of eyes may catch my simple mistake. Here are a few snippets:

//Motor Driver 2:

int L_PWM2 = 10;
int R_PWM2 = 9;



//Motor driver 1:
int L_PWM1 = 3;
int R_PWM1 = 11;

and then I declare the pins here:

  pinMode(L_PWM1, OUTPUT);
  pinMode(R_PWM1, OUTPUT);

  pinMode(L_PWM2, OUTPUT);
  pinMode(R_PWM2, OUTPUT);

and I use this simple code to control the motors:


    forward();
    delay(1000);
    backward();
    delay(1000);
    left();
    delay(1000);
    right();
    delay(1000);

This is the code used in each function:


void backward() {

  analogWrite(L_PWM1, 190);
  digitalWrite(R_PWM1, LOW);
  digitalWrite(L_PWM2, LOW);
  analogWrite(R_PWM2, 190);
}
void forward() {

  digitalWrite(L_PWM1, LOW);
  analogWrite(R_PWM1, 190);
  analogWrite(L_PWM2, 190);
  digitalWrite(R_PWM2, LOW);
}

void left() {

  analogWrite(L_PWM1, 190);
  digitalWrite(R_PWM1, LOW);
  analogWrite(L_PWM2, 190);
  digitalWrite(R_PWM2, LOW);
}

void right() {

  digitalWrite(L_PWM1, LOW);
  analogWrite(R_PWM1, 190);
  digitalWrite(L_PWM2, LOW);
  analogWrite(R_PWM2, 190);
}

void stopAll() {

  digitalWrite(L_PWM1, LOW);
  digitalWrite(R_PWM1, LOW);
  digitalWrite(L_PWM2, LOW);
  digitalWrite(R_PWM2, LOW);
}

Is there anything I am missing, or doing wrong here? If you need the full code, I can provide it.

Thank you so much for your time,
transistor_man

I'm not quite sure what you are testing here. You should write a test program that runs only the two motors and does nothing else.

Always post the entire test code (which should be the absolute required minimum code). The error is probably not in the snippets.

You are doing the right things in swapping wires, etc. and I understand your frustration!

Finally. After I have completely removed everything and kept only the code for the motors, I finally got it working!!! :smile: The problem was actually the servo. Not sure why, but calling servo.attach() made the motor drivers do very strange things... Removing the servo code made everything work perfectly! I will try and write some code that doesn't require the servo.h library, so that I can hopefully keep the servo. Not sure if that will help with the servo, but I got what I wanted!

Thank you so, so much for your time and patience,
transistor_man

Sorry, I didn't notice you were using a servo.

The standard servo library conflicts with the analogWrite PWM, knocking out Timer1. Use the ServoTimer2 library to get around that.

Don't try to power the servo from the Arduino 5V pin, that can damage the Arduino. Use a separate power supply for the servo, and connect the grounds.

Wow, it all comes together now! have an external 5V regulator powering the servo separately, so current isn't a problem. I had no clue that the servo library messed with the PWM system. That's great to know! I have learned a ton just from this thread. I wish I could mark multiple comments as answers :wink: Thank you very much!

transistor_man

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.