Jump to content

Broken Fssb r3 WH force sensing stick. 4 x strain gauge to ardunio conversion. Ard code with stick angle emulation v0.9


trigen

Recommended Posts

Hi there

 

Got some questions about a conversion as my FFSB r3 decided to just die for practically no reason (second hand, out of warranty) and i do not wish to pay 415+ eur when i can fix it for 30-40 using some strain gauge amps and ardunio. While ill loose the software  there's not really many axis features in the FSSB software that i cant program in ardunio in a few days. Just the angle shift really. 

 

While im fairly sure i need 4 amps is it possible to get away with 2 amps with 2 gauges connected?  

 

What ive noticed on the ones ive tested (and now lost track of so im unable to test ) is that there's a fair amount of noise even with 10x filter in MMjoy2 using these https://www.ebay.com/itm/183934688576  Would a capacitor in between the gauge and the board be fine?  If so, what would be sufficient?  Or any suggestions for amps are welcome. 

As you can see its easy to just tap into here and just use the FSSB hardware. 

20210710_113756.jpg

20210710_113828 (2).jpg

 


Edited by trigen

1080 ti, i7700k 5ghz, 16gb 3600 cl14 ddr4 oc

Link to comment
Share on other sites

  • 3 weeks later...

Using ardunio micro 
Smoothed library: Dl trough Ard software. 

Joystick library https://github.com/MHeironimus/ArduinoJoystickLibrary
https://www.ebay.com/itm/174794426405 

 

Ive had to make some compromises and use 4 ebay amps then combine those into 2 axes with one on each side. I invert one of the amps to get + -   It works very well and cost me about 35 euro instead of 400++ due to the WH r3 being out of production. Plus their support professionalism = no comment...  You should probably connect each axis strain + 1 pot and resistor for a wheatstone bridge but i had this stuff.

I will program all the axis features the FSSB has and add a physical switch to change things around. Maybe later i will add a software solution.

 

The easiest way would be to just solder on wires to the top circuit board but i needed the space so i took it out.  Apart from the connection rod to the stick which needs to be strong im quite sure you could easily 3d print something similar and have no cross talk in the axes. Then you could have your own force sensing stick that does move a bit but with less force than steel which is of course best. 

Ignore the melted wires on the connection. I did a last ditch attempt to save it and baked it in the oven to reflow (which ive rescued other boards with)  thinking the wires would not melt. I added new shielding. 

FSSB r3.jpg

Please note Force and offsets and not currently working. Just added varables

//#include <AnalogSmooth.h>

#include <Joystick.h>
#include <Smoothed.h>

/*
For the true false flags, use this list. Its all in  Joystick.h
    bool includeXAxis = true,
    bool includeYAxis = true,
    bool includeZAxis = true,
    bool includeRxAxis = true,
    bool includeRyAxis = true,
    bool includeRzAxis = true,
    bool includeRudder = true,
    bool includeThrottle = true,
    bool includeAccelerator = true,
    bool includeBrake = true,
    bool includeSteering = true);
  */
Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID,
  JOYSTICK_TYPE_MULTI_AXIS, 32, 0,
  true, true, false, false, false, false,
  true, true, false, false, false);
 
 
// Variable

#define YfAxisPin A0
#define YbAxisPin A1
#define XlAxisPin A2 
#define XrAxisPin A3

// Add pins for the different ranges. Just using a variable for now. 
// Max force from trigger height. 
// Max force for y is about 8kg
// Max force for X left is about 8kg  X right is about 6kg 
// Max force in % 
int YMaxforce = 100;
int XMaxforce = 100;

// add offset to X Y  WIP need to figure out how to angle 
int Offset = 0;

// Add smoothing for all axis 
Smoothed <int> YfAxis;
Smoothed <int> YbAxis;
Smoothed <int> XlAxis;
Smoothed <int> XrAxis;

int SmoothValue = 30;

