Open pkaser opened 4 years ago
In fact, this is not important, as long as it is called before getForce()
, because these two interfaces are used to pass the array address, otherwise it will cause a null pointer exception.
It is important because your example wont compile and gives and error. I posted this so that you could adjust your example so other people that aren't experienced programmers will be able to get their code to compile.
X spring forces also seem to always calculate out to 0. Y seems to work fine, but I am double checking my code to verify I havent made a typo.
The example code just shows the calling process, it is not compilable.
Check whether the effect params settings are correct and whether the X axis is used as the action axis in the game.
I guess if you want to have examples that work or dont is up to you.
The effect params are set. the X and Y axis are reporting correct values. The X force is always 0. If I swap the effect params I still only get Y forces calculated. I am using ForceTest, not a game. It simulates a lot of the FFB variables.
Could you send me the ForceTset please?I will check it later.
as well as your code.
Here is ForceTest.exe:
Here is my current code. I havent figured out the effects yet, like damper, inertia, friction, etc setting yet so they may be all wrong the way I have them implemented. Same with almost everything in here. I'm new to Arduino. It is a joystick made from a Leonardo, a MotoShield, a 12v/2amp power supply, and an old Microsoft Sidewinder Pro Force Feedback V1 that has had all the electronics removed. I am using only the motors and the yoke and have 3D printed a temporary testing mounting bracket. 90% of it works great with XPForce with X-Plane 11.41.
I really appreciate how much you have done to make this happen, and I happily share my code for anyone else trying to do the same thing.
`#include "Joystick.h"
int32_t forces[2] = { 0 };
long posX; long posY;
int centerX; int centerY;
int lastX = 0; int lastY = 0;
// Motor int dirX = 12; int dirY = 13;
int brakeX = 9; // NIU int brakeY = 8; // NIU
int motorX = 3; // int motorY = 11; //
//current draw on motors int loadX = A0; int loadY = A1;
// joystick encoders int encoderX1 = 0; int encoderX2 = 1; int encoderY1 = 2; int encoderY2 = 4;
int xDirection = LOW; int yDirection = LOW; int centerFound = LOW;
int dur = 2; int strength = 100;
long oldX = -999; long oldY = -999;
const int loopDelay = 20;
int minX = 0; int maxX = 0; int minY = 0; int maxY = 0;
Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID,JOYSTICK_TYPE_JOYSTICK, 0, 0, // Button Count, Hat Switch Count true, true, false, // X and Y, but no Z Axis false, false, false, // No Rx, Ry, or Rz false, false, // No rudder or throttle false, false, false); // No accelerator, brake, or steering
Gains gain[2]; EffectParams effects[2];
//
Encoder encoderX(encoderX1, encoderX2); Encoder encoderY(encoderY1, encoderY2);
void setup() { Serial.begin(9600); delay(2000); //Give the serial port time to catch up so we can debug Serial.println("Setting up..."); pinMode(dirX, OUTPUT); //Initiates Motor Channel X pin pinMode(dirY, OUTPUT); //Initiates Motor Channel Y pin
Joystick.begin(true); doSetGains(); }
void loop(){ if (centerFound == 0){ Serial.println("--Centering"); doFindCenter(); } doJoystickStuff(); doFFBStuff(); delay(loopDelay); }
void doFindCenter(){ int cDur = 80; int cStrength = 255; int tXDir; int tYDir; int tPosX; int tPosY;
doMoveX(cStrength,cDur,HIGH);
maxX = stopXMove();
doMoveX(cStrength,cDur,LOW);
minX = stopXMove();
int centerX = (minX + maxX)/2;
doMoveY(cStrength,cDur,HIGH);
maxY = stopYMove();
doMoveY(cStrength,cDur,LOW);
minY = stopYMove();
int centerY = (minY + maxY)/2;
centerX = ((minX + maxX)/2)-2; centerY = ((minY + maxY)/2)-2;
Joystick.setXAxisRange(minX,maxX);
Joystick.setYAxisRange(minY,maxY);
tPosX = encoderX.read();
tPosY = encoderY.read();
do {
//center X
if (centerX > tPosX){tXDir = HIGH;} else {tXDir = LOW;}
doMoveX(255,2,tXDir);
tPosX = stopXMove();
}
while (tPosX != centerX);
do {
//center Y
if (centerY > tPosY){tYDir = HIGH;} else {tYDir = LOW;}
doMoveY(255,2,tYDir);
tPosY = stopYMove();
}
while (tPosY != centerY);
stopXMove();
stopYMove();
centerFound = 1;
}
int stopXMove(){ return doMoveX(0, 10, HIGH); }
int stopYMove(){ return doMoveY(0, 10, HIGH); }
int doMoveX(int tStrength, int tDuration, int tDirection){ digitalWrite(dirX, tDirection); //High=Forward / Low=Reverse analogWrite(motorX, tStrength); //Spins the motor on Channel A at full speed delay(tDuration); // analogWrite(motorX, 0); //Stops motor delay(2); return encoderX.read(); }
int doMoveY(int tStrength, int tDuration, int tDirection){ digitalWrite(dirY, tDirection); //High=Forward / Low=Reverse analogWrite(motorY, tStrength); //Spins the motor on Channel A at full speed delay(tDuration); // analogWrite(motorY, 0); //Stops motor delay(2); return encoderY.read(); }
void doFFBStuff(){ //}
}
void doJoystickStuff(){
posX = encoderX.read(); posY = encoderY.read();
Joystick.setXAxis(posX); Joystick.setYAxis(posY);
effects[0].springMaxPosition = maxX/2; effects[1].springMaxPosition = maxY/2; effects[0].frictionMaxPositionChange = lastX - posX; effects[1].frictionMaxPositionChange = maxY; effects[0].inertiaMaxAcceleration = maxX; effects[1].inertiaMaxAcceleration = 100; effects[0].damperMaxVelocity = 10; effects[1].damperMaxVelocity = 100;
effects[0].springPosition = posX; effects[1].springPosition = posY; effects[0].frictionPositionChange = lastX - posX; effects[1].frictionPositionChange = lastY - posY; effects[0].inertiaAcceleration = 100; effects[1].inertiaAcceleration = 100; effects[0].damperVelocity=100; effects[1].damperVelocity=100;
Joystick.setEffectParams(effects); Joystick.getForce(forces);
int xMoveDir = 0; int yMoveDir = 0; //Get Force [-255,255] you can set PWM with this value Serial.println(""); Serial.print(" - XF: "); Serial.print(forces[0]); Serial.print(" YF: "); Serial.print(forces[1]); //if (forces[0] != 0 || forces[1] != 0 ){ if (forces[0]<0){ xMoveDir = LOW; } else if (forces[0]>0){ xMoveDir = HIGH; } if (forces[1]<0){ yMoveDir = LOW; } else if (forces[1]>0){ yMoveDir = HIGH; } if (forces[0]!=0){ doMoveX(abs(forces[0]),dur,xMoveDir); } else { doMoveX(0,2,xMoveDir); }; if (forces[1]!=0) { doMoveY(abs(forces[1]),dur,yMoveDir); } else { doMoveY(0,2,yMoveDir); };
lastX = posX; lastY = posY;
}
void doSetGains(){ //set x axis gains gain[0].totalGain = 100; gain[0].constantGain = 100; gain[0].rampGain = 100; gain[0].squareGain = 100; gain[0].sineGain = 100; gain[0].triangleGain = 100; gain[0].sawtoothdownGain = 100; gain[0].sawtoothupGain = 100; gain[0].springGain = 100; gain[0].damperGain = 100; gain[0].inertiaGain = 100; gain[0].frictionGain = 100;
//set y axis gains gain[1].totalGain = 100; gain[1].constantGain = 100; gain[1].rampGain = 100; gain[1].squareGain = 100; gain[1].sineGain = 100; gain[1].triangleGain = 100; gain[1].sawtoothdownGain = 100; gain[1].sawtoothupGain = 100; gain[1].springGain = 100; gain[1].damperGain = 100; gain[1].inertiaGain = 100; gain[1].frictionGain = 100;
Joystick.setGains(gain);
} `
Hi,there is no wrong in your code. I Traced the USB report output which from ForceTest.It set the multi-axis ffb paramers in a different way,it may take me a few more days to figure this out.
Hello, fist thank you very much for your work. I try to build an Yoke with your library and i have following components in use: Arduino Leonardo and two BTS7960B H-Bridges. I used the Code from "pkaser" and have now the Problem, that the Y axis work great with all Effects in XPForce, but the X axis wont work in XPForce. In the TestForce tool, the X axis generate Force but no Effects. Has anybody an Idea, what the Problem is?
"#include "Joystick.h"
int32_t forces[2] = {0};
long posX; long posY;
int centerX; int centerY;
int lastX = 0; int lastY = 0;
// MotorX int motorXR = 5; // int motorXL = 6; //
// MotorY int motorYR = 10; // int motorYL = 11; //
// joystick encoders int encoderX1 = 0; int encoderX2 = 1; int encoderY1 = 2; int encoderY2 = 3;
int xDirection = LOW; int yDirection = LOW; int centerFound = LOW;
int dur = 2; int strength = 100;
long oldX = -999; long oldY = -999;
const int loopDelay = 5;
int minX = 0; int maxX = 0; int minY = 0; int maxY = 0;
//X-axis & Y-axis REQUIRED Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID, JOYSTICK_TYPE_JOYSTICK, 0, 0, // Button Count, Hat Switch Count true, true, false, // X and Y, but no Z Axis false, false, false, // No Rx, Ry, or Rz false, false, // No rudder or throttle false, false, false); // No accelerator, brake, or steering
Gains gain[2]; EffectParams effects[2];
//
Encoder encoderX(encoderX1, encoderX2); Encoder encoderY(encoderY1, encoderY2);
void setup() { Serial.begin(9600); delay(2000); //Give the serial port time to catch up so we can debug Serial.println("Setting up...");
Joystick.begin(true); doSetGains(); }
void loop() { if (centerFound == 0) { Serial.println("--Centering"); doFindCenter(); } doJoystickStuff(); doFFBStuff(); delay(loopDelay); }
void doFindCenter() { int cDur = 1000; int cStrength = 50; int tXDir; int tYDir; int tPosX; int tPosY;
doMoveX(cStrength, cDur, HIGH); maxX = stopXMove(); Serial.println(maxX); doMoveX(cStrength, cDur, LOW); minX = stopXMove(); int centerX = (minX + maxX) / 2; doMoveY(cStrength, cDur, HIGH); maxY = stopYMove(); Serial.println(maxY); doMoveY(cStrength, cDur, LOW); minY = stopYMove(); int centerY = (minY + maxY) / 2;
centerX = ((minX + maxX) / 2) - 2; centerY = ((minY + maxY) / 2) - 2;
Joystick.setXAxisRange(minX, maxX); Joystick.setYAxisRange(minY, maxY); tPosX = encoderX.read(); tPosY = encoderY.read(); do { //center X if (centerX < tPosX) { tXDir = HIGH; } else { tXDir = LOW; } doMoveX(155, 2, tXDir); tPosX = stopXMove();
} while (tPosX != centerX);
do { //center Y if (centerY < tPosY) { tYDir = HIGH; } else { tYDir = LOW; } doMoveY(155, 2, tYDir); tPosY = stopYMove();
} while (tPosY != centerY); // stopXMove(); //stopYMove(); centerFound = 1;
}
int stopXMove() { return doMoveX(0, 10, HIGH); }
int stopYMove() { return doMoveY(0, 10, HIGH); }
int doMoveX(int tStrength, int tDuration, int tDirection) { if (tDirection == HIGH) { analogWrite(motorXL, tStrength); //Spins the motor on Channel A at full speed } else { analogWrite(motorXR, tStrength); //Spins the motor on Channel A at full speed } delay(tDuration); analogWrite(motorXR, 0); //Stops motor analogWrite(motorXL, 0); //Stops motor delay(2); return encoderX.read(); }
int doMoveY(int tStrength, int tDuration, int tDirection) { if (tDirection == HIGH) { // Serial.print("High"); analogWrite(motorYR, tStrength); //Spins the motor on Channel A at full speed } else { analogWrite(motorYL, tStrength); //Spins the motor on Channel A at full speed } delay(tDuration); analogWrite(motorYR, 0); //Stops motor analogWrite(motorYL, 0); //Stops motor delay(2); return encoderY.read(); }
void doFFBStuff() { //}
}
void doJoystickStuff() {
posX = encoderX.read(); posY = encoderY.read();
Joystick.setXAxis(posX); Joystick.setYAxis(posY);
effects[0].springMaxPosition = maxX / 2; effects[1].springMaxPosition = maxY / 2; effects[0].frictionMaxPositionChange = maxX; effects[1].frictionMaxPositionChange = maxY; effects[0].inertiaMaxAcceleration = 100; effects[1].inertiaMaxAcceleration = 100; effects[0].damperMaxVelocity = 100; effects[1].damperMaxVelocity = 100;
effects[0].springPosition = posX; effects[1].springPosition = posY; effects[0].frictionPositionChange = lastX - posX; effects[1].frictionPositionChange = lastY - posY; effects[0].inertiaAcceleration = 100; effects[1].inertiaAcceleration = 100; effects[0].damperVelocity = 100; effects[1].damperVelocity = 100;
Joystick.setEffectParams(effects); Joystick.getForce(forces);
int xMoveDir = 0; int yMoveDir = 0; //Get Force [-255,255] you can set PWM with this value //Serial.println(""); //Serial.print(" - XF: "); //Serial.print(forces[0]); //Serial.print(" YF: "); //Serial.print(forces[1]); if (forces[0] > 0) { xMoveDir = LOW; } else if (forces[0] < 0) { xMoveDir = HIGH; } if (forces[1] < 0) { yMoveDir = LOW; } else if (forces[1] > 0) { yMoveDir = HIGH; } if (forces[0] != 0) { doMoveX(abs(forces[0]), dur, xMoveDir); } else { doMoveX(0, 2, xMoveDir); }; if (forces[1] != 0) { doMoveY(abs(forces[1]), dur, yMoveDir); } else { doMoveY(0, 2, yMoveDir); };
lastX = posX; lastY = posY;
}
void doSetGains() { //set x axis gains gain[0].totalGain = 100; gain[0].constantGain = 100; gain[0].rampGain = 100; gain[0].squareGain = 100; gain[0].sineGain = 100; gain[0].triangleGain = 100; gain[0].sawtoothdownGain = 100; gain[0].sawtoothupGain = 100; gain[0].springGain = 100; gain[0].damperGain = 100; gain[0].inertiaGain = 100; gain[0].frictionGain = 100;
//set y axis gains gain[1].totalGain = 100; gain[1].constantGain = 100; gain[1].rampGain = 100; gain[1].squareGain = 100; gain[1].sineGain = 100; gain[1].triangleGain = 100; gain[1].sawtoothdownGain = 100; gain[1].sawtoothupGain = 100; gain[1].springGain = 100; gain[1].damperGain = 100; gain[1].inertiaGain = 100; gain[1].frictionGain = 100;
Joystick.setGains(gain);
}"
can you guy post encoder files for test. I can't found compatible library for this. Thank you
Can you post your doFFBStuff() function ?
Thank you
Here is my current code. I havent figured out the effects yet, like damper, inertia, friction, etc setting yet so they may be all wrong the way I have them implemented. Same with almost everything in here. I'm new to Arduino. It is a joystick made from a Leonardo, a MotoShield, a 12v/2amp power supply, and an old Microsoft Sidewinder Pro Force Feedback V1 that has had all the electronics removed. I am using only the motors and the yoke and have 3D printed a temporary testing mounting bracket. 90% of it works great with XPForce with X-Plane 11.41.
I really appreciate how much you have done to make this happen, and I happily share my code for anyone else trying to do the same thing.
`#include "Joystick.h" #include "Encoder.h"
int32_t forces[2] = { 0 };
long posX; long posY;
int centerX; int centerY;
int lastX = 0; int lastY = 0;
// Motor int dirX = 12; int dirY = 13;
int brakeX = 9; // NIU int brakeY = 8; // NIU
int motorX = 3; // int motorY = 11; //
//current draw on motors int loadX = A0; int loadY = A1;
// joystick encoders int encoderX1 = 0; int encoderX2 = 1; int encoderY1 = 2; int encoderY2 = 4;
int xDirection = LOW; int yDirection = LOW; int centerFound = LOW;
int dur = 2; int strength = 100;
long oldX = -999; long oldY = -999;
const int loopDelay = 20;
int minX = 0; int maxX = 0; int minY = 0; int maxY = 0;
Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID,JOYSTICK_TYPE_JOYSTICK, 0, 0, // Button Count, Hat Switch Count true, true, false, // X and Y, but no Z Axis false, false, false, // No Rx, Ry, or Rz false, false, // No rudder or throttle false, false, false); // No accelerator, brake, or steering
Gains gain[2]; EffectParams effects[2];
//
Encoder encoderX(encoderX1, encoderX2); Encoder encoderY(encoderY1, encoderY2);
void setup() { Serial.begin(9600); delay(2000); //Give the serial port time to catch up so we can debug Serial.println("Setting up..."); pinMode(dirX, OUTPUT); //Initiates Motor Channel X pin pinMode(dirY, OUTPUT); //Initiates Motor Channel Y pin
Joystick.begin(true); doSetGains(); }
void loop(){ if (centerFound == 0){ Serial.println("--Centering"); doFindCenter(); } doJoystickStuff(); doFFBStuff(); delay(loopDelay); }
void doFindCenter(){ int cDur = 80; int cStrength = 255; int tXDir; int tYDir; int tPosX; int tPosY;
doMoveX(cStrength,cDur,HIGH); maxX = stopXMove(); doMoveX(cStrength,cDur,LOW); minX = stopXMove(); int centerX = (minX + maxX)/2; doMoveY(cStrength,cDur,HIGH); maxY = stopYMove(); doMoveY(cStrength,cDur,LOW); minY = stopYMove(); int centerY = (minY + maxY)/2;
centerX = ((minX + maxX)/2)-2; centerY = ((minY + maxY)/2)-2;
Joystick.setXAxisRange(minX,maxX); Joystick.setYAxisRange(minY,maxY); tPosX = encoderX.read(); tPosY = encoderY.read(); do { //center X if (centerX > tPosX){tXDir = HIGH;} else {tXDir = LOW;} doMoveX(255,2,tXDir); tPosX = stopXMove();
} while (tPosX != centerX);
do { //center Y if (centerY > tPosY){tYDir = HIGH;} else {tYDir = LOW;} doMoveY(255,2,tYDir); tPosY = stopYMove();
} while (tPosY != centerY); stopXMove(); stopYMove(); centerFound = 1;
}
int stopXMove(){ return doMoveX(0, 10, HIGH); }
int stopYMove(){ return doMoveY(0, 10, HIGH); }
int doMoveX(int tStrength, int tDuration, int tDirection){ digitalWrite(dirX, tDirection); //High=Forward / Low=Reverse analogWrite(motorX, tStrength); //Spins the motor on Channel A at full speed delay(tDuration); // analogWrite(motorX, 0); //Stops motor delay(2); return encoderX.read(); }
int doMoveY(int tStrength, int tDuration, int tDirection){ digitalWrite(dirY, tDirection); //High=Forward / Low=Reverse analogWrite(motorY, tStrength); //Spins the motor on Channel A at full speed delay(tDuration); // analogWrite(motorY, 0); //Stops motor delay(2); return encoderY.read(); }
void doFFBStuff(){ //}
}
void doJoystickStuff(){
posX = encoderX.read(); posY = encoderY.read();
Joystick.setXAxis(posX); Joystick.setYAxis(posY);
effects[0].springMaxPosition = maxX/2; effects[1].springMaxPosition = maxY/2; effects[0].frictionMaxPositionChange = lastX - posX; effects[1].frictionMaxPositionChange = maxY; effects[0].inertiaMaxAcceleration = maxX; effects[1].inertiaMaxAcceleration = 100; effects[0].damperMaxVelocity = 10; effects[1].damperMaxVelocity = 100;
effects[0].springPosition = posX; effects[1].springPosition = posY; effects[0].frictionPositionChange = lastX - posX; effects[1].frictionPositionChange = lastY - posY; effects[0].inertiaAcceleration = 100; effects[1].inertiaAcceleration = 100; effects[0].damperVelocity=100; effects[1].damperVelocity=100;
Joystick.setEffectParams(effects); Joystick.getForce(forces);
int xMoveDir = 0; int yMoveDir = 0; //Get Force [-255,255] you can set PWM with this value Serial.println(""); Serial.print(" - XF: "); Serial.print(forces[0]); Serial.print(" YF: "); Serial.print(forces[1]); //if (forces[0] != 0 || forces[1] != 0 ){ if (forces[0]<0){ xMoveDir = LOW; } else if (forces[0]>0){ xMoveDir = HIGH; } if (forces[1]<0){ yMoveDir = LOW; } else if (forces[1]>0){ yMoveDir = HIGH; } if (forces[0]!=0){ doMoveX(abs(forces[0]),dur,xMoveDir); } else { doMoveX(0,2,xMoveDir); }; if (forces[1]!=0) { doMoveY(abs(forces[1]),dur,yMoveDir); } else { doMoveY(0,2,yMoveDir); };
lastX = posX; lastY = posY;
}
void doSetGains(){ //set x axis gains gain[0].totalGain = 100; gain[0].constantGain = 100; gain[0].rampGain = 100; gain[0].squareGain = 100; gain[0].sineGain = 100; gain[0].triangleGain = 100; gain[0].sawtoothdownGain = 100; gain[0].sawtoothupGain = 100; gain[0].springGain = 100; gain[0].damperGain = 100; gain[0].inertiaGain = 100; gain[0].frictionGain = 100;
//set y axis gains gain[1].totalGain = 100; gain[1].constantGain = 100; gain[1].rampGain = 100; gain[1].squareGain = 100; gain[1].sineGain = 100; gain[1].triangleGain = 100; gain[1].sawtoothdownGain = 100; gain[1].sawtoothupGain = 100; gain[1].springGain = 100; gain[1].damperGain = 100; gain[1].inertiaGain = 100; gain[1].frictionGain = 100;
Joystick.setGains(gain);
} `
Hello Pkaser did you find a solution and got it to work perfectly?
It appears gains should be set in setup() and not before as in your example.