Monday, October 31, 2016

Arduino with FSX (Part 5)

An 8-Axis 256-Button Arduino Joystick— 

The Arduino has been successfully programmed to act as a 128 or 256 button HID-USB device that can communicate through USB with a PC. Unfortunately, FSX has the limitation of 32 buttons/switches per USB device. However, if the 128/256 buttons can be partitioned as multiple joystick data streams, then the one Arduino can appear to be multiple 32 button joysticks to FSX. A different USB driver must be used on the PC that divides the Arduino data string into data strings from multiple joysticks, each with a different ID, and sends those data strings to FSX. FSX acts on the data as coming from individual joysticks. A 256-button joystick  programmed as dual 128-button joysticks is described later. Thirty-two buttons from each joystick can be used by FSX. Extra buttons beyond 32 are just ignored.

The original 40-button Arduino joystick was modified to 256-Buttons by Eagle forum member "overpro"  (ref: forums.eagle.ru/showthread.php?p=2522938). "overpro" developed Arduino hardware based on a pin matrix (16 x 16 = 256 pins) to provide the pins necessary to handle 256 buttons/switches. He also includes some dedicated pins for rotary encoder inputs. In post #150, "overpro" provides an Arduino sketch "CVP_JoystickController.ino" which creates the 256 button data stream sent over HID-USB to a PC. The associated "CVP_Joystick_1HID256Btns.hex" file is used to flash the HID-USB (see post #142 of the above forum). Also in the forum comments are references to Pointy's Joystick Test and Peter Dowson's HID device scanner (HID Scanner.exe). This forum has a wealth of information about the development of a large joystick but the forum discussion is lengthy, making it sometimes difficult to understand the best path forward.