// init joystick libary
void setup() {
    Joystick.begin();
    Serial.begin(38400);
  // Ranges are 1023 by default
  Joystick.setYAxisRange(0, 2048);
  Joystick.setXAxisRange(0, 2048);


// Begin smoothing.     
    YfAxis.begin(SMOOTHED_AVERAGE, SmoothValue);
    YbAxis.begin(SMOOTHED_AVERAGE, SmoothValue);
    XlAxis.begin(SMOOTHED_AVERAGE, SmoothValue);
    XrAxis.begin(SMOOTHED_AVERAGE, SmoothValue);
 

}
void loop() {

// Read the value from the sensor
  int YfAxisValue = analogRead(YfAxisPin);
  int YbAxisValue = analogRead(YbAxisPin);
  
  int XlAxisValue = analogRead(XlAxisPin);
  int XrAxisValue = analogRead(XrAxisPin);

 // Add the new value to both sensor value stores
 
  YfAxis.add(YfAxisValue);
  YbAxis.add(YbAxisValue);
  XlAxis.add(XlAxisValue);
  XrAxis.add(XrAxisValue);


// ******** Y Axis ***************

  int YfAxisCValue = YfAxis.get();
  int YbAxisCValue = YbAxis.get();
  

  // remap Yaxisback
   YbAxisCValue = map(YbAxisCValue, 1023, 0, 0, 1023);
  int  YcombinedValue = YfAxisCValue + YbAxisCValue;
// Set joystick Axis
  Joystick.setYAxis(YcombinedValue + Offset);
 
 // debug prints for serial monitor
 // Serial.println (String("Yf:") + YfAxisCValue);
 // Serial.println (String("Bf:") + YbAxisCValue);
 // Serial.println (String("Y combined:") + YcombinedValue);
  
// *********  X axis  **************

  int XlAxisCValue = XlAxis.get(); 
  int XrAxisCValue = XrAxis.get(); 

  XrAxisCValue = map(XrAxisCValue, 1023, 0, 0, 1023);
  int  XcombinedValue = XlAxisCValue + XrAxisCValue;

  // Set joystick Axis
  Joystick.setXAxis(XcombinedValue + Offset);
  
 // debug prints 
 // Serial.println (String("Xl:") + XlAxisCValue);
 // Serial.println (String("Xr:") + XrAxisCValue);
 // Serial.println (String("X combined:") + XcombinedValue);



 

}

 


Edited by trigen
  • Thanks 1

1080 ti, i7700k 5ghz, 16gb 3600 cl14 ddr4 oc

Link to comment
Share on other sites

  • trigen changed the title to Broken Fssb r3 WH force sensing stick. 4 x strain gauge to ardunio conversion. Fix and code inside

if you want to know how this all actually works you can follow this post. There's more in depth how ive set things up with the pots and why im using 2 inputs for each axis.  but mainly im researching how to do the angle adjust. 
https://forum.arduino.cc/t/joystick-how-to-add-xx-offset-angle-to-x-y-for-12-degree-offset/888828/7

1080 ti, i7700k 5ghz, 16gb 3600 cl14 ddr4 oc

Link to comment
Share on other sites

Hi trigen. Nice work with the strain gauges, they are always an interesting topic. For the rotation you will need to use "Rotation of Axes" theory. You should be able to find the equations pretty easily but they are:

 

x' = x*cos(a) + y*sin(a)

y' = -x*sin(a) + y*cos(a)

 

Where: x and y are your raw sensor readings,

a is the angle of rotation (12 deg),

x' and y' are the rotated results

 

This will bring up the problem that microcontrollers don't like trig functions so you may need to create a lookup table for it.

There is likely a library for Arduino built specifically for this. At a glance the Geometry library looks like it can handle the transformations.

Coding this efficiently is way out of my abilities but hope it helps get you on the right path at least. Looking forward to seeing more updates 🙂

 

Cheers

Boltz


Edited by Boltz
  • Like 1
Link to comment
Share on other sites

Thank you very much for the tip Boltz!  Turns out it was that easy but i would never have figured it out myself as im a math muppet so i enlisted the help of some very clever guys on the ardunio forums! 
 

/* please put some text you'll search for one day here */

const float sintheta = sin(-12 * PI / 180);
const float costheta = cos(-12 * PI / 180);

float x, y;

float newX, newY;

void setup()
{
	Serial.begin(115200);
	
	Serial.println(sintheta);
	Serial.println(costheta);

// set some x y vales here, whatevs

 	x = 13.2;
  	y = 14.6;

// do the maths

	newX = x * costheta - y * sintheta;
	newY = x * sintheta + y * costheta;

// and print the results here to see if

	Serial.println(newX);
	Serial.println(newY);
}


void loop()
{
}


 

At the moment i need to add and subtract a certain number to get the center point to be correct and that isnt 1:1 and it changes depending on bitrate so with the help of the same guys i hope to find a better way to calculate that on the fly. It does however appear to work correctly. Still working out the kinks.

 

