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)



No comments:

Post a Comment