In another forum thread (ref: forums.eagle.ru/showthread.php?t=117011, post #1), member "overpro" provides a fairly comprehensive explanation of a "composite" USB device that creates two joysticks from one Arduino HID-USB device.

I followed the above procedures using a Mega 2560 but without the 16x16 pin matrix. Both Pointy's Joystick Test and Peter Dowson's HID Scanner revealed the two 128 pin joysticks, and it was confirmed (by shorting pins to ground) that only the first 32 pins from either joystick were sensed by FSX. However, FSX did sense the two as separate joysticks, and each could have their pins assigned to different FSUIPC functions. Using "overpro's" code does provide a means of adding two 32-pin joysticks to FSX. One of the joysticks also handles the 8-axes which can be connected to potentiometers for control surfaces.

Sorting through all of the above details took several days of reading, prototyping, and testing.

Refinements I want to investigate to what has been developed by "overpro", "riclamer", and "Darran", include integration of rotary encoders as input devices, and port expanders for adding additional pins without using the pin matrix approach. I have no opinion whether port expanders are any better or worse than pin matrices, I just want to learn about port expanders and to integrate them into the discussion.

For FSX, it seems that the easiest approach using Arduino Joysticks is using 32 digital pins of a Mega 2560 for buttons/switches and 8 analog pins for control axes. Rotary encoders each require 2 digital pins, so 32 pins translates to a maximum of 16 encoders per Arduino joystick. Encoders are easily handled by MobiFlight, so maybe that is a better solution. The topic of LED displays used to show the state of a switch is discussed in various forums. I have read that USB can handle two-way traffic, but I have yet to read how LED's can be controlled on the Arduino by FSX. MobiFlight handles both LED and digital displays, which makes that even more attractive from that perspective. Future blogs in this series will investigate rotary encoders and port expanders in more detail. If anyone has examples of how to control LED's over HID-USB, please let me know. Thanks.

Useful references -




(Oct 31, 2016)

Wednesday, October 26, 2016

Arduino with FSX (Part 4)

Rudder Pedals and Brakes — 


Early in the FSX Flight Training, one exercise uses rudder steering and brakes to taxi around an airport. That requirement was the only motivation required to build a set of rudder pedals with toe brakes for use with FSX. To be honest, rudder and brakes have been rarely used in the VFR flight training course, but I have an interest in flying older military aircraft that do not have auto-pilot, auto-rudder, and many modern conveniences. It has taken a bit of work to make the rudders and brakes function as desired, mainly because I want pedals that have some resistance to being applied, that they re-center as pressure is reduced, and that the distance and angle of my feet and legs provide good ability to apply the rudders and brakes in a comfortable manner.

The prototype pedals followed the design of Bruce May (How To Build Rudder Pedals, 2006). After using those pedals a short while, I was unhappy with the lack of smoothness of the pedals sliding when pressure was applied by my feet. The pedals worked smoothly when moved by hand, but the pressure of my feet and legs made the prototype fail to work satisfactorily. On the other hand, the rubber balls under the toe brakes provided excellent press tension and return  when pressure was released.


I chose to use potentiometers as the rotational sensor devices. A modified version of the Arduino Uno 8-axis, 40-button Joystick discussed in Part 3 of this blog series was used as the sensor controller. Only 3 axes (rudder, left brake, right brake) were attached to pins A0, A1, and A2. The potentiometers were connected between +5V and ground with the wiper being connected to an analog pin. To reduce noise, all other axes were connected to ground. No digital pins were connected as buttons.

In FSUIPC, the 3 axes were calibrated and worked fairly well. The largest issues I experienced were discussed above--pedals not operating smoothly.

In the second iteration, rotary encoders were used in place of the potentiometers. That test failed to be satisfactory, since the hardware linkage connecting to the encoders did not make them rotate through sufficient detents (clicks) to register a satisfactory signal. While a 90 degree turn of a potentiometer makes a big change in its resistance value, the same 90 degree turn of a rotary encoder is just 5 clicks which was not sufficient to provide an adequate signal. To use rotary encoders would require re-design of the sensor linkage, such as, using a track and gear. I found gears that fit 6mm rotary encoder shafts fairly easily at a reasonable cost on eBay, and the matching track was not too expensive, but the shipping was like $50 for 12 lbs of track. I just need about 2 feet of track, not 12 lbs. I might have to try to fabricate some track.

I reviewed the design of rudder pedals in FlightSim Rudder Pedals. That design used small plastic rollers to provide smooth pedal movements. In addition, springs were used to provide tension and centering. Those seemed like really needed improvements.

I also reviewed the design of FlightSim "RogerioS" DIY Rudder pedals and toe brakes. That design included drawer slides to provide smooth pedal action. The slides look pretty heavy duty, but I suspect they provide good rolling action to handle the strong pressure from legs and feet.

Another concern I have with my prototype is that as the aluminum bar rotates due to leg/foot pressure, the whole bar is also under pressure to the rear from both legs pushing towards the rear, with some relief when pressure is reduced by one or both legs. The rotational axis of that bar must be under quite a bit of pressure where the center axis bolt is located.

I have also been reducing friction between various connections that rub as the pedals are moved, such as, the pins that move the potentiometers. Milled edges in aluminum tend to be rough and need to be polished to reduce friction. Aluminum against aluminum caused much friction, steel against aluminum reduced that friction, and the next improvement will test steel against steel which I believe will reduce friction even further. This may not be a revelation to people with metal working experience.

The third iteration re-installed the potentiometers, improved the strength of the overall hardware and their fittings, added some small plastic rollers to improve movement of the pedals under pressure, and added screen door springs to: 1) add tension against leg/foot pressure for a more realistic feel; and, 2) to help re-center the pedals to their neutral position as leg/foot pressure is reduced. Lastly, I added an upright shield that provides a foot rest for moving the pedals. The foot has to be rotated over that rest to apply the toe brakes but the motion feels satisfactory. These changes made big improvements in my satisfaction with the pedals and brakes. The pedal-brake may be re-designed in a future iteration.

Arduino 3-Axis Sketch for Pedals and Rudder --