void loop() {

 // Serial.println(String("Sintheta:")+ sintheta);
 // Serial.println(String("Sintheta:")+ costheta);


// Read the value from the sensor
  int YfAxisValue = analogRead(YfAxisPin);
  int YbAxisValue = analogRead(YbAxisPin);
  
  int XlAxisValue = analogRead(XlAxisPin) + Offset;
  int XrAxisValue = analogRead(XrAxisPin) + Offset;

 // Add the new value to both sensor value stores
 
  YfAxis.add(YfAxisValue);
  YbAxis.add(YbAxisValue);
  XlAxis.add(XlAxisValue);
  XrAxis.add(XrAxisValue);

  // Get axis from smoothed 
  
// Y
  int YfAxisCValue = YfAxis.get();
  int YbAxisCValue = YbAxis.get();

// X
  int XlAxisCValue = XlAxis.get(); 
  int XrAxisCValue = XrAxis.get(); 

// ******** Y Axis ***************


  // Since we use 4 amsp 2 front 2 back that are set to 0v to get the full range one way we we need to remap one for each to reverse the numbers

  
   YbAxisCValue = map(YbAxisCValue, 1023, 0, 0, 1023);
   XrAxisCValue = map(XrAxisCValue, 1023, 0, 0, 1023);

  // combine axises and then adjust to 12 degree rotational offset
   
  float  YcombinedValue = YfAxisCValue + YbAxisCValue ;
  float  XcombinedValue = XlAxisCValue + XrAxisCValue ;

  newX =  XcombinedValue * costheta - YcombinedValue * sintheta - 199 ;
  newY =  XcombinedValue * sintheta + YcombinedValue * costheta + 248; // added + 248 here to conpensate for center. I can also add these at Joystick.setYAxis(newY + 248)
  
  
// Set joystick Axis
  Joystick.setYAxis(newY);
  Joystick.setXAxis(newX);

 

 


Edited by trigen

1080 ti, i7700k 5ghz, 16gb 3600 cl14 ddr4 oc

Link to comment
Share on other sites

FSSB with angle adjust v 0.9


4 amp version to combine strain gauges into one and get double resolution and gain range.  You need to set all amps to 0 so you get the full range. Then in the code it will reverse one as one will compress and the other expand so they cancel each other out in this configuration. If you place one on top and one on the bottom you dont need to reverese. After its combined into one axis. 
 

Basic. 2 amp/pot version.  Should be working properly but report any bugs. 

It will rotate both axes to emulate the HW setup in the f16 stick. 



Todo. Add different force levels and tie into HW switches. 

Huge thank you to alto777 on the Ardunio forums for helping me out. No chance i could have done it without him. And a nudge to gcjr as well. Cheers! 

F-16_F6- stick rotation.jpg

 

//https://github.com/MHeironimus/ArduinoJoystickLibrary
// Amps ive used https://www.ebay.com/itm/174794426405
// DL smoothed library from the ardunio IDE

#include <Joystick.h>
#include <Smoothed.h>

#include <Adafruit_ADS1X15.h>
 
#include<Wire.h>

Adafruit_ADS1115 ads;

/* Angle adjust math you set the angle on the first line with -12 (minus is clockwise) or XX value. Enable with true or false */

int SensorRotationEmu = false;
int angle = -12; 


// Add pins for the different ranges. Just using a variable for now. Not currently implementd
// Max force from trigger height. 
// Max force for y is about 8kg
// Max force for X left is about 8kg  X right is about 6kg 
// Max force in kg 
int YMaxforce = 8;
int XMaxforce = 8;

// set amount of smoothing for the axis
int SmoothValue = 5;

// Set the joystick range. Only set the positive number. Center point will be this number divided by two
int joyLowRange = -32767;
int joyHighRange = 32767; // 65534

/*
Set flags for Joystick axes. For some reason it refuse to work with only X Y so ive added rudder and throttle
For the true false flags, use this list. Its all in  Joystick.h
    bool includeXAxis = true,
    bool includeYAxis = true,
    bool includeZAxis = true,
    bool includeRxAxis = true,
    bool includeRyAxis = true,
    bool includeRzAxis = true,
    bool includeRudder = true,
    bool includeThrottle = true,
    bool includeAccelerator = true,
    bool includeBrake = true,
    bool includeSteering = true);
  */
Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID,
  JOYSTICK_TYPE_MULTI_AXIS, 32, 0,
  true, true, false, false, false, false,
  true, true, false, false, false);

// Add smoothing for all axis 
Smoothed <int> YfAxis;
Smoothed <int> YbAxis;
Smoothed <int> XlAxis;
Smoothed <int> XrAxis;

