Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BTS7960 + DC Motor for FFB Wheel #43

Open
Vee-21 opened this issue Mar 5, 2022 · 7 comments
Open

BTS7960 + DC Motor for FFB Wheel #43

Vee-21 opened this issue Mar 5, 2022 · 7 comments

Comments

@Vee-21
Copy link

Vee-21 commented Mar 5, 2022

Hi all

First of all thanks YukMingLaw for creating this, I think this will be the final piece to finish my racing arcade cabinet project.

I've got my arcade wheel, pedals and 6 speed shifter working using the standard Joystick library and I'm now trying to get FFB working. I'm still new to Arduino and coding so my logic and explanation will be very basic.

My steering wheel uses a potentiometer and is connected to A0 on the Leonardo. As far as I know the BTS7960 motor drive has two input pins Right PWM and Left PWM which I've connected to pin 3 and 4.

My question is would this setup work with this library? I saw that the example has 3 outputs which I'm not sure how they would work with the BTS7960. I'm guessing in the example (SingleJoystickFFB.ino) Pin 6 and 7 would connect to the BTS7960 motor drive Right and Left PWM?

Any help/links would be appreciated.

Cheers

@crimzzon92
Copy link

crimzzon92 commented Mar 5, 2022

I have 775 DC motor driven by BTS7960 and it works perfectly.

Drive motors whit this code. I have the two enable pins connected to the same pin on Arduino. that's way I only cal out right or left in the code.

 // X Axis Funktion

if(forces[0] > 0){
analogWrite(ROLL_L_PWM,abs(forces[0]));
analogWrite(ROLL_R_PWM, 0);
digitalWrite(ROLL_L_EN,HIGH);
}else{
analogWrite(ROLL_R_PWM,abs(forces[0]));
analogWrite(ROLL_L_PWM, 0);
digitalWrite(ROLL_R_EN,HIGH);
}

@Vee-21
Copy link
Author

Vee-21 commented Mar 6, 2022

Thanks for the response crimzzon92. I'm still new to all this so I'm a bit confused how to wiring would look like for your example.

So in the code I would have something like:

const int bts_R_PWM = 3;
const int bts_L_PWM = 4;
const int bts_R_Enable = 5; //Left and right enable = the same pin?
const int bts_L_Enable = 5; //Left and right enable = the same pin?

pinMode(3, OUTPUT); //Connected to BTS7960 Pin 1 - Right PWM
pinMode(4, OUTPUT); //Connected to BTS7960 Pin 2 - Left PWM
pinMode(5, OUTPUT); //Connected to BTS7960 Pin 3 & 4 (Right Enable / Left Enable Input) ?

if(forces[0] > 0){
analogWrite(L_PWM,abs(forces[0]));
analogWrite(R_PWM, 0);
digitalWrite(L_Enable,HIGH);
} else{
analogWrite(R_PWM,abs(forces[0]));
analogWrite(L_PWM, 0);
digitalWrite(R_Enable,HIGH);
}

@crimzzon92
Copy link

crimzzon92 commented Mar 6, 2022

I should work.

I have the pins signed like this

const int PITCH_R_EN = 16;
const int PITCH_L_EN = 16;
const int PITCH_R_PWM = 10;
const int PITCH_L_PWM = 5;

Another tips are to make the PWM frequency higher on the arduino. the default is 950 Hz & 500 Hz for the PWM pins on the Arduino pro micro. I had a really bad noise coming from the dc motors. So I find an old library that allows you to change the frequency in fixed ranges. The only useable range is 4000Hz because the max is 31000 Hz but the BTS7960 only handles up to 25000Hz.

but 4000Hz makes a big difference in the sound coming from the motors.

#include <PWMFrequency.h>

void setup(){
// Set the PWM to 4000 Hz frequency
setPWMPrescaler(5, 8);
setPWMPrescaler(6, 8);
setPWMPrescaler(9, 8);
setPWMPrescaler(10, 8);
}

Link to Library: https://github.com/TheDIYGuy999/PWMFrequency

@Vee-21
Copy link
Author

Vee-21 commented Mar 21, 2022

Thanks for the help crimzzon92!

My last question how did you setup your Joystick? For my current setup which doesn't use FFB I use:

Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID,JOYSTICK_TYPE_MULTI_AXIS,
8, 0, // Button Count, Hat Switch Count
false, false, false, // X, Y, Z Axis
false, false, false, //Rx, Ry, Rz
false, false, //rudder, throttle
true, true, true); //accelerator, brake, steering

From what I understand I need to enable X Y Axis for the FFB to work so would I just simply use:

Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID,JOYSTICK_TYPE_MULTI_AXIS,
8, 0, // Button Count, Hat Switch Count
true, true, false, // X, Y, Z Axis
false, false, false, //Rx, Ry, Rz
false, false, //rudder, throttle
true, true, true); //accelerator, brake, steering

My complete code is below:

