WIP PID

Dependencies:   USBDEVICE USBJoystick mbed

Fork of USBJoystick_HelloWorld2 by Wim Huiskamp

Committer:
Cirrus01
Date:
Sat Jul 07 10:48:38 2018 +0000
Revision:
1:caf8a4134cbf
Parent:
0:e43878690c0e
First

Who changed what in which revision?

UserRevisionLine numberNew contents of line
wim 0:e43878690c0e 1 /* mbed USBJoystick Library Demo
wim 0:e43878690c0e 2 * Copyright (c) 2012, v01: Initial version, WH,
wim 0:e43878690c0e 3 * Modified USBMouse code ARM Limited.
wim 0:e43878690c0e 4 * (c) 2010-2011 mbed.org, MIT License
wim 0:e43878690c0e 5 * 2016, v02: Updated USBDevice Lib, Added waitForConnect, Updated 32 bits button
wim 0:e43878690c0e 6 *
wim 0:e43878690c0e 7 * Permission is hereby granted, free of charge, to any person obtaining a copy
wim 0:e43878690c0e 8 * of this software and associated documentation files (the "Software"), to deal
wim 0:e43878690c0e 9 * in the Software without restriction, inclumosig without limitation the rights
wim 0:e43878690c0e 10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
wim 0:e43878690c0e 11 * copies of the Software, and to permit persons to whom the Software is
wim 0:e43878690c0e 12 * furnished to do so, subject to the following conditions:
wim 0:e43878690c0e 13 *
wim 0:e43878690c0e 14 * The above copyright notice and this permission notice shall be included in
wim 0:e43878690c0e 15 * all copies or substantial portions of the Software.
wim 0:e43878690c0e 16 *
wim 0:e43878690c0e 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
wim 0:e43878690c0e 18 * IMPLIED, INCLUmosiG BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
wim 0:e43878690c0e 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
wim 0:e43878690c0e 20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
wim 0:e43878690c0e 21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
wim 0:e43878690c0e 22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
wim 0:e43878690c0e 23 * THE SOFTWARE.
wim 0:e43878690c0e 24 */
wim 0:e43878690c0e 25
wim 0:e43878690c0e 26 #include "mbed.h"
Cirrus01 1:caf8a4134cbf 27 #include "config.h"
wim 0:e43878690c0e 28 #include "USBJoystick.h"
wim 0:e43878690c0e 29
wim 0:e43878690c0e 30 //#define LANDTIGER 1
wim 0:e43878690c0e 31
Cirrus01 1:caf8a4134cbf 32 // number of elements in an array
Cirrus01 1:caf8a4134cbf 33 #define countof(x) (sizeof(x)/sizeof((x)[0]))
Cirrus01 1:caf8a4134cbf 34
Cirrus01 1:caf8a4134cbf 35 // The Simulator Device
wim 0:e43878690c0e 36 USBJoystick joystick;
wim 0:e43878690c0e 37
Cirrus01 1:caf8a4134cbf 38 // Variables for Button input
Cirrus01 1:caf8a4134cbf 39 DigitalIn *buttonDigIn[NUM_OF_BUTTONS]; // config.h
Cirrus01 1:caf8a4134cbf 40 DigitalIn *hatDigIn[NUM_OF_HAT_BUTTONS]; // config.h
Cirrus01 1:caf8a4134cbf 41
wim 0:e43878690c0e 42 // Variables for Heartbeat and Status monitoring
wim 0:e43878690c0e 43 DigitalOut myled1(LED1);
wim 0:e43878690c0e 44 DigitalOut myled2(LED2);
wim 0:e43878690c0e 45 DigitalOut myled3(LED3);
wim 0:e43878690c0e 46 DigitalOut heartbeatLED(LED4);
wim 0:e43878690c0e 47
Cirrus01 1:caf8a4134cbf 48 AnalogIn xi(A0);
Cirrus01 1:caf8a4134cbf 49 AnalogIn yi(A1);
Cirrus01 1:caf8a4134cbf 50 AnalogIn fi(A2);
Cirrus01 1:caf8a4134cbf 51 AnalogIn bi(A3);
Cirrus01 1:caf8a4134cbf 52 AnalogIn ri(A4);
Cirrus01 1:caf8a4134cbf 53 AnalogIn ti(A5);
Cirrus01 1:caf8a4134cbf 54
wim 0:e43878690c0e 55 Ticker heartbeat;
wim 0:e43878690c0e 56 Serial pc(USBTX, USBRX); // tx, rx
wim 0:e43878690c0e 57
wim 0:e43878690c0e 58 // Heartbeat monitor
wim 0:e43878690c0e 59 void pulse() {
wim 0:e43878690c0e 60 heartbeatLED = !heartbeatLED;
wim 0:e43878690c0e 61 }
wim 0:e43878690c0e 62
wim 0:e43878690c0e 63 void heartbeat_start() {
wim 0:e43878690c0e 64 heartbeatLED=1;
wim 0:e43878690c0e 65 heartbeat.attach(&pulse, 0.5);
wim 0:e43878690c0e 66 }
wim 0:e43878690c0e 67
wim 0:e43878690c0e 68 void heartbeat_stop() {
wim 0:e43878690c0e 69 heartbeat.detach();
wim 0:e43878690c0e 70 }
wim 0:e43878690c0e 71
Cirrus01 1:caf8a4134cbf 72 // button state
Cirrus01 1:caf8a4134cbf 73 struct ButtonState
Cirrus01 1:caf8a4134cbf 74 {
Cirrus01 1:caf8a4134cbf 75 // current on/off state
Cirrus01 1:caf8a4134cbf 76 int pressed;
Cirrus01 1:caf8a4134cbf 77
Cirrus01 1:caf8a4134cbf 78 // Sticky time remaining for current state. When a
Cirrus01 1:caf8a4134cbf 79 // state transition occurs, we set this to a debounce
Cirrus01 1:caf8a4134cbf 80 // period. Future state transitions will be ignored
Cirrus01 1:caf8a4134cbf 81 // until the debounce time elapses.
Cirrus01 1:caf8a4134cbf 82 int t;
Cirrus01 1:caf8a4134cbf 83 } buttonState[NUM_OF_BUTTONS];
Cirrus01 1:caf8a4134cbf 84
Cirrus01 1:caf8a4134cbf 85 // timer for button reports
Cirrus01 1:caf8a4134cbf 86 static Timer buttonTimer;
Cirrus01 1:caf8a4134cbf 87
Cirrus01 1:caf8a4134cbf 88 // initialize the button inputs
Cirrus01 1:caf8a4134cbf 89 void initButtons()
Cirrus01 1:caf8a4134cbf 90 {
Cirrus01 1:caf8a4134cbf 91 // create the digital inputs
Cirrus01 1:caf8a4134cbf 92 for (int i = 0 ; i < countof(buttonDigIn) ; ++i)
Cirrus01 1:caf8a4134cbf 93 {
Cirrus01 1:caf8a4134cbf 94 if (i < countof(buttonMap) && buttonMap[i] != NC)
Cirrus01 1:caf8a4134cbf 95 buttonDigIn[i] = new DigitalIn(buttonMap[i]);
Cirrus01 1:caf8a4134cbf 96 else
Cirrus01 1:caf8a4134cbf 97 buttonDigIn[i] = 0;
Cirrus01 1:caf8a4134cbf 98 }
Cirrus01 1:caf8a4134cbf 99
Cirrus01 1:caf8a4134cbf 100 // start the button timer
Cirrus01 1:caf8a4134cbf 101 buttonTimer.start();
Cirrus01 1:caf8a4134cbf 102 }
Cirrus01 1:caf8a4134cbf 103
Cirrus01 1:caf8a4134cbf 104
Cirrus01 1:caf8a4134cbf 105 // read the button input state
Cirrus01 1:caf8a4134cbf 106 uint32_t readButtons()
Cirrus01 1:caf8a4134cbf 107 {
Cirrus01 1:caf8a4134cbf 108 // start with all buttons off
Cirrus01 1:caf8a4134cbf 109 uint32_t buttons = 0;
Cirrus01 1:caf8a4134cbf 110
Cirrus01 1:caf8a4134cbf 111 // figure the time elapsed since the last scan
Cirrus01 1:caf8a4134cbf 112 int dt = buttonTimer.read_ms();
Cirrus01 1:caf8a4134cbf 113
Cirrus01 1:caf8a4134cbf 114 // reset the timef for the next scan
Cirrus01 1:caf8a4134cbf 115 buttonTimer.reset();
Cirrus01 1:caf8a4134cbf 116
Cirrus01 1:caf8a4134cbf 117 // scan the button list
Cirrus01 1:caf8a4134cbf 118 uint32_t bit = 1;
Cirrus01 1:caf8a4134cbf 119 DigitalIn **di = buttonDigIn;
Cirrus01 1:caf8a4134cbf 120 ButtonState *bs = buttonState;
Cirrus01 1:caf8a4134cbf 121 for (int i = 0 ; i < countof(buttonDigIn) ; ++i, ++di, ++bs, bit <<= 1)
Cirrus01 1:caf8a4134cbf 122 {
Cirrus01 1:caf8a4134cbf 123 // read this button
Cirrus01 1:caf8a4134cbf 124 if (*di != 0)
Cirrus01 1:caf8a4134cbf 125 {
Cirrus01 1:caf8a4134cbf 126 // deduct the elapsed time since the last update
Cirrus01 1:caf8a4134cbf 127 // from the button's remaining sticky time
Cirrus01 1:caf8a4134cbf 128 bs->t -= dt;
Cirrus01 1:caf8a4134cbf 129 if (bs->t < 0)
Cirrus01 1:caf8a4134cbf 130 bs->t = 0;
Cirrus01 1:caf8a4134cbf 131
Cirrus01 1:caf8a4134cbf 132 // If the sticky time has elapsed, note the new physical
Cirrus01 1:caf8a4134cbf 133 // state of the button. If we still have sticky time
Cirrus01 1:caf8a4134cbf 134 // remaining, ignore the physical state; the last state
Cirrus01 1:caf8a4134cbf 135 // change persists until the sticky time elapses so that
Cirrus01 1:caf8a4134cbf 136 // we smooth out any "bounce" (electrical transients that
Cirrus01 1:caf8a4134cbf 137 // occur when the switch contact is opened or closed).
Cirrus01 1:caf8a4134cbf 138 if (bs->t == 0)
Cirrus01 1:caf8a4134cbf 139 {
Cirrus01 1:caf8a4134cbf 140 // get the new physical state
Cirrus01 1:caf8a4134cbf 141 int pressed = !(*di)->read();
Cirrus01 1:caf8a4134cbf 142
Cirrus01 1:caf8a4134cbf 143 // update the button's logical state if this is a change
Cirrus01 1:caf8a4134cbf 144 if (pressed != bs->pressed)
Cirrus01 1:caf8a4134cbf 145 {
Cirrus01 1:caf8a4134cbf 146 // store the new state
Cirrus01 1:caf8a4134cbf 147 bs->pressed = pressed;
Cirrus01 1:caf8a4134cbf 148
Cirrus01 1:caf8a4134cbf 149 // start a new sticky period for debouncing this
Cirrus01 1:caf8a4134cbf 150 // state change
Cirrus01 1:caf8a4134cbf 151 bs->t = 25;
Cirrus01 1:caf8a4134cbf 152 }
Cirrus01 1:caf8a4134cbf 153 }
Cirrus01 1:caf8a4134cbf 154
Cirrus01 1:caf8a4134cbf 155 // if it's pressed, OR its bit into the state
Cirrus01 1:caf8a4134cbf 156 if (bs->pressed)
Cirrus01 1:caf8a4134cbf 157 buttons |= bit;
Cirrus01 1:caf8a4134cbf 158 }
Cirrus01 1:caf8a4134cbf 159 }
Cirrus01 1:caf8a4134cbf 160
Cirrus01 1:caf8a4134cbf 161 // return the new button list
Cirrus01 1:caf8a4134cbf 162 return buttons;
Cirrus01 1:caf8a4134cbf 163 }
Cirrus01 1:caf8a4134cbf 164
Cirrus01 1:caf8a4134cbf 165 // timer for hat button reports
Cirrus01 1:caf8a4134cbf 166 static Timer hatTimer;
Cirrus01 1:caf8a4134cbf 167
Cirrus01 1:caf8a4134cbf 168 // button state
Cirrus01 1:caf8a4134cbf 169 struct HatState
Cirrus01 1:caf8a4134cbf 170 {
Cirrus01 1:caf8a4134cbf 171 // current on/off state
Cirrus01 1:caf8a4134cbf 172 int pressed;
Cirrus01 1:caf8a4134cbf 173
Cirrus01 1:caf8a4134cbf 174 // Sticky time remaining for current state. When a
Cirrus01 1:caf8a4134cbf 175 // state transition occurs, we set this to a debounce
Cirrus01 1:caf8a4134cbf 176 // period. Future state transitions will be ignored
Cirrus01 1:caf8a4134cbf 177 // until the debounce time elapses.
Cirrus01 1:caf8a4134cbf 178 int t;
Cirrus01 1:caf8a4134cbf 179 } hatState[NUM_OF_HAT_BUTTONS];
Cirrus01 1:caf8a4134cbf 180
Cirrus01 1:caf8a4134cbf 181 // initialize the hat inputs
Cirrus01 1:caf8a4134cbf 182 void initHat()
Cirrus01 1:caf8a4134cbf 183 {
Cirrus01 1:caf8a4134cbf 184 // create the digital inputs
Cirrus01 1:caf8a4134cbf 185 for (int i = 0 ; i < countof(hatDigIn) ; ++i)
Cirrus01 1:caf8a4134cbf 186 {
Cirrus01 1:caf8a4134cbf 187 if (i < countof(hatMap) && hatMap[i] != NC)
Cirrus01 1:caf8a4134cbf 188 hatDigIn[i] = new DigitalIn(hatMap[i]);
Cirrus01 1:caf8a4134cbf 189 else
Cirrus01 1:caf8a4134cbf 190 hatDigIn[i] = 0;
Cirrus01 1:caf8a4134cbf 191 }
Cirrus01 1:caf8a4134cbf 192 }
Cirrus01 1:caf8a4134cbf 193
Cirrus01 1:caf8a4134cbf 194 // read the button input state
Cirrus01 1:caf8a4134cbf 195 uint32_t readHat()
Cirrus01 1:caf8a4134cbf 196 {
Cirrus01 1:caf8a4134cbf 197 // start with all buttons off
Cirrus01 1:caf8a4134cbf 198 uint8_t hat = 0;
Cirrus01 1:caf8a4134cbf 199
Cirrus01 1:caf8a4134cbf 200 // figure the time elapsed since the last scan
Cirrus01 1:caf8a4134cbf 201 int dt = hatTimer.read_ms();
Cirrus01 1:caf8a4134cbf 202
Cirrus01 1:caf8a4134cbf 203 // reset the timef for the next scan
Cirrus01 1:caf8a4134cbf 204 hatTimer.reset();
Cirrus01 1:caf8a4134cbf 205
Cirrus01 1:caf8a4134cbf 206 // scan the button list
Cirrus01 1:caf8a4134cbf 207 uint8_t bit = 1;
Cirrus01 1:caf8a4134cbf 208 DigitalIn **di = hatDigIn;
Cirrus01 1:caf8a4134cbf 209 HatState *bs = hatState;
Cirrus01 1:caf8a4134cbf 210 for (int i = 0 ; i < countof(hatDigIn) ; ++i, ++di, ++bs, bit <<= 1)
Cirrus01 1:caf8a4134cbf 211 {
Cirrus01 1:caf8a4134cbf 212 // read this button
Cirrus01 1:caf8a4134cbf 213 if (*di != 0)
Cirrus01 1:caf8a4134cbf 214 {
Cirrus01 1:caf8a4134cbf 215 // deduct the elapsed time since the last update
Cirrus01 1:caf8a4134cbf 216 // from the button's remaining sticky time
Cirrus01 1:caf8a4134cbf 217 bs->t -= dt;
Cirrus01 1:caf8a4134cbf 218 if (bs->t < 0)
Cirrus01 1:caf8a4134cbf 219 bs->t = 0;
Cirrus01 1:caf8a4134cbf 220
Cirrus01 1:caf8a4134cbf 221 // If the sticky time has elapsed, note the new physical
Cirrus01 1:caf8a4134cbf 222 // state of the button. If we still have sticky time
Cirrus01 1:caf8a4134cbf 223 // remaining, ignore the physical state; the last state
Cirrus01 1:caf8a4134cbf 224 // change persists until the sticky time elapses so that
Cirrus01 1:caf8a4134cbf 225 // we smooth out any "bounce" (electrical transients that
Cirrus01 1:caf8a4134cbf 226 // occur when the switch contact is opened or closed).
Cirrus01 1:caf8a4134cbf 227 if (bs->t == 0)
Cirrus01 1:caf8a4134cbf 228 {
Cirrus01 1:caf8a4134cbf 229 // get the new physical state
Cirrus01 1:caf8a4134cbf 230 int pressed = !(*di)->read();
Cirrus01 1:caf8a4134cbf 231
Cirrus01 1:caf8a4134cbf 232 // update the button's logical state if this is a change
Cirrus01 1:caf8a4134cbf 233 if (pressed != bs->pressed)
Cirrus01 1:caf8a4134cbf 234 {
Cirrus01 1:caf8a4134cbf 235 // store the new state
Cirrus01 1:caf8a4134cbf 236 bs->pressed = pressed;
Cirrus01 1:caf8a4134cbf 237
Cirrus01 1:caf8a4134cbf 238 // start a new sticky period for debouncing this
Cirrus01 1:caf8a4134cbf 239 // state change
Cirrus01 1:caf8a4134cbf 240 bs->t = 25;
Cirrus01 1:caf8a4134cbf 241 }
Cirrus01 1:caf8a4134cbf 242 }
Cirrus01 1:caf8a4134cbf 243
Cirrus01 1:caf8a4134cbf 244 // if it's pressed, OR its bit into the state
Cirrus01 1:caf8a4134cbf 245 if (bs->pressed)
Cirrus01 1:caf8a4134cbf 246 hat |= bit;
Cirrus01 1:caf8a4134cbf 247 }
Cirrus01 1:caf8a4134cbf 248 }
Cirrus01 1:caf8a4134cbf 249
Cirrus01 1:caf8a4134cbf 250 // return the new button list
Cirrus01 1:caf8a4134cbf 251 return hat;
Cirrus01 1:caf8a4134cbf 252 }
wim 0:e43878690c0e 253
wim 0:e43878690c0e 254 int main() {
Cirrus01 1:caf8a4134cbf 255 //uint16_t i = 0;
wim 0:e43878690c0e 256 int16_t throttle = 0;
wim 0:e43878690c0e 257 int16_t rudder = 0;
Cirrus01 1:caf8a4134cbf 258 int16_t flaps = 0;
Cirrus01 1:caf8a4134cbf 259 int16_t breaks = 0;
wim 0:e43878690c0e 260 int16_t x = 0;
wim 0:e43878690c0e 261 int16_t y = 0;
Cirrus01 1:caf8a4134cbf 262 //int32_t radius = 120;
Cirrus01 1:caf8a4134cbf 263 //int32_t angle = 0;
Cirrus01 1:caf8a4134cbf 264 //uint8_t tmp = 0;
wim 0:e43878690c0e 265 uint32_t buttons = 0;
wim 0:e43878690c0e 266 uint8_t hat = 0;
wim 0:e43878690c0e 267
wim 0:e43878690c0e 268 pc.printf("Hello World from Joystick!\n\r");
Cirrus01 1:caf8a4134cbf 269
Cirrus01 1:caf8a4134cbf 270 initButtons();
Cirrus01 1:caf8a4134cbf 271 initHat();
wim 0:e43878690c0e 272 heartbeat_start();
wim 0:e43878690c0e 273
wim 0:e43878690c0e 274 while (1) {
Cirrus01 1:caf8a4134cbf 275 /* // Basic Joystick
Cirrus01 1:caf8a4134cbf 276 throttle = (i >> 8) & 0xFF; // value -127 .. 128
Cirrus01 1:caf8a4134cbf 277 rudder = (i >> 8) & 0xFF; // value -127 .. 128
Cirrus01 1:caf8a4134cbf 278 flaps = (i >> 8) & 0xFF; // value -127 .. 128
Cirrus01 1:caf8a4134cbf 279 breaks = (i >> 8) & 0xFF; // value -127 .. 128
wim 0:e43878690c0e 280
wim 0:e43878690c0e 281 #if (BUTTONS4 == 1)
wim 0:e43878690c0e 282 buttons = (i >> 8) & 0x0F; // value 0 .. 15, one bit per button
wim 0:e43878690c0e 283 #endif
wim 0:e43878690c0e 284 #if (BUTTONS8 == 1)
wim 0:e43878690c0e 285 buttons = (i >> 8) & 0xFF; // value 0 .. 255, one bit per button
wim 0:e43878690c0e 286 #endif
wim 0:e43878690c0e 287 #if (BUTTONS32 == 1)
wim 0:e43878690c0e 288 tmp = (i >> 8) & 0xFF; // value 0 .. 255, one bit per button
wim 0:e43878690c0e 289 buttons = (( tmp << 0) & 0x000000FF);
wim 0:e43878690c0e 290 buttons = buttons | ((~tmp << 8) & 0x0000FF00);
wim 0:e43878690c0e 291 buttons = buttons | (( tmp << 16) & 0x00FF0000);
wim 0:e43878690c0e 292 buttons = buttons | ((~tmp << 24) & 0xFF000000);
wim 0:e43878690c0e 293 #endif
wim 0:e43878690c0e 294
wim 0:e43878690c0e 295 #if (HAT4 == 1)
wim 0:e43878690c0e 296 hat = (i >> 8) & 0x03; // value 0, 1, 2, 3 or 4 for neutral
wim 0:e43878690c0e 297 #endif
wim 0:e43878690c0e 298 #if (HAT8 == 1)
wim 0:e43878690c0e 299 hat = (i >> 8) & 0x07; // value 0..7 or 8 for neutral
wim 0:e43878690c0e 300 #endif
Cirrus01 1:caf8a4134cbf 301 i++;
wim 0:e43878690c0e 302
Cirrus01 1:caf8a4134cbf 303 //x = cos((double)angle*3.14/180.0)*radius; // value -127 .. 128
Cirrus01 1:caf8a4134cbf 304 //y = sin((double)angle*3.14/180.0)*radius; // value -127 .. 128
Cirrus01 1:caf8a4134cbf 305 //angle += 3;
Cirrus01 1:caf8a4134cbf 306 */
wim 0:e43878690c0e 307
Cirrus01 1:caf8a4134cbf 308 buttons = readButtons();
Cirrus01 1:caf8a4134cbf 309 hat = readHat();
Cirrus01 1:caf8a4134cbf 310
Cirrus01 1:caf8a4134cbf 311 x = int(((double)xi.read() - 0.5) * 254);
Cirrus01 1:caf8a4134cbf 312 y = int(((double)yi.read() - 0.5) * 254);
Cirrus01 1:caf8a4134cbf 313 flaps = int(((double)fi.read() - 0.5) * 254);
Cirrus01 1:caf8a4134cbf 314 breaks = int(((double)bi.read() - 0.5) * 254);
Cirrus01 1:caf8a4134cbf 315 rudder = int(((double)ri.read() - 0.5) * 254);
Cirrus01 1:caf8a4134cbf 316 throttle = int(((double)ti.read() - 0.5) * 254);
Cirrus01 1:caf8a4134cbf 317
Cirrus01 1:caf8a4134cbf 318 joystick.update(throttle, rudder, flaps, breaks, x, y, buttons, hat);
wim 0:e43878690c0e 319 wait(0.001);
wim 0:e43878690c0e 320 }
wim 0:e43878690c0e 321
Cirrus01 1:caf8a4134cbf 322 //pc.printf("Bye World!\n\r");
wim 0:e43878690c0e 323 }