// init joystick libary
void setup() {
    Joystick.begin();
    Serial.begin(38400);
    Wire.begin();
    ads.begin();

  // ads.setGain(GAIN_TWOTHIRDS);  // 2/3x gain +/- 6.144V  1 bit = 3mV      0.1875mV (default)
  // ads.setGain(GAIN_ONE);        // 1x gain   +/- 4.096V  1 bit = 2mV      0.125mV
  // ads.setGain(GAIN_TWO);        // 2x gain   +/- 2.048V  1 bit = 1mV      0.0625mV
  // ads.setGain(GAIN_FOUR);       // 4x gain   +/- 1.024V  1 bit = 0.5mV    0.03125mV
  // ads.setGain(GAIN_EIGHT);      // 8x gain   +/- 0.512V  1 bit = 0.25mV   0.015625mV
  // ads.setGain(GAIN_SIXTEEN);    // 16x gain  +/- 0.256V  1 bit = 0.125mV  0.0078125mV
    
    
    ads.setGain(GAIN_ONE);    // +/- 0.256V  1 bit = 0.0078125mV 



 // Sets joystick ranges
  Joystick.setYAxisRange(joyLowRange, joyHighRange);
  Joystick.setXAxisRange(joyLowRange, joyHighRange);


// Begin smoothing.     
  YfAxis.begin(SMOOTHED_AVERAGE, SmoothValue);
  YbAxis.begin(SMOOTHED_AVERAGE, SmoothValue);
  XlAxis.begin(SMOOTHED_AVERAGE, SmoothValue);
  XrAxis.begin(SMOOTHED_AVERAGE, SmoothValue);
 
}
void loop() {

 // Serial.println(String("Sintheta:")+ sintheta);
 // Serial.println(String("Sintheta:")+ costheta);


// Read the value from the sensor using 4x so they will be combined later. 
  int YfAxisValue = ads.readADC_SingleEnded(0); // Front strain gauge
  int YbAxisValue = ads.readADC_SingleEnded(1); // Back strain gauge
  
  int XlAxisValue = ads.readADC_SingleEnded(2);// left strain gauge
  int XrAxisValue = ads.readADC_SingleEnded(3); // right strain gauge

 // Add the new value to both sensor value stores
 
  YfAxis.add(YfAxisValue);
  YbAxis.add(YbAxisValue);
  XlAxis.add(XlAxisValue);
  XrAxis.add(XrAxisValue);

  // Get axis from smoothed 
  
// Y
  int YfAxisSmoothValue = YfAxis.get();
  int YbAxisSmoothValue = YbAxis.get() + 16383;

// X
  int XlAxisSmoothValue = XlAxis.get(); 
  int XrAxisSmoothValue = XrAxis.get() + 16383; 


  // Since we use 4 amsp 2 front 2 back that are set to 0v to get the full range one way we we need to remap one for each to reverse the numbers

  /*
  YbAxisCValue = map(YbAxisCValue, 1023, 0, 0, 1023);
  XrAxisCValue = map(XrAxisCValue, 1023, 0, 0, 1023);
  */
  YbAxisSmoothValue = map(YbAxisSmoothValue, joyHighRange / 2, 0, 0, joyHighRange / 2);
  XrAxisSmoothValue = map(XrAxisSmoothValue, joyHighRange / 2, 0, 0, joyHighRange / 2);

  // combine axises and then adjust to 12 degree rotational offset
  
  float  XcombinedValue = (XlAxisSmoothValue + XrAxisSmoothValue);  
  float  YcombinedValue = (YfAxisSmoothValue + YbAxisSmoothValue);


  if (SensorRotationEmu == true) {   
    const float sintheta = sin(angle * PI / 180);
    const float costheta = cos(angle * PI / 180);

  //float x, y;
  //float newX, newY;

  // move the origin to 0 so the angle rotation is correct
    YcombinedValue -= joyHighRange / 2; // now joyX is -1023 to 1023 
    XcombinedValue -= joyHighRange / 2; // same
    //Serial.println (String("Y translation:") + YcombinedValue);

    float newX =  XcombinedValue * costheta - YcombinedValue * sintheta;
    float newY =  XcombinedValue * sintheta + YcombinedValue * costheta; 

   // Send the values to the joystick library and move origin back so the center point is 1023
    Joystick.setYAxis(newY + joyHighRange / 2 );
    Joystick.setXAxis(newX + joyHighRange / 2 );
      
}
  else {
     float  Xc = (XlAxisSmoothValue + XrAxisSmoothValue); 
    // Send the values to the joystick library 
    Joystick.setYAxis(YcombinedValue);
    Joystick.setXAxis(XcombinedValue);
    //Serial.println(XcombinedValue);

      char buffer[96];
      for (int kk = 0; kk < 4; kk++) {
      sprintf(buffer, "Y f: %d Y b: %d X L:  %d X R %d Y comb: %d X comb: %d \n", YbAxisSmoothValue, YfAxisSmoothValue, XrAxisSmoothValue, XlAxisSmoothValue, XcombinedValue, YcombinedValue );
      Serial.println(buffer);
      } 
 
  }



}

 

 

FSSB_r3.ino

FSSB_r3_2_pots.ino


Edited by trigen

1080 ti, i7700k 5ghz, 16gb 3600 cl14 ddr4 oc

Link to comment
Share on other sites

  • trigen changed the title to Broken Fssb r3 WH force sensing stick. 4 x strain gauge to ardunio conversion. Ard code with stick angle emulation v0.9
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...