`
#include <Joystick.h>

Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID,JOYSTICK_TYPE_MULTI_AXIS,
8, 0, // Button Count, Hat Switch Count
true, true, false, // X, Y, Z Axis - X & Y enabled for FFB
false, false, false, //Rx, Ry, Rz
false, false, //rudder, throttle
true, true, true); //accelerator, brake, steering

//Setup steering, brake and accel pins
const int steerPin = A0;
const int brakePin = A2;
const int accelPin = A1;

//BTS7960 Pins (RPWM / LPWM) (Right / Left Pulse Width Modulation)
const int bts_R_PWM = 3; //Yellow
const int bts_L_PWM = 4; //Purple
const int bts_R_Enable = 5; //Left and right enable = Pin 5 (Orange)
const int bts_L_Enable = 5; //Left and right enable = Pin 5 (Orange)

//Setup Values
int steerValue;
int brakeValue;
int accelValue;

//Setup FFB Gains
Gains mygains[2];
EffectParams myeffectparams[2];
int32_t forces[2] = {0};

void setup() {

//Initialise button pins
pinMode(7, INPUT_PULLUP); //Mode
pinMode(8, INPUT_PULLUP); //View
pinMode(3, OUTPUT); //Connected to BTS7960 Pin 1 - Right PWM
pinMode(4, OUTPUT); //Connected to BTS7960 Pin 2 - Left PWM
pinMode(5, OUTPUT); //Connected to BTS7960 Pin 3 & 4 (Right Enable / Left Enable Input)

//set X Axis gains
mygains[0].totalGain = 50;
mygains[0].springGain = 80;

//set Y Axis gains
mygains[1].totalGain = 50;
mygains[1].springGain = 70;

//Steering Options - X Axis or Steering
//Joystick.setXAxisRange(0, 1023); //Steering Wheel - Joystick.setXAxisRange(min, max);
Joystick.setSteeringRange(0, 960);

//Brake Options - Y Axis or Brake
//Joystick.setYAxisRange(0, 1023); //Brake Pedal - Joystick.setYAxisRange(min, max);
Joystick.setBrakeRange(400, 767);

//Accelerator Options - Z Axis or Acceleratro
//Joystick.setZAxisRange(0, 1023); //Accel Pedal - Joystick.setZAxisRange(min, max);
Joystick.setAcceleratorRange(490, 915);

//Enable FFB gains
Joystick.setGains(mygains);

//Start Joystick
Joystick.begin();
}

//Start loop
void loop() {
BrakePedal();
SteerWheel();
AccelPedal();
FFB();
}

void SteerWheel(){
steerValue = analogRead(steerPin);
//Joystick.setXAxis(steerValue);
Joystick.setSteering(steerValue);
}

void BrakePedal(){
brakeValue = analogRead(brakePin);
Joystick.setBrake(brakeValue);
Serial.println(brakeValue); // Testing analog input
}

void AccelPedal(){
accelValue = analogRead(accelPin);
Joystick.setAccelerator(accelValue);
}

void FFB(){
//FFB - Set X Axis Spring Effect Param
myeffectparams[0].springMaxPosition = 960;
myeffectparams[0].springPosition = steerValue;

//FFB - Send HID data to PC
Joystick.setXAxis(steerValue);

//FFB - Receive HID-PID data from PC and calculate forces
Joystick.setEffectParams(myeffectparams);
Joystick.getForce(forces);
if(forces[0] > 0){
analogWrite(bts_L_PWM,abs(forces[0]));
analogWrite(bts_R_PWM, 0);
digitalWrite(bts_L_Enable,HIGH);
} else{
analogWrite(bts_R_PWM,abs(forces[0]));
analogWrite(bts_L_PWM, 0);
digitalWrite(bts_R_Enable,HIGH);
}
}`

@crimzzon92
Copy link

Yes, you need X & Y to be true for FFB to work. Then change JOYSTICK_TYPE_MULTI_AXIS to JOYSTICK_TYPE_JOYSTICK. fore some reason. when using Multi_Axis windows won't see your device. then put in all the forces gain into the code. If I did not, the forces acted weird on me. you can just set the ones you don't want to 0. Remember to set the gain value low when testing whit motor. if your motor is powerful you can get hurt. a 775 dc motor on 100% is strong. I have everything set to around 20-30%. but that value depends on gearing a so one.

mygains[0].rampGain = 100;//0-100
mygains[0].squareGain = 100;//0-100
mygains[0].sineGain = 100;//0-100
mygains[0].triangleGain = 100;//0-100
mygains[0].sawtoothdownGain = 100;//0-100
mygains[0].sawtoothupGain = 100;//0-100
mygains[0].constantGain = 100;//0-100
mygains[0].springGain = 100;//0-100
mygains[0].damperGain = 100;//0-100
mygains[0].inertiaGain = 100;//0-100
mygains[0].frictionGain = 100;//0-100
mygains[0].customGain = 100;//0-100

Hope its helps!

@1781741527
Copy link

Hello, I would like to ask, have you ever encountered a situation where the force feedback done by this library causes the game to drop frames in the game? I'm also having a similar issue, I seem to have fixed the issue with force feedback acquisition, but it's causing my game to drop frames very badly!
I feel like the device is constantly fetching game data from the game, causing the game to drop frames, but I don't know how to fix it yet, so I'm wondering if your project is complete? Can you give me some help?

@numpad0
Copy link

numpad0 commented Dec 1, 2024

I'm using BTS7960 too, and can report that below actually works in my setup! It's out of range at 31kHz but it's completely inaudible and so far the driver hasn't caught fire.

setPWMPrescaler(9, 1);
setPWMPrescaler(10, 1);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants