Jump to content

Open Source Joystick FFB / DIY FFB Joystick


Recommended Posts

I too have been dreaming of a OSW style system for flightsticks. Though I think that directdrive is not the way to go. Directdrive servo motors are quite heavy, big and expensive. In my dreams I would like to build a real size stick which would have even nearly real life forces (like forces met in P-51 for example). I think that best way to achieve that would be to use for example windshield wiper motor with a proper gearing or belt drive. In a flightstick it is not very important to have very rapid and accurate changes which on the other hand is important in racing games which supports the idea of directdrive there.

No, maybe not a servo, at least not one as it's used in the OSW. That would be 300-400€ per servo and you need two of them.

 

One idea I had a couple of days ago was that it might be possible to use actuators.(I think you can get some for

That would have the advantage that you don't need to convert the rotation movement into a linear movement and a 2D movement using 2 or 4 of them would be easier to realize.

It wouldn't be a small construction, though and mainly useful for a home cockpit rather than a desk-mounted stick.

 

Also, I'm not yet sure how much an appropriate actuator costs, I only know about those that are used in motion rigs and those would be both too strong and too expensive.

 

In addition, I'm not yet sure if they would yield the required precision and feedback.

 

Edit: Sorry if this is not yet a main topic for me, I need to build my OSW first. ;)

Link to comment
Share on other sites

  • Replies 419
  • Created
  • Last Reply

Top Posters In This Topic

Hi

For getting enough Force to the Grip it would be easy to use DC-Motors (brushless or Brushed is of no concern).

Using an H-Bridge Driver (L298N can supply 5A) that is capable of powering two decent Motors. And the Controller can give Direction through 4 Pins (two for each Motor / or 2 Pins given some circuit for switching) and two PWM signals for manipulating the Motors Rotation Speed.

In Combination with some Gearbox for degreasing the turn Speed that will give us a Cheap and Powerful solution.

For the Crazy ones:

Using optocouplers on the Direction Pins to switch some contactors (? German: Schürtz schalter) and an external Frequency Modulator on the PWM pin.

That can source industrial Motors with enough Force to lift a plane.

Now to get the Ball rolling:

Here is my Descriptor for an Force Feedback Joystick.

It contains most Forces (excluding custom force)

4 Axis with 16bit res

4 Axis with 10bit res

4 directional Buttons (cooli)

32 Buttons.

(That is the maximum for Windows Directx inputs. Raw data could be much more but is not supported by all games)

 

 
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x04, // USAGE (Joystick)
0xa1, 0x01, // COLLECTION (Application)
0xa1, 0x00, // COLLECTION (Physical)
0x85, 0x01,
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x30, // USAGE (X)
0x09, 0x31, // USAGE (Y)
0x09, 0x32, // USAGE (Z)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x26, 0xff, 0x71, // LOGICAL_MAXIMUM (25000)
0x75, 0x10, // REPORT_SIZE (16)
0x95, 0x03, // REPORT_COUNT (3)
0x81, 0x02, // INPUT (Data,Var,Abs)
//HID_RI_END_COLLECTION(0),
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x33, // USAGE (X)
0x95, 0x01, // REPORT_COUNT (1)
0x75, 0x10, // REPORT_SIZE (16)
0x26, 0xff, 0xff, // LOGICAL_MAXIMUM (32000)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x34, // USAGE (Ry)
0x09, 0x35, // USAGE (Rz)
0x09, 0x36, // USAGE (Slider)
0x09, 0x36, // USAGE (Slider)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x26, 0x00, 0x04, // LOGICAL_MAXIMUM (1024)
0x75, 0x10, // REPORT_SIZE (16)
0x95, 0x04, // REPORT_COUNT (5)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x05, 0x09, // USAGE_PAGE (Button)
0x19, 0x01, // USAGE_MINIMUM (Button 1)
0x29, 0x20, // USAGE_MAXIMUM (Button 48)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x95, 0x20, // REPORT_COUNT (48)
0x75, 0x01, // REPORT_SIZE (1)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x39, // Usage (Hat switch)
0x09, 0x39, // Usage (Hat switch)
0x09, 0x39, // Usage (Hat switch)
0x09, 0x39, // Usage (Hat switch)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x07, // Logical Maximum (7)
0x35, 0x00, // Physical Minimum (0)
0x46, 0x3B, 0x01, // Physical Maximum (315)
0x75, 0x04, // Report Size (4)
0x95, 0x04, // Report Count (4)
0x65, 0x14, // Unit (20)
0x81, 0x42, // Input (variable,absolute,null_state)
0xc0, // END_COLLECTION

0x05,0x0F, // USAGE_PAGE (Physical Interface)
0x09,0x92, // USAGE (PID State Report)
0xA1,0x02, // COLLECTION (Logical)
0x85,0x02, // REPORT_ID (02)
0x09,0x9F, // USAGE (Device Paused)
0x09,0xA0, // USAGE (Actuators Enabled)
0x09,0xA4, // USAGE (Safety Switch)
0x09,0xA5, // USAGE (Actuator Override Switch)
0x09,0xA6, // USAGE (Actuator Power)
0x15,0x00, // LOGICAL_MINIMUM (00)
0x25,0x01, // LOGICAL_MINIMUM (01)
0x35,0x00, // PHYSICAL_MINIMUM (00)
0x45,0x01, // PHYSICAL_MAXIMUM (01)
0x75,0x01, // REPORT_SIZE (01)
0x95,0x05, // REPORT_COUNT (05)
0x81,0x02, // INPUT (Data,Var,Abs)
0x95,0x03, // REPORT_COUNT (03)
0x81,0x03, // INPUT (Constant,Var,Abs)
0x09,0x94, // USAGE (Effect Playing)
0x15,0x00, // LOGICAL_MINIMUM (00)
0x25,0x01, // LOGICAL_MAXIMUM (01)
0x35,0x00, // PHYSICAL_MINIMUM (00)
0x45,0x01, // PHYSICAL_MAXIMUM (01)
0x75,0x01, // REPORT_SIZE (01)
0x95,0x01, // REPORT_COUNT (01)
0x81,0x02, // INPUT (Data,Var,Abs)
0x09,0x22, // USAGE (Effect Block Index)
0x15,0x01, // LOGICAL_MINIMUM (01)
0x25,0x28, // LOGICAL_MAXIMUM (28)
0x35,0x01, // PHYSICAL_MINIMUM (01)
0x45,0x28, // PHYSICAL_MAXIMUM (28)
0x75,0x07, // REPORT_SIZE (07)
0x95,0x01, // REPORT_COUNT (01)
0x81,0x02, // INPUT (Data,Var,Abs)
0xC0, // END COLLECTION ()

