Demo for USBJoystick updated for 32 buttons.
Dependencies: USBDevice USBJoystick_SIM mbed USBJoystick_2
Fork of USBJoystick_HelloWorld2 by
Diff: main.cpp
- Revision:
- 1:b106cf2e99ba
- Parent:
- 0:e43878690c0e
- Child:
- 2:967da2faedcd
--- a/main.cpp Thu Jan 05 14:23:14 2017 +0000 +++ b/main.cpp Sun Jul 22 10:36:35 2018 +0000 @@ -2,7 +2,7 @@ * Copyright (c) 2012, v01: Initial version, WH, * Modified USBMouse code ARM Limited. * (c) 2010-2011 mbed.org, MIT License - * 2016, v02: Updated USBDevice Lib, Added waitForConnect, Updated 32 bits button + * 2016, v02: Updated USBDevice Lib, Added waitForConnect, Updated 32 bits button * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -24,6 +24,7 @@ */ #include "mbed.h" +#include "config.h" #include "USBJoystick.h" //#define LANDTIGER 1 @@ -32,79 +33,331 @@ USBJoystick joystick; // Variables for Heartbeat and Status monitoring -DigitalOut myled1(LED1); +DigitalOut myled1(LED4); DigitalOut myled2(LED2); DigitalOut myled3(LED3); -DigitalOut heartbeatLED(LED4); +DigitalOut heartbeatLED(LED1); + +AnalogIn inX(A0); +AnalogIn inY(A1); +AnalogIn inRudder(A2); +AnalogIn inThrottle(A3); +AnalogIn inBreaks(A4); +AnalogIn inFlaps(A5); Ticker heartbeat; Serial pc(USBTX, USBRX); // tx, rx +// number of elements in an array +#define countof(x) (sizeof(x)/sizeof((x)[0])) + +// button input map array +DigitalIn *buttonDigIn[NUM_OF_BUTTONS]; // config.h + +// hat button input map array +DigitalIn *hatDigIn[NUM_OF_HAT_BUTTONS]; // config.h + // Heartbeat monitor -void pulse() { - heartbeatLED = !heartbeatLED; +void pulse() +{ + heartbeatLED = !heartbeatLED; +} + +void heartbeat_start() +{ + heartbeatLED=1; + heartbeat.attach(&pulse, 0.5); +} + +void heartbeat_stop() +{ + heartbeat.detach(); } -void heartbeat_start() { - heartbeatLED=1; - heartbeat.attach(&pulse, 0.5); -} +// button state +struct ButtonState +{ + // current on/off state + int pressed; + + // Sticky time remaining for current state. When a + // state transition occurs, we set this to a debounce + // period. Future state transitions will be ignored + // until the debounce time elapses. + int bt; +} buttonState[NUM_OF_BUTTONS]; -void heartbeat_stop() { - heartbeat.detach(); +// timer for button reports +static Timer buttonTimer; + +// initialize the button inputs +void initButtons() +{ + // create the digital inputs + for (int i = 0 ; i < countof(buttonDigIn) ; ++i) + { + if (i < countof(buttonMap) && buttonMap[i] != NC) + buttonDigIn[i] = new DigitalIn(buttonMap[i]); + else + buttonDigIn[i] = 0; + } + + // start the button timer + buttonTimer.start(); } -int main() { - uint16_t i = 0; - int16_t throttle = 0; - int16_t rudder = 0; - int16_t x = 0; - int16_t y = 0; - int32_t radius = 120; - int32_t angle = 0; - uint8_t tmp = 0; - uint32_t buttons = 0; - uint8_t hat = 0; +// read the button input state +uint32_t readButtons() +{ + // start with all buttons off + uint32_t buttons = 0; + + // figure the time elapsed since the last scan + int dt = buttonTimer.read_ms(); + + // reset the timef for the next scan + buttonTimer.reset(); - pc.printf("Hello World from Joystick!\n\r"); + // scan the button list + uint32_t bit = 1; + DigitalIn **di = buttonDigIn; + ButtonState *bs = buttonState; + for (int i = 0 ; i < countof(buttonDigIn) ; ++i, ++di, ++bs, bit <<= 1) + { + // read this button + if (*di != 0) + { + // deduct the elapsed time since the last update + // from the button's remaining sticky time + bs->bt -= dt; + if (bs->bt < 0) + bs->bt = 0; + + // If the sticky time has elapsed, note the new physical + // state of the button. If we still have sticky time + // remaining, ignore the physical state; the last state + // change persists until the sticky time elapses so that + // we smooth out any "bounce" (electrical transients that + // occur when the switch contact is opened or closed). + if (bs->bt == 0) + { + // get the new physical state + int pressed = !(*di)->read(); + + // update the button's logical state if this is a change + if (pressed != bs->pressed) + { + // store the new state + bs->pressed = pressed; + + // start a new sticky period for debouncing this + // state change + bs->bt = 10; + } + } + + // if it's pressed, OR its bit into the state + if (bs->pressed) + buttons |= bit; + } + } + + // return the new button list + return buttons; +} - heartbeat_start(); +// hat state +struct HatState +{ + // current on/off state + int pressed; + + // Sticky time remaining for current state. When a + // state transition occurs, we set this to a debounce + // period. Future state transitions will be ignored + // until the debounce time elapses. + int ht; +} hatState[NUM_OF_HAT_BUTTONS]; + +// timer for hat reports +static Timer hatTimer; + +// initialize the hat inputs +void initHat() +{ + // create the digital inputs + for (int i = 0 ; i < countof(hatDigIn) ; ++i) + { + if (i < countof(hatMap) && hatMap[i] != NC) + hatDigIn[i] = new DigitalIn(hatMap[i]); + else + hatDigIn[i] = 0; + } +} - while (1) { - // Basic Joystick - throttle = (i >> 8) & 0xFF; // value -127 .. 128 - rudder = (i >> 8) & 0xFF; // value -127 .. 128 +// read the hat button input state +uint8_t readHat() +{ + // start with all buttons off + uint8_t hat = 0; + + // figure the time elapsed since the last scan + int dt = hatTimer.read_ms(); + + // reset the timef for the next scan + hatTimer.reset(); + + // scan the button list + uint8_t bit = 1; + DigitalIn **di = hatDigIn; + HatState *hs = hatState; + for (int i = 0 ; i < countof(hatDigIn) ; ++i, ++di, ++hs, bit <<= 1) + { + // read this button + if (*di != 0) + { + // deduct the elapsed time since the last update + // from the button's remaining sticky time + hs->ht -= dt; + if (hs->ht < 0) + hs->ht = 0; + + // If the sticky time has elapsed, note the new physical + // state of the button. If we still have sticky time + // remaining, ignore the physical state; the last state + // change persists until the sticky time elapses so that + // we smooth out any "bounce" (electrical transients that + // occur when the switch contact is opened or closed). + if (hs->ht == 0) + { + // get the new physical state + int pressed = !(*di)->read(); + + // update the button's logical state if this is a change + if (pressed != hs->pressed) + { + // store the new state + hs->pressed = pressed; + + // start a new sticky period for debouncing this + // state change + hs->ht = 10; + } + } + + // if it's pressed, OR its bit into the state + if (hs->pressed) + hat |= bit; + pc.printf("Hat: %d\n", hat); + } + } + + // return the new button list + //pc.printf("Hat: %d", hat); + return hat; +} -#if (BUTTONS4 == 1) - buttons = (i >> 8) & 0x0F; // value 0 .. 15, one bit per button -#endif -#if (BUTTONS8 == 1) - buttons = (i >> 8) & 0xFF; // value 0 .. 255, one bit per button -#endif -#if (BUTTONS32 == 1) - tmp = (i >> 8) & 0xFF; // value 0 .. 255, one bit per button - buttons = (( tmp << 0) & 0x000000FF); - buttons = buttons | ((~tmp << 8) & 0x0000FF00); - buttons = buttons | (( tmp << 16) & 0x00FF0000); - buttons = buttons | ((~tmp << 24) & 0xFF000000); -#endif +int main() +{ + //uint16_t i = 0; + int16_t throttle = 0; + int16_t rudder = 0; + int16_t breaks = 0; + int16_t flaps = 0; + int16_t x = 0; + int16_t y = 0; + //int32_t radius = 120; + //int32_t angle = 0; + //uint8_t tmp = 0; + //uint32_t tmp = 1; + uint32_t buttons = 0; + uint8_t hat = 0; + + pc.printf("Hello World from Joystick!\n\r"); + + initButtons(); + initHat(); + + heartbeat_start(); -#if (HAT4 == 1) - hat = (i >> 8) & 0x03; // value 0, 1, 2, 3 or 4 for neutral + while (1) { + // Basic Joystick + // throttle = (i >> 8) & 0xFF; // value -127 .. 128 + // rudder = (i >> 8) & 0xFF; // value -127 .. 128 + // breaks = (i >> 8) & 0xFF; // value 0 .. 255 + // flaps = (i >> 8) & 0xFF; // value 0 .. 255 + +/* +#if (BUTTONS4 == 1) + buttons = (i >> 8) & 0x0F; // value 0 .. 15, one bit per button +#endif +#if (BUTTONS8 == 1) + buttons = (i >> 8) & 0xFF; // value 0 .. 255, one bit per button +#endif +#if (BUTTONS32 == 1) + //tmp = (i >> 8) & 0xFF; // value 0 .. 255, one bit per button + //buttons = (( tmp << 0) & 0x000000FF); + //buttons = buttons | ((~tmp << 8) & 0x0000FF00); + //buttons = buttons | (( tmp << 16) & 0x00FF0000); + //buttons = buttons | ((~tmp << 24) & 0xFF000000);// + buttons = tmp; + tmp += 1; + pc.printf("Tmp: %u\n", tmp); +#endif + +#if (HAT4 == 1) + hat = (i >> 8) & 0x03; // value 0, 1, 2, 3 or 4 for neutral #endif #if (HAT8 == 1) - hat = (i >> 8) & 0x07; // value 0..7 or 8 for neutral -#endif - i++; + hat = (i >> 8) & 0x07; // value 0..7 or 8 for neutral +#endif + i++; + + //x = cos((double)angle*3.14/180.0)*radius; // value -127 .. 128 + //y = sin((double)angle*3.14/180.0)*radius; // value -127 .. 128 + //angle += 3; +*/ + + buttons = readButtons(); + hat = readHat(); + //pc.printf("Hat: %d\n", hat); - x = cos((double)angle*3.14/180.0)*radius; // value -127 .. 128 - y = sin((double)angle*3.14/180.0)*radius; // value -127 .. 128 - angle += 3; + throttle = inThrottle.read() * 256 - 128; + if(throttle < -127) + throttle = -127; + if(throttle > 127) + throttle = 127; + rudder = inRudder.read() * 256 - 128; + if(rudder < -127) + rudder = -127; + if(rudder > 127) + rudder = 127; + breaks = inBreaks.read() * 256 - 127; + if(breaks < -127) + breaks = -127; + if(breaks > 127) + breaks = 127; + flaps = inFlaps.read() * 256 - 127; + if(flaps < -127) + flaps = -127; + if(flaps > 127) + flaps = 127; - joystick.update(throttle, rudder, x, y, buttons, hat); - wait(0.001); - } - - pc.printf("Bye World!\n\r"); + x = inX.read() * 256 - 127; + if(x < -127) + x = -127; + if(x > 127) + x = 127; + y = inY.read() * 254 - 127; + if(y < -127) + y = -127; + if(y < 127) + y = 127; + + joystick.update(throttle, rudder, breaks, flaps, x, y, buttons, hat); + wait(0.01); + } + + //pc.printf("Bye World!\n\r"); } \ No newline at end of file