Ries Twisk / Mbed 2 deprecated JoyStick

Dependencies:   USBDevice mbed-rtos mbed

Fork of JoyStick by Ries Twisk

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 #include "mbed.h"
rvt 0:33bc88c4ab31 2 #include "USBHID.h"
rvt 0:33bc88c4ab31 3 #include "USBJoystick.h"
rvt 0:33bc88c4ab31 4 #include "LowPassFilter.h"
rvt 0:33bc88c4ab31 5 #include "AnalogInFiltered.h"
rvt 5:a0bb17c379ce 6 #include "AutoScale.h"
rvt 4:2cc58c173de8 7 #include "Button.h"
rvt 0:33bc88c4ab31 8 #include "rtos.h"
rvt 0:33bc88c4ab31 9
rvt 1:5b2ab44eb31f 10 // When set, it will send debug data over USB serial
rvt 5:a0bb17c379ce 11 #define TTY_DEBUG false
rvt 0:33bc88c4ab31 12
rvt 0:33bc88c4ab31 13 // Value that defines when to start sending data this prevents the noise sending loads's of data over HID
rvt 5:a0bb17c379ce 14 #define DATA_CHANGE_TRIGGER 8
rvt 0:33bc88c4ab31 15
rvt 1:5b2ab44eb31f 16 // Activity LED for HID data
rvt 1:5b2ab44eb31f 17 #define HIDACTIVITYLED LED3
rvt 0:33bc88c4ab31 18
rvt 0:33bc88c4ab31 19 // Structure that hold's the dataset of the input's
rvt 0:33bc88c4ab31 20 Mutex analogValueMutex;
rvt 0:33bc88c4ab31 21 struct AnalogData {
rvt 5:a0bb17c379ce 22 union {
rvt 5:a0bb17c379ce 23 struct {
rvt 5:a0bb17c379ce 24 uint32_t bit0:1;
rvt 5:a0bb17c379ce 25 uint32_t bit1:1;
rvt 5:a0bb17c379ce 26 uint32_t bit2:1;
rvt 5:a0bb17c379ce 27 uint32_t bit3:1;
rvt 5:a0bb17c379ce 28 uint32_t bit4:1;
rvt 5:a0bb17c379ce 29 uint32_t bit5:1;
rvt 5:a0bb17c379ce 30 uint32_t bit6:1;
rvt 5:a0bb17c379ce 31 uint32_t bit7:1;
rvt 5:a0bb17c379ce 32 uint32_t bit8:1;
rvt 5:a0bb17c379ce 33 uint32_t bit9:1;
rvt 5:a0bb17c379ce 34 uint32_t bit10:1;
rvt 5:a0bb17c379ce 35 uint32_t bit11:1;
rvt 5:a0bb17c379ce 36 uint32_t bit12:1;
rvt 5:a0bb17c379ce 37 uint32_t bit13:1;
rvt 5:a0bb17c379ce 38 uint32_t bit14:1;
rvt 5:a0bb17c379ce 39 uint32_t bit15:1;
rvt 5:a0bb17c379ce 40 uint32_t bit16:1;
rvt 5:a0bb17c379ce 41 uint32_t bit17:1;
rvt 5:a0bb17c379ce 42 uint32_t bit18:1;
rvt 5:a0bb17c379ce 43 uint32_t bit19:1;
rvt 5:a0bb17c379ce 44 uint32_t bit20:1;
rvt 5:a0bb17c379ce 45 uint32_t bit21:1;
rvt 5:a0bb17c379ce 46 uint32_t bit22:1;
rvt 5:a0bb17c379ce 47 uint32_t bit23:1;
rvt 5:a0bb17c379ce 48 uint32_t bit24:1;
rvt 5:a0bb17c379ce 49 uint32_t bit25:1;
rvt 5:a0bb17c379ce 50 uint32_t bit26:1;
rvt 5:a0bb17c379ce 51 uint32_t bit27:1;
rvt 5:a0bb17c379ce 52 uint32_t bit28:1;
rvt 5:a0bb17c379ce 53 uint32_t bit29:1;
rvt 5:a0bb17c379ce 54 uint32_t bit30:1;
rvt 5:a0bb17c379ce 55 uint32_t bit31:1;
rvt 5:a0bb17c379ce 56 };
rvt 5:a0bb17c379ce 57 uint32_t button;
rvt 5:a0bb17c379ce 58 } buttons;
rvt 0:33bc88c4ab31 59 long value1;
rvt 0:33bc88c4ab31 60 long value2;
rvt 0:33bc88c4ab31 61 long value3;
rvt 0:33bc88c4ab31 62 long value4;
rvt 0:33bc88c4ab31 63 } analogData;
rvt 0:33bc88c4ab31 64
rvt 3:0742b0b42ac9 65
rvt 1:5b2ab44eb31f 66
rvt 1:5b2ab44eb31f 67
rvt 1:5b2ab44eb31f 68 /**
rvt 1:5b2ab44eb31f 69 Debug thread to show some values from the system over USB serial.
rvt 1:5b2ab44eb31f 70 Ensure that TTY_DEBUG is defined so that these routines will get activated.
rvt 1:5b2ab44eb31f 71 This is what I do to view the values on OSX within a terminal
rvt 1:5b2ab44eb31f 72 $ cd /dev
rvt 1:5b2ab44eb31f 73 $ ls | grep usbmodem
rvt 1:5b2ab44eb31f 74 cu.usbmodemfa1232
rvt 1:5b2ab44eb31f 75 tty.usbmodemfa1232
rvt 1:5b2ab44eb31f 76 $ screen tty.usbmodemfa1232
rvt 1:5b2ab44eb31f 77 */
rvt 2:ae7a31a3c618 78 const char *byte_to_binary16(int x)
rvt 2:ae7a31a3c618 79 {
rvt 2:ae7a31a3c618 80 static char b[17];
rvt 2:ae7a31a3c618 81 b[0] = '\0';
rvt 2:ae7a31a3c618 82
rvt 2:ae7a31a3c618 83 int z;
rvt 5:a0bb17c379ce 84 for (z = 32768; z > 0; z >>= 1) {
rvt 2:ae7a31a3c618 85 strcat(b, ((x & z) == z) ? "1" : "0");
rvt 2:ae7a31a3c618 86 }
rvt 2:ae7a31a3c618 87
rvt 2:ae7a31a3c618 88 return b;
rvt 2:ae7a31a3c618 89 }
rvt 2:ae7a31a3c618 90
rvt 2:ae7a31a3c618 91
rvt 0:33bc88c4ab31 92 void debug_thread(void const *args)
rvt 0:33bc88c4ab31 93 {
rvt 2:ae7a31a3c618 94 // Serial port for debug data
rvt 2:ae7a31a3c618 95 Serial pc(USBTX, USBRX); // tx, rx
rvt 2:ae7a31a3c618 96
rvt 1:5b2ab44eb31f 97 // Make a local copy
rvt 1:5b2ab44eb31f 98 AnalogData previous;
rvt 0:33bc88c4ab31 99 while (true) {
rvt 1:5b2ab44eb31f 100 // Lock and copy input values
rvt 0:33bc88c4ab31 101 analogValueMutex.lock();
rvt 5:a0bb17c379ce 102 const AnalogData localCopy = analogData;
rvt 0:33bc88c4ab31 103 analogValueMutex.unlock();
rvt 0:33bc88c4ab31 104
rvt 0:33bc88c4ab31 105 // Send to USB
rvt 0:33bc88c4ab31 106 pc.printf("\x1B[0;0H");
rvt 0:33bc88c4ab31 107 pc.printf("Yoke and Pedals!\n\r");
rvt 5:a0bb17c379ce 108 pc.printf("Analog in p20: %d diff: %d \n\r",localCopy.value1,localCopy.value1-previous.value1);
rvt 0:33bc88c4ab31 109 pc.printf("Analog in p19: %d diff: %d \n\r",localCopy.value2,localCopy.value2-previous.value2);
rvt 5:a0bb17c379ce 110 pc.printf("Buttons: %d \n\r",localCopy.buttons.button);
rvt 1:5b2ab44eb31f 111
rvt 1:5b2ab44eb31f 112 // Make local copy so we can show diff version
rvt 5:a0bb17c379ce 113 previous = localCopy;
rvt 0:33bc88c4ab31 114 Thread::wait(1000);
rvt 0:33bc88c4ab31 115 }
rvt 0:33bc88c4ab31 116 }
rvt 3:0742b0b42ac9 117
rvt 0:33bc88c4ab31 118
rvt 2:ae7a31a3c618 119
rvt 0:33bc88c4ab31 120 void hid_thread(void const *args)
rvt 0:33bc88c4ab31 121 {
rvt 1:5b2ab44eb31f 122 //USB HID JoyStick
rvt 1:5b2ab44eb31f 123 USBJoystick joystick;
rvt 1:5b2ab44eb31f 124
rvt 1:5b2ab44eb31f 125 // Activity led for HID data transmissions
rvt 1:5b2ab44eb31f 126 DigitalOut hIDActivity(HIDACTIVITYLED);
rvt 1:5b2ab44eb31f 127
rvt 0:33bc88c4ab31 128 while (true) {
rvt 0:33bc88c4ab31 129 // Wait for analog in to have some data
rvt 1:5b2ab44eb31f 130 hIDActivity=false;
rvt 0:33bc88c4ab31 131 Thread::signal_wait(0x1);
rvt 1:5b2ab44eb31f 132 hIDActivity=true;
rvt 0:33bc88c4ab31 133
rvt 0:33bc88c4ab31 134 // Make a local copy of the data
rvt 0:33bc88c4ab31 135 analogValueMutex.lock();
rvt 5:a0bb17c379ce 136 const AnalogData localCopy = analogData;
rvt 0:33bc88c4ab31 137 analogValueMutex.unlock();
rvt 0:33bc88c4ab31 138
rvt 0:33bc88c4ab31 139 // Update joystick's info
rvt 0:33bc88c4ab31 140 joystick.update(
rvt 4:2cc58c173de8 141 localCopy.value1,
rvt 0:33bc88c4ab31 142 localCopy.value2,
rvt 0:33bc88c4ab31 143 localCopy.value3,
rvt 0:33bc88c4ab31 144 localCopy.value4,
rvt 5:a0bb17c379ce 145 localCopy.buttons.button);
rvt 0:33bc88c4ab31 146
rvt 0:33bc88c4ab31 147 // Wait 50 ms to send a other USB update
rvt 0:33bc88c4ab31 148 Thread::wait(50);
rvt 0:33bc88c4ab31 149 }
rvt 0:33bc88c4ab31 150 }
rvt 0:33bc88c4ab31 151
rvt 0:33bc88c4ab31 152
rvt 0:33bc88c4ab31 153
rvt 0:33bc88c4ab31 154 int main()
rvt 0:33bc88c4ab31 155 {
rvt 5:a0bb17c379ce 156 analogData.buttons.button = 0;
rvt 4:2cc58c173de8 157 analogData.value1=0.;
rvt 4:2cc58c173de8 158 analogData.value2=0.;
rvt 4:2cc58c173de8 159 analogData.value3=0.;
rvt 4:2cc58c173de8 160 analogData.value4=0.;
rvt 4:2cc58c173de8 161
rvt 4:2cc58c173de8 162 Button but5(p5, true, true);
rvt 4:2cc58c173de8 163 Button but6(p6, true, true);
rvt 4:2cc58c173de8 164 Button but7(p7, true, true);
rvt 4:2cc58c173de8 165 Button but8(p8, true, true);
rvt 4:2cc58c173de8 166 Button but9(p9, true, true);
rvt 4:2cc58c173de8 167 Button but10(p10, true, true);
rvt 4:2cc58c173de8 168 Button but11(p11, true, true);
rvt 4:2cc58c173de8 169 Button but12(p12, true, true);
rvt 4:2cc58c173de8 170 Button but13(p13, true, true);
rvt 4:2cc58c173de8 171 Button but14(p14, true, true);
rvt 4:2cc58c173de8 172 Button but15(p15, true, true);
rvt 4:2cc58c173de8 173 Button but16(p16, true, true);
rvt 4:2cc58c173de8 174 Button but17(p17, true, true);
rvt 4:2cc58c173de8 175 Button but21(p21, true, true);
rvt 4:2cc58c173de8 176 Button but22(p22, true, true);
rvt 4:2cc58c173de8 177 Button but23(p23, true, true);
rvt 4:2cc58c173de8 178 Button but24(p24, true, true);
rvt 4:2cc58c173de8 179 Button but25(p25, true, true);
rvt 0:33bc88c4ab31 180
rvt 3:0742b0b42ac9 181 if (TTY_DEBUG) {
rvt 3:0742b0b42ac9 182 Thread _debugThread(debug_thread);
rvt 5:a0bb17c379ce 183 }
rvt 0:33bc88c4ab31 184
rvt 0:33bc88c4ab31 185 // Initialise moving average filters
rvt 5:a0bb17c379ce 186 LowPassFilter lowPassFilter1(new AnalogFilterInterface(),0.99f); // The close the alpha value is to 1, the lower the cut-off frequency
rvt 5:a0bb17c379ce 187 LowPassFilter lowPassFilter2(new AnalogFilterInterface(),0.99f);
rvt 5:a0bb17c379ce 188 LowPassFilter lowPassFilter3(new AnalogFilterInterface(),0.96f);
rvt 5:a0bb17c379ce 189
rvt 5:a0bb17c379ce 190 AutoScale autoScale1(&lowPassFilter1, -32768, 32767, 1.01);
rvt 5:a0bb17c379ce 191 AutoScale autoScale2(&lowPassFilter2, -32768, 32767, 1.01);
rvt 5:a0bb17c379ce 192 AutoScale autoScale3(&lowPassFilter3, -32768, 32767, 1.01);
rvt 0:33bc88c4ab31 193
rvt 0:33bc88c4ab31 194 // Initialise analog input and tell it what fulters to use
rvt 5:a0bb17c379ce 195 AnalogInFiltered ai1(&autoScale1, p20, DATA_CHANGE_TRIGGER);
rvt 5:a0bb17c379ce 196 AnalogInFiltered ai2(&autoScale2, p19, DATA_CHANGE_TRIGGER);
rvt 5:a0bb17c379ce 197 AnalogInFiltered ai3(&autoScale3, p18, DATA_CHANGE_TRIGGER);
rvt 5:a0bb17c379ce 198
rvt 5:a0bb17c379ce 199 Thread _hid_thread(hid_thread);
rvt 0:33bc88c4ab31 200 while (true) {
rvt 0:33bc88c4ab31 201 // Measure analog in's
rvt 5:a0bb17c379ce 202 ai1.setData(0);
rvt 5:a0bb17c379ce 203 ai2.setData(0);
rvt 5:a0bb17c379ce 204 ai3.setData(0);
rvt 4:2cc58c173de8 205
rvt 4:2cc58c173de8 206 but5.measure();
rvt 4:2cc58c173de8 207 but6.measure();
rvt 4:2cc58c173de8 208 but7.measure();
rvt 4:2cc58c173de8 209 but8.measure();
rvt 4:2cc58c173de8 210 but9.measure();
rvt 4:2cc58c173de8 211 but10.measure();
rvt 4:2cc58c173de8 212 but11.measure();
rvt 4:2cc58c173de8 213 but12.measure();
rvt 4:2cc58c173de8 214 but13.measure();
rvt 4:2cc58c173de8 215 but14.measure();
rvt 4:2cc58c173de8 216 but15.measure();
rvt 4:2cc58c173de8 217 but16.measure();
rvt 4:2cc58c173de8 218 but17.measure();
rvt 5:a0bb17c379ce 219
rvt 4:2cc58c173de8 220 but21.measure();
rvt 4:2cc58c173de8 221 but22.measure();
rvt 4:2cc58c173de8 222 but23.measure();
rvt 4:2cc58c173de8 223 but24.measure();
rvt 4:2cc58c173de8 224 but25.measure();
rvt 0:33bc88c4ab31 225
rvt 0:33bc88c4ab31 226 // test of any of the values have been changed, so we only update when data was actually changed
rvt 5:a0bb17c379ce 227 const bool isChanged =
rvt 5:a0bb17c379ce 228 ai1.getIsChanged() ||
rvt 5:a0bb17c379ce 229 ai2.getIsChanged() ||
rvt 5:a0bb17c379ce 230 ai3.getIsChanged() ||
rvt 5:a0bb17c379ce 231 but5.getIsChanged() ||
rvt 5:a0bb17c379ce 232 but6.getIsChanged() ||
rvt 5:a0bb17c379ce 233 but7.getIsChanged() ||
rvt 5:a0bb17c379ce 234 but8.getIsChanged() ||
rvt 5:a0bb17c379ce 235 but9.getIsChanged() ||
rvt 5:a0bb17c379ce 236 but10.getIsChanged() ||
rvt 5:a0bb17c379ce 237 but11.getIsChanged() ||
rvt 5:a0bb17c379ce 238 but12.getIsChanged() ||
rvt 5:a0bb17c379ce 239 but13.getIsChanged() ||
rvt 5:a0bb17c379ce 240 but14.getIsChanged() ||
rvt 5:a0bb17c379ce 241 but15.getIsChanged() ||
rvt 5:a0bb17c379ce 242 but16.getIsChanged() ||
rvt 5:a0bb17c379ce 243 but17.getIsChanged() ||
rvt 5:a0bb17c379ce 244 but21.getIsChanged() ||
rvt 5:a0bb17c379ce 245 but22.getIsChanged() ||
rvt 5:a0bb17c379ce 246 but23.getIsChanged() ||
rvt 5:a0bb17c379ce 247 but24.getIsChanged() ||
rvt 5:a0bb17c379ce 248 but25.getIsChanged();
rvt 0:33bc88c4ab31 249 if (
rvt 5:a0bb17c379ce 250 isChanged
rvt 5:a0bb17c379ce 251 ) {
rvt 0:33bc88c4ab31 252 // Copy analog data to global data
rvt 0:33bc88c4ab31 253 analogValueMutex.lock();
rvt 5:a0bb17c379ce 254 analogData.buttons.bit0 = but5.getData();
rvt 5:a0bb17c379ce 255 analogData.buttons.bit1 = but6.getData();
rvt 5:a0bb17c379ce 256 analogData.buttons.bit2 = but7.getData();
rvt 5:a0bb17c379ce 257 analogData.buttons.bit3 = but8.getData();
rvt 5:a0bb17c379ce 258 analogData.buttons.bit4 = but9.getData();
rvt 5:a0bb17c379ce 259 analogData.buttons.bit5 = but10.getData();
rvt 5:a0bb17c379ce 260 analogData.buttons.bit6 = but11.getData();
rvt 5:a0bb17c379ce 261 analogData.buttons.bit7 = but12.getData();
rvt 5:a0bb17c379ce 262 analogData.buttons.bit8 = but13.getData();
rvt 5:a0bb17c379ce 263 analogData.buttons.bit9 = but14.getData();
rvt 5:a0bb17c379ce 264 analogData.buttons.bit10 = but15.getData();
rvt 5:a0bb17c379ce 265 analogData.buttons.bit11 = but16.getData();
rvt 5:a0bb17c379ce 266 analogData.buttons.bit12 = but17.getData();
rvt 5:a0bb17c379ce 267 analogData.buttons.bit13 = but21.getData();
rvt 5:a0bb17c379ce 268 analogData.buttons.bit14 = but22.getData();
rvt 5:a0bb17c379ce 269 analogData.buttons.bit15 = but23.getData();
rvt 5:a0bb17c379ce 270 analogData.buttons.bit16 = but24.getData();
rvt 5:a0bb17c379ce 271 analogData.buttons.bit17 = but25.getData();
rvt 4:2cc58c173de8 272
rvt 2:ae7a31a3c618 273 analogData.value1 = ai1.getData();
rvt 2:ae7a31a3c618 274 analogData.value2 = ai2.getData();
rvt 5:a0bb17c379ce 275 analogData.value3 = ai3.getData();
rvt 4:2cc58c173de8 276 analogData.value4 = 0.;
rvt 0:33bc88c4ab31 277 analogValueMutex.unlock();
rvt 0:33bc88c4ab31 278
rvt 0:33bc88c4ab31 279 // Signal that data has been changed
rvt 0:33bc88c4ab31 280 _hid_thread.signal_set(0x1);
rvt 0:33bc88c4ab31 281 }
rvt 0:33bc88c4ab31 282 Thread::wait(1);
rvt 0:33bc88c4ab31 283 }
rvt 0:33bc88c4ab31 284 }
rvt 0:33bc88c4ab31 285