Introduction: Motor Driver BTS7960 43A

Picture of Motor Driver BTS7960 43A

When you Build Your project , Sometimes you faced some issue with Motor driving Control , Specially if you want to control High Power Motor , I want to write about a nice Motor driver Module , it's BTS7960 half bridge motor controller .

The BTS 7960 is a fully integrated high current half , bridge for motor drive applications , comes with Two package as in pictures .

The Operating Voltage of 24V And Continuous current of 43A Max  , PWM capability of up to 25 kHz combined with active freewheeling 

In this artical I want to show you How we can use it with arduino and control High power Motor , And change The PWM Frequency of the arduino .

Step 1: Inside the Datasheet

Picture of Inside the Datasheet

The datasheet for this IC Give us useful data 

this IC Have a good protection  circuit such as :

1) Undervoltage Shut Down: To avoid uncontrolled motion of the driven motor at low voltages the device shuts off . 
if the Supply voltage VUV(OFF) droped under 5.4V , The Motor driver will switched Off , And won't turned on untill the Supply voltage increased to 5.5V Or more .

2)Overtemperature Protection: The BTS 7960 is protected against overtemperature by an integrated temperature
sensor. Overtemperature leads to a shut down of both output stages.

3)Current Limitation : The current in the bridge is measured in both switches, High and Low side ,if The current reaching the limit current (Iclx)  the switch is deactivated and the other switch is activated for a certain time(Tcls).

You can read The datasheet for more info 

Step 2: Connect It to the Arduino

Picture of Connect It to the Arduino
The connection of  this module to Arduino Board is shown in schematic Below , 2 PWM Pin must connected to PWM Pin on the arduino , EN pin connected to digital pin on the arduino , The motor driver channel Will be disable if EN Pin is LOW .

Simple code for arduino below .

/*........................
BTS7960 Motor Driver Test
Written By : Mohannad Rawashdeh
Code for :
https://www.instructables.com/member/Mohannad+Rawashdeh/
*/
int RPWM=5;
int LPWM=6;
// timer 0
int L_EN=7;
int R_EN=8;

void setup() {
  // put your setup code here, to run once:
  for(int i=5;i<9;i++){
   pinMode(i,OUTPUT);
  }
   for(int i=5;i<9;i++){
   digitalWrite(i,LOW);
  }
   delay(1000);
    Serial.begin(9600);
  }



void loop() {
  // put your main code here, to run repeatedly:
  Serial.println("EN High");
  digitalWrite(R_EN,HIGH);
  digitalWrite(L_EN,HIGH);
delay(1000);
for(int i=0;i<256;i++){
  analogWrite(RPWM,i);
//  analogWrite(LPWM,255-i);
  delay(100);
}
delay(500);
for(int i=255;i>0;i--){
  analogWrite(RPWM,i);
// analogWrite(LPWM,255-i);
  delay(100);
}
delay(500);
Serial.println("EN LOW");
digitalWrite(R_EN,LOW);
  digitalWrite(L_EN,LOW);
delay(1000);
for(int i=0;i<256;i++){
  analogWrite(RPWM,i);
  delay(100);
}
delay(500);
for(int i=255;i>0;i--){
  analogWrite(RPWM,i);
  delay(100);
}
delay(500);
}

And this is a video to show how this code works 

the PWM Frequency on the arduino UNO Atmega328p - Timer0 is 970Hz , This is a low PWM Frequency , in the next step we want to increase PWM Frequency .

Step 3: PWM ... Arduino Timer

Picture of PWM ... Arduino Timer

arduino Uno atmega 328p MCU has 3 timers , Time0,,Time2 8 Bit and Time1 16Bit  

Timer0 is connected to pin D5 , D6  , we want to increase the frequency "More smoothly control " 

Note That Timer0 is control the  (delay , millis ) on the arduino , so any change on the prescale of this timer will change the delay and millis time .

int RPWM=5;
int LPWM=6;
int L_EN=7;
int R_EN=8;

  void setPWMfrequency(int freq){
   TCCR0B = TCCR0B & 0b11111000 | freq ;
  }
 
  void MotorActiveStatus(char Side,boolean s){
    boolean state=s;
    if(Side=='R'){
    digitalWrite(R_EN,s);
    }
    if(Side=='L'){
    digitalWrite(L_EN,s);
    }    
  }
  void setMotor(char side,byte pwm){
   if(side=='R'){
    analogWrite(RPWM,pwm);
   }
    if(side=='L'){
    analogWrite(LPWM,pwm);
   }
  }
  void closeMotor(char side){
     if(side=='R'){
    digitalWrite(RPWM,LOW);
     }
     if(side=='L'){
    digitalWrite(LPWM,LOW);
     }

     }
