|
|
View previous topic :: View next topic |
Author |
Message |
PrinceNai
Joined: 31 Oct 2016 Posts: 471 Location: Montenegro
|
IBT-2 H-Bridge module with two BTS7960 chips |
Posted: Fri Feb 24, 2023 11:01 am |
|
|
I bought myself this module and gave it a try. Works as advertised
Code: |
/* IBT-2 H-Bridge module is a high power motor driver based on two BTS7960 chips.
It has 6 control pins:
R_IS forward drive alarm output - side current, not used
L_IS backward drive alarm output - side current, not used
R_EN forward drive enable, active HIGH
L_EN backward drive enable, active HIGH
R_PWM forward PWM or HIGH to rotate RIGHT
L_PWM backward PWM or HIGH to rotate LEFT
...............................................................
Control logic works from 3,3V to 5V.
...............................................................
Rotation (right and left are subjective):
R_EN and L_EN are both driven HIGH.
Two hardware PWM signals from PIC connected to R_PWM and L_PWM.
If RIGHT rotation is desired, L_PWM is LOW and PWM signal is fed to R_PWM.
If LEFT rotation is desired, R_PWM is LOW and PWM signal is fed to L_PWM.
Speed is somewhat proportional to PWM duty cycle.
Stop:
Both R_EN and L_EN driven low, PWM disabled on both streams.
...............................................................
*/
#include <18F46K22.h>
#device ADC=10
#FUSES NOWDT, NOPUT //No Watch Dog Timer, NOPUT for debug
// #FUSES PUT
#device ICD=TRUE
#use delay(internal=32000000)
#USE PWM(OUTPUT=PIN_C2, FREQUENCY=8005Hz, DUTY=0, stream = RIGHT, PWM_ON) // CCS complains on 8000Hz with resolution of 9,97 bits. This gives full 10 bit PWM resolution.
#USE PWM(OUTPUT=PIN_C1, FREQUENCY=8005Hz, DUTY=0, stream = LEFT, PWM_ON) // 8kHz PWM, period 125us
// ****************************************************************************
int16 SPEED = 0;
#DEFINE R_EN PIN_B0
#DEFINE L_EN PIN_B1
#DEFINE R_PWM PIN_C2
#DEFINE L_PWM PIN_C1
// *********************** FUNCTIONS **************************
void MOTOR_RIGHT(int16 SPEED_OF_MOTOR){
output_high(L_EN);
output_high (R_EN);
pwm_off(LEFT); // turn off LEFT PWM
output_low(L_PWM); // drive pin LOW
pwm_on(RIGHT); // start RIGHT PWM
pwm_set_duty_percent(RIGHT, SPEED_OF_MOTOR); // set PWM1 duty cycle percentage to SPEED, 0 - 1000
}
// ............................................................
void MOTOR_LEFT(int16 SPEED_OF_MOTOR){ // same as above, other direction
output_high(R_EN);
output_high (L_EN);
pwm_off(RIGHT);
output_low(R_PWM); // turn OFF right PWM
pwm_on(LEFT);
pwm_set_duty_percent(LEFT, SPEED_OF_MOTOR); // set PWM2 duty cycle percentage
}
// ............................................................
void MOTOR_STOP (void){
output_low(R_EN); // stop the motor
output_low(L_EN);
pwm_off(RIGHT);
pwm_off(LEFT);
}
// ******************* END OF FUNCTIONS ***********************
void main(){
while(TRUE){
// play some with the motor. If you use a big one, bolt it down :-)
SPEED = 0; // ramp up speed right and left
while (SPEED <= 1010){
MOTOR_RIGHT(SPEED);
SPEED = SPEED + 10;
delay_ms(50);
}
MOTOR_STOP();
delay_ms(50);
SPEED = 0;
while (SPEED <= 1010){
MOTOR_LEFT(SPEED);
SPEED = SPEED + 10;
delay_ms(50);
}
MOTOR_STOP();
delay_ms(50);
MOTOR_RIGHT(1000); // full-on right
delay_ms(2000);
MOTOR_STOP();
delay_ms(50);
MOTOR_LEFT(1000); // full-on left
delay_ms(2000);
MOTOR_STOP();
delay_ms(50);
MOTOR_RIGHT(500); // half speed right
delay_ms(2000);
MOTOR_STOP();
delay_ms(50);
MOTOR_LEFT(500); // half speed left
delay_ms(2000);
MOTOR_STOP();
delay_ms(50);
} // while TRUE
} // MAIN
|
|
|
|
PrinceNai
Joined: 31 Oct 2016 Posts: 471 Location: Montenegro
|
|
Posted: Sun Feb 26, 2023 10:43 am |
|
|
Added the ability to control the motor via a pot on AN0.
Code: |
/* IBT-2 H-Bridge module is a high power motor driver based on two BTS7960 chips.
It has 6 control pins:
R_IS forward drive alarm output - side current, not used
L_IS backward drive alarm output - side current, not used
R_EN forward drive enable, active HIGH
L_EN backward drive enable, active HIGH
R_PWM forward PWM or HIGH to rotate RIGHT
L_PWM backward PWM or HIGH to rotate LEFT
...............................................................
Control logic works from 3,3V to 5V.
...............................................................
Rotation (right and left are subjective):
R_EN and L_EN are both driven HIGH.
Two hardware PWM signals from PIC connected to R_PWM and L_PWM.
If RIGHT rotation is desired, L_PWM is LOW and PWM signal is fed to R_PWM.
If LEFT rotation is desired, R_PWM is LOW and PWM signal is fed to L_PWM.
Speed is somewhat proportional to PWM duty cycle.
Stop:
Both R_EN and L_EN driven low, PWM disabled on both streams.
...............................................................
*/
#include <18F46K22.h>
#device ADC=10
#FUSES NOWDT, NOPUT //No Watch Dog Timer, NOPUT for debug
// #FUSES PUT
#device ICD=TRUE
#use delay(internal=32000000)
#USE PWM(OUTPUT=PIN_C2, FREQUENCY=8005Hz, DUTY=0, stream = RIGHT, PWM_ON) // CCS complains on 8000Hz with resolution of 9,97 bits. This gives full 10 bit PWM resolution.
#USE PWM(OUTPUT=PIN_C1, FREQUENCY=8005Hz, DUTY=0, stream = LEFT, PWM_ON) // 8kHz PWM, period 125us
#use rs232(UART1,baud=19200, bits = 8, parity=N,stream = DEBUG,errors) // output RAW ADC readings
// ****************************************************************************
#DEFINE R_EN PIN_B0
#DEFINE L_EN PIN_B1
#DEFINE R_PWM PIN_C2
#DEFINE L_PWM PIN_C1
// ********************** VARIABLES ***************************
int16 SPEED = 0; // desired speed of the motor, 0 - 1000
int16 ADC_VAL = 0; // ADC reading
signed int32 Temp = 0; // used to transform ADC readings to speed and direction info
// *********************** FUNCTIONS **************************
void MOTOR_RIGHT(int16 SPEED_OF_MOTOR){
output_high(L_EN);
output_high (R_EN);
pwm_off(LEFT); // turn off LEFT PWM
output_low(L_PWM); // drive pin LOW
pwm_on(RIGHT); // start RIGHT PWM
pwm_set_duty_percent(RIGHT, SPEED_OF_MOTOR); // set PWM1 duty cycle percentage to SPEED, 0 - 1000
}
// ............................................................
void MOTOR_LEFT(int16 SPEED_OF_MOTOR){ // same as above, other direction
output_high(R_EN);
output_high (L_EN);
pwm_off(RIGHT);
output_low(R_PWM); // turn OFF right PWM
pwm_on(LEFT);
pwm_set_duty_percent(LEFT, SPEED_OF_MOTOR); // set PWM2 duty cycle percentage
}
// ............................................................
void MOTOR_STOP (void){
output_low(R_EN); // stop the motor
output_low(L_EN);
pwm_off(RIGHT);
pwm_off(LEFT);
}
// ............................................................
int16 READ_AN0 (void){
int16 val;
set_adc_channel(0);
delay_us(3);
val = read_adc(); // values from 0 - 1023
fprintf(DEBUG, "\n\rADCraw:%lu", val); // print raw ADC values to debug port
return val;
}
// ******************* END OF FUNCTIONS ***********************
void main(){
//TAD must be at last 1us
setup_adc_ports(sAN0, VSS_VDD);
setup_adc(ADC_CLOCK_DIV_32 | ADC_TAD_MUL_20); // TAD 1us, acq. time 20us
// ............................................................
while(TRUE){
// play some with the motor. If you use a big one, bolt it down :-)
SPEED = 0; // ramp up speed right and left
while (SPEED <= 1010){
MOTOR_RIGHT(SPEED);
SPEED = SPEED + 10;
delay_ms(50);
}
MOTOR_STOP();
delay_ms(50);
SPEED = 0;
while (SPEED <= 1010){
MOTOR_LEFT(SPEED);
SPEED = SPEED + 10;
delay_ms(50);
}
MOTOR_STOP();
delay_ms(50);
MOTOR_RIGHT(1000); // full-on right
delay_ms(2000);
MOTOR_STOP();
delay_ms(50);
MOTOR_LEFT(1000); // full-on left
delay_ms(2000);
MOTOR_STOP();
delay_ms(50);
MOTOR_RIGHT(500); // half speed right
delay_ms(2000);
MOTOR_STOP();
delay_ms(50);
MOTOR_LEFT(500); // half speed left
delay_ms(2000);
MOTOR_STOP();
delay_ms(50);
// Run the motor via a pot on AN0. Pot on min. or max. gives full speed in both directions,
// slows the motor towards the middle, stops the motor in the middle
while(1){
ADC_VAL = READ_AN0(); // values from 0 - 1023
// LEFT rotation
// Transform ADC reading so that a reading of 0 from pot gives full speed and 448 stops the motor
if(ADC_VAL <= 448){ // LEFT rotation, lower 448 steps of the ADC
Temp = (int32)ADC_VAL - 448; // 0 => -448, 448 => 0
Temp = Temp*(-1); // get positive values, 0 => 448 , 448 => 0
Temp = Temp * 1000; // transform Temp to 0 - 1000 for SPEED PWM
Temp = Temp/448;
SPEED = (int16)TEMP; // casting is important, without that values are not correct!
MOTOR_LEFT(SPEED);
}
// RIGHT rotation
else if (ADC_VAL >= 575){ // RIGHT rotation, upper 448 steps of the adc
ADC_VAL = ADC_VAL - 575; // transform to 0 - 448
Temp = (int32)ADC_VAL * 1000; // transform ADC reading to 0 - 1000 for SPEED PWM
Temp = Temp/448;
SPEED = (int16)TEMP;
MOTOR_RIGHT(SPEED);
}
else{ // motor STOP in between, ADC from 449 - 574
MOTOR_STOP();
}
delay_ms(100);
} // while loop
} // while TRUE
} // MAIN
|
|
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|