0x09,0x21, // USAGE (Set Effect Report)
0xA1,0x02, // COLLECTION (Logical)
0x85,0x01, // REPORT_ID (01)
0x09,0x22, // USAGE (Effect Block Index)
0x15,0x01, // LOGICAL_MINIMUM (01)
0x25,0x28, // LOGICAL_MAXIMUM (28)
0x35,0x01, // PHYSICAL_MINIMUM (01)
0x45,0x28, // PHYSICAL_MAXIMUM (28)
0x75,0x08, // REPORT_SIZE (08)
0x95,0x01, // REPORT_COUNT (01)
0x91,0x02, // OUTPUT (Data,Var,Abs)
0x09,0x25, // USAGE (25)
0xA1,0x02, // COLLECTION (Logical)
0x09,0x26, // USAGE (26)
0x09,0x27, // USAGE (27)
0x09,0x30, // USAGE (30)
0x09,0x31, // USAGE (31)
0x09,0x32, // USAGE (32)
0x09,0x33, // USAGE (33)
0x09,0x34, // USAGE (34)
0x09,0x40, // USAGE (40)
0x09,0x41, // USAGE (41)
0x09,0x42, // USAGE (42)
0x09,0x43, // USAGE (43)
0x09,0x28, // USAGE (28)
0x25,0x0C, // LOGICAL_MAXIMUM (0C)
0x15,0x01, // LOGICAL_MINIMUM (01)
0x35,0x01, // PHYSICAL_MINIMUM (01)
0x45,0x0C, // PHYSICAL_MAXIMUM (0C)
0x75,0x08, // REPORT_SIZE (08)
0x95,0x01, // REPORT_COUNT (01)
0x91,0x00, // OUTPUT (Data)
0xC0, // END COLLECTION ()
0x09,0x50, // USAGE (Duration)
0x09,0x54, // USAGE (Trigger Repeat Interval)
0x09,0x51, // USAGE (Sample Period)
0x15,0x00, // LOGICAL_MINIMUM (00)
0x26,0xFF,0x7F, // LOGICAL_MAXIMUM (7F FF)
0x35,0x00, // PHYSICAL_MINIMUM (00)
0x46,0xFF,0x7F, // PHYSICAL_MAXIMUM (7F FF)
0x66,0x03,0x10, // UNIT (Eng Lin:Time)
0x55,0xFD, // UNIT_EXPONENT (-3)
0x75,0x10, // REPORT_SIZE (10)
0x95,0x03, // REPORT_COUNT (03)
0x91,0x02, // OUTPUT (Data,Var,Abs)
0x55,0x00, // UNIT_EXPONENT (00)
0x66,0x00,0x00, // UNIT (None)
0x09,0x52, // USAGE (Gain)
0x15,0x00, // LOGICAL_MINIMUM (00)
0x26,0xFF,0x00, // LOGICAL_MAXIMUM (00 FF)
0x35,0x00, // PHYSICAL_MINIMUM (00)
0x46,0x10,0x27, // PHYSICAL_MAXIMUM (10000)
0x75,0x08, // REPORT_SIZE (08)
0x95,0x01, // REPORT_COUNT (01)
0x91,0x02, // OUTPUT (Data,Var,Abs)
0x09,0x53, // USAGE (Trigger Button)
0x15,0x01, // LOGICAL_MINIMUM (01)
0x25,0x08, // LOGICAL_MAXIMUM (08)
0x35,0x01, // PHYSICAL_MINIMUM (01)
0x45,0x08, // PHYSICAL_MAXIMUM (08)
0x75,0x08, // REPORT_SIZE (08)
0x95,0x01, // REPORT_COUNT (01)
0x91,0x02, // OUTPUT (Data,Var,Abs)
0x09,0x55, // USAGE (Axes Enable)
0xA1,0x02, // COLLECTION (Logical)
0x05,0x01, // USAGE_PAGE (Generic Desktop)
0x09,0x30, // USAGE (X)
0x09,0x31, // USAGE (Y)
0x15,0x00, // LOGICAL_MINIMUM (00)
0x25,0x01, // LOGICAL_MAXIMUM (01)
0x75,0x01, // REPORT_SIZE (01)
0x95,0x02, // REPORT_COUNT (02)
0x91,0x02, // OUTPUT (Data,Var,Abs)
0xC0, // END COLLECTION ()
0x05,0x0F, // USAGE_PAGE (Physical Interface)
0x09,0x56, // USAGE (Direction Enable)
0x95,0x01, // REPORT_COUNT (01)
0x91,0x02, // OUTPUT (Data,Var,Abs)
0x95,0x05, // REPORT_COUNT (05)
0x91,0x03, // OUTPUT (Constant,Var,Abs)
0x09,0x57, // USAGE (Direction)
0xA1,0x02, // COLLECTION (Logical)
0x0B,0x01,0x00,0x0A,0x00,
0x0B,0x02,0x00,0x0A,0x00,
0x66,0x14,0x00, // UNIT (Eng Rot:Angular Pos)
0x55,0xFE, // UNIT_EXPONENT (FE)
0x15,0x00, // LOGICAL_MINIMUM (00)
0x26,0xFF,0x00, // LOGICAL_MAXIMUM (00 FF)
0x35,0x00, // PHYSICAL_MINIMUM (00)
0x47,0xA0,0x8C,0x00,0x00, // PHYSICAL_MAXIMUM (00 00 8C A0)
0x66,0x00,0x00, // UNIT (None)
0x75,0x08, // REPORT_SIZE (08)
0x95,0x02, // REPORT_COUNT (02)
0x91,0x02, // OUTPUT (Data,Var,Abs)
0x55,0x00, // UNIT_EXPONENT (00)
0x66,0x00,0x00, // UNIT (None)
0xC0, // END COLLECTION ()
0x05,0x0F, // USAGE_PAGE (Physical Interface)
// 0x09,0xA7, // USAGE (Start Delay)
0x66,0x03,0x10, // UNIT (Eng Lin:Time)
0x55,0xFD, // UNIT_EXPONENT (-3)
0x15,0x00, // LOGICAL_MINIMUM (00)
0x26,0xFF,0x7F, // LOGICAL_MAXIMUM (7F FF)
0x35,0x00, // PHYSICAL_MINIMUM (00)
0x46,0xFF,0x7F, // PHYSICAL_MAXIMUM (7F FF)
0x75,0x10, // REPORT_SIZE (10)
0x95,0x01, // REPORT_COUNT (01)
// 0x91,0x02, // OUTPUT (Data,Var,Abs)
0x66,0x00,0x00, // UNIT (None)
0x55,0x00, // UNIT_EXPONENT (00)
0xC0, // END COLLECTION ()

0x05,0x0F, // USAGE_PAGE (Physical Interface)
0x09,0x5A, // USAGE (Set Envelope Report)
0xA1,0x02, // COLLECTION (Logical)
0x85,0x02, // REPORT_ID (02)
0x09,0x22, // USAGE (Effect Block Index)
0x15,0x01, // LOGICAL_MINIMUM (01)
0x25,0x28, // LOGICAL_MAXIMUM (28)
0x35,0x01, // PHYSICAL_MINIMUM (01)
0x45,0x28, // PHYSICAL_MAXIMUM (28)
0x75,0x08, // REPORT_SIZE (08)
0x95,0x01, // REPORT_COUNT (01)
0x91,0x02, // OUTPUT (Data,Var,Abs)
0x09,0x5B, // USAGE (Attack Level)
0x09,0x5D, // USAGE (Fade Level)
0x15,0x00, // LOGICAL_MINIMUM (00)
0x26,0x10,0x27, // LOGICAL_MAXIMUM (00 FF)
0x35,0x00, // PHYSICAL_MINIMUM (00)
0x46,0x10,0x27, // PHYSICAL_MAXIMUM (10000)
0x75,0x10, // REPORT_SIZE (08)

0x95,0x02, // REPORT_COUNT (02)
0x91,0x02, // OUTPUT (Data,Var,Abs)
0x09,0x5C, // USAGE (5C)
0x09,0x5E, // USAGE (5E)
0x66,0x03,0x10, // UNIT (Eng Lin:Time)
0x55,0xFD, // UNIT_EXPONENT (-3)
0x26,0xFF,0x7F, // LOGICAL_MAXIMUM (7F FF)
0x46,0xFF,0x7F, // PHYSICAL_MAXIMUM (7F FF)
0x75,0x10, // REPORT_SIZE (10)
0x91,0x02, // OUTPUT (Data,Var,Abs)
0x45,0x00, // PHYSICAL_MAXIMUM (00)
0x66,0x00,0x00, // UNIT (None)
0x55,0x00, // UNIT_EXPONENT (00)
0xC0, // END COLLECTION ()