void setup() {
  // put your setup code here, to run once:
  setPWMfrequency(0x02);// timer 0 , 3.92KHz
  for(int i=5;i<9;i++){
   pinMode(i,OUTPUT);
  }
   for(int i=5;i<9;i++){
   digitalWrite(i,LOW);
  }
   delay(1000);
   MotorActiveStatus('R',true);
   MotorActiveStatus('L',true);
    Serial.begin(9600);
  }

void loop() {
  // put your main code here, to run repeatedly:
for(int i=0;i<256;i++){
  setMotor('R',i);
  delay(500);
}
delay(1000);
closeMotor('R');
delay(1000);
  for(int i=0;i<256;i++){
  setMotor('L',i);
  delay(500);
}
delay(1000);
closeMotor('L');
delay(1000);
}

if we want to use this code with another timer " timer 2 " just change  D5 , D6 To pin D3 , D11 Respectively

int RPWM=3;
int LPWM=11;
int L_EN=7;
int R_EN=8;

  void setPWMfrequency(int freq){
   TCCR2B = TCCR2B & 0b11111000 | freq ;
  }
 
  void MotorActiveStatus(char Side,boolean s){
    boolean state=s;
    if(Side=='R'){
    digitalWrite(R_EN,s);
    }
    if(Side=='L'){
    digitalWrite(L_EN,s);
    }    
  }
  void setMotor(char side,byte pwm){
   if(side=='R'){
    analogWrite(RPWM,pwm);
   }
    if(side=='L'){
    analogWrite(LPWM,pwm);
   }
  }
  void closeMotor(char side){
     if(side=='R'){
    digitalWrite(RPWM,LOW);
     }
     if(side=='L'){
    digitalWrite(LPWM,LOW);
     }

     }
void setup() {
  // put your setup code here, to run once:
  setPWMfrequency(0x02);// timer 2 , 3.92KHz
  for(int i=5;i<9;i++){
   pinMode(i,OUTPUT);
  }
   for(int i=5;i<9;i++){
   digitalWrite(i,LOW);
  }
   delay(1000);
   MotorActiveStatus('R',true);
   MotorActiveStatus('L',true);
    Serial.begin(9600);
  }

void loop() {
  // put your main code here, to run repeatedly:
for(int i=0;i<256;i++){
  setMotor('R',i);
  delay(50);
}
delay(500);
closeMotor('R');
delay(1000);
  for(int i=0;i<256;i++){
  setMotor('L',i);
  delay(50);
}
delay(500);
closeMotor('L');
delay(1000);
}

 

Step 4: Arduino Mega Timer

Picture of Arduino Mega Timer

For arduino MEGA 2560 ,  it has 5 timers  : 

timer 0 (controls pin 13, 4)
timer 1 (controls pin 12, 11)
timer 2 (controls pin 10, 9)
timer 3 (controls pin 5, 3, 2)
timer 4 (controls pin 8, 7, 6)

This code For arduino mega with Timer 1 and 3  :

// code for Arduino Mega2560 and BTS7960 Motor driver
// written by : Mohannad Rawashdeh

int RPWM=3;
int LPWM=11;
int L_EN=7;
int R_EN=8;

  void setPWMfrequency(int freq){
    TCCR1B = TCCR2B & 0b11111000 | freq ;
    TCCR3B = TCCR2B & 0b11111000 | freq ;
  }
 
  void MotorActiveStatus(char Side,boolean s){
    boolean state=s;
    if(Side=='R'){
    digitalWrite(R_EN,s);
    }
    if(Side=='L'){
    digitalWrite(L_EN,s);
    }    
  }
  void setMotor(char side,byte pwm){
   if(side=='R'){
    analogWrite(RPWM,pwm);
   }
    if(side=='L'){
    analogWrite(LPWM,pwm);
   }
  }
  void closeMotor(char side){
     if(side=='R'){
    digitalWrite(RPWM,LOW);
     }
     if(side=='L'){
    digitalWrite(LPWM,LOW);
     }

     }
void setup() {
  // put your setup code here, to run once:
  setPWMfrequency(0x02);// timer 2 , 3.92KHz
  for(int i=5;i<9;i++){
   pinMode(i,OUTPUT);
  }
   for(int i=5;i<9;i++){
   digitalWrite(i,LOW);
  }
   delay(1000);
   MotorActiveStatus('R',true);
   MotorActiveStatus('L',true);
    Serial.begin(9600);
  }

