HID Joystick - For use with X-Plane or other programs that can read HID JoySticks

Dependencies:   USBDevice mbed-rtos mbed

Fork of JoyStick by Ries Twisk

This is a simple Joystick HID that I use for xplane and a home build yoke + paddels, see this forum with the look and feel of it : http://forums.x-plane.org/index.php?showtopic=70041

The analog input are filtered with a LowPass IIR filter and the digital input's will be derived from the analog input and de-bounced.

The analog values are read at a 1Khz interval and to ensure we don't push the USB stack to much at a maximum rate of 20 updates/sec HID data is send over USB only if any values where changed. The JoyStick will send 16Bit analog values as opposite of 8 bit values that are normally used to increase accuracy of the whole system. This is well noticeable within x-plane!

The JoyStick uses the JoyStick copied from Wim Huiskamp and modified to suite my needs and the MBED RTOS libraries for reading analog inputs, sending debug data over USB and sending HID data, 3 threads in total.

Committer:
rvt
Date:
Wed Jun 22 12:50:16 2016 +0000
Revision:
5:a0bb17c379ce
Parent:
4:2cc58c173de8
Latest

Who changed what in which revision?

UserRevisionLine numberNew contents of line
rvt 0:33bc88c4ab31 1 /* USBJoystick.h */
rvt 0:33bc88c4ab31 2 /* USB device example: Joystick*/
rvt 0:33bc88c4ab31 3 /* Copyright (c) 2011 ARM Limited. All rights reserved. */
rvt 0:33bc88c4ab31 4 /* Modified Mouse code for Joystick - WH 2012 */
rvt 0:33bc88c4ab31 5
rvt 0:33bc88c4ab31 6 #ifndef USBJOYSTICK_H
rvt 0:33bc88c4ab31 7 #define USBJOYSTICK_H
rvt 0:33bc88c4ab31 8
rvt 0:33bc88c4ab31 9 #include "USBHID.h"
rvt 0:33bc88c4ab31 10
rvt 0:33bc88c4ab31 11 #define REPORT_ID_JOYSTICK 4
rvt 0:33bc88c4ab31 12
rvt 0:33bc88c4ab31 13 /* Common usage */
rvt 0:33bc88c4ab31 14 enum JOY_BUTTON {
rvt 0:33bc88c4ab31 15 JOY_B0 = 1,
rvt 0:33bc88c4ab31 16 JOY_B1 = 2,
rvt 0:33bc88c4ab31 17 JOY_B2 = 4,
rvt 0:33bc88c4ab31 18 JOY_B3 = 8,
rvt 2:ae7a31a3c618 19 JOY_B4 = 16,
rvt 0:33bc88c4ab31 20 };
rvt 0:33bc88c4ab31 21
rvt 0:33bc88c4ab31 22 /**
rvt 0:33bc88c4ab31 23 *
rvt 0:33bc88c4ab31 24 * USBJoystick example
rvt 0:33bc88c4ab31 25 * @code
rvt 0:33bc88c4ab31 26 * #include "mbed.h"
rvt 0:33bc88c4ab31 27 * #include "USBJoystick.h"
rvt 0:33bc88c4ab31 28 *
rvt 0:33bc88c4ab31 29 * USBJoystick joystick;
rvt 0:33bc88c4ab31 30 *
rvt 0:33bc88c4ab31 31 * int main(void)
rvt 0:33bc88c4ab31 32 * {
rvt 0:33bc88c4ab31 33 * while (1)
rvt 0:33bc88c4ab31 34 * {
rvt 0:33bc88c4ab31 35 * joystick.move(20, 0);
rvt 0:33bc88c4ab31 36 * wait(0.5);
rvt 0:33bc88c4ab31 37 * }
rvt 0:33bc88c4ab31 38 * }
rvt 0:33bc88c4ab31 39 *
rvt 0:33bc88c4ab31 40 * @endcode
rvt 0:33bc88c4ab31 41 *
rvt 0:33bc88c4ab31 42 *
rvt 0:33bc88c4ab31 43 * @code
rvt 0:33bc88c4ab31 44 * #include "mbed.h"
rvt 0:33bc88c4ab31 45 * #include "USBJoystick.h"
rvt 0:33bc88c4ab31 46 * #include <math.h>
rvt 0:33bc88c4ab31 47 *
rvt 0:33bc88c4ab31 48 * USBJoystick joystick;
rvt 0:33bc88c4ab31 49 *
rvt 0:33bc88c4ab31 50 * int main(void)
rvt 0:33bc88c4ab31 51 * {
rvt 0:33bc88c4ab31 52 * int16_t i = 0;
rvt 0:33bc88c4ab31 53 * int16_t throttle = 0;
rvt 0:33bc88c4ab31 54 * int16_t rudder = 0;
rvt 0:33bc88c4ab31 55 * int16_t x = 0;
rvt 0:33bc88c4ab31 56 * int16_t y = 0;
rvt 0:33bc88c4ab31 57 * int32_t radius = 120;
rvt 0:33bc88c4ab31 58 * int32_t angle = 0;
rvt 0:33bc88c4ab31 59 * int8_t button = 0;
rvt 0:33bc88c4ab31 60 * int8_t hat = 0;
rvt 0:33bc88c4ab31 61 *
rvt 0:33bc88c4ab31 62 * while (1) {
rvt 0:33bc88c4ab31 63 * // Basic Joystick
rvt 0:33bc88c4ab31 64 * throttle = (i >> 8) & 0xFF; // value -127 .. 128
rvt 0:33bc88c4ab31 65 * rudder = (i >> 8) & 0xFF; // value -127 .. 128
rvt 0:33bc88c4ab31 66 * button = (i >> 8) & 0x0F; // value 0 .. 15, one bit per button
rvt 0:33bc88c4ab31 67 * hat = (i >> 8) & 0x07; // value 0..7 or 8 for neutral
rvt 0:33bc88c4ab31 68 * i++;
rvt 0:33bc88c4ab31 69 *
rvt 0:33bc88c4ab31 70 * x = cos((double)angle*3.14/180.0)*radius; // value -127 .. 128
rvt 0:33bc88c4ab31 71 * y = sin((double)angle*3.14/180.0)*radius; // value -127 .. 128
rvt 0:33bc88c4ab31 72 * angle += 3;
rvt 0:33bc88c4ab31 73 *
rvt 0:33bc88c4ab31 74 * joystick.update(throttle, rudder, x, y, button, hat);
rvt 0:33bc88c4ab31 75 *
rvt 0:33bc88c4ab31 76 * wait(0.001);
rvt 0:33bc88c4ab31 77 * }
rvt 0:33bc88c4ab31 78 * }
rvt 0:33bc88c4ab31 79 * @endcode
rvt 0:33bc88c4ab31 80 */
rvt 0:33bc88c4ab31 81
rvt 0:33bc88c4ab31 82
rvt 0:33bc88c4ab31 83 class USBJoystick: public USBHID {
rvt 0:33bc88c4ab31 84 public:
rvt 0:33bc88c4ab31 85
rvt 0:33bc88c4ab31 86 /**
rvt 0:33bc88c4ab31 87 * Constructor
rvt 0:33bc88c4ab31 88 *
rvt 0:33bc88c4ab31 89 * @param vendor_id Your vendor_id (default: 0x1234)
rvt 0:33bc88c4ab31 90 * @param product_id Your product_id (default: 0x0002)
rvt 0:33bc88c4ab31 91 * @param product_release Your product_release (default: 0x0001)
rvt 0:33bc88c4ab31 92 */
rvt 0:33bc88c4ab31 93 USBJoystick(uint16_t vendor_id = 0x1234, uint16_t product_id = 0x0100, uint16_t product_release = 0x0001):
rvt 0:33bc88c4ab31 94 USBHID(0, 0, vendor_id, product_id, product_release, false)
rvt 0:33bc88c4ab31 95 {
rvt 0:33bc88c4ab31 96 _init();
rvt 0:33bc88c4ab31 97 connect();
rvt 0:33bc88c4ab31 98 };
rvt 0:33bc88c4ab31 99
rvt 0:33bc88c4ab31 100 /**
rvt 0:33bc88c4ab31 101 * Write a state of the mouse
rvt 0:33bc88c4ab31 102 *
rvt 0:33bc88c4ab31 103 * @param t throttle position
rvt 0:33bc88c4ab31 104 * @param r rudder position
rvt 0:33bc88c4ab31 105 * @param x x-axis position
rvt 0:33bc88c4ab31 106 * @param y y-axis position
rvt 0:33bc88c4ab31 107 * @param buttons buttons state
rvt 0:33bc88c4ab31 108 * @returns true if there is no error, false otherwise
rvt 0:33bc88c4ab31 109 */
rvt 4:2cc58c173de8 110 bool update(int16_t t, int16_t r, int16_t x, int16_t y, uint32_t buttons);
rvt 0:33bc88c4ab31 111
rvt 0:33bc88c4ab31 112 /**
rvt 0:33bc88c4ab31 113 * Write a state of the mouse
rvt 0:33bc88c4ab31 114 *
rvt 0:33bc88c4ab31 115 * @returns true if there is no error, false otherwise
rvt 0:33bc88c4ab31 116 */
rvt 0:33bc88c4ab31 117 bool update();
rvt 0:33bc88c4ab31 118
rvt 0:33bc88c4ab31 119 /**
rvt 0:33bc88c4ab31 120 * Move the throttle position
rvt 0:33bc88c4ab31 121 *
rvt 0:33bc88c4ab31 122 * @param t throttle position
rvt 0:33bc88c4ab31 123 * @returns true if there is no error, false otherwise
rvt 0:33bc88c4ab31 124 */
rvt 0:33bc88c4ab31 125 bool throttle(int16_t t);
rvt 0:33bc88c4ab31 126
rvt 0:33bc88c4ab31 127 /**
rvt 0:33bc88c4ab31 128 * Move the rudder position
rvt 0:33bc88c4ab31 129 *
rvt 0:33bc88c4ab31 130 * @param r rudder position
rvt 0:33bc88c4ab31 131 * @returns true if there is no error, false otherwise
rvt 0:33bc88c4ab31 132 */
rvt 0:33bc88c4ab31 133 bool rudder(int16_t r);
rvt 0:33bc88c4ab31 134
rvt 0:33bc88c4ab31 135 /**
rvt 0:33bc88c4ab31 136 * Move the cursor to (x, y)
rvt 0:33bc88c4ab31 137 *
rvt 0:33bc88c4ab31 138 * @param x-axis position
rvt 0:33bc88c4ab31 139 * @param y-axis position
rvt 0:33bc88c4ab31 140 * @returns true if there is no error, false otherwise
rvt 0:33bc88c4ab31 141 */
rvt 0:33bc88c4ab31 142 bool move(int16_t x, int16_t y);
rvt 0:33bc88c4ab31 143
rvt 0:33bc88c4ab31 144 /**
rvt 0:33bc88c4ab31 145 * Press one or several buttons
rvt 0:33bc88c4ab31 146 *
rvt 0:33bc88c4ab31 147 * @param button button state
rvt 0:33bc88c4ab31 148 * @returns true if there is no error, false otherwise
rvt 0:33bc88c4ab31 149 */
rvt 4:2cc58c173de8 150 bool button(uint32_t button);
rvt 2:ae7a31a3c618 151
rvt 0:33bc88c4ab31 152 /*
rvt 0:33bc88c4ab31 153 * To define the report descriptor. Warning: this method has to store the length of the report descriptor in reportLength.
rvt 0:33bc88c4ab31 154 *
rvt 0:33bc88c4ab31 155 * @returns pointer to the report descriptor
rvt 0:33bc88c4ab31 156 */
rvt 0:33bc88c4ab31 157 virtual uint8_t * reportDesc();
rvt 0:33bc88c4ab31 158
rvt 0:33bc88c4ab31 159 private:
rvt 0:33bc88c4ab31 160 int16_t _t;
rvt 0:33bc88c4ab31 161 int16_t _r;
rvt 0:33bc88c4ab31 162 int16_t _x;
rvt 0:33bc88c4ab31 163 int16_t _y;
rvt 4:2cc58c173de8 164 uint32_t _button;
rvt 0:33bc88c4ab31 165
rvt 0:33bc88c4ab31 166 void _init();
rvt 0:33bc88c4ab31 167 };
rvt 0:33bc88c4ab31 168
rvt 0:33bc88c4ab31 169 #endif