From 75821c6d48e04d581cd0c48480f58537b55a1e5a Mon Sep 17 00:00:00 2001 From: Jarno Rankinen Date: Sun, 5 Jan 2020 21:23:30 +0200 Subject: [PATCH 1/2] v 1.1 - Changed to display as a single joystick for Linux systems - Added input filtering to allow controlling with keyboard --- throttleQuadrant.ino | 145 +++++++++++++++++++++++++++---------------- 1 file changed, 90 insertions(+), 55 deletions(-) diff --git a/throttleQuadrant.ino b/throttleQuadrant.ino index fe8d29f..fc9d93f 100644 --- a/throttleQuadrant.ino +++ b/throttleQuadrant.ino @@ -1,6 +1,6 @@ /************************************************************************************ * Throttle Quadrant using Arduino Micro & slide potentiometers - * version 1.0 + * version 1.1 * * https://github.com/jarnorankinen/ThrottleQuadrant * @@ -24,7 +24,8 @@ * - Upload to Arduino * - Repeat for each axis * - * Future features: input averaging to filter the slight movements of levers in simulator + * v1.1 Switched to Joystick.h (single joystick library) for hassle-free Linux support. Changed behavior to update joystick axis output value + * only if raw value changes more than +/-3, to filter input and allow simultaneous keyboard control. * **********************************************************************************/ @@ -32,35 +33,51 @@ -#include "Joystick3.h" +#include "Joystick.h" +#define Joystick_includeRxAxis false +#define Joystick_includeRyAxis false +#define Joystick_includeRzAxis false -uint16_t xa = 0; // raw data from the slider -uint16_t xamin = 14, xamax = 236; //min & max values for calibration -int xa_axis = 0; // the value to give to the Joystick axis +uint16_t throttle_l = 0; // raw data from the slider +uint16_t throttle_lmin = 14, throttle_lmax = 236; //min & max values for calibration +int throttle_l_axis = 0; // the value to give to the Joystick axis +int tl_old = 0; -uint16_t ya = 0; -uint16_t yamin = 14, yamax = 234; -int ya_axis = 0; +uint16_t throttle_r = 0; +uint16_t throttle_rmin = 14, throttle_rmax = 234; +int throttle_r_axis = 0; +int tr_old = 0; -uint16_t xb = 0; -uint16_t xbmin = 14, xbmax = 226; -int xb_axis = 0; +uint16_t prop_l = 0; +uint16_t prop_lmin = 14, prop_lmax = 226; +int prop_l_axis = 0; +int pl_old = 0; -uint16_t yb = 0; -uint16_t ybmin = 14, ybmax = 232; -int yb_axis = 0; +uint16_t prop_r = 0; +uint16_t prop_rmin = 14, prop_rmax = 232; +int prop_r_axis = 0; +int pr_old = 0; -uint16_t xc = 0; -uint16_t xcmin = 15, xcmax = 231; -int xc_axis = 0; +uint16_t mix_l = 0; +uint16_t mix_lmin = 15, mix_lmax = 231; +int mix_l_axis = 0; +int ml_old = 0; -uint16_t yc = 0; -uint16_t ycmin = 15, ycmax = 235; -int yc_axis = 0; +uint16_t mix_r = 0; +uint16_t mix_rmin = 15, mix_rmax = 235; +int mix_r_axis = 0; +int mr_old = 0; + +double rotation_multip = 1.591; /************* SET THIS AS true TO TURN CALIBRATION ON********************/ bool calib = false; //Serial monitor on/off +unsigned int delta(uint16_t a, uint16_t b) { + int x = a - b; + return abs(x); +} + void setup() { //Check that these are correct for your build @@ -72,60 +89,78 @@ void setup() { pinMode(A5, INPUT_PULLUP); //yc Serial.begin(9600); - Joystick[0].begin(); - Joystick[1].begin(); - Joystick[2].begin(); + Joystick.begin(false); + tl_old = throttle_l = analogRead(A0); + tr_old = throttle_r = analogRead(A1); + pl_old = prop_l = analogRead(A2); + pr_old = prop_r = analogRead(A3); + ml_old = mix_l = analogRead(A4); + mr_old = mix_r = analogRead(A5); + } void loop() { - xa = analogRead(A0); - xa_axis = 256*xa/(xamax-xamin+5) - 128 - xamin; //convert raw values -> -128 - 128 (roughly, joystick calibration is still recommended via e.g. Windows joystick interface) + throttle_l = analogRead(A0); + throttle_l_axis = 256*throttle_l/(throttle_lmax-throttle_lmin+5) - 128 - throttle_lmin; //convert raw values -> -128 - 128 (roughly, joystick calibration is still recommended via e.g. Windows joystick interface) - ya = analogRead(A1); - ya_axis = 256*ya/(yamax-yamin+5) - 128 - yamin; + throttle_r = analogRead(A1); + throttle_r_axis = 256*throttle_r/(throttle_rmax-throttle_rmin+5) - 128 - throttle_rmin; - xb = analogRead(A2); - xb_axis = 256*xb/(xbmax-xbmin+5) - 128 - xbmin; + prop_l = analogRead(A2); + prop_l_axis = 256*prop_l/(prop_lmax-prop_lmin+5) - 128 - prop_lmin; - yb = analogRead(A3); - yb_axis = 256*yb/(ybmax-ybmin+5) - 128 - ybmin; + prop_r = analogRead(A3); + prop_r_axis = prop_r * rotation_multip - (prop_rmin + 5); + //prop_r_axis = 256*prop_r/(prop_rmax-prop_rmin+5) - prop_rmin; - xc = analogRead(A4); - xc_axis = 256*xc/(xcmax-xcmin+5) - 128 - xcmin; + mix_l = analogRead(A4); + mix_l_axis = mix_l * rotation_multip - (mix_lmin + 5); - yc = analogRead(A5); - yc_axis = 256*yc/(ycmax-ycmin+5) - 128 - ycmin; + mix_r = analogRead(A5); + mix_r_axis = 254*(mix_r - mix_rmin)/(mix_rmax - mix_rmin); if(calib==true) { //Serial monitor for calibration Serial.println(); - Serial.print("xa=");Serial.print(xa); + Serial.print("throttle_l=");Serial.print(throttle_l); Serial.print(" -> "); - Serial.print("xa_axis=");Serial.println(xa_axis); - Serial.print("ya=");Serial.print(ya); + Serial.print("throttle_l_axis=");Serial.println(throttle_l_axis); + Serial.print("throttle_r=");Serial.print(throttle_r); Serial.print(" -> "); - Serial.print("ya_axis=");Serial.println(ya_axis); - Serial.print("xb=");Serial.print(xb); + Serial.print("throttle_r_axis=");Serial.println(throttle_r_axis); + Serial.print("prop_l=");Serial.print(prop_l); Serial.print(" -> "); - Serial.print("xb_axis=");Serial.println(xb_axis); - Serial.print("yb=");Serial.print(yb); + Serial.print("prop_l_axis=");Serial.println(prop_l_axis); + Serial.print("prop_r=");Serial.print(prop_r); Serial.print(" -> "); - Serial.print("yb_axis=");Serial.println(yb_axis); - Serial.print("xc=");Serial.print(xc); + Serial.print("prop_r_axis=");Serial.println(prop_r_axis); + Serial.print("mix_l=");Serial.print(mix_l); Serial.print(" -> "); - Serial.print("xc_axis=");Serial.println(xc_axis); - Serial.print("yc=");Serial.print(yc); + Serial.print("mix_l_axis=");Serial.println(mix_l_axis); + Serial.print("mix_r=");Serial.print(mix_r); Serial.print(" -> "); - Serial.print("yc_axis=");Serial.println(yc_axis); + Serial.print("mix_r_axis=");Serial.println(mix_r_axis); } - //Set the axis values using Joystick library - Joystick[0].setXAxis(xa_axis); - Joystick[0].setYAxis(ya_axis); - Joystick[1].setXAxis(xb_axis); - Joystick[1].setYAxis(yb_axis); - Joystick[2].setXAxis(xc_axis); - Joystick[2].setYAxis(yc_axis); + Joystick.setXAxis(throttle_l_axis); + Joystick.setYAxis(throttle_r_axis); + Joystick.setZAxis(prop_l_axis); + Joystick.setXAxisRotation(prop_r_axis); + Joystick.setYAxisRotation(mix_l_axis); + Joystick.setRudder(mix_r_axis); + + + if (delta(throttle_l_axis, tl_old)>3 || delta(throttle_r_axis, tr_old)>3 || delta(prop_l_axis, pl_old)>3 || delta(prop_r_axis, pr_old)>3 || delta(mix_l_axis, ml_old)>3 || delta(mix_r_axis, mr_old)>3){ + tl_old = throttle_l_axis; + tr_old = throttle_r_axis; + pl_old = prop_l_axis; + pr_old = prop_r_axis; + ml_old = mix_l_axis; + mr_old = mix_r_axis; + Joystick.sendState(); + + } + delay(20); //this reduces load on the controller } -- 2.40.1 From 1d1c1c7269144e1b6dee7d63cb50ea423a8c71dc Mon Sep 17 00:00:00 2001 From: Jarno Rankinen Date: Mon, 6 Jan 2020 07:32:51 +0200 Subject: [PATCH 2/2] v1.11 Improved signal filtering --- throttleQuadrant.ino | 105 +++++++++++++++++++++++++------------------ 1 file changed, 61 insertions(+), 44 deletions(-) diff --git a/throttleQuadrant.ino b/throttleQuadrant.ino index fc9d93f..bf99fc6 100644 --- a/throttleQuadrant.ino +++ b/throttleQuadrant.ino @@ -1,6 +1,6 @@ /************************************************************************************ * Throttle Quadrant using Arduino Micro & slide potentiometers - * version 1.1 + * version 1.11 * * https://github.com/jarnorankinen/ThrottleQuadrant * @@ -14,18 +14,26 @@ * Shows up as three joysticks, all named "Arduino Micro", use simulators own interface to bind the controls to correct axis. * It may be necessary to invert some axis. * - * Calibration: (for xa-axis in this example) + * Calibration: (for throttle_l-axis in this example, you only need to do this once or after hardware modifications) * - Set calib = true * - Upload to Arduino * - Open the serial monitor - * - Move the slilder corresponding to xa-axis to its min & max positions - * - Note the min & max values of xa - * - Input the values to xamin & xamax + * - Move the slider corresponding to throttle_l-axis to its min & max positions + * - Note the min & max values of throttle_l + * - Input the values to throttle_lmin & throttle_lmax * - Upload to Arduino * - Repeat for each axis + * - Afterwards set calib == false & Upload to Arduino + * - Remember to calibrate controller in the simulator * - * v1.1 Switched to Joystick.h (single joystick library) for hassle-free Linux support. Changed behavior to update joystick axis output value - * only if raw value changes more than +/-3, to filter input and allow simultaneous keyboard control. + * Changelog: + * + * v1.0 Initial release + * + * v1.1 Switched to Joystick.h (single joystick library) for hassle-free Linux support. Changed behavior to update joystick axis output value + * only if raw value changes more than +/-3, to filter input and allow simultaneous keyboard control. + * + * v1.11 Added rule to ignore spike values outside min-max range * **********************************************************************************/ @@ -34,29 +42,26 @@ #include "Joystick.h" -#define Joystick_includeRxAxis false -#define Joystick_includeRyAxis false -#define Joystick_includeRzAxis false uint16_t throttle_l = 0; // raw data from the slider uint16_t throttle_lmin = 14, throttle_lmax = 236; //min & max values for calibration -int throttle_l_axis = 0; // the value to give to the Joystick axis -int tl_old = 0; +int throttle_l_axis = -128; // the value to give to the Joystick axis +int tl_old = -128; uint16_t throttle_r = 0; uint16_t throttle_rmin = 14, throttle_rmax = 234; -int throttle_r_axis = 0; -int tr_old = 0; +int throttle_r_axis = -128; +int tr_old = -128; uint16_t prop_l = 0; uint16_t prop_lmin = 14, prop_lmax = 226; -int prop_l_axis = 0; -int pl_old = 0; +int prop_l_axis = 127; +int pl_old = 127; uint16_t prop_r = 0; uint16_t prop_rmin = 14, prop_rmax = 232; -int prop_r_axis = 0; -int pr_old = 0; +int prop_r_axis = 359; +int pr_old = 359; uint16_t mix_l = 0; uint16_t mix_lmin = 15, mix_lmax = 231; @@ -101,24 +106,36 @@ void setup() { } void loop() { - throttle_l = analogRead(A0); - throttle_l_axis = 256*throttle_l/(throttle_lmax-throttle_lmin+5) - 128 - throttle_lmin; //convert raw values -> -128 - 128 (roughly, joystick calibration is still recommended via e.g. Windows joystick interface) - throttle_r = analogRead(A1); - throttle_r_axis = 256*throttle_r/(throttle_rmax-throttle_rmin+5) - 128 - throttle_rmin; + throttle_l = analogRead(A0); + if (calib == false && (throttle_l > throttle_lmax)) throttle_l = throttle_lmax; + if (calib == false && (throttle_l < throttle_lmin)) throttle_l = throttle_lmin; + throttle_l_axis = 256*throttle_l/(throttle_lmax-throttle_lmin+5) - 128 - throttle_lmin; //convert raw values -> -128 - 128 (roughly, joystick calibration is still recommended via e.g. Windows joystick interface) - prop_l = analogRead(A2); - prop_l_axis = 256*prop_l/(prop_lmax-prop_lmin+5) - 128 - prop_lmin; + throttle_r = analogRead(A1); + if (calib == false && (throttle_r > throttle_rmax)) throttle_r = throttle_rmax; + if (calib == false && (throttle_r < throttle_rmin)) throttle_r = throttle_rmin; + throttle_r_axis = 256*throttle_r/(throttle_rmax-throttle_rmin+5) - 128 - throttle_rmin; + + prop_l = analogRead(A2); + if (calib == false && (prop_l > prop_lmax)) prop_l = prop_lmax; + if (calib == false && (prop_l < prop_lmin)) prop_l = prop_lmin; + prop_l_axis = 256*prop_l/(prop_lmax-prop_lmin+5) - 128 - prop_lmin; - prop_r = analogRead(A3); - prop_r_axis = prop_r * rotation_multip - (prop_rmin + 5); - //prop_r_axis = 256*prop_r/(prop_rmax-prop_rmin+5) - prop_rmin; + prop_r = analogRead(A3); + if (calib == false && (prop_r > prop_rmax)) prop_r = prop_rmax; + if (calib == false && (prop_r < prop_rmin)) prop_r = prop_rmin; + prop_r_axis = prop_r * rotation_multip - (prop_rmin + 5); - mix_l = analogRead(A4); - mix_l_axis = mix_l * rotation_multip - (mix_lmin + 5); - - mix_r = analogRead(A5); - mix_r_axis = 254*(mix_r - mix_rmin)/(mix_rmax - mix_rmin); + mix_l = analogRead(A4); + if (calib == false && (mix_l > mix_lmax)) mix_l = mix_lmax; + if (calib == false && (mix_l < mix_lmin)) mix_l = mix_lmin; + mix_l_axis = mix_l * rotation_multip - (mix_lmin + 5); + + mix_r = analogRead(A5); + if (calib == false && (mix_r > mix_rmax)) mix_r = mix_rmax; + if (calib == false && (mix_r < mix_rmin)) mix_r = mix_rmin; + mix_r_axis = 254*(mix_r - mix_rmin)/(mix_rmax - mix_rmin); if(calib==true) { //Serial monitor for calibration Serial.println(); @@ -141,26 +158,26 @@ void loop() { Serial.print(" -> "); Serial.print("mix_r_axis=");Serial.println(mix_r_axis); } - - //Set the axis values using Joystick library - Joystick.setXAxis(throttle_l_axis); - Joystick.setYAxis(throttle_r_axis); - Joystick.setZAxis(prop_l_axis); - Joystick.setXAxisRotation(prop_r_axis); - Joystick.setYAxisRotation(mix_l_axis); - Joystick.setRudder(mix_r_axis); - - + Serial.println(mix_l); + //Serial.println(mix_l_axis); + if (delta(throttle_l_axis, tl_old)>3 || delta(throttle_r_axis, tr_old)>3 || delta(prop_l_axis, pl_old)>3 || delta(prop_r_axis, pr_old)>3 || delta(mix_l_axis, ml_old)>3 || delta(mix_r_axis, mr_old)>3){ + if (delta(throttle_l_axis, tl_old)<200 || delta(throttle_r_axis, tr_old)<200 || delta(prop_l_axis, pl_old)<200 || delta(prop_r_axis, pr_old)<200 || delta(mix_l_axis, ml_old)<200 || delta(mix_r_axis, mr_old)<200){ tl_old = throttle_l_axis; tr_old = throttle_r_axis; pl_old = prop_l_axis; pr_old = prop_r_axis; ml_old = mix_l_axis; mr_old = mix_r_axis; + Joystick.setXAxis(throttle_l_axis); + Joystick.setYAxis(throttle_r_axis); + Joystick.setZAxis(prop_l_axis); + Joystick.setXAxisRotation(prop_r_axis); + Joystick.setYAxisRotation(mix_l_axis); + Joystick.setRudder(mix_r_axis); Joystick.sendState(); - + } } - delay(20); //this reduces load on the controller + delay(20); } -- 2.40.1