void loop() {
  // put your main code here, to run repeatedly:
for(int i=0;i<256;i++){
  setMotor('R',i);
  delay(50);
}
delay(500);
closeMotor('R');
delay(1000);
  for(int i=0;i<256;i++){
  setMotor('L',i);
  delay(50);
}
delay(500);
closeMotor('L');
delay(1000);
}

Comments

laoadam (author)2017-10-22

Hi,

do you have the detail for how to connect a joystick to it and control the car?

Thanks

Adam

what type of a joystick you have ?

Hi Mohannad thanks for your reply,
right now I have a 'Nintendo Nunchuk Controller '
like this:
https://www.amazon.co.uk/Nintendo-Nunchuk-Controller-Add-On-Wii/dp/B000IMYKQ0

If this no work, I can buy whatever working joystick.
Thanks
Adam

for Nintendo Nunchuk Controller I don't know how it works "i don't have one either " but for other Joystick (for example like this : https://goo.gl/xQH5hi or this https://goo.gl/iqp5AN ) the joystick has x and y axis and give you 2 analouge signal for each axis , after that you can use your arduino board to see the voltage value for each axis .

now how do you want to control the car ? wireless ? like bluetooth or wifi or RF ?

RichardR246 (author)2017-03-13

HI,

I have a Nema 17, which I like to use bts7960. Do I use the VCC to supply 24v power to the motor.

no for nema 17 you need to connect the power supply with 12V

better alternative : A4988

fbyic2015 (author)2015-11-03

hi

how or where can i download the bts7960 library for arduino?

DonaldC32 (author)fbyic20152017-03-10

You don't need a hardware specific library for this hardware, it is built for arduino, just use the standard PWM library, and that should take care of it.

druid442 (author)fbyic20152016-03-17

there is no library

Jaket78 (author)2016-09-06

I am having a little trouble with the code. I don't understand the portion under "void setup" I managed to get it to work like the fan in the video. However, I am trying to set it up on a tracked RC tank. I am looking for the most basic code that will turn the motor one direction and the code to turn it another direction. I have used Hbridges before but the having to use the L_EN and R_EN I don't understand their use. Could someone post the very basic code to spin the motor in one direction and then stop it and reverse at a set speed.

farmerkeith (author)Jaket782016-09-06

Hi Jake,

There are lots of things I could say about this software. It could be clearer to read and better performance for the computer (Arduino). However I will just try to get you going.

The code under "void setup" is first:

for(int i=5;i<9;i++){
pinMode(i,OUTPUT);
}

This is a loop that sets pins 5, 6, 7 and 8 as OUTPUT. These 4 pins are the ones used for RPWM, LPWM, L_EN and R_EN (note the order goes R, L, L, R - if I had been doing it I would have used R, L, R, L and avoid the crossover in the wiring).

The next few lines are:

for(int i=5;i<9;i++){
digitalWrite(i,LOW);
}

Another loop, this time to set pins 5, 6, 7 and 8 to LOW (ie logic 0).

Then there is a 1 second delay, and the serial monitor is started.

Now under void loop ()

First we turn on both Enable pins:

digitalWrite(R_EN,HIGH);
digitalWrite(L_EN,HIGH);

After a delay, ramp up the PWM on the RPWM pin:

for(int i=0;i<256;i++){
analogWrite(RPWM,i);
// analogWrite(LPWM,255-i);
delay(100);
}

Note that the 3rd line is commented out (// analogWrite(LPWM,255-i);) so it does nothing. At the moment LPWM is LOW, due to setup() when it was set to LOW.

So the motor will gradually increase in speed, in steps of 1/256, from 1/256 to 255/256, increasing one step every 100 ms. It will take about 25 seconds to go from stopped to full speed.

The next section of code ramps the speed down from full to zero.

I believe the next section of code after that is intended to run the motor backwards, but there are two errors so it does nothing.

Here is the code "as is" with my comments:

Serial.println("EN LOW"); // prints to serial monitor, no effect on motor
digitalWrite(R_EN,LOW); // disable Right motor driver
digitalWrite(L_EN,LOW); // disable Left motor driver
delay(1000);
for(int i=0;i<256;i++){
analogWrite(RPWM,i); // RPWM ramp as before,

// does nothing because motor driver is disabled
delay(100);
}
delay(500);
for(int i=255;i>0;i--){
analogWrite(RPWM,i); RPWM ramp as before,

delay(100);
}
delay(500);
}