0x09,0x5F, // USAGE (Set Condition Report)
0xA1,0x02, // COLLECTION (Logical)
0x85,0x03, // REPORT_ID (03)
0x09,0x22, // USAGE (Effect Block Index)
0x15,0x01, // LOGICAL_MINIMUM (01)
0x25,0x28, // LOGICAL_MAXIMUM (28)
0x35,0x01, // PHYSICAL_MINIMUM (01)
0x45,0x28, // PHYSICAL_MAXIMUM (28)
0x75,0x08, // REPORT_SIZE (08)
0x95,0x01, // REPORT_COUNT (01)
0x91,0x02, // OUTPUT (Data,Var,Abs)
0x09,0x23, // USAGE (Parameter Block Offset)
0x15,0x00, // LOGICAL_MINIMUM (00)
0x25,0x01, // LOGICAL_MAXIMUM (01)
0x35,0x00, // PHYSICAL_MINIMUM (00)
0x45,0x01, // PHYSICAL_MAXIMUM (01)
0x75,0x04, // REPORT_SIZE (04)
0x95,0x01, // REPORT_COUNT (01)
0x91,0x02, // OUTPUT (Data,Var,Abs)
0x09,0x58, // USAGE (Type Specific Block Offset)
0xA1,0x02, // COLLECTION (Logical)
0x0B,0x01,0x00,0x0A,0x00, // USAGE (Instance 1)
0x0B,0x02,0x00,0x0A,0x00, // USAGE (Instance 2)
0x75,0x02, // REPORT_SIZE (02)
0x95,0x02, // REPORT_COUNT (02)
0x91,0x02, // OUTPUT (Data,Var,Abs)
0xC0, // END COLLECTION ()
0x15,0x80, // LOGICAL_MINIMUM (80)
0x25,0x7F, // LOGICAL_MAXIMUM (7F)
0x36,0xF0,0xD8, // PHYSICAL_MINIMUM (-10000)
0x46,0x10,0x27, // PHYSICAL_MAXIMUM (10000)
0x09,0x60, // USAGE (CP Offset)
0x09,0x61, // USAGE (Positive Coefficient)
0x09,0x62, // USAGE (Negative Coefficient)
0x09,0x63, // USAGE (Positive Saturation)
0x09,0x64, // USAGE (Negative Saturation)
0x09,0x65, // USAGE (Dead Band )
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x26, 0x10, 0x27, // LOGICAL_MAXIMUM (25000)
0x75, 0x10, // REPORT_SIZE (16)
//0x75,0x08, // REPORT_SIZE (08) 
0x95,0x06, // REPORT_COUNT (01)
0x91,0x02, // OUTPUT (Data,Var,Abs)
0x36,0xF0,0xD8, // PHYSICAL_MINIMUM (-10000)
0x46,0x10,0x27, // PHYSICAL_MAXIMUM (10000)
/*
0x95,0x02, // REPORT_COUNT (01) // ???? WAS 2 with "negative coeff"
0x91,0x02, // OUTPUT (Data,Var,Abs)
0x15,0x00, // LOGICAL_MINIMUM (00)
0x26, 0x10, 0x27, // LOGICAL_MAXIMUM (00 FF)
0x35,0x00, // PHYSICAL_MINIMUM (00)
0x46,0x10,0x27, // PHYSICAL_MAXIMUM (10000)

0x09,0x63, // USAGE (Positive Saturation)
0x09,0x64, // USAGE (Negative Saturation)
0x75,0x10, // REPORT_SIZE (08)
0x95,0x02, // REPORT_COUNT (02)
// 0x91,0x02, // OUTPUT (Data,Var,Abs)
// 0x09,0x65, // USAGE (Dead Band )
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x26, 0x10, 0x27, // LOGICAL_MAXIMUM (25000)
0x46,0x10,0x27, // PHYSICAL_MAXIMUM (10000)
0x95,0x01, // REPORT_COUNT (01)
// 0x91,0x02, // OUTPUT (Data,Var,Abs)
*/
0xC0, // END COLLECTION ()

0x09,0x6E, // USAGE (Set Periodic Report)
0xA1,0x02, // COLLECTION (Logical)
0x85,0x04, // REPORT_ID (04)
0x09,0x22, // USAGE (Effect Block Index)
0x15,0x01, // LOGICAL_MINIMUM (01)
0x25,0x28, // LOGICAL_MAXIMUM (28)
0x35,0x01, // PHYSICAL_MINIMUM (01)
0x45,0x28, // PHYSICAL_MAXIMUM (28)
0x75,0x08, // REPORT_SIZE (08)
0x95,0x01, // REPORT_COUNT (01)
0x91,0x02, // OUTPUT (Data,Var,Abs)
0x09,0x70, // USAGE (Magnitude)
0x15,0x00, // LOGICAL_MINIMUM (00)
0x26,0xFF,0x00, // LOGICAL_MAXIMUM (00 FF)
0x35,0x00, // PHYSICAL_MINIMUM (00)
0x46,0x10,0x27, // PHYSICAL_MAXIMUM (10000)
0x75,0x08, // REPORT_SIZE (08)
0x95,0x01, // REPORT_COUNT (01)
0x91,0x02, // OUTPUT (Data,Var,Abs)
0x09,0x6F, // USAGE (Offset)
0x15,0x80, // LOGICAL_MINIMUM (80)
0x25,0x7F, // LOGICAL_MAXIMUM (7F)
0x36,0xF0,0xD8, // PHYSICAL_MINIMUM (-10000)
0x46,0x10,0x27, // PHYSICAL_MAXIMUM (10000)
0x95,0x01, // REPORT_COUNT (01)
0x91,0x02, // OUTPUT (Data,Var,Abs)
0x09,0x71, // USAGE (Phase)
0x66,0x14,0x00, // UNIT (Eng Rot:Angular Pos)
0x55,0xFE, // UNIT_EXPONENT (FE)
0x15,0x00, // LOGICAL_MINIMUM (00)
0x26,0xFF,0x00, // LOGICAL_MAXIMUM (00 FF)
0x35,0x00, // PHYSICAL_MINIMUM (00)
0x47,0xA0,0x8C,0x00,0x00, // PHYSICAL_MAXIMUM (00 00 8C A0)
0x91,0x02, // OUTPUT (Data,Var,Abs)
0x09,0x72, // USAGE (Period)
0x26,0xFF,0x7F, // LOGICAL_MAXIMUM (7F FF)
0x46,0xFF,0x7F, // PHYSICAL_MAXIMUM (7F FF)
0x66,0x03,0x10, // UNIT (Eng Lin:Time)
0x55,0xFD, // UNIT_EXPONENT (-3)
0x75,0x10, // REPORT_SIZE (10)
0x95,0x01, // REPORT_COUNT (01)
0x91,0x02, // OUTPUT (Data,Var,Abs)
0x66,0x00,0x00, // UNIT (None)
0x55,0x00, // UNIT_EXPONENT (00)
0xC0, // END COLLECTION ()

0x09,0x73, // USAGE (Set Constant Force Report)
0xA1,0x02, // COLLECTION (Logical)
0x85,0x05, // REPORT_ID (05)
0x09,0x22, // USAGE (Effect Block Index)
0x15,0x01, // LOGICAL_MINIMUM (01)
0x25,0x28, // LOGICAL_MAXIMUM (28)
0x35,0x01, // PHYSICAL_MINIMUM (01)
0x45,0x28, // PHYSICAL_MAXIMUM (28)
0x75,0x08, // REPORT_SIZE (08)
0x95,0x01, // REPORT_COUNT (01)
0x91,0x02, // OUTPUT (Data,Var,Abs)
0x09,0x70, // USAGE (Magnitude)
0x16,0x01,0xFF, // LOGICAL_MINIMUM (-255)
0x26,0xFF,0x00, // LOGICAL_MAXIMUM (255)
0x36,0xF0,0xD8, // PHYSICAL_MINIMUM (-10000)
0x46,0x10,0x27, // PHYSICAL_MAXIMUM (10000)
0x75,0x10, // REPORT_SIZE (10)
0x95,0x01, // REPORT_COUNT (01)
0x91,0x02, // OUTPUT (Data,Var,Abs)
0xC0, // END COLLECTION ()

0x09,0x74, // USAGE (Set Ramp Force Report)
0xA1,0x02, // COLLECTION (Logical)
0x85,0x06, // REPORT_ID (06)
0x09,0x22, // USAGE (Effect Block Index)
0x15,0x01, // LOGICAL_MINIMUM (01)
0x25,0x28, // LOGICAL_MAXIMUM (28)
0x35,0x01, // PHYSICAL_MINIMUM (01)
0x45,0x28, // PHYSICAL_MAXIMUM (28)
0x75,0x08, // REPORT_SIZE (08)
0x95,0x01, // REPORT_COUNT (01)
0x91,0x02, // OUTPUT (Data,Var,Abs)
0x09,0x75, // USAGE (Ramp Start)
0x09,0x76, // USAGE (Ramp End)
0x15,0x80, // LOGICAL_MINIMUM (-128)
0x25,0x7F, // LOGICAL_MAXIMUM (127)
//0x15,0x00,
//0x25,0xff,
0x36,0xF0,0xD8, // PHYSICAL_MINIMUM (-10000)
0x46,0x10,0x27, // PHYSICAL_MAXIMUM (10000)
0x75,0x08, // REPORT_SIZE (08)
0x95,0x02, // REPORT_COUNT (02)
0x91,0x02, // OUTPUT (Data,Var,Abs)
0xC0, // END COLLECTION ()

