How to modify the sketch to control a two PWM pins input motor driver?

The attached sketch is for H-Bridge with one PWM pin and two directions inputs motor driver. How to modify it to control a BTS7960 43A motor driver which has two PWM input: R_PWM / L_PWM.
Thanks.

#include <VirtualWire.h>
 
//motor A connected between A01 and A02
//motor B connected between B01 and B02

int STBY = 10; //standby  ////  An integer (more commonly called an int) is a number without a decimal point.


//Motor A
int PWMA = 3; //Speed control 
int AIN1 = 9; //Direction
int AIN2 = 8; //Direction

//Motor B
int PWMB = 5; //Speed control
int BIN1 = 6; //Direction
int BIN2 = 16; //Direction  ////WAS16

const boolean FORWARD = HIGH; ////The const keyword stands for constant. It is a variable qualifier that modifies the behavior of the variable, making a variable "read-only". This means that the variable can be used just as any other variable of its type, but its value cannot be changed. You will get a compiler error if you try to assign a value to a const variable.
const boolean REVERSE = LOW;
float speed_Max = 255; //pwm usually goes from 0-255  ////A float is a floating-point number, which means it is a number that has a decimal place
float speed_Min = 0;
float analogInput_Max = 1023;  ////bool类型只有两个值:true =1 、false=0。
float analogInput_Min = 0;
float analogInput_Middle_X = 515;//ideally it would be analogInput_Max / 2
float analogInput_Middle_Y = 495;//ideally it would be analogInput_Max / 2
float deadBand = 0;
float middleMax = (analogInput_Max / 2) + deadBand;
float middleMin = (analogInput_Max / 2) - deadBand;
boolean pastDirection = FORWARD;

void setup(){
 
 Serial.begin( 9600 );
 
 pinMode(STBY, OUTPUT); //// pin: the number of the pin whose mode you wish to set; mode: INPUT, OUTPUT, or INPUT_PULLUP.
 
 pinMode(PWMA, OUTPUT);
 pinMode(AIN1, OUTPUT);
 pinMode(AIN2, OUTPUT);
 
 pinMode(PWMB, OUTPUT);
 pinMode(BIN1, OUTPUT);
 pinMode(BIN2, OUTPUT);
 
 //receiver setup
 vw_set_rx_pin(2);          //Sets pin 12 as the RX Pin  //// should be pin '2'
 vw_set_ptt_inverted(true); // Required for DR3100
 vw_setup(2000);            // Bits per sec
 vw_rx_start();             // Start the receiver PLL running
}

void loop(){

 uint8_t buf[VW_MAX_MESSAGE_LEN]; // This declares a variable array. instead of 7 variables buf1, buf2 etc...
 uint8_t buflen = VW_MAX_MESSAGE_LEN;
 if (vw_get_message(buf, &buflen)) // Non-blocking
 {
 int i;
    int column = 0;
    String message;
    int commands[30];
    
        // Message with a good checksum received, dump it. 
        for (i = 0; i < buflen; i++)
        {     
         //DEBUG:
         Serial.print(char(buf[i]));
         
         if(char(buf[i]) == '|'){
         commands[column] = message.toInt();
         message = "";
         column++;
         }else{
         message += char(buf[i]);
         }
        }
        //one more time to capture the last value since the message does not end with |
        commands[column] = message.toInt();
        
        // DEBUG 
// Serial.print("X: "); 
// Serial.print(commands[0]);
// Serial.print(" Y: ");
// Serial.println(commands[1]);
 
 motorControl(commands[0], commands[1]);
 
 }
 
}

void move(int motor, int speed, boolean direction){
 digitalWrite(STBY, HIGH); //disable standby //// Write a HIGH or a LOW value to a digital pin.
 
 if(motor == 1){
 digitalWrite(AIN1, direction);
 digitalWrite(AIN2, !direction);
 analogWrite(PWMA, speed);   //// Writes an analog value (PWM wave) to a pin.
 }else{
 digitalWrite(BIN1, !direction);
 digitalWrite(BIN2, direction);
 analogWrite(PWMB, speed);
 }
}

void motorControl(float x, float y) {
 boolean currentDirection = y >= analogInput_Middle_Y;

 //map(value, fromLow, fromHigh, toLow, toHigh);
 if(currentDirection == REVERSE){
 y = map(y, analogInput_Middle_Y, analogInput_Min, speed_Min, speed_Max) ;  
 }else{
 y = map(y, analogInput_Middle_Y, analogInput_Max, speed_Min, speed_Max);
 }
  
 int subtractFromLeft = map(x, analogInput_Middle_X, analogInput_Min, speed_Min, y);
 int subtractFromRight = map(x, analogInput_Middle_X, analogInput_Max, speed_Min, y);

 if(subtractFromRight < 0){
 subtractFromRight = 0;
 }
 
 if(subtractFromLeft < 0){
 subtractFromLeft = 0;
 }
 
 int Throttle_RIGHT = y - subtractFromRight;
 int Throttle_LEFT = y - subtractFromLeft;
 
 boolean currentDirection_LEFT = currentDirection;
 boolean currentDirection_RIGHT = currentDirection;
 
 
 if(Throttle_LEFT < 1 && Throttle_RIGHT > 1){
 currentDirection_LEFT = !currentDirection; ////如果值为true,则!运算后为false
 Throttle_LEFT = Throttle_RIGHT;
 }
 
 if(Throttle_RIGHT < 1 && Throttle_LEFT > 1){
 currentDirection_RIGHT = !currentDirection;
 Throttle_RIGHT = Throttle_LEFT;
 }
 
 move(1, Throttle_LEFT, currentDirection_LEFT);
 move(2, Throttle_RIGHT, currentDirection_RIGHT);
 
// Serial.print("Throttle_LEFT: ");
// Serial.print(Throttle_LEFT);
// Serial.print(" Throttle_RIGHT: ");
// Serial.print(Throttle_RIGHT);
// Serial.println("");
// 
// if(Throttle_LEFT >= -400 && Throttle_LEFT <= 400){
// motors.setM1Speed( Throttle_LEFT );
// }
// 
// if(Throttle_RIGHT >= -400 && Throttle_RIGHT <= 400){
// motors.setM2Speed( Throttle_RIGHT );
// }
// delay(2);
  
}

The attached sketch

Looks like you forgot a step, like actually attaching the code.

is for H-Bridge with one PWM pin and two directions

Two directions implies that it is a dual H bridge, for controlling two motors. If it is, it must have 2 PWM pins, to control the speed of each independently.

PaulS:
Looks like you forgot a step, like actually attaching the code.
Two directions implies that it is a dual H bridge, for controlling two motors. If it is, it must have 2 PWM pins, to control the speed of each independently.

Thank you PaulS.
I reattached the code.

The Motor Driver BTS7960 43A used here: Double BTS7960B DC 43A Stepper Motor Driver H-Bridge PWM For Arduino Smart Car | eBay

is a single bridge that can control only one motor, but need two PWM input. that's why can't use one Arduino to control a car. what can be done with it?

The Motor Driver BTS7960 43A used here

An ebay link is useless.

The usual way to control a motor driver that requires separate PWM signals for FWD and REV is like this

if (direction == 'F') {
  digitalWrite(revPin, LOW);
  analogWrite(fwdPin, pwmVal);
}
else {
  digitalWrite(fwdPin, LOW);
  analogWrite(revPin, pwmVal);
}

...R

Robin2:
The usual way to control a motor driver that requires separate PWM signals for FWD and REV is like this

if (direction == 'F') {

digitalWrite(revPin, LOW);
  analogWrite(fwdPin, pwmVal);
}
else {
  digitalWrite(fwdPin, LOW);
  analogWrite(revPin, pwmVal);
}




...R

Thank you Robin2.

The sketch attached is for a type of motor driver that used one PWM input and two pins to control the directions of one motor.

But here need two PWM input and two EN pins to control one motor, how to control two motors ?

laoadam:
how to control two motors ?

Two times what is needed to control one motor :slight_smile:

You can probably set the enable pins in setup() and leave them set. Or just tie them to the appropriate voltage in hardware.

...R

Robin2:
Two times what is needed to control one motor :slight_smile:

You can probably set the enable pins in setup() and leave them set. Or just tie them to the appropriate voltage in hardware.

...R

thank you, how to set two timers? and set the PWM frequency of ~20K.

laoadam:
thank you, how to set two timers? and set the PWM frequency of ~20K.

What two timers?

Google should find you the instructions for changing the Arduino PWM frequency - or study the relevant Atmel datasheet. It is not the sort of thing my brain remembers. DO NOT change the settings for HardwareTimer0 as it is used for millis() and micros()

...R

void move(int motor, int speed, boolean direction){
 
 if(motor == 1){
   if(direction) {
     digitalWrite(AIN1, LOW);
     analogWrite(AIN2, speed);  
   } else  {
     digitalWrite(AIN2, LOW);
     analogWrite(AIN1, speed);  
   }
 }else{
    if(direction) {
     digitalWrite(BIN1, LOW);
     analogWrite(BIN2, speed);  
   } else  {
     digitalWrite(BIN2, LOW);
     analogWrite(BIN1, speed);  
   }
 }
}

Robin2:
What two timers?

Google should find you the instructions for changing the Arduino PWM frequency - or study the relevant Atmel datasheet. It is not the sort of thing my brain remembers. DO NOT change the settings for HardwareTimer0 as it is used for millis() and micros()

...R

Thank you Robin2.

In this case, Timer0 and Timer1 (conflict with VW) can't be used, even the UNO don't have enough pins for 4 PWM, do I have to pick MEGA? or do you have a recommendation which board better?

Here is a knowledge question, is it possible to setup Timer3 & Timer4 at void setup parallel? can this setup enable 4 PWM pins say in MEGA2560? if not change the PWM frequency, can I use any PWM compatible pin as PWM output no matter which Timer it belongs to?

MorganS:

void move(int motor, int speed, boolean direction){

if(motor == 1){
  if(direction) {
    digitalWrite(AIN1, LOW);
    analogWrite(AIN2, speed);

Thank you MorganS,

Sorry I didn't catch your meaning, the old sketch used Ain/Bin for a TB6612FNG dual motor driver that has Ain/Bin pins. The new motor driver is BTS7960 has only LPWM/RPWM to control the direction and speed simultaneously。

laoadam:
do I have to pick MEGA? or do you have a recommendation which board better?

A Mega seems like a good idea as it has more Timers and hence more PWM pins.

Here is a knowledge question, is it possible to setup Timer3 & Timer4 at void setup parallel? can this setup enable 4 PWM pins say in MEGA2560?

Yes

if not change the PWM frequency, can I use any PWM compatible pin as PWM output no matter which Timer it belongs to?

I don't understand what you have in mind. Each PWM pin is associated with a specfic Timer - 2 pins per Timer.

...R

Robin2:
A Mega seems like a good idea as it has more Timers and hence more PWM pins.
Yes

I don't understand what you have in mind. Each PWM pin is associated with a specfic Timer - 2 pins per Timer.

...R

Thank you Robin2,

What I mean is if I just use the system PWM frequency, say Arduino UNO has ~490Hz, and don't specific any Timer, can I use all PWM pins as output pin?

Sorry I didn't catch your meaning, the old ...

You can name the pins whatever you want. I just used the shorter names because I'm typing on a phone.

laoadam:
Thank you Robin2,

What I mean is if I just use the system PWM frequency, say Arduino UNO has ~490Hz, and don't specific any Timer, can I use all PWM pins as output pin?

The PWM pins are directly linked to the hardware timers. You can't reassign them.

Try this, which only uses 2 PWM pins...

void move(int motor, int speed, boolean direction){
 
 if(motor == 1){
   if(direction) {
     digitalWrite(AIN1, LOW);
     analogWrite(AIN2, speed);  
   } else  {
     digitalWrite(AIN1, HIGH);
     analogWrite(AIN2, 255-speed);  
   }
 }else{
    if(direction) {
     digitalWrite(BIN1, LOW);
     analogWrite(BIN2, speed);  
   } else  {
     digitalWrite(BIN1, HIGH);
     analogWrite(BIN2, 255-speed);  
   }
 }
}

MorganS:
Try this, which only uses 2 PWM pins...

That's clever. But some drivers treat both pins HIGH as a braking situation.

...R

MorganS:
You can name the pins whatever you want. I just used the shorter names because I'm typing on a phone.
The PWM pins are directly linked to the hardware timers. You can't reassign them.

Try this, which only uses 2 PWM pins...

void move(int motor, int speed, boolean direction){

if(motor == 1){
  if(direction) {
    digitalWrite(AIN1, LOW);
 
Thank you MorganS.

I'll test them out.

Robin2:
A Mega seems like a good idea as it has more Timers and hence more PWM pins.
Yes

I don't understand what you have in mind. Each PWM pin is associated with a specfic Timer - 2 pins per Timer.

...R

Another question is when hookup the L_EN/R_EN to UNO, the motor doesn't run even set the both pin 'HIGH', but hookup L_EN/R_EN to Vcc by breadboard, the motor runs. why?

Again, here is a code sample, it used pin 5/6, can it use pin3/11 instead of?

/*........................
BTS7960 Motor Driver Test
Written By : Mohannad Rawashdeh
Code for :

*/
int RPWM=5;
int LPWM=6;
// timer 0
int L_EN=7;
int R_EN=8;

laoadam:
Another question is when hookup the L_EN/R_EN to UNO, the motor doesn't run even set the both pin 'HIGH', but hookup L_EN/R_EN to Vcc by breadboard, the motor runs. why?

Could be a bad connection or a missing GND connection.

Again, here is a code sample, it used pin 5/6, can it use pin3/11 instead of?

Please post the complete program and use code tags.
codeButton.png

so your code looks like this

...R

laoadam:
Another question is when hookup the L_EN/R_EN to UNO, the motor doesn't run even set the both pin 'HIGH', but hookup L_EN/R_EN to Vcc by breadboard, the motor runs. why?

Again, here is a code sample, it used pin 5/6, can it use pin3/11 instead of?

/*........................
BTS7960 Motor Driver Test
Written By : Mohannad Rawashdeh
Code for :
Mohannad Rawashdeh's Activity - Instructables
*/
int RPWM=5;
int LPWM=6;
// timer 0
int L_EN=7;
int R_EN=8;

Robin2:
Could be a bad connection or a missing GND connection.
Please post the complete program and use code tags.
codeButton.png

so your code looks like this

...R

Thank you.

/*........................
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);
}