The simplest fix is to get rid of the two lines that disable the motor drivers (eg comment them out with // at the beginning of the line).

And then change the two analogWrite lines from RPWM to LPWM.

So now it looks like this:

delay(1000);
for(int i=0;i<256;i++){
analogWrite(LPWM,i); // LPWM rampup

delay(100);
}
delay(500);
for(int i=255;i>0;i--){
analogWrite(LPWM,i); LPWM ramp down

delay(100);
}

I hope this helps.

I have not tested this code.

See also comment from OlegK34 who does not mention changing the RPWMs to LPWMs. But I think he must have.

Good luck,

Keith

OlegK34 made it! (author)2016-08-06

First and foremost, thank you for detailed and thorough instruction

Using the very first code example my motor would only turn in one direction, and after long wait, repeat.

It turns out the problem was in the second part of code where the motor is supposed to change direction. Particularly, these two lines:

digitalWrite(R_EN,LOW);
digitalWrite(L_EN,LOW);

render motor off.

When changed to

digitalWrite(R_EN,HIGH);
digitalWrite(L_EN,HIGH);

everything worked nicely, just like in the video.

I guess, these lines might be useful between cycles when the motor might need to be turned off intentionally.

Again, many thanks, hope my observation might be of use for the next maker.

Cheers,

O.K.

AliK140 (author)2016-05-02

Because from where i brought it they said it can be used for 2 motors plz help me

farmerkeith (author)AliK1402016-06-15

Alik140, With this module you can control one motor in both directions (forward and reverse) or 2 motors each in one direction only. I hope you found your answer somewhere else before this.

AliK140 (author)2016-05-02

Because from where i brought it they said it can be used for 2 motors plz help me

AliK140 (author)2016-05-02

Can anyone tell me that this module can be used to control 2 dc motor or not?

druid442 (author)2016-03-17

hi !

tell me if i'm wrong, but this way i will be able to have full power even at slow speed ?

have a nice day

DwijadasS (author)2015-07-11

Hi, I think I am too excited after seeing this tutorial.

I am making a mini lift system between ground-first floor to carry stuffs weight 10kg or less. I am planning to use this Driver to control a DC motor. Since its a lift I need to make gradual speed decrease stop and gradual speed increment from start.

Is it possible to do using this Driver ? (demo video speed increases, I think its possible to increase decrease gradually)

thyish (author)2015-03-01

Thanks for the instruction. I also have some questions about the BTS7960,

Do you think it would work for brushless dc motor that has 3 input instead of 2? Can I just add another BTS7960 to total up to 3 in the same board? Do you have any suggestion on that?

Thanks

laptophead (author)2014-05-31

Mohanad,

Thanks for the nice instructions. I got some questions.

I thought this was a 2 motor driver? Not possible?

What is the advantage of going on high freq PMW? Why is not 1000Hz good enough?

Why do you need to send PMW on 2 pins to control one motor?

I have two of these modules. Can one arduino mega run two motors at different speeds at the same time? Ramp up and down is based on delay. That would affect the other motor. Right? Is there a way to do it?

Thanks.

AlexC23 (author)laptophead2015-02-12

This module has 2 half bridges on board, thus one H bridge so it will control the speed and direction of 1 motor as far as I know.

I'm using two of these at the moment, one on each motor.

jjdorris (author)laptophead2014-12-30

I know this is kind of a late reply but you can control the speed of two different motors at different rates. You need to use the registers rather than trying to code around it. I think this article does a pretty good job of explaining the process:

http://letsmakerobots.com/node/28278

Here's another (to me) not so clear explanation from the Arduino website:

http://letsmakerobots.com/node/28278

Hope this helps.

Jim

jjdorris (author)jjdorris2014-12-30

Oops, accidentally pasted the same link twice. Here's the second one:

http://arduino.cc/en/Tutorial/SecretsOfArduinoPWM

Jim

About This Instructable

74,258views

88favorites

License:

Bio: Maker, PCB designer , electronics instructor from Jordan just one word ! I Adore electronics follow me on FB https://www.facebook.com/Mohannad-Rawashdeh-Raw-774983565988641/
More by Mohannad Rawashdeh:Convert Your Pringles Cans to RTTTL Audio PlayerTTP224 Digital Touch Sensor Applications Using ArduinoRF 315MHz/433MHz Wireless and Arduino...again!
Add instructable to: