Browse Source

Fixed dead zone algorithm, some other small changes.

Thomas Buck 7 years ago
parent
commit
6514740813
6 changed files with 155 additions and 92 deletions
  1. 1
    1
      Saitek-X52-PPM.ino
  2. 4
    4
      hid_parser.cpp
  3. 7
    8
      hid_parser.h
  4. 109
    68
      joystick_events.cpp
  5. 27
    11
      joystick_events.h
  6. 7
    0
      x52.cpp

+ 1
- 1
Saitek-X52-PPM.ino View File

@@ -24,7 +24,7 @@ USB usb;
24 24
 USBHub hub(&usb);
25 25
 HIDUniversal hid(&usb);
26 26
 X52 x52(&usb, &hid);
27
-JoystickEvents joyevents;
27
+JoystickEventsDeadZone joyevents;
28 28
 JoystickReportParser joy(&joyevents);
29 29
 
30 30
 void setup() {

+ 4
- 4
hid_parser.cpp View File

@@ -1,10 +1,10 @@
1 1
 /*
2 2
  * Saitek X52 Arduino USB Host Shield Library.
3 3
  * Copyright 2016 by Thomas Buck <xythobuz@xythobuz.de>
4
- * 
4
+ *
5 5
  * Based on the USB Host Library HID Joystick example
6 6
  * https://www.circuitsathome.com/mcu/hid-joystick-code-sample
7
- * 
7
+ *
8 8
  * This program is free software; you can redistribute it and/or
9 9
  * modify it under the terms of the GNU General Public License as
10 10
  * published by the Free Software Foundation, version 2.
@@ -36,8 +36,8 @@ void JoystickReportParser::Parse(HID* hid, bool is_rpt_id, uint8_t len, uint8_t*
36 36
         }
37 37
     }
38 38
 
39
-    // Dump whole USB HID packet for debugging purposes
40 39
 #ifdef DEBUG_OUTPUT
40
+    // Dump whole USB HID packet for debugging purposes
41 41
     Serial.println("");
42 42
     Serial.print("Packet: ");
43 43
     for (uint8_t i = 0; i < (8 + len); i++) {
@@ -67,7 +67,7 @@ void JoystickReportParser::Parse(HID* hid, bool is_rpt_id, uint8_t len, uint8_t*
67 67
         buffer.Ry = buf[6];
68 68
         buffer.Slider = buf[7];
69 69
 
70
-        joyEvents->OnGamePadChanged((const GamePadEventData*)&buffer);
70
+        joyEvents->OnGamePadChanged(buffer);
71 71
 
72 72
         for (uint8_t i = 0; i < RPT_GEMEPAD_LEN; i++) {
73 73
             oldPad[i] = buf[i];

+ 7
- 8
hid_parser.h View File

@@ -1,10 +1,10 @@
1 1
 /*
2 2
  * Saitek X52 Arduino USB Host Shield Library.
3 3
  * Copyright 2016 by Thomas Buck <xythobuz@xythobuz.de>
4
- * 
4
+ *
5 5
  * Based on the USB Host Library HID Joystick example
6 6
  * https://www.circuitsathome.com/mcu/hid-joystick-code-sample
7
- * 
7
+ *
8 8
  * This program is free software; you can redistribute it and/or
9 9
  * modify it under the terms of the GNU General Public License as
10 10
  * published by the Free Software Foundation, version 2.
@@ -20,19 +20,18 @@
20 20
 #define BUFFER_SIZE 16
21 21
 
22 22
 class JoystickReportParser : public HIDReportParser {
23
-    JoystickEvents* joyEvents;
23
+  public:
24
+    JoystickReportParser(JoystickEvents* evt);
25
+    virtual void Parse(HID* hid, bool is_rpt_id, uint8_t len, uint8_t* bufPart);
24 26
 
27
+  private:
25 28
     uint8_t buf[BUFFER_SIZE];
26 29
     uint8_t oldPad[RPT_GEMEPAD_LEN];
27 30
     uint8_t oldHat;
28 31
     uint64_t oldButtons;
29 32
     uint8_t oldMouse;
30 33
     GamePadEventData buffer;
31
-
32
-  public:
33
-    JoystickReportParser(JoystickEvents* evt);
34
-
35
-    virtual void Parse(HID* hid, bool is_rpt_id, uint8_t len, uint8_t* bufPart);
34
+    JoystickEvents* joyEvents;
36 35
 };
37 36
 
38 37
 #endif // __HID_PARSER_H__

+ 109
- 68
joystick_events.cpp View File

@@ -1,10 +1,10 @@
1 1
 /*
2 2
  * Saitek X52 Arduino USB Host Shield Library.
3 3
  * Copyright 2016 by Thomas Buck <xythobuz@xythobuz.de>
4
- * 
4
+ *
5 5
  * Based on the USB Host Library HID Joystick example
6 6
  * https://www.circuitsathome.com/mcu/hid-joystick-code-sample
7
- * 
7
+ *
8 8
  * This program is free software; you can redistribute it and/or
9 9
  * modify it under the terms of the GNU General Public License as
10 10
  * published by the Free Software Foundation, version 2.
@@ -15,92 +15,109 @@
15 15
 //#define DEBUG_OUTPUT_RAW
16 16
 #define DEBUG_OUTPUT
17 17
 
18
+const GamePadEventData JoystickEventsDeadZone::deadZone(
19
+    0, 0, 0, 0, 0, 50, 0
20
+);
21
+const uint8_t JoystickEventsDeadZone::deadZoneMouseX = 0;
22
+const uint8_t JoystickEventsDeadZone::deadZoneMouseY = 0;
18 23
 
19
-/*
20
- * Uuuhhh TODO!!
21
- * This is not a deadzone, this is something like sensitivity.
22
- * For deadzone, we need to only apply it from the center outwards.
23
- */
24
+const GamePadEventData JoystickEventsDeadZone::centerValue(
25
+    0x3FF, 0x3FF, 0x7F,
26
+    0x7F, 0x7F, 0x1FF, 0x7F
27
+);
28
+const uint8_t JoystickEventsDeadZone::centerMouseX = 0x7F;
29
+const uint8_t JoystickEventsDeadZone::centerMouseY = 0x7F;
24 30
 
25
-
26
-JoystickEvents::JoystickEvents()
27
-        : lastData(0), lastMouseX(0), lastMouseY(0), deadZone(0) {
28
-    deadZone.X = 0;
29
-    deadZone.Y = 0;
30
-    deadZone.Z = 0;
31
-    deadZone.Rx = 0;
32
-    deadZone.Ry = 0;
33
-    deadZone.Rz = 50;
34
-    deadZoneMouseX = 0;
35
-    deadZoneMouseY = 0;
36
-}
37
-
38
-void JoystickEvents::OnGamePadChanged(const GamePadEventData *evt) {
31
+void JoystickEventsDeadZone::OnGamePadChanged(const GamePadEventData& evt) {
39 32
 #ifdef DEBUG_OUTPUT_RAW
40 33
     Serial.print("X: ");
41
-    PrintHex<uint16_t > (evt->X, 0x80);
34
+    PrintHex<uint16_t > (evt.X, 0x80);
42 35
     Serial.print(" Y: ");
43
-    PrintHex<uint16_t > (evt->Y, 0x80);
36
+    PrintHex<uint16_t > (evt.Y, 0x80);
44 37
     Serial.print(" Z: ");
45
-    PrintHex<uint8_t > (evt->Z, 0x80);
38
+    PrintHex<uint8_t > (evt.Z, 0x80);
46 39
     Serial.print(" Rx: ");
47
-    PrintHex<uint8_t > (evt->Rx, 0x80);
40
+    PrintHex<uint8_t > (evt.Rx, 0x80);
48 41
     Serial.print(" Ry: ");
49
-    PrintHex<uint8_t > (evt->Ry, 0x80);
42
+    PrintHex<uint8_t > (evt.Ry, 0x80);
50 43
     Serial.print(" Rz: ");
51
-    PrintHex<uint16_t > (evt->Rz, 0x80);
44
+    PrintHex<uint16_t > (evt.Rz, 0x80);
52 45
     Serial.print(" S: ");
53
-    PrintHex<uint8_t > (evt->Slider, 0x80);
46
+    PrintHex<uint8_t > (evt.Slider, 0x80);
54 47
     Serial.println("");
55 48
 #endif
56 49
 
57
-    GamePadEventData newData = lastData;
50
+    GamePadEventData newData = centerValue;
51
+
52
+#ifdef DEBUG_OUTPUT
58 53
     uint8_t updated = 0;
54
+#endif
55
+
56
+    if ((evt.X > (centerValue.X + deadZone.X))
57
+            || (evt.X < (centerValue.X - deadZone.X))) {
58
+        newData.X = evt.X;
59 59
 
60
-    if ((evt->X > (lastData.X + deadZone.X))
61
-            || (evt->X < (lastData.X - deadZone.X))) {
62
-        newData.X = evt->X;
60
+#ifdef DEBUG_OUTPUT
63 61
         updated = 1;
62
+#endif
64 63
     }
65 64
 
66
-    if ((evt->Y > (lastData.Y + deadZone.Y))
67
-            || (evt->Y < (lastData.Y - deadZone.Y))) {
68
-        newData.Y = evt->Y;
65
+    if ((evt.Y > (centerValue.Y + deadZone.Y))
66
+            || (evt.Y < (centerValue.Y - deadZone.Y))) {
67
+        newData.Y = evt.Y;
68
+
69
+#ifdef DEBUG_OUTPUT
69 70
         updated = 1;
71
+#endif
70 72
     }
71 73
 
72
-    if ((evt->Z > (lastData.Z + deadZone.Z))
73
-            || (evt->Z < (lastData.Z - deadZone.Z))) {
74
-        newData.Z = evt->Z;
74
+    if ((evt.Z > (centerValue.Z + deadZone.Z))
75
+            || (evt.Z < (centerValue.Z - deadZone.Z))) {
76
+        newData.Z = evt.Z;
77
+
78
+#ifdef DEBUG_OUTPUT
75 79
         updated = 1;
80
+#endif
76 81
     }
77 82
 
78
-    if ((evt->Rx > (lastData.Rx + deadZone.Rx))
79
-            || (evt->Rx < (lastData.Rx - deadZone.Rx))) {
80
-        newData.Rx = evt->Rx;
83
+    if ((evt.Rx > (centerValue.Rx + deadZone.Rx))
84
+            || (evt.Rx < (centerValue.Rx - deadZone.Rx))) {
85
+        newData.Rx = evt.Rx;
86
+
87
+#ifdef DEBUG_OUTPUT
81 88
         updated = 1;
89
+#endif
82 90
     }
83 91
 
84
-    if ((evt->Ry > (lastData.Ry + deadZone.Ry))
85
-            || (evt->Ry < (lastData.Ry - deadZone.Ry))) {
86
-        newData.Ry = evt->Ry;
92
+    if ((evt.Ry > (centerValue.Ry + deadZone.Ry))
93
+            || (evt.Ry < (centerValue.Ry - deadZone.Ry))) {
94
+        newData.Ry = evt.Ry;
95
+
96
+#ifdef DEBUG_OUTPUT
87 97
         updated = 1;
98
+#endif
88 99
     }
89 100
 
90
-    if ((evt->Rz > (lastData.Rz + deadZone.Rz))
91
-            || (evt->Rz < (lastData.Rz - deadZone.Rz))) {
92
-        newData.Rz = evt->Rz;
101
+    if ((evt.Rz > (centerValue.Rz + deadZone.Rz))
102
+            || (evt.Rz < (centerValue.Rz - deadZone.Rz))) {
103
+        newData.Rz = evt.Rz;
104
+
105
+#ifdef DEBUG_OUTPUT
93 106
         updated = 1;
107
+#endif
94 108
     }
95 109
 
96
-    if ((evt->Slider > (lastData.Slider + deadZone.Slider))
97
-            || (evt->Slider < (lastData.Slider - deadZone.Slider))) {
98
-        newData.Slider = evt->Slider;
110
+    if ((evt.Slider > (centerValue.Slider + deadZone.Slider))
111
+            || (evt.Slider < (centerValue.Slider - deadZone.Slider))) {
112
+        newData.Slider = evt.Slider;
113
+
114
+#ifdef DEBUG_OUTPUT
99 115
         updated = 1;
116
+#endif
100 117
     }
101 118
 
102
-    if (updated) {
103 119
 #ifdef DEBUG_OUTPUT
120
+    if (updated) {
104 121
         Serial.print("X: ");
105 122
         PrintHex<uint16_t > (newData.X, 0x80);
106 123
         Serial.print(" Y: ");
@@ -116,35 +133,49 @@ void JoystickEvents::OnGamePadChanged(const GamePadEventData *evt) {
116 133
         Serial.print(" S: ");
117 134
         PrintHex<uint8_t > (newData.Slider, 0x80);
118 135
         Serial.println("");
119
-#endif
120 136
     }
137
+#endif
121 138
 
122
-    lastData = *evt;
139
+    if (client) {
140
+        client->OnGamePadChanged(newData);
141
+    }
123 142
 }
124 143
 
125
-void JoystickEvents::OnHatSwitch(uint8_t hat) {
144
+void JoystickEventsDeadZone::OnHatSwitch(uint8_t hat) {
126 145
 #ifdef DEBUG_OUTPUT
127 146
     Serial.print("Hat Switch: ");
128 147
     PrintHex<uint8_t > (hat, 0x80);
129 148
     Serial.println("");
130 149
 #endif
150
+
151
+    if (client) {
152
+        client->OnHatSwitch(hat);
153
+    }
131 154
 }
132 155
 
133
-void JoystickEvents::OnButtonUp(uint8_t but_id) {
156
+void JoystickEventsDeadZone::OnButtonUp(uint8_t but_id) {
134 157
 #ifdef DEBUG_OUTPUT
135 158
     Serial.print("Up: ");
136 159
     Serial.println(but_id, DEC);
137 160
 #endif
161
+
162
+    if (client) {
163
+        client->OnButtonUp(but_id);
164
+    }
138 165
 }
139 166
 
140
-void JoystickEvents::OnButtonDn(uint8_t but_id) {
167
+void JoystickEventsDeadZone::OnButtonDn(uint8_t but_id) {
141 168
 #ifdef DEBUG_OUTPUT
142 169
     Serial.print("Down: ");
143 170
     Serial.println(but_id, DEC);
144 171
 #endif
172
+
173
+    if (client) {
174
+        client->OnButtonDn(but_id);
175
+    }
145 176
 }
146 177
 
147
-void JoystickEvents::OnMouseMoved(uint8_t x, uint8_t y) {
178
+void JoystickEventsDeadZone::OnMouseMoved(uint8_t x, uint8_t y) {
148 179
 #ifdef DEBUG_OUTPUT_RAW
149 180
     Serial.print("Mouse X: ");
150 181
     PrintHex<uint8_t >(x, 0x80);
@@ -153,33 +184,43 @@ void JoystickEvents::OnMouseMoved(uint8_t x, uint8_t y) {
153 184
     Serial.println("");
154 185
 #endif
155 186
 
156
-    uint8_t newX = lastMouseX;
157
-    uint8_t newY = lastMouseY;
187
+    uint8_t newX = centerMouseX;
188
+    uint8_t newY = centerMouseY;
189
+
190
+#ifdef DEBUG_OUTPUT
158 191
     uint8_t updated = 0;
159
-    
160
-    if ((x > (lastMouseX + deadZoneMouseX))
161
-            || (x < (lastMouseX - deadZoneMouseX))) {
192
+#endif
193
+
194
+    if ((x > (centerMouseX + deadZoneMouseX))
195
+            || (x < (centerMouseX - deadZoneMouseX))) {
162 196
         newX = x;
197
+
198
+#ifdef DEBUG_OUTPUT
163 199
         updated = 1;
200
+#endif
164 201
     }
165 202
 
166
-    if ((y > (lastMouseY + deadZoneMouseY))
167
-            || (y < (lastMouseY - deadZoneMouseY))) {
203
+    if ((y > (centerMouseY + deadZoneMouseY))
204
+            || (y < (centerMouseY - deadZoneMouseY))) {
168 205
         newY = y;
206
+
207
+#ifdef DEBUG_OUTPUT
169 208
         updated = 1;
209
+#endif
170 210
     }
171 211
 
172
-    if (updated) {
173 212
 #ifdef DEBUG_OUTPUT
213
+    if (updated) {
174 214
         Serial.print("Mouse X: ");
175 215
         PrintHex<uint8_t >(newX, 0x80);
176 216
         Serial.print("\tY: ");
177 217
         PrintHex<uint8_t >(newY, 0x80);
178 218
         Serial.println("");
179
-#endif
180 219
     }
220
+#endif
181 221
 
182
-    lastMouseX = x;
183
-    lastMouseY = y;
222
+    if (client) {
223
+        client->OnMouseMoved(x, y);
224
+    }
184 225
 }
185 226
 

+ 27
- 11
joystick_events.h View File

@@ -1,10 +1,10 @@
1 1
 /*
2 2
  * Saitek X52 Arduino USB Host Shield Library.
3 3
  * Copyright 2016 by Thomas Buck <xythobuz@xythobuz.de>
4
- * 
4
+ *
5 5
  * Based on the USB Host Library HID Joystick example
6 6
  * https://www.circuitsathome.com/mcu/hid-joystick-code-sample
7
- * 
7
+ *
8 8
  * This program is free software; you can redistribute it and/or
9 9
  * modify it under the terms of the GNU General Public License as
10 10
  * published by the Free Software Foundation, version 2.
@@ -13,28 +13,44 @@
13 13
 #ifndef __JOYSTICK_EVENTS_H__
14 14
 #define __JOYSTICK_EVENTS_H__
15 15
 
16
-struct GamePadEventData {
17
-    GamePadEventData(uint16_t v) : X(v), Y(v), Z(v), Rx(v), Ry(v), Rz(v) { }
18
-    
16
+class GamePadEventData {
17
+  public:
18
+    GamePadEventData(uint16_t v) : X(v), Y(v), Z(v), Rx(v), Ry(v), Rz(v), Slider(v) { }
19
+    GamePadEventData(uint16_t x, uint16_t y, uint8_t z, uint8_t rx, uint8_t ry,
20
+            uint16_t rz, uint8_t slider)
21
+            : X(x), Y(y), Z(z), Rx(rx), Ry(ry), Rz(rz), Slider(slider) { }
22
+
19 23
     uint16_t X, Y, Rz; // 11bit, 11bit, 10bit
20 24
     uint8_t Z, Rx, Ry, Slider;
21 25
 };
22 26
 
23 27
 class JoystickEvents {
24 28
   public:
25
-    JoystickEvents();
29
+    JoystickEvents(JoystickEvents* _client = NULL) : client(_client) { }
30
+    virtual void OnGamePadChanged(const GamePadEventData& evt) = 0;
31
+    virtual void OnHatSwitch(uint8_t hat) = 0;
32
+    virtual void OnButtonUp(uint8_t but_id) = 0;
33
+    virtual void OnButtonDn(uint8_t but_id) = 0;
34
+    virtual void OnMouseMoved(uint8_t x, uint8_t y) = 0;
26 35
 
27
-    virtual void OnGamePadChanged(const GamePadEventData *evt);
36
+  protected:
37
+    JoystickEvents* client;
38
+};
39
+
40
+class JoystickEventsDeadZone : public JoystickEvents {
41
+  public:
42
+    virtual void OnGamePadChanged(const GamePadEventData& evt);
28 43
     virtual void OnHatSwitch(uint8_t hat);
29 44
     virtual void OnButtonUp(uint8_t but_id);
30 45
     virtual void OnButtonDn(uint8_t but_id);
31 46
     virtual void OnMouseMoved(uint8_t x, uint8_t y);
32 47
 
33 48
   protected:
34
-    GamePadEventData lastData;
35
-    GamePadEventData deadZone;
36
-    uint8_t lastMouseX, lastMouseY;
37
-    uint8_t deadZoneMouseX, deadZoneMouseY;
49
+    const static GamePadEventData deadZone;
50
+    const static uint8_t deadZoneMouseX, deadZoneMouseY;
51
+
52
+    const static GamePadEventData centerValue;
53
+    const static uint8_t centerMouseX, centerMouseY;
38 54
 };
39 55
 
40 56
 #endif // __JOYSTICK_EVENTS_H__

+ 7
- 0
x52.cpp View File

@@ -140,6 +140,13 @@ void X52::setMFDText(uint8_t line, const char* text) {
140 140
 }
141 141
 
142 142
 uint8_t X52::sendCommand(uint16_t command, uint16_t val) {
143
+    if ((!usb) || (!hid)) {
144
+#ifdef DEBUG_OUTPUT
145
+        Serial.println("Invalid objects!");
146
+#endif
147
+        return 42;
148
+    }
149
+
143 150
     const uint8_t valLo = (val & 0x00FF);
144 151
     const uint8_t valHi = (val & 0xFF00) >> 8;
145 152
 

Loading…
Cancel
Save