0x09,0x68, // USAGE (Custom Force Data Report)
0xA1,0x02, // COLLECTION (Logical)
0x85,0x07, // REPORT_ID (07)
0x09,0x22, // USAGE (Effect Block Index)
0x15,0x01, // LOGICAL_MINIMUM (01)
0x25,0x28, // LOGICAL_MAXIMUM (28)
0x35,0x01, // PHYSICAL_MINIMUM (01)
0x45,0x28, // PHYSICAL_MAXIMUM (28)
0x75,0x08, // REPORT_SIZE (08)
0x95,0x01, // REPORT_COUNT (01)
0x91,0x02, // OUTPUT (Data,Var,Abs)
0x09,0x6C, // USAGE (Custom Force Data Offset)
0x15,0x00, // LOGICAL_MINIMUM (00)
0x26,0x10,0x27, // LOGICAL_MAXIMUM (10000)
0x35,0x00, // PHYSICAL_MINIMUM (00)
0x46,0x10,0x27, // PHYSICAL_MAXIMUM (10000)
0x75,0x10, // REPORT_SIZE (10)
0x95,0x01, // REPORT_COUNT (01)
0x91,0x02, // OUTPUT (Data,Var,Abs)
0x09,0x69, // USAGE (Custom Force Data)
0x15,0x81, // LOGICAL_MINIMUM (-127)
0x25,0x7F, // LOGICAL_MAXIMUM (127)
0x35,0x00, // PHYSICAL_MINIMUM (00)
0x46,0xFF,0x00, // PHYSICAL_MAXIMUM (255)
0x75,0x08, // REPORT_SIZE (08)
0x95,0x0C, // REPORT_COUNT (0C)
0x92,0x02,0x01, // OUTPUT ( Data,Var,Abs,Buf)
0xC0, // END COLLECTION ()

0x09,0x66, // USAGE (Download Force Sample)
0xA1,0x02, // COLLECTION (Logical)
0x85,0x08, // REPORT_ID (08)
0x05,0x01, // USAGE_PAGE (Generic Desktop)
0x09,0x30, // USAGE (X)
0x09,0x31, // USAGE (Y)
0x15,0x81, // LOGICAL_MINIMUM (-127)
0x25,0x7F, // LOGICAL_MAXIMUM (127)
0x35,0x00, // PHYSICAL_MINIMUM (00)
0x46,0xFF,0x00, // PHYSICAL_MAXIMUM (255)
0x75,0x08, // REPORT_SIZE (08)
0x95,0x02, // REPORT_COUNT (02)
0x91,0x02, // OUTPUT (Data,Var,Abs)
0xC0, // END COLLECTION ()

0x05,0x0F, // USAGE_PAGE (Physical Interface)
0x09,0x77, // USAGE (Effect Operation Report)
0xA1,0x02, // COLLECTION (Logical)
0x85,0x0A, // REPORT_ID (0A)
0x09,0x22, // USAGE (Effect Block Index)
0x15,0x01, // LOGICAL_MINIMUM (01)
0x25,0x28, // LOGICAL_MAXIMUM (28)
0x35,0x01, // PHYSICAL_MINIMUM (01)
0x45,0x28, // PHYSICAL_MAXIMUM (28)
0x75,0x08, // REPORT_SIZE (08)
0x95,0x01, // REPORT_COUNT (01)
0x91,0x02, // OUTPUT (Data,Var,Abs)
0x09,0x78, // USAGE (78)
0xA1,0x02, // COLLECTION (Logical)
0x09,0x79, // USAGE (Op Effect Start)
0x09,0x7A, // USAGE (Op Effect Start Solo)
0x09,0x7B, // USAGE (Op Effect Stop)
0x15,0x01, // LOGICAL_MINIMUM (01)
0x25,0x03, // LOGICAL_MAXIMUM (03)
0x75,0x08, // REPORT_SIZE (08)
0x95,0x01, // REPORT_COUNT (01)
0x91,0x00, // OUTPUT (Data,Ary,Abs)
0xC0, // END COLLECTION ()
0x09,0x7C, // USAGE (Loop Count)
0x15,0x00, // LOGICAL_MINIMUM (00)
0x26,0xFF,0x00, // LOGICAL_MAXIMUM (00 FF)
0x35,0x00, // PHYSICAL_MINIMUM (00)
0x46,0xFF,0x00, // PHYSICAL_MAXIMUM (00 FF)
0x91,0x02, // OUTPUT (Data,Var,Abs)
0xC0, // END COLLECTION ()

0x09,0x90, // USAGE (PID Block Free Report)
0xA1,0x02, // COLLECTION (Logical)
0x85,0x0B, // REPORT_ID (0B)
0x09,0x22, // USAGE (Effect Block Index)
0x25,0x28, // LOGICAL_MAXIMUM (28)
0x15,0x01, // LOGICAL_MINIMUM (01)
0x35,0x01, // PHYSICAL_MINIMUM (01)
0x45,0x28, // PHYSICAL_MAXIMUM (28)
0x75,0x08, // REPORT_SIZE (08)
0x95,0x01, // REPORT_COUNT (01)
0x91,0x02, // OUTPUT (Data,Var,Abs)
0xC0, // END COLLECTION ()

0x09,0x96, // USAGE (PID Device Control)
0xA1,0x02, // COLLECTION (Logical)
0x85,0x0C, // REPORT_ID (0C)
0x09,0x97, // USAGE (DC Enable Actuators)
0x09,0x98, // USAGE (DC Disable Actuators)
0x09,0x99, // USAGE (DC Stop All Effects)
0x09,0x9A, // USAGE (DC Device Reset)
0x09,0x9B, // USAGE (DC Device Pause)
0x09,0x9C, // USAGE (DC Device Continue)
0x15,0x01, // LOGICAL_MINIMUM (01)
0x25,0x06, // LOGICAL_MAXIMUM (06)
0x75,0x08, // REPORT_SIZE (08)
0x95,0x01, // REPORT_COUNT (01)
0x91,0x00, // OUTPUT (Data)
0xC0, // END COLLECTION ()

0x09,0x7D, // USAGE (Device Gain Report)
0xA1,0x02, // COLLECTION (Logical)
0x85,0x0D, // REPORT_ID (0D)
0x09,0x7E, // USAGE (Device Gain)
0x15,0x00, // LOGICAL_MINIMUM (00)
0x26,0xFF,0x00, // LOGICAL_MAXIMUM (00 FF)
0x35,0x00, // PHYSICAL_MINIMUM (00)
0x46,0x10,0x27, // PHYSICAL_MAXIMUM (10000)
0x75,0x08, // REPORT_SIZE (08)
0x95,0x01, // REPORT_COUNT (01)
0x91,0x02, // OUTPUT (Data,Var,Abs)
0xC0, // END COLLECTION ()

0x09,0x6B, // USAGE (Set Custom Force Report)
0xA1,0x02, // COLLECTION (Logical)
0x85,0x0E, // REPORT_ID (0E)
0x09,0x22, // USAGE (Effect Block Index)
0x15,0x01, // LOGICAL_MINIMUM (01)
0x25,0x28, // LOGICAL_MAXIMUM (28)
0x35,0x01, // PHYSICAL_MINIMUM (01)
0x45,0x28, // PHYSICAL_MAXIMUM (28)
0x75,0x08, // REPORT_SIZE (08)
0x95,0x01, // REPORT_COUNT (01)
0x91,0x02, // OUTPUT (Data,Var,Abs)
0x09,0x6D, // USAGE (Sample Count)
0x15,0x00, // LOGICAL_MINIMUM (00)
0x26,0xFF,0x00, // LOGICAL_MAXIMUM (00 FF)
0x35,0x00, // PHYSICAL_MINIMUM (00)
0x46,0xFF,0x00, // PHYSICAL_MAXIMUM (00 FF)
0x75,0x08, // REPORT_SIZE (08)
0x95,0x01, // REPORT_COUNT (01)
0x91,0x02, // OUTPUT (Data,Var,Abs)
0x09,0x51, // USAGE (Sample Period)
0x66,0x03,0x10, // UNIT (Eng Lin:Time)
0x55,0xFD, // UNIT_EXPONENT (-3)
0x15,0x00, // LOGICAL_MINIMUM (00)
0x26,0xFF,0x7F, // LOGICAL_MAXIMUM (32767)
0x35,0x00, // PHYSICAL_MINIMUM (00)
0x46,0xFF,0x7F, // PHYSICAL_MAXIMUM (32767)
0x75,0x10, // REPORT_SIZE (10)
0x95,0x01, // REPORT_COUNT (01)
0x91,0x02, // OUTPUT (Data,Var,Abs)
0x55,0x00, // UNIT_EXPONENT (00)
0x66,0x00,0x00, // UNIT (None)
0xC0, // END COLLECTION ()