"riclamer" modified Darran's Arduino Joystick code to output axis (A0-A5) and pin (D2-D13) data that are sensed by an Arduino Uno. Some users had problems with the code which turned out to be an array not being defined properly. That bug is fixed in the code below. While testing the code, I realized that the axis values (potentiometer readings) were extremely variable due to noise from the inexpensive devices. I have added some code to average 5 readings of each analog pin (potentiometer wiper) and use the average as the reading. I also compare the current reading to the past reading to determine if there is a change greater than 100. If so, the value gets used. Otherwise the value is ignored. If any one of the analog values (analog A0, A1, A2) varies by more than 100 from its previous value (or any D pin changes value), then the joyReport gets transmitted to FSX with the updated values. Using averaged values seems to have reduced the sending of widely fluctuating values to FSX while not causing delays to the controls. Ground any unused analog pin to minimize noise on the axes. The digital pins do not need to be grounded if they are not connected, since they are set to INPUT_PULLUP.


/*
   riclamer_big_joystik_mod

   Lowell Bahner
   October, 2016

   This sketch includes a fix for array dimension btn[] from 12 to 13.
   Riclamer's code is limited to use only 12 pins on the Uno (pins D2-D13)
   even though joyReport is dimensioned for 40 pins.
   Riclamer added an offset of 16 in the original code, which moves the
   pin number up by 16 in the total of 32 pins used by FSX. Offset has been
   reset to 0, since the Arduino Joystick is a separate device to FSX
   which provides an additional 32 pins (only 12 used in this sketch).

   The axis values were quite variable due to noisy signals of potentiometers.
   The axis values are now read 5 times and averaged to reduce variability
   of the pot values due to noise.
   A change of > 100 is also required from the previous value
   before a new value is transmitted.

   Both of these changes can be adjusted by the user.

   Only 3 Axes are programmed in for use with rudder pedals (1) and brakes (2).
   Digital pins are not used by the foot pedals.

   joyReport is only transmitted to FSX when there is a change of an axis or pin

*/


/* Arduino USB Joystick HID demo */

/* Author: Darran Hunt
   Released into the public domain.
   Update by RICLAMER in 25/03/2014 to use Analog ports and digital ports
   This code is to be used with Arduino UNO (6 axis and 12 Buttons)
   This code is compatible with Arduino Mega.
*/

/* INSTALLATION
  Just install POT to each analog port. Using the _Grnd _Analog _5V Arduino.
  Like this image: http://arduino.cc/en/uploads/Tutorial/joy_sch_480.jpg
  To setup the buttons, just install your prefered button switch between GND and Port Digital 02~13.
  Use Flip to erease and burn this firmware DFU: https://github.com/harlequin-tech/arduino-usb/blob/master/firmwares/Arduino-big-joystick.hex
  I used Arduino R3 with Atmega 16U2.
*/

// to turn on DEBUG, define DEBUG. Make sure to undef DEBUG for joystick use
//#undef DEBUG
#define DEBUG

#define NUM_BUTTONS 40     // you don't need to change this value
#define NUM_AXES 8        // 6 axes to UNO, and 8 to MEGA. If you are using UNO, don't need to change this value.

typedef struct joyReport_t {
  int16_t axis[NUM_AXES];
  uint8_t button[(NUM_BUTTONS + 7) / 8]; // 8 buttons per byte
} joyReport_t;

joyReport_t joyReport;
joyReport_t prevjoyReport;
uint8_t sendFlag;

uint8_t btn[13]; // fix riclamer's [12] dimension to [13]
// the array counts from 0 for 13 values, [0,1,2,...12]. 12 pins (D2-D13) are counted as 1,2,3...12.
int fulloff = 0;
uint8_t offset = 0;

void setup(void);
void loop(void);
void setButton(joyReport_t *joy, uint8_t button);
void clearButton(joyReport_t *joy, uint8_t button);
void sendJoyReport(joyReport_t *report);


void setup()
{
  //set pin to input Button
  for ( int portId = 02; portId < 13; portId ++ )
  {
    pinMode( portId, INPUT_PULLUP);
  }
  Serial.begin(115200);
  delay(200);
  sendFlag = 0; // clear one shot sendFlag

  for (uint8_t ind = 0; ind < 8; ind++) {
    joyReport.axis[ind] = ind * 1000;
  }
  for (uint8_t ind = 0; ind < sizeof(joyReport.button); ind++) {
    joyReport.button[ind] = 0;
  }
}

