Hi, I also been strongling to get my IBT_2 (BTS9760) board to work and get the a DC motor to run!
I finally did hit.
It took me a long time to figure out how the BTS9760 worked. I also reverse engineered the board to figure out how it all connected.
Here is the electronic diagram of the IBT_2.
IBT_2.pdf (37.2 KB)
My code is simple, or so I think. I have 2 releases.
The first version I use pins 8 and 9 in PWM with the available resolution of 8 bits (256). The function which calls the starting of the motor is also a loop with the while instruction, which is not effective as code but makes it possible to understand the proper functioning of this card and of the DC motor which is connected.
The second, pins 6 and 7 are used with a frequency at 16MHz, 16-bit resolution (65536). But in fact, since the specific frequency is at 16 MHz, the PWM has a resolution of 500, which represents a resolution of 9 bits.
/*
Arduino MEGA2560 code BTS7960 DC motor Driver - should work with other Adrduino boards
Written by Donald Wright openvolta.org, on June 24, 2019 in Satin-Jérôme, Québec, Canada
You can control a motor to rotate in both direction Clockwise(CW)
and Counter-clockwise(CCW). This perfor by reading pin 12.
A potentiometer is used to vary the speed of the DC motor and pin A0 is use.
* This code is "AS IS" without warranty or liability. Free to be used as long as you keep this note intact.*
* This code has been download from Robojax.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Please refer to the gnu.org website <https://www.gnu.org/licenses/>. to received and read a copy of the GNU General Public License
READ THE CODE TO FAMILIARIZE YOURSELF WITH IT.
**********************************************************************************************************************************
**** NOTE, IF YOUR DIRECTION IS SET TO LOW (GND), THE MOTOR WILL START IF YOU ARE ABOVE THERSHOLD. I HAVE NOT YET FIGURED WHY ****
**** I DID NOT EXPERIANCE THIS ISSUE WHEN THE DIRECTION PPIN IS SET HI (5V) ******************************************************
**********************************************************************************************************************************
*/
// Pin definitions
const int RPWM_PIN = 6; // OC4A RPWM pin 6 of the Arduino to pin 1 of IBT_2
const int R_EN_PIN = 3; // R_EN pin 3 of the Arduino to pin 3 of IBT_2
const int R_IS_PIN = A1; // Analog current sens of the Right MOSFET pin A0 to pin 5 of IBT_2 - not yet implemented in this code
const int LPWM_PIN = 7; // OC4B LPWM pin 7 of the Arduino to pin 2 of IBT_2
const int L_EN_PIN = 4; // L_EN pin 4 of the Arduino to pin 4 of IBT_2
const int L_IS_PIN = A2; // Analog current sens of the Left MOSFET pin A1 to pin 6 of IBT_2 - not yet implemented in this code
const int DIRECTION_PIN = 12; // Boolean input for motor direction (clockwise/counter-clockwise)
const int SPEED_PIN = A0; // Analog input for motor speed (PWM) adjustment
void setup() {
// Set the motor control pins as outputs
pinMode(RPWM_PIN, OUTPUT);
pinMode(R_EN_PIN, OUTPUT);
pinMode(LPWM_PIN, OUTPUT);
pinMode(L_EN_PIN, OUTPUT);
pinMode(DIRECTION_PIN, INPUT_PULLUP);
digitalWrite(R_EN_PIN, LOW); // turn OFF the Right motor driver chip
digitalWrite(L_EN_PIN, LOW); // turn OFF the left motor driver chip
// Set Timer/Counter4 Control Registers (TCCR4A and TCCR4B) for PWM phase-correct waveform
TCCR4A = 0b10100010; // Set COM4A1, COM4B1, and WGM41 bits
TCCR4B = 0b00010001; // Set WGM43, WGM42, and CS40 bits This set the PWM in Phase correct mode.
// Set ICR4 (Input Capture Register) for TOP value
ICR4 = 500; // (16000000 / (2 * N * TOP)) = 500, for a frequency of 16 kHz,
// where TOP = 16000 and N is the prescaler set to 1
// Set the initial values of OCR4A and OCR4B for symmetric PWM
OCR4A = 0; // Clear for no PWM
OCR4B = 0; // Clear for no PWM
// Start serial communication at 115200 baud rate - use for trouble shooting.
Serial.begin(115200);
}
void loop() {
static bool last_direction=0;
//digitalWrite(R_EN_PIN, LOW); // turn OFF the Right motor driver chip
//digitalWrite(L_EN_PIN, LOW); // turn OFF the left motor driver chip
//OCR4A = 0; // Clear for no PWM
//OCR4B = 0; // Clear for no PWM
// Check to see if there is a command for speed and the current direction
int speed = analogRead(SPEED_PIN); //read pin A0 of the Arduino.
bool direction = digitalRead(DIRECTION_PIN); // read current direction
// Check to speed, if it's bellow 124, turn off and accept change in the direction
if (speed < 124 )
// if it's speed is below 124, there is no need to run the
// motor since the PWM width is very small. The average output
// voltage will be so low and high current may occur, and the
// motor will not run anyway. So the motor and the MOSFETs are
// force to no PWM and force low. Also, the current motor last_direct
// is assigned the motor direction. And it's the only time that the
// motor is allowed to change direction. This is to prevent
// a direction change when the motor is running.
// NOTE: the RUN speed is dependent of the DC motor desing and built.
{
//Serial.print("Speed = "); Serial.println(speed); //Use for troubleshooting code
//Serial.print("Direction = "); Serial.println(direction); //Use for troubleshooting code
//Serial.print("Previous direction = "); Serial.println(last_direction); //Use for troubleshooting code
digitalWrite(R_EN_PIN, LOW); // turn OFF the Right motor driver chip
digitalWrite(L_EN_PIN, LOW); // turn OFF the Left motor driver chip
OCR4A = 0; // Clear for no PWM
OCR4B = 0; // Clear for no PWM;
last_direction = direction; // Assigned to last_direction the current direction
}
//run motor if speed is greater or equivalent to 125
else if (direction == last_direction && speed >= 124)
{
motorControl(direction,speed);
}
// if there is a direction change, stop motor and user set speed below accepted treshold
else if (direction != last_direction)
{
OCR4A = 0; // Clear for no PWM
OCR4B = 0; // Clear for no PWM;
Serial.println();
Serial.println("Motor stop and speed input ingnord"); //Send msg tu user to set spped at zero befor attempting to change direction.
Serial.println();
}
}
// Function to control the motor
void motorControl(bool direction, int speed)
{
int speedPWM = map(speed, 0, 1023, 0, ICR4); // map speedPWM to the ICR4 to match resolution
// Enabling the MOSFETs
digitalWrite(R_EN_PIN, HIGH); // turn ON the Right motor driver chip
digitalWrite(L_EN_PIN, HIGH); // turn ON the left motor driver chip
// Set the motor direction
if (direction)
{
OCR4A = speedPWM; // Set speed and run RPWM - analogWright not use // analogWrite(RPWM_PIN, speedPWM);
OCR4B = 0; // Activate left motor drive LOW side ON of the BT_2 board //digitalWrite(LPWM_PIN, LOW);
}
else
{
OCR4B = speedPWM; // RUN LPWM - analogWright not use // analogWrite(LPWM_PIN, speedPWM);
OCR4A = 0; //digitalWrite(RPWM_PIN, LOW); // Activate Right motor driver LOW Side ON of the BT_2 board
}
// Print the register values to the serial monitor
//Serial.print("TCCR4A = "); Serial.print(TCCR4A, BIN); Serial.print(" "); Serial.println(TCCR4A);
//Serial.print("TCCR4B = "); Serial.print(TCCR4B, BIN); Serial.print(" "); Serial.println(TCCR4B);
//Serial.print("ICR4 = "); Serial.print(ICR4, BIN); Serial.print(" "); Serial.println(ICR4);
//Serial.print("OCR4A = "); Serial.print(OCR4A, BIN); Serial.print(" "); Serial.println(OCR4A);
//Serial.print("OCR4B = "); Serial.print(OCR4B, BIN); Serial.print(" "); Serial.println(OCR4B);
Serial.print("Speed = "); Serial.print(speed); Serial.print(" "); Serial.print("Direction = "); Serial.println(direction);
}
Hope you find it helfull
SAFETY ISSUE:
NOTE THAT IF YOUR DIRECTION PIN IS SET TO LOW (GND), THE MOTOR WILL START IF YOU ARE ABOVE THRESHOLD SPEED (minimum PWM width). I HAVE NOT YET FIGURED WHY. I DID NOT EXPERIANCE THIS ISSUE WHEN THE DIRECTION PPIN IS SET HI (5V).