0x09,0xAB, // USAGE (Create New Effect Report)
0xA1,0x02, // COLLECTION (Logical)
0x85,0x05, // REPORT_ID (05)
0x09,0x25, // USAGE (Effect Type)
0xA1,0x02, // COLLECTION (Logical)
0x09,0x26, // USAGE (26)
0x09,0x27, // USAGE (27)
0x09,0x30, // USAGE (30)
0x09,0x31, // USAGE (31)
0x09,0x32, // USAGE (32)
0x09,0x33, // USAGE (33)
0x09,0x34, // USAGE (34)
0x09,0x40, // USAGE (40)
0x09,0x41, // USAGE (41)
0x09,0x42, // USAGE (42)
0x09,0x43, // USAGE (43)
0x09,0x28, // USAGE (28)
0x25,0x0C, // LOGICAL_MAXIMUM (0C)
0x15,0x01, // LOGICAL_MINIMUM (01)
0x35,0x01, // PHYSICAL_MINIMUM (01)
0x45,0x0C, // PHYSICAL_MAXIMUM (0C)
0x75,0x08, // REPORT_SIZE (08)
0x95,0x01, // REPORT_COUNT (01)
0xB1,0x00, // FEATURE (Data)
0xC0, // END COLLECTION ()
0x05,0x01, // USAGE_PAGE (Generic Desktop)
0x09,0x3B, // USAGE (Byte Count)
0x15,0x00, // LOGICAL_MINIMUM (00)
0x26,0xFF,0x01, // LOGICAL_MAXIMUM (511)
0x35,0x00, // PHYSICAL_MINIMUM (00)
0x46,0xFF,0x01, // PHYSICAL_MAXIMUM (511)
0x75,0x0A, // REPORT_SIZE (0A)
0x95,0x01, // REPORT_COUNT (01)
0xB1,0x02, // FEATURE (Data,Var,Abs)
0x75,0x06, // REPORT_SIZE (06)
0xB1,0x01, // FEATURE (Constant,Ary,Abs)
0xC0, // END COLLECTION ()

0x05,0x0F, // USAGE_PAGE (Physical Interface)
0x09,0x89, // USAGE (PID Block Load Report)
0xA1,0x02, // COLLECTION (Logical)
0x85,0x06, // REPORT_ID (06)
0x09,0x22, // USAGE (Effect Block Index)
0x25,0x28, // LOGICAL_MAXIMUM (28)
0x15,0x01, // LOGICAL_MINIMUM (01)
0x35,0x01, // PHYSICAL_MINIMUM (01)
0x45,0x28, // PHYSICAL_MAXIMUM (28)
0x75,0x08, // REPORT_SIZE (08)
0x95,0x01, // REPORT_COUNT (01)
0xB1,0x02, // FEATURE (Data,Var,Abs)
0x09,0x8B, // USAGE (Block Load Status)
0xA1,0x02, // COLLECTION (Logical)
0x09,0x8C, // USAGE (Block Load Success)
0x09,0x8D, // USAGE (Block Load Full)
0x09,0x8E, // USAGE (Block Load Error)
0x25,0x03, // LOGICAL_MAXIMUM (03)
0x15,0x01, // LOGICAL_MINIMUM (01)
0x35,0x01, // PHYSICAL_MINIMUM (01)
0x45,0x03, // PHYSICAL_MAXIMUM (03)
0x75,0x08, // REPORT_SIZE (08)
0x95,0x01, // REPORT_COUNT (01)
0xB1,0x00, // FEATURE (Data)
0xC0, // END COLLECTION ()
0x09,0xAC, // USAGE (RAM Pool Available)
0x15,0x00, // LOGICAL_MINIMUM (00)
0x27,0xFF,0xFF,0x00,0x00, // LOGICAL_MAXIMUM (00 00 FF FF)
0x35,0x00, // PHYSICAL_MINIMUM (00)
0x47,0xFF,0xFF,0x00,0x00, // PHYSICAL_MAXIMUM (00 00 FF FF)
0x75,0x10, // REPORT_SIZE (10)
0x95,0x01, // REPORT_COUNT (01)
0xB1,0x00, // FEATURE (Data)
0xC0, // END COLLECTION ()

0x09,0x7F, // USAGE (PID Pool Report)
0xA1,0x02, // COLLECTION (Logical)
0x85,0x07, // REPORT_ID (07)
0x09,0x80, // USAGE (RAM Pool Size)
0x75,0x10, // REPORT_SIZE (10)
0x95,0x01, // REPORT_COUNT (01)
0x15,0x00, // LOGICAL_MINIMUM (00)
0x35,0x00, // PHYSICAL_MINIMUM (00)
0x27,0xFF,0xFF,0x00,0x00, // LOGICAL_MAXIMUM (00 00 FF FF)
0x47,0xFF,0xFF,0x00,0x00, // PHYSICAL_MAXIMUM (00 00 FF FF)
0xB1,0x02, // FEATURE (Data,Var,Abs)
0x09,0x83, // USAGE (Simultaneous Effects Max)
0x26,0xFF,0x00, // LOGICAL_MAXIMUM (00 FF)
0x46,0xFF,0x00, // PHYSICAL_MAXIMUM (00 FF)
0x75,0x08, // REPORT_SIZE (08)
0x95,0x01, // REPORT_COUNT (01)
0xB1,0x02, // FEATURE (Data,Var,Abs)
0x09,0xA9, // USAGE (Device Managed Pool)
0x09,0xAA, // USAGE (Shared Parameter Blocks)
0x75,0x01, // REPORT_SIZE (01)
0x95,0x02, // REPORT_COUNT (02)
0x15,0x00, // LOGICAL_MINIMUM (00)
0x25,0x01, // LOGICAL_MAXIMUM (01)
0x35,0x00, // PHYSICAL_MINIMUM (00)
0x45,0x01, // PHYSICAL_MAXIMUM (01)
0xB1,0x02, // FEATURE (Data,Var,Abs)
0x75,0x06, // REPORT_SIZE (06)
0x95,0x01, // REPORT_COUNT (01)
0xB1,0x03, // FEATURE ( Cnst,Var,Abs)
0xC0, // END COLLECTION ()

0xc0, // END_COLLECTION

The threemost dangerous threads to Programmers:

  • Fresh air
  • Bright sun light
  • The horrifying screams of singingbirds

Link to comment
Share on other sites

@Berniyh, linear actuators that are used in the cheaper motion sims (scn5, scn6) wont work on a flight stick as the internal gearing means that the internal motors can move the actuator but pushing against the actuator will not move it.

 

So a motor is ideal, stepper, servo, basic dc etc as you can have it give off a force while still being able to overcome that force with the stick. Mechanically it's simple enough to connect a stick to a motor.

 

@MetalGear, I wish I had a bit more time to help with this as it has interested me over the years as well. I might have a bit of time in a couple of weeks.

 

Have you got your descriptor running on something? arduino or some other environment? I coould at least get it running in the meantime and see if I can do something later.

Link to comment
Share on other sites

Hi

Yes the descriptor is working but you will need to add some functions for the USB communication.

I use a SDK600 with ATMEGA32U4

And the AVR Studio 7.0

But I think it will work with a teensy or pro micro as well.

I see if I can find the rest of this Project as I had put it on hold for I couldn't sort out the Timing Problems when using multiple Forces at the same time.

 

Greatings

MetalGear_Honk

The threemost dangerous threads to Programmers:

  • Fresh air
  • Bright sun light
  • The horrifying screams of singingbirds

Link to comment
Share on other sites

I have every kind of motor and driver on hand. Stepper, servo or DC. If anyone writes a full arduino sketch for X,Y,Z motors for joystick and rudders, not interested in buttons at this moment. I will immediately make elegant FFB gimbal testing rigs, and send them around for testing, as many as needed. I will see if the motors can run it 1:1 or they need to be on a gear/belt ratio.

Link to comment
Share on other sites

Hi

I do not think that we can make an Arduino sketch to test the FFB.

Or can a Micro be booted as different device?

I don't own one, and normaly use AVR Studio

If it is possible I will see if I can port my Test code to Arduino.

For a test Rig:

What DC Motor have you at Hand?

FFB Needs Feedback from Axis Position so Pots deeded to be attached (I used Hall sensor and glued the Magnets to the Axis)

The threemost dangerous threads to Programmers:

  • Fresh air
  • Bright sun light
  • The horrifying screams of singingbirds

Link to comment
Share on other sites

Oh, I didn't really mean arduino specifically. Any micro controller, doesn't matter to me. What I can do is immediately design and prototype a mechanical gimbal for it, including all electrical hardware too. Powerful servos are expensive so that's out. But making my own is easy. So can FFB work with a stepper? I can implement axis position with a pot, no problem. Or does it need to be dc motor + H-bridge + potentiometer? We can do it with the weakest/cheapest components off ebay first. If proof of concept works, we scale it up. I have a bunch of these H-bridge arduino 2A dc motor drivers:

 

http://www.ebay.com/itm/New-L298N-DC-Stepper-Motor-Driver-Module-Dual-H-Bridge-Control-Board-for-Arduino-/191674305541?hash=item2ca0adcc05:g:WFsAAOxyni9S~v5g

Up to these 30A full bridge ones:

http://www.ebay.com/itm/221994167638?_trksid=p2057872.m2749.l2649&ssPageName=STRK%3AMEBIDX%3AIT

 

Bunch of small dc motors on hand, but I'll order some stronger ones. I'm building my own servos anyway. It just can't be with a worm gearbox because it only works one way. Motor can turn the shaft, but shaft cant turn the motor. So watch out for "powerful dc motor" listings on ebay, most of them are with worm gearboxes. Regular spur gear reduction might be ok, but if ratio is too high / has too many gears it will make the shaft hard to turn or not smooth.

 

What about a motor like this for testing:

http://www.ebay.com/itm/31ZY-DC-12V-6500rpm-Magnetic-Tubular-Motor-High-Torque-Brushed-Motor/172311967490?_trksid=p2047675.c100005.m1851&_trkparms=aid%3D222007%26algo%3DSIC.MBE%26ao%3D1%26asc%3D20131003132420%26meid%3D250d69b143a344e0be791bb3317af347%26pid%3D100005%26rk%3D2%26rkt%3D6%26sd%3D322099951495

12V, 1.6A, 1000gcm stalling torque. On a 10:1 belt drive it would make it 10kgcm. Typical jostick shaft is 15cm so that would give us 600 grams of force at the grip. Enough for testing, and cheap.

 

If a stepper motor + driver + custom potentiometer/hall sensor position control can work, those are 12.6kgcm stalling torque on the shaft, for 25$.


Edited by hegykc
Link to comment
Share on other sites

A stepper should work but I would think a DC motor would be easier to get going as you only have to manage the PWM with a set voltage.

 

If I was playing around with it I might not even worry about positioning in the first instance and just use something else like another joystick as I believe the games still send the FFB to the FFB controller. Only saying this as if it was me I would go for hall sensors and put off the positing part until I knew have the mechanics were worked out. So I would probably do some initial testing by holding the real stick in one hand while mimicking the same movements on the FFB stick while feeling the forces.

 

I guess you only really need to see the motors turning to know its working lol. Nothing like feeling it though :)

Link to comment
Share on other sites

If I was playing around with it I might not even worry about positioning in the first instance and just use something else like another joystick as I believe the games still send the FFB to the FFB controller.

 

They have changed it in DCS World. It used to be like that but now the latest versions require that at least one axis is bound to a FFB device in DCS. When you have one axis bound to an FFB device then DCS sends FFB data to all controllers. So if the other joystick is FFB stick then it should work fine. Or if no FFB stick available bind one axis to FFB steering wheel for example.

Link to comment
Share on other sites

Hi

For using Steppers:

If we use a Stepper driver between Controller and Dual H-Bridge it is almost the same as a DC Motor.

Two Wires for direction (one is not really used but kept for compatibility) and the PWM is giving the steps (but Needs to made slower).

So it will be only one Number to Change in the software.

For the Positioning:

It needs to be on the Initial test. Some Forces are responding to Stick Position.

Maybe it would be good for all to get a look at the PID Document for understanding how the Transfers are done by USB. I am more than happy to help in understanding as it took me weeks to understand it myself :-)

In short:

All Force functions are send to the Device and only activated when needed.

It is possible to slave Functions to Joystick Buttons (gun trigger + Square wave function)

The spring effect is directly corresponding to the Position of the stick. As it increases by the distance to the defined Center (not necessary natural Center)

Friction and Damper functions respond to the change in Stick Position. (Speed of stick Position Change)

For the test Setup:

I think for the very first tests it will be enough to use a Hand full of LED and 2 10k pots.

A used this to determine the directions that the Motor will turn (2x2LED) and how strong they are turning (2LED Dimmed by PWM) and of course the pots to simulate stick movement.

But if hegykc can bring up some better test rig it would be great.

For the code:

I have found my "old test source" it is not finished and it has only some of the Functions added. But it is a start. Now I need to know how to upload it here. (Never done uploading code. is it the same as with Pictures?)

greatings

MetalGear_Honk

The threemost dangerous threads to Programmers:

  • Fresh air
  • Bright sun light
  • The horrifying screams of singingbirds

Link to comment
Share on other sites

Hello. Very interesting discussion.

 

I was thinking also about something similar but because I don't have resources to build one from scratch I was thinking to steampunk my G940 when I will replace it with a Warthog.

 

What I was thinking was to replace the gimbals mechanism from that classic cardanic cross like to a (stabilized) ball joint and instead of motors and gears to use simple electromagnets driven (amplified if necessary) by same logic board.

 

Also... how about we drop FFB (ForceFeedBack) from name and call it something like Bidirectional Active Controller. So no one would think at rumble anymore.

[sIGPIC][/sIGPIC]

I5 4670k, 32GB, GTX 1070, Thrustmaster TFRP, G940 Throttle extremely modded with Bodnar 0836X and Bu0836A,

Warthog Joystick with F-18 grip, Oculus Rift S - Almost all is made from gifts from friends, the most expensive parts at least

Link to comment
Share on other sites

We can go with a real gimbal testing rig right away.I don't have time at the moment to read up on ffb documentation, but there isn't really a need to anyway. You just supply me with the electronic hardware info like what we need:

 

So, a DC motor + H-bridge driver + potentiometer right? After I design the testing gimbal I can provide you with the info you need, like the motor gear ratio/turns/range of movement or potentiometer range used etc. I'm dealing with arduino based motor control right now so I have a moderate understanding of it. I see you mentioned on the page before you use "atmega32u4", Is that for actual motor control or something else? What chip would be used with this test?

Link to comment
Share on other sites

Ah great.

Ok the ATMEGA32u4 is the Microcontroller used in the Arduino Micro.

So that is where all code goes.

I ordered some Pro Micro boards for testing. Hopefully those can be programmed using "FLIP" (Atmel Software). That way we can hook up the board with your H-Bridge board (add in an External Power source) and we are ready to go.

I do not know what Controller you have at Hand. I think a Teensy or better an Arduino pro micro would be good.

I will look up some Info’s how to Program These.

Then I can give you the wiring for the rig. Assuming you will use the Motor and L298 Board you named bevor.

And I still do not know how to upload the Software.

The threemost dangerous threads to Programmers:

  • Fresh air
  • Bright sun light
  • The horrifying screams of singingbirds

Link to comment
Share on other sites

I have every type of arduino on hand: pro, mini, micro, mega, uno, due you name it. Also a teensy 2.0++ and can order 2.0 or 3.1, what ever works. But that doesn't mean we need to go that route. What ever works for you to program it. If I don't have it, I'll order it.

 

For me to start on the testing rig mechanics, all I needed was type of motor, type of driver and type of position control. For the position control I have potentiometers but I'm making my own hall effect sensors with custom made smd pcb's and custom housings. I have a bunch of those L298 drivers on hand, but you can search for "arduino motor control" on ebay and pick any driver board you want/need and I'll order it:

 

http://www.ebay.com/sch/i.html?_from=R40&_trksid=p2050601.m570.l1313.TR0.TRC0.H0.Xarduino+dc+motor+module.TRS0&_nkw=arduino+dc+motor+module&_sacat=0

 

The same for controllers, and it doesn't even need to be arduino compatible.

 

EDIT: what about just a high torque RC servo? Those are 15kgcm so 10x more powerfull than all we listed above and ready-to-go all-in-one package for 5$??

 

I have these on hand:

http://www.ebay.com/itm/MG996R-Metal-Torque-Gear-Digital-Servo-For-Futaba-RC-Truck-Car-Boat-Helicopter-/311619663165?hash=item488dfab53d:g:FeYAAOSwqfNXlbXV


Edited by hegykc
Link to comment
Share on other sites

I started working on a DIY FFB stick a couple years ago, but it was a slow burner project. Earlier this year I turned up the heat on it, diving deeper into the gimbal design, and motor/drive choice (more on that below). But I had to jump back into the software and electronics because yes, that is the biggest task. Anyone that tells you, however, that any part of a _good_ FFB stick is simple hasn't spent enough time understanding them yet. This isn't a trivial DIY project. It is my hope that my efforts can help other DIY'ers wanting to make a FFB stick. So maybe it's time I started collaborating with others. I'm an EE (I design digital and analog circuitry for embedded products), I write software, and I have a well setup CNC machine shop. But I can't do it all at once, and I really want to get a working prototype ASAP.

 

I have investigated much into the USB PID spec and software and yes, it is a mess. Much of the spec is incomplete or incorrect. The 3DPvert project from the Descent forums (by Grendlel) and Adapt-FFB-Joy projects inspired me years ago as I am a long time Descent fan. I used these projects to get my old Microsoft 3DPro and Microsoft FFB Pro sticks working. The patent issues may be a problem as well, but I have no knowledge of what is patented or how. I fear, though, that Immersion's patents are the reason we don't have any commercially viable FFB sticks on the market, and won't for a long time.

 

Even if the commercial market was willing to make FFB sticks (and there are many reasons beyond patents why they would not), what we get would likely be sub-standard, and weak in some way or the other. By weak, I mean, poor feedback feel (like most FFB sticks that were made), weak plastic parts needed for mass production, and poor long term reliability. I don't blame the FFB stick makers for this. A FFB stick is nothing but compromises. I'm still amazed that the MS FFB2 was only a $200 product, yet it is probably the best overall FFB stick made (best feel, best reliability), and amazingly all using plastic parts and no roller bearings. Even the G940 uses metal roller bearings in it's plastic parts. But the MS FFB2 isn't perfect. To make it better would have been prohibitively expensive for a consumer product.

 

So for my own project, I started designing CNC machined aluminum gimbals with roller bearings. Because the motors can't be mounted to the gimbal axis directly, they must be mounted stationary, and transfer their torque into a gimbal that rotates in two directions without moving the motors. It's a trivial concept, but it's not like a normal joystick gimbal. Requires a lot more bearings and parts. This is just the prototype. It has to allow me to try different motor/gearing vs. stick weight setups (short stick, stick extension, heavy stick vs. light stick) so the first iteration will be over designed on purpose. The stick movement system (motors, gearing, and the PID loops to make it work without oscillating itself to pieces) is a big tuning project, and the tuning changes with every change to the stick (stick length, motor torque, weight of the stick).

 

It is possible to come up with a specific formula for tuning that other DIY'ers could follow, but as people will want to customize the sticks for their simpits, making something that simplifies this process for people that don't understand PID loops is important. To be clear, this is a bigger deal for a FFB stick than it is for a FFB wheel. But I have to admit, I"m not speaking from experience with a FFB device. My experience is from tuning CNC machine PID feedback loops. More complicated than needed for a FFB stick but it taught me the reason why mass, speed, and motor drive strength matter - and probably why a couple of you commented on the difficulties of getting accurate movement in a FFB device. It is interesting that the plastic FFB sticks gain an advantage here. Plastic means less mass, weaker motors, and easier to tune. There is a reason why it takes two MS FFB2 mechanisms to drive a metal Thrustmaster Cougar or Warthog stick handle. Everything gets exponentially bigger with weight (bigger motors, gearing, gimbals, etc.).

 

Regarding motors, and direct drive vs. geared

 

Stepper motors - no. You need motors that spin freely, and stepper motors do not. Also steppers are "start/stop/start/stop" in their motion (hence the name stepper motor) and very noisy. A stepper would not provide a good FFB experience. It would be funny to see, though. If you've seen any videos of a CNC machine using stepper motors, you know what I mean. :-)

 

DC brushed motors are the cheapest choice, and this is what all consumer FFB sticks have used as far as I know. But I think some of the newer consumer FFB wheels are using 3 phase AC servo motors. There is a difference in cost and quality. DC brushed motors will give a notchy feel in the movement as you pass the brushes over the gaps in the main shaft. DC Brushless, or AC Servo motors will not be notchy, but they are more expensive - possibly a LOT more expensive.

 

For a quality FFB stick, I was planning to start with DC brushless. Honestly, though, because of the need to pick a proper motor for the application, I might have to just spec a motor and buy it from a vendor instead of trying to find any old motor on eBay. For DIY'ers, this may become a problem as motor, gearing, and torque are critical factors to figure out. You can easily waste a lot of money and time buying motors only to find out they don't offer a good feel or enough torque.

 

It's not just a matter of if the motor is strong enough for the FFB effect. It's whether the motor is strong enough to drive a stick (of given length and weight) accurately without saturating. If the motor saturates (what happens when the motor is too weak), then it is more like a light switch banging from 0 to full torque as the output driver constantly bangs off the maximum output voltage trying to drive the motor. Again poor FFB feel, and a critical part of the PID tuning process. You can always just get an oversized motor, but trust me, one of the biggest compromises in a FFB stick is finding the smallest motor that will fit in the case and still provide good FFB feel. For simpit builders with floor mounted sticks, this doesn't matter. For someone trying to make something smallish in size for on a desktop, or a pedestal in front of an office chair, it does.

 

As for attachment to the gimbal shafts, direct drive it out. Well, maybe if I used a nice AC servo motor, but those would be prohibitively expensive, and probably too large for a small desktop FFB joystick. Again, it might be OK for simpit builders. So the method of attachment is gears, or belts. Belts will wear out over time, but provide the smoothest operation. Belts and their gears should be commonly available off the shelf parts. Gears are the common choice for FFB sticks, but they are always plastic. That is actually probably better than using metal gears. Metal will have more stringent lubrication requirements (you'll have to re-grease them regularly or you'll get rapid metal grinding and wear). Plastic is more forgiving here. Getting rid of backlash so there is no mechanical dead zone is the reason why all this matters. That, and being able to buy such parts off the shelf because I don't want to waste my time custom machining such parts - especially the gears. Gear design and machining them is not trivial - not if you don't want any backlash. I might look into 3D printed parts, but this isn't something you can do on a common hobby 3D printer. The tolerance and strength isn't there. Hence 3D Printed means expensive.

 

Another option is wire driven (like a gear, but you use piano wire wrapped around a shaft to spin the gear or motor). I don't like this idea, because I assume the wire will also wear out and break. So I would rather people have to replace a belt than have to replace a wire. But there are a few examples of DIY FFB controllers using wire drive.

 

It might be possible to get creative with new concepts like linear magnetic drives. But this is probably highly custom and will take up more space than it is worth. I haven't looked deep into this yet.

 

Software

If there is a possibility to collaborate on an open source joystick FFB software project, than that would help give me more time to work on the mechanical stuff, and the electronics. Yes, there may be off the shelf electronics to make this work, but my plans go way beyond what any off the shelf stuff can offer. That's a topic for another day.

 

The software has 3 components to it. 1) USB PID, 2) the actual FFB drive software on the stick which requires implementing the USB PID stuff as well as PID feedback looks for the FFB movement. Don't confuse USB PID (Physical Interface Device) with PID feedback loops which is about the equations used to tune an electro/mechanical moving device. 3) Software to allow DIY'ers to actually use all this stuff to build and tune their own DIY projects with any competence. I've left out some details, but my point is, it's not good enough to just make some source code. It needs to be refined enough to make it easier for DIY'ers to create their own custom variations of a stick. I.e. help with PID feedback tuning and adjusting parameters.

 

All my comments above are assuming the use of the USB PID spec, which is the FFB that all our flight sims follow (DirectX to USB PID). Of course with custom software written directly for DCS, for example, the FFB can be made immensely better. But that's a project for another day and has to be done for each flight sim - a support nightmare.

 

Maybe there is a chance for the Internet community to re-define FFB on the PC to provide something better than USB PID and do it in a way that the sim developers will jump on board. But if anyone is going to do that, it needs to be a dedicated team willing to make it work long term, providing SDK's to the sim developers, support, and hand holding (and maybe dealing with possible legal and patent issues). In other words, a well organized effort. Otherwise we would just be wasting the time of the sim developers. I'd like to see it happen (and would pledge my support to help), because the USB PID stuff is somewhat disappointing. But for now, I'm grinding my teeth on just getting a prototype working any way I can.

 

 

So what is my point with all this

 

For those that have read this far, my goals are to make a FFB stick for my own purposes, but if I'm going to do it for myself, I should help enable others to do it as well. That might mean working on open source software, but will also mean making parts (mechanical and electronics) which others can use to build their own custom FFB sticks. Unfortunately, none of this helps the average sim pilot that just wants a FFB stick and wants to go fly. But doing a complete FFB joystick product is a major business venture, and not likely a very profitable one. If it were, the major companies would still be doing it.

 

So let's see where this goes.

  • Like 1
Link to comment
Share on other sites

I like where this is going. (And excellent post Drakoz!)

 

For best results use "zero cogging" DC motors. A reasonable gear ratio is needed to counter joystick lever forces (human input) while not drawing excessive stall currents on the motor and driver circuit. And as you've noted MetalGear_Honk and Drakoz, a good PID is essential for an Arduino to control the motors. I've got the hardware sorted but not the software driver.


Edited by BrassEm
Speeling
Link to comment
Share on other sites

I think the choice of gearing and motor is not crucial at this stage. But it will be important to specify what is the required min. RPM output of a motor+gear combo to give sufficient speed for the force load effects.

Also the gearing has to be backslash free.

[sIGPIC][/sIGPIC]



KG13 Control Grip Building

Control Stick and Rudder Design



 

i7 8700K, Asus Z370-E, 1080 Ti, 32Gb RAM, EVO960 500Gb, Oculus CV1

Link to comment
Share on other sites

I would be interested in ffb that is dcs or fsx/prepar3d specific, and non DIY. Especially if that greatly simplifies the test. For a DIY solution most of the work would go to into designing restrictions and making manuals and tutorials.

 

For starters, let's just try to make a dcs specific ffb that "works". Doesn't matter if it's 10x too weak, not smooth enough or wires brake. Just a proof of concept to build up on.


Edited by hegykc
Link to comment
Share on other sites

Best way to get started on software testing with a real stick is to use an existing FFB stick.

 

I grabbed an old Logitech stick for parts for exactly this purpose (a Logitech Wingman Force). It has a decent gimbal, large DC brushed motors, and an analog drive circuit to drive the motors. So I believe all I need is a DAC out and maybe an opamp to adjust the voltage range to match the existing analog circuit. And because the analog motor driver circuit is separate from the CPU board, it is possible to just remove the existing CPU Board and tap into the motor driver cable directly.

 

I'll report what I find when I get a chance to figure it out. Then I can use this to start figuring out software.

Link to comment
Share on other sites

Yeah I can't help with software/firmware/coding. I am a mechanical engineer and expert cad designer. I design and build my own automated CAM machinery (for cheap, low end, low volume applications just like this), which is where I get my limited arduino motor/motion control knowledge.

 

But you guys just tell me what motor, what driver board, and what controller board you use, and I'll design and build both the gimbal/joystick base now, and the equipment to manufacture the gimbal/joystick base later.

Link to comment
Share on other sites

Hi all

Good to see that more People are willing to help.

Some thoughts on Motors:

Steps from Steppers can be minimized with Stepper Drivers. For example if we take a Stepper with 200 Steps / turn. That will make a 1, 8 Degree step on full step mode. 0.9 On Half step (that is possible without Driver).

Now modern Driver can do 1/64 or 1/128 that would make 0.028 / 0.014 Degree. I think that would be acceptable.

For brushed Motors (and all Motors in General) using some gear Ratio (Belt /gear) that would decrease the gap feel.

I have not tested it so someone might have some more Info’s for us.

Now to get a FFB Stick we really need to stay with the USB Standard that is the most common used for FFB and the only one that is supported by all Sims I am Aware of.

Making a Special Version for DCS (Export.lua data Transfer) would take almost as much time as the PID-USB Version. And it will only be good for DCS.

@Hegyhc:

I will try and use the L298 with a brushless DC Motor

For the Controller I will Experiment with the pro Micro

The threemost dangerous threads to Programmers:

  • Fresh air
  • Bright sun light
  • The horrifying screams of singingbirds

Link to comment
Share on other sites

Forget stepper motors for FFB applications. They depend on cogging which is not what you want where you want smooth input command feel for a joystick interface. They have low torque, and because of that loose command steps if stalled.

 

DC brushed motors cog as well. This is not what you want for a joystick interface where you want smooth input command feel. But this will do for basic principle testing.

 

Toothed belts are not good as they can cog as well. V belts slip under torque. Good quality gears is best.

 

(Even MSFFB2 cogs!)

Link to comment
Share on other sites

Alright so brushless DC motor it is. I can test laser cut gears, 3d printed gears (not the hobby FDM printers but industrial quality), V-belts, tooth belts... you name it, I can make it and test it.

 

For torque, let's say a desktop joystick shaft is 15cm in length. And let's say we want close to 1kg torque at the top. That would require a 15kg/cm torque motor. (or weaker with gear reduction)

 

What about rc hight torque digital servos? Those are exactly 15kg/cm, 0.14 second 60 degree rotation, metal gears and cost 5$ and eliminate the need for a driver board?

http://www.electronicoscaldas.com/datasheet/MG996R_Tower-Pro.pdf

Link to comment
Share on other sites

Forget stepper motors for FFB applications. They depend on cogging which is not what you want where you want smooth input command feel for a joystick interface. They have low torque, and because of that loose command steps if stalled.

 

DC brushed motors cog as well. This is not what you want for a joystick interface where you want smooth input command feel. But this will do for basic principle testing.

 

Toothed belts are not good as they can cog as well. V belts slip under torque. Good quality gears is best.

 

(Even MSFFB2 cogs!)

 

True steppers are a nonstarter, but gears are pretty bad for this as well, you can really feel the teeth meshing and ratcheting and backlash is the enemy.

 

Toothed belts are sometimes used for this, at least power transmission on actuators on high end motion platforms, though they are special 'Citroen' drive type, where the teeth are arranged in a 'v' pattern.

 

Best in a case like this is to use 'shaft winding'. It works like pulleys but with tensioned steel cable, where the drive end has a cross-hole drilled in the shaft and 2-3 wraps winding around it before going to the reduction pulley/bellcrank, which is is also fixed to.

 

This is one of the only ways to provide smooth power transmission on a limited space budget. High level sims use this technique if pinched for space, or more commonly they use direct drive 3ph ac servomechanisms hooked to pushrods like real controls etc.

 

I work for a company that makes top level motion platforms and control loading hardware. I come from a background in DIY tough, so long before that I used to pick Roland Van Roy's brain a lot and collaborated with him on a loading scheme he tested functional. Here's an electromechanical circuit I designed for control loading called a 'dual driven pot' that is a known functional route, so I guess this is my contribution to this project for now. http://www.simprojects.nl/images/FF%20idea.JPG

 

 

The way it works:

 

1. airspeed data is extracted from sim and assigned digital value (0-255), which defines the current max potential force

2. DAC converts it to variable voltage, say 0-10vdc (arbitrary, based on drive needs)

3. generate inverse of signal

4. feed signal and its inverse into the end contacts on a pot

5. the wiper generates your left/right variable drive signal based on

a) max potential from line 1

b) displacement of stick from center

 

When centered, forces will be zero regardless of airspeed but if deflected to max, it will go up to the max value defined by current airspeed, or any value in between you stop at. This provides variable centering forces based on airspeed, which is the baseline of all control loading. From there it would be pretty easy to add offset effects like trim, but going beyond that is when things get dicey.

 

For any of the rest of the effects, you would have to have a pre-scripted library of jolts/bumps/shakes/etc, to be triggered at appropriate moments, which req you to have pretty deep access to a sim, and req that same access to ANY sim you want to use it in. Extracting airspeed is one thing, but the rest is a whole nother beast.

 

I've stayed out of this thread because it's such a can of worms, and in all honesty the hardware is the easy part once you reconcile the implications of the line above. This is a tough wheel to reinvent, so in all honesty the best DIY FF you are going to come up with is tapping the drive signals on MS FFII and redirecting them to bigger motors/hardware.

 

Even Roland Van Roy settled on this method, despite having fully functional DIY FF stuff long MS stopped making that stick as well as a great library of effects and a sim that makes it easy to extract parameters from (FSX).

 

Anyone seriously considering taking this on would be well served by bookmarking and studying Roland's site thoroughly, he is very knowledgeable on this subject and has a lot of years of practical experience reinventing this wheel. http://www.simprojects.nl/index.htm

 

 

edit: Drakoz: don't rule out shaft winding, your assessment is in error about it wearing out and such unless you under engineer it. For instance, 1/8" aircraft cable is rated at 1000lbs... the toy-like forces of a DIY control loading mechanism will never approach this and tensioning is the only tricky part, but the more room you have the easier it is because turnbuckles can be used. Another option besides cable is Spectra/Kevlar type rigging rope... it's significantly stronger than steel cable and has 1/25 the amount of stretch/creep and is much easier on the fingers to work with..


Edited by Thadiun Okona
Link to comment
Share on other sites

  • Recently Browsing   0 members

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