// Send an HID report to the USB interface
void sendJoyReport(struct joyReport_t *report)
{
#ifndef DEBUG
  //Serial.write((uint8_t *)report, sizeof(joyReport_t));
  // do not send duplicate values
  //
  if (memcmp( report, &prevjoyReport, sizeof( joyReport_t ) ) != 0)
  {
    Serial.write((uint8_t *)report, sizeof(joyReport_t));
    memcpy ( &prevjoyReport, report, sizeof( joyReport_t ) );
    sendFlag = 1; // set sendFlag=1 report was different
  } else {
    sendFlag = 0; // report did not change
  }
  //
  // end do not send duplicate values
#else
  // dump human readable output for debugging
  for (uint8_t ind = 0; ind < NUM_AXES; ind++) {
    Serial.print("axis[");
    Serial.print(ind);
    Serial.print("]= ");
    Serial.print(report->axis[ind]);
    Serial.print(" ");
  }
  Serial.println();
  for (uint8_t ind = 0; ind < NUM_BUTTONS / 8; ind++) {
    Serial.print("button[");
    Serial.print(ind);
    Serial.print("]= ");
    Serial.print(report->button[ind], HEX);
    Serial.print(" ");
  }
  Serial.println();
#endif
}

// turn a button on
void setButton(joyReport_t *joy, uint8_t button)
{
  uint8_t index = button / 8;
  uint8_t bit = button - 8 * index;

  joy->button[index] |= 1 << bit;
}

// turn a button off
void clearButton(joyReport_t *joy, uint8_t button)
{
  uint8_t index = button / 8;
  uint8_t bit = button - 8 * index;

  joy->button[index] &= ~(1 << bit);
}

/*
   Read Digital port for Button
   Read Analog port for axis
*/
void loop()
{
  // Create Array with value of switch button
  for (int bt = 1; bt < 13; bt ++)
  {
    btn[bt] = digitalRead(bt + 1); // reads pins D2-D13
  }
  // Power ON button if it is pressed. buton 17 at 28
  for (int on = 1; on < 13; on++)
  {
    if (btn[on] == LOW)
    {
      setButton(&joyReport, on + offset - 1);
      //  Serial.println("botao ON");
      //  Serial.println(on+16);
    }
    //else {
    //  fulloff = fulloff++;
    //}   //Power off all Button, if all button are not press
    //if (fulloff == 11)
    //{
    //  for (uint8_t cont = 0; cont < 40; cont++)
    //  {
    //    clearButton(&joyReport, cont);
    //  }
    //  Serial.println("Every button is off");
    //}
  }

  uint8_t diffCopy = 0;

  /* Adjust Analog axes on A0, A1, A2*/
  /* Arduino UNO has 6 analog pins of 8 possible. Set pin to 0 if not used */
  for (uint8_t axis = 0; axis < 3; axis++) {
    int tmp = joyReport.axis[axis]; // copy previous axis value
    // Average 5 readings of port to get better values from noisy pots
    int sumAxis = 0;
    int avg = 0;
    for (int i = 0; i < 5; i++) {
      sumAxis = sumAxis + analogRead(axis);
    }
    avg = sumAxis / 5;
    joyReport.axis[axis] = map(avg, 0, 1023, -32768, 32767 );
    //joyReport.axis[axis] = map(analogRead(axis), 0, 1023, -32768, 32767 );

    // only change axis if avg reading changes by > 100
    // flag change in axis value > 100
    if (abs(joyReport.axis[axis] - tmp) > 100) diffCopy = 1;
  }
  //Set un-used analog pins to 0 to reduce spurious values in joyReport.
  //joyReport.axis[0] = 0;
  //joyReport.axis[1] = 0;
  //joyReport.axis[2] = 0;
  joyReport.axis[3] = 0;
  joyReport.axis[4] = 0;
  joyReport.axis[5] = 0;
  joyReport.axis[6] = 0;
  joyReport.axis[7] = 0;

  if (diffCopy > 0) {
    //Send Data to HID
    sendJoyReport(&joyReport);
    diffCopy = 0;
    
    // clear the digital pins from re-sending data
    for (uint8_t cont = 0; cont < 40; cont++)
    {
      clearButton(&joyReport, cont);
    }
  }

  delay(100);
  fulloff = 0;
}



Useful references -

(Oct 26, 2016)

Friday, October 21, 2016

Arduino with FSX (Part 3)

Arduino as a HID Joystick — 
To a new user this will be confusing--USB, HID, joysticks, hardware ports, and USB drivers. We all know that USB just works--you plug it in and by magic it works. Well, that is true if there is a USB driver on the PC which works with the device at the other end of the USB cable. The following discussion is about making the Arduino look like a USB device (not a vanilla Arduino serial device) and getting it to work on a USB port with a USB driver on the PC. 
A vanilla Arduino Uno or Mega uses the on-board USB chip (ATmega 16U2) for communicating through a USB cable with the Arduino IDE on a Mac/PC/Unix computer. The Arduino IDE communicates with the Arduino through Serial-USB and is used to download programs to the Arduino, and for sending and receiving data between the computer and the Arduino.
On a PC, a driver is required to connect an external USB device to a particular software. Windows uses different HID-USB drivers to connect to keyboards, mice, game controls, or joysticks  (HID, Human Input Device). FSX can accept data from a HID-USB joystick connected to a USB port using the Microsoft Game Controller driver in Windows. Some companies provide their own USB drivers to interface to their hardware, rather than relying on the MS drivers included with Windows. 
The MS Game Controller driver provided with Windows allows the PC to communicate through a USB port to external joystick hardware and obtain data from potentiometers for adjusting rotating axes (joystick up-down, left-right, back-and-forth) or from buttons and switches. In FSX, there is a limit of 32 buttons/switches per USB device. Those who are building large and complex aircraft cockpits run into this limitation of 32 buttons/switches pretty quickly. A future blog will examine alternatives so that additional buttons/switches might be accommodated.
As previously stated, the ATmega 16U2 USB chip on an Arduino Uno or Mega is normally programmed as a Serial-USB device. On the PC, a serial-USB driver is used to connect the Arduino through USB to the Arduino IDE. To use an Arduino as an FSX device, that USB chip has to be reprogrammed as a HID-USB device that can communicate through a USB port using the MS Game Controller driver. FSX can then accept data from the external Arduino hardware through USB to FSX running on the PC.
I run FSX on a dedicated PC, but I do my software development work primarily on a Mac. In my case, all of the process of writing and testing Arduino sketches, and programming the Arduino USB chip is conducted on the Mac. The Arduino (as a joystick controller) is then plugged into the PC USB for use with FSX.
Why not just use MobiFlight as the controller for joysticks that use rotational controls (potentiometers)? As of 2016, MobiFlight software did not connect to potentiometers. There have been some requests by users with the MobiFlight developer about adding that functionality. At this time, lacking MobiFlight as an option, adapting an Arduino to act as a joystick device is a workable, but somewhat tedious, solution.
The process of creating an Arduino Joystick— 
Several things are needed to implement an Arduino joystick:
  1. Arduino R3 Uno or Mega with ATmega 16U2 USB chip (not a CH340 USB chip).
  2. Arduino sketch that converts potentiometer values and button/switch signals to a defined string of data that is transmitted through USB to the PC.
  3. Software and/or hardware for reprogramming the 16U2 USB chip.
  4. The Arduino USB chip reprogrammed as a HID-USB device that can send and receive formatted data strings to/from a PC. The PC USB driver adjusts to that USB data definition and delivers the string of data to FSX.
  5. Patience to deal with technical issues.
The simplest approach for using an Arduino as a joystick, is to use one Arduino as one joystick controller, each with a unique ID. FSX can connect to each Arduino joystick as a separate device with axis controls and/or 32 buttons/switches. Each Arduino would connect through a USB cable. The 8-axes 40-button joystick described below, is such a device. Since the Uno does not have 32 digital pins, a Mega 2560 with 54 digital and 16 analog pins can to be used. For development and testing, an Uno with 14 digital and 6 analog pins can be used with the understanding that the number of functional pins will be limited. Additional pins can be added to an Arduino, either by using a matrix or port expanders. Adding port expanders will be discussed in future blogs.

The 8-Axis 40-Button Arduino Joystick— 
The original code for a 40-button Arduino joystick was published on the web by Darran (ref: http::hunt.net.nz/users/darran/weblog/15f92/Arduino_UNO_Big_Joystick_HID_firmware.html, Jan 22, 2013), however that web page was discontinued during 2016. A copy of that webpage was found at (ref: archive.is/KbXom). Darran's web page is a must read since he clearly outlined the steps for creating an Arduino HID-USB joystick with 8 axes and 40 buttons. That software will form the basis for many of the discussions in this blog series. 
Joystick Process Steps:
1) Load your sketch into Arduino using the standard USB cable and the Arduino 16U2 chip programmed as Serial-USB. (the hex files for Uno and Mega can be downloaded from https::github.com/arduino/Arduino/tree/master/hardware/arduino/avr/firmwares/atmegaxxu2/arduino-usbserial. No need to "make" any files. )
2) Put the R3 Uno or Mega into DFU mode. This simply requires momentarily shorting two pins of the USB-ICSP nearest the USB jack with a metal wire.
3) Flash (program) the Arduino USB 16U2 chip as HID-USB using Darran's "Arduino-big-joystick.hex".
4) Attach Arduino Joystick to PC USB.
Copies of Darran's sketch and USB .hex firmware are online at github.com/harlequin-tech.
-- An Example Sketch
The example sketch "big_joystick_demo.ino" provided by Darran is a bit confusing at first. To see the code work, change the "#undef DEBUG" to "#define DEBUG" so the debugging Print.serial statements will display on the Serial Monitor. That will demonstrate that the code does in fact work. The code loops to sequentially turn on and off one button after another, so you might wonder "How can I use this with FSX? Hold that thought for a while, while you perfect the other steps required for making an Arduino joystick work. Remember to "#undef DEBUG" before flashing the USB chip, since the data sent through USB can not be corrupted with the Serial.print debug data that can be viewed on Serial Monitor.
-- Put the Arduino into DFU mode and Flash the chip
The 16U2 chip is placed in dfu mode by shorting two pins of the USB-ICSP. On a PC, use "FLIP" to program the 16U2 chip. On a Mac, the dfu software needs to be downloaded and installed. Then Terminal app is used for entering the dfu commands for flashing the 16U2 chip. Flashing the 16U2 chip is an easy process once you do it a couple of times. See ref: www.instructables.com/id/DFU-programmer-on-Mac-OS-X/ for the steps for using dfu. FLIP or dfu will be used to flash the desired .hex file into the 16U2 chip.
-- Test the configuration to make sure axes and buttons are working as desired
At the hardware/firmware level you can check the USB port.


  • On a Mac, System Information:USB can be used to see what USB devices are attached. An Arduino (Serial-USB) will display as "Communication Device":Product ID: 0x0043, etc. If the Arduino has been put into dfu mode, the device will display as "Composite Device":Product ID: 0x2fef, etc. Once the HID-USB hex file is flashed, the device will display as "Arduino Joystick":   Product ID: 0x2043, etc.


  • With "Arduino Joystick" connected to PC USB port: Open "Devices", locate the MS Game Controller icon that represents the "Arduino Joystick", right click the icon and choose "Game controller settings". Choose "Arduino Joystick" from list, and click Properties. The Properties window will display with the 6 Axes (horizontal bars) and 32 buttons. The axes will move in small increments. The 32 buttons will cycle on and off.
If these tests check out, the HID-USB Arduino Joystick has been successfully installed.

Other tests that can be conducted to determine what the USB configuration looks like to the PC include:



(Oct 21, 2016)



Monday, October 17, 2016

Arduino with FSX (Part 2)

Trim and Flaps Control — 

Trim and flaps are basic to flying any aircraft. I found trying to adjust trim and flaps using the mouse or keyboard keys while flying with a stick was very difficult and unnatural. I wanted to adjust trim using trim 
wheels and the flaps to be controlled by moving a lever up and down to provide the various flap positions required for flying.


The options that I found on the internet were: 1) commercial control boxes; or, 2) various plans for DIY constructed control boxes. Since I like to build things, I chose the latter option. The next question was how would it work? 


I found that most users referenced and relied on a software product, FSUIPC, and that it was an essential software tool. 

I found another software product, MobiFlight, which used an Arduino Mega 2560 with the MobiFlight software through USB to interact with FSX via FSUIPC. This seemed like an attractive approach since it used an Arduino as the controller computer, it had a user-friendly interface, and it connected to the PC running FSX through USB.


The first road block I found was that MobiFlight did not connect to potentiometers, but did connect to rotary encoders. I had to learn about rotary encoders.


I ordered KY040 rotary encoders from eBay, and while I was waiting for them to arrive, I watched the Mobiflight you-tube training about constructing and testing hardware for FSX. That seemed like a solid approach. When the KY040 rotary encoders arrived, I successfully tested them with Mobiflight to send trim signals to FSX. Once that testing was completed, I ordered Arduino Mega 2560 boards from eBay. The first two boards I received were not Arduino boards even though the description on eBay stated they were R3 Mega 2560 boards. Instead they used CH340 USB chips and the clock ran on a 12 MHz crystal, rather than 16 MHz. It turned out that MobiFlight ran fine on these knock-off boards, but I decided to place another order for R3 Mega 2560 boards from an eBay vendor that documented their boards used the proper USB chip. The critical difference in these boards is the USB controller chip. The CH340 USB chip in the knock-off board is a dedicated serial-USB chip which works for most vanilla Arduino applications. The Arduino Mega uses the ATmega 16U2 USB chip which can be reprogrammed to be serial-USB or HID-USB. HID-USB will be discussed in later blogs about building joyStick devices.

 


The Arduino Uno and Mega 2560 use the ATmega 16U2 USB chip (left picture) which can communicate through, and be programmed through the USB-ICSP pins. A clone board that uses a CH340 Serial-USB chip (right photo, 16-pin IC) does not have the USB-ICSP pins. One other thing, while discussing eBay Arduino boards--some knock-off boards use chips that are not pre-programmed. You may have to program the USB chip or the main processor chip to make the board work as an Arduino. It can be distressing when you get your new board, plug it in, and it just does not work. It takes some time to figure out if there is a hardware or software problem. And it takes more time to fix the problem, if it can be fixed.

Working Trim-Flaps-Gear Controller Prototype --


I fly using a stick in my right hand. I wanted to control trim, flaps, gear, hook, and speed brake with my left hand, as used in some Navy aircraft. The picture shows how I assembled these functions into one box that can be mounted for left hand use. The Trim, Flaps, and Gear Control Box continues to be a work in progress, but it has become fairly mature. The Control Box, with Arduino Mega 2560 and MobiFlight, now provides:
  • Elevator Trim Wheel using KY040
  • Aileron Trim Wheel using KY040
  • Rudder Trim Wheel using KY040
  • Flaps Control using 4 position rotary switch
  • Gear Control using 2 position rotary switch
  • Speed Brake using DPDT toggle switch
  • Tail Hook using DPDT toggle switch
  • 4 LED's for flap position indicators
  • 3 LED's for gear position indicators
  • 1 LED for speed brake position indicator
  • 1 LED for tail hook position indicator
  • 8-digit readouts for elevator trim count and % elevator
  • 8-digit readouts for aileron trim count and % aileron
  • 8-digit readouts for rudder trim count and % rudder
My first build focused on the Trim wheels using rotary encoders. Flap and gear switches and LED's were then added and tested. After struggling with trim during flights, I added the out-board displays so I could better understand how trim was affecting the flight simulations. Initially I had a few problems when controls did not respond quickly while flying simulations, such as, flaps down on approach. This problem was fixed by turning off debug logging (both in FSX and MobiFlight) which interfered with control actions being taken in a timely manner.
MobiFlight uses FSUIPC offset addresses for many actions. Therefore, purchase a license for FSUIPC, so that you will have that tool available for use in all your controllers.

TODO - 

1) Figure out how to check the position of a switch and reset FSX to use that switch setting, in case the initial switch pulse was missed due to the processor being busy and missing the switch.

2) MobiFlight Control Mapping - make a table of the control, the Mobi device, the FSX control, the control mode (keypress, FSUIPC offset, FSX direct), size (byte, word, int4, int8), value (0,1, 16384, etc), transforms, pre-conditions.

(Oct 17, 2016)


    Thursday, October 13, 2016

    Arduino with FSX (Part 1)

    Short History — 

    FSX is flight simulator software that continues to have a large following of professional and non-professional pilots, and gamers who want realistic flying experiences. FS was marketed by Microsoft beginning in 1982 as Flight Simulator 1.0, and progressed through multiple revisions as FS2000, FS2002, FS2004 (aka FS9), and FSX in 2006. Microsoft closed down further work on FS in 2009. Dovetail Games obtained the rights to FS in 2014 and develop the Microsoft Flight Simulator X: Steam Edition. (ref: https://en.wikipedia.org/wiki/Microsoft_Flight_Simulator_X)


    FS has progressed from 8-bit and 16-bit DOS and Windows machines using only a mouse, keyboard, or game controller for flying the simulator missions, to 64-bit PC's with multiple flat-screen views and full-scale 737 cockpits with all the buttons, switches, and instruments.


    This blog shares my experience as a beginner FSX simulator pilot that has added hardware control devices with knobs, buttons, switches, and displays, as flight sticks, rudder pedals, trim controls, and digital readouts. 


    While several sources of hardware and software add-ons for FSX exist, there are a large number of FSX users that build their own hardware and adapt software to use their simulator cockpit hardware with FSX.


    This blog primarily centers on Microsoft FSX Gold Edition as the flight simulation software with add-ons that will be described in later parts of this series of blogs. For these blogs, my FSX runs in a Windows 8.1 Bootcamp partition on a Mac Mini (2012, 16 Gb RAM, 64-bit). Multiple USB 2.0 and 3.0 port expanders are used for connecting hardware to the PC. Two flat-screen displays are used for various FSX windows.


    Future blogs in this series will discuss the Arduino microprocessor as a USB device for adding switches, digital displays, rotary encoders, and port expanders to FSX. These switches and displays then connect through USB to the PC for sending and receiving data that ultimately controls or logs some action of the airplane during the FSX flight simulation.


    The development work discussed in this blog builds on work done by so many and shared on the web through many web sites and discussion forums. Thanks to all of you who share your ideas and software so that others can benefit.


    Arduino and FSX


    I have been tinkering with Arduino's for a few years as a hobby, and when I began using FSX Flight Simulator, I had several thoughts: 1) I can not fly FSX using a keyboard and mouse. That just did not work for me; so, 2) I purchased a Saitek X-52 flight stick which works pretty well, but the button mappings to FSX was a new area of confusion. The FSX software could be used to map the buttons and axes, and the Saitek software could also map the buttons and axes. Then there were drivers from other software companies that seemed to replace the Saitek drivers. Each one had their own interface and means of adjusting and tuning the various controls. All of this may seem pretty simple to someone who has some FSX experience, but to a new user, the goal was to learn to fly the flight school lessons successfully, and not be mired down trying to figure out how to make a button work.

    I had some military flight training many years ago, and I can remember what that felt like. One goal for this flight simulator training is to regain the fun of flying, which translates into hands-on hardware--trim wheels, flight stick, gear controls, rudder pedals, brakes, and at some point, guns, rockets, and bombs (simulated that is).

    It seemed to me that there had to be a way to use the Arduino as a controller for hands-on hardware used with FSX. It took a while to sort through all the scattered bits and pieces on the internet, but several people have succeeded. The work presented here is based on those previous works, of which I am grateful.

    Through this series of blogs, I will try to assemble those various bits and pieces of knowledge that I have gained into one source which may be of use to someone that desires to follow this path. 

    I ask that anyone that has implemented Arduino's with FSX and want to share that information, provide their comments and links.

    (Oct 13, 2016)