Skip to content

Commit 4606f10

Browse files
authored
Merge pull request #8 from dmadison/development
Examples, Boards, and Volatility
2 parents 1b61dad + e099488 commit 4606f10

File tree

5 files changed

+258
-112
lines changed

5 files changed

+258
-112
lines changed

examples/BasicGamepad/BasicGamepad.ino

Lines changed: 0 additions & 77 deletions
This file was deleted.

examples/GamepadPins/GamepadPins.ino

Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
/*
2+
* Project Arduino XInput Library
3+
* @author David Madison
4+
* @link github.com/dmadison/ArduinoXInput
5+
* @license MIT - Copyright (c) 2019 David Madison
6+
*
7+
* Permission is hereby granted, free of charge, to any person obtaining a copy
8+
* of this software and associated documentation files (the "Software"), to deal
9+
* in the Software without restriction, including without limitation the rights
10+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
* copies of the Software, and to permit persons to whom the Software is
12+
* furnished to do so, subject to the following conditions:
13+
*
14+
* The above copyright notice and this permission notice shall be included in
15+
* all copies or substantial portions of the Software.
16+
*
17+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23+
* THE SOFTWARE.
24+
*
25+
* Example: GamepadPins
26+
* Description: Uses all of the available pin inputs to build a 'complete'
27+
* Xbox gamepad, with both analog joysticks, both triggers,
28+
* and all of the main buttons.
29+
*
30+
* * Joysticks should be your typical 10k dual potentiometers.
31+
* * Triggers can be either analog (pots) or digital (buttons).
32+
* Set the 'TriggerButtons' variable to change between the two.
33+
* * Buttons use the internal pull-ups and should be connected
34+
* directly to ground.
35+
*
36+
* These pins are designed around the Leonardo's layout. You
37+
* may need to change the pin numbers if you're using a
38+
* different board type
39+
*
40+
*/
41+
42+
#include <XInput.h>
43+
44+
// Setup
45+
const boolean UseLeftJoystick = true; // set to false to disable left joystick
46+
const boolean InvertLeftYAxis = false; // set to true to use inverted left joy Y
47+
48+
const boolean UseRightJoystick = true; // set to false to disable right joystick
49+
const boolean InvertRightYAxis = false; // set to true to use inverted right joy Y
50+
51+
const boolean UseTriggerButtons = true; // set to false if using analog triggers
52+
53+
const int ADC_Max = 1023; // 10 bit
54+
55+
// Joystick Pins
56+
const int Pin_LeftJoyX = A0;
57+
const int Pin_LeftJoyY = A1;
58+
const int Pin_RightJoyX = A2;
59+
const int Pin_RightJoyY = A3;
60+
61+
// Trigger Pins
62+
const int Pin_TriggerL = A4;
63+
const int Pin_TriggerR = A5;
64+
65+
// Button Pins
66+
const int Pin_ButtonA = 0;
67+
const int Pin_ButtonB = 1;
68+
const int Pin_ButtonX = 2;
69+
const int Pin_ButtonY = 3;
70+
71+
const int Pin_ButtonLB = 4;
72+
const int Pin_ButtonRB = 5;
73+
74+
const int Pin_ButtonBack = 6;
75+
const int Pin_ButtonStart = 7;
76+
77+
const int Pin_ButtonL3 = 8;
78+
const int Pin_ButtonR3 = 9;
79+
80+
// Directional Pad Pins
81+
const int Pin_DpadUp = 10;
82+
const int Pin_DpadDown = 11;
83+
const int Pin_DpadLeft = 12;
84+
const int Pin_DpadRight = 13;
85+
86+
void setup() {
87+
// If using buttons for the triggers, use internal pull-up resistors
88+
if (UseTriggerButtons == true) {
89+
pinMode(Pin_TriggerL, INPUT_PULLUP);
90+
pinMode(Pin_TriggerR, INPUT_PULLUP);
91+
}
92+
// If using potentiometers for the triggers, set range
93+
else {
94+
XInput.setTriggerRange(0, ADC_Max);
95+
}
96+
97+
// Set buttons as inputs, using internal pull-up resistors
98+
pinMode(Pin_ButtonA, INPUT_PULLUP);
99+
pinMode(Pin_ButtonB, INPUT_PULLUP);
100+
pinMode(Pin_ButtonX, INPUT_PULLUP);
101+
pinMode(Pin_ButtonY, INPUT_PULLUP);
102+
103+
pinMode(Pin_ButtonLB, INPUT_PULLUP);
104+
pinMode(Pin_ButtonRB, INPUT_PULLUP);
105+
106+
pinMode(Pin_ButtonBack, INPUT_PULLUP);
107+
pinMode(Pin_ButtonStart, INPUT_PULLUP);
108+
109+
pinMode(Pin_ButtonL3, INPUT_PULLUP);
110+
pinMode(Pin_ButtonR3, INPUT_PULLUP);
111+
112+
pinMode(Pin_DpadUp, INPUT_PULLUP);
113+
pinMode(Pin_DpadDown, INPUT_PULLUP);
114+
pinMode(Pin_DpadLeft, INPUT_PULLUP);
115+
pinMode(Pin_DpadRight, INPUT_PULLUP);
116+
117+
// Set joystick range to the ADC max
118+
XInput.setJoystickRange(0, ADC_Max);
119+
}
120+
121+
void loop() {
122+
// Read pin values and store in variables
123+
// (Note the "!" to invert the state, because LOW = pressed)
124+
boolean buttonA = !digitalRead(Pin_ButtonA);
125+
boolean buttonB = !digitalRead(Pin_ButtonB);
126+
boolean buttonX = !digitalRead(Pin_ButtonX);
127+
boolean buttonY = !digitalRead(Pin_ButtonY);
128+
129+
boolean buttonLB = !digitalRead(Pin_ButtonLB);
130+
boolean buttonRB = !digitalRead(Pin_ButtonRB);
131+
132+
boolean buttonBack = !digitalRead(Pin_ButtonBack);
133+
boolean buttonStart = !digitalRead(Pin_ButtonStart);
134+
135+
boolean buttonL3 = !digitalRead(Pin_ButtonL3);
136+
boolean buttonR3 = !digitalRead(Pin_ButtonR3);
137+
138+
boolean dpadUp = !digitalRead(Pin_DpadUp);
139+
boolean dpadDown = !digitalRead(Pin_DpadDown);
140+
boolean dpadLeft = !digitalRead(Pin_DpadLeft);
141+
boolean dpadRight = !digitalRead(Pin_DpadRight);
142+
143+
// Set XInput buttons
144+
XInput.setButton(BUTTON_A, buttonA);
145+
XInput.setButton(BUTTON_B, buttonB);
146+
XInput.setButton(BUTTON_X, buttonX);
147+
XInput.setButton(BUTTON_Y, buttonY);
148+
149+
XInput.setButton(BUTTON_LB, buttonLB);
150+
XInput.setButton(BUTTON_RB, buttonRB);
151+
152+
XInput.setButton(BUTTON_BACK, buttonBack);
153+
XInput.setButton(BUTTON_START, buttonStart);
154+
155+
XInput.setButton(BUTTON_L3, buttonL3);
156+
XInput.setButton(BUTTON_R3, buttonR3);
157+
158+
// Set XInput DPAD values
159+
XInput.setDpad(dpadUp, dpadDown, dpadLeft, dpadRight);
160+
161+
// Set XInput trigger values
162+
if (UseTriggerButtons == true) {
163+
// Read trigger buttons
164+
boolean triggerLeft = !digitalRead(Pin_TriggerL);
165+
boolean triggerRight = !digitalRead(Pin_TriggerR);
166+
167+
// Set the triggers as if they were buttons
168+
XInput.setButton(TRIGGER_LEFT, triggerLeft);
169+
XInput.setButton(TRIGGER_RIGHT, triggerRight);
170+
}
171+
else {
172+
// Read trigger potentiometer values
173+
int triggerLeft = analogRead(Pin_TriggerL);
174+
int triggerRight = analogRead(Pin_TriggerR);
175+
176+
// Set the trigger values as analog
177+
XInput.setTrigger(TRIGGER_LEFT, triggerLeft);
178+
XInput.setTrigger(TRIGGER_RIGHT, triggerRight);
179+
}
180+
181+
// Set left joystick
182+
if (UseLeftJoystick == true) {
183+
int leftJoyX = analogRead(Pin_LeftJoyX);
184+
int leftJoyY = analogRead(Pin_LeftJoyY);
185+
186+
// White lie here... most generic joysticks are typically
187+
// inverted by default. If the "Invert" variable is false
188+
// then we need to do this transformation.
189+
if (InvertLeftYAxis == false) {
190+
leftJoyY = ADC_Max - leftJoyY;
191+
}
192+
193+
XInput.setJoystick(JOY_LEFT, leftJoyX, leftJoyY);
194+
}
195+
196+
// Set right joystick
197+
if (UseRightJoystick == true) {
198+
int rightJoyX = analogRead(Pin_RightJoyX);
199+
int rightJoyY = analogRead(Pin_RightJoyY);
200+
201+
if (InvertRightYAxis == false) {
202+
rightJoyY = ADC_Max - rightJoyY;
203+
}
204+
205+
XInput.setJoystick(JOY_RIGHT, rightJoyX, rightJoyY);
206+
}
207+
208+
// Send control data to the computer
209+
XInput.send();
210+
}

examples/TestAll/TestAll.ino renamed to examples/SimulateAll/SimulateAll.ino

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@
2222
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2323
* THE SOFTWARE.
2424
*
25-
* Example: TestAll
25+
* Example: SimulateAll
2626
* Description: Automatically activate all possible XInput controls.
2727
* Useful to test that everything is functioning properly.
2828
*
29-
* WARNING: This will spam inputs! Ground pin '0' to stop.
29+
* WARNING: This will spam inputs! Ground pin '0' (RX) to stop.
3030
*
3131
*/
3232

@@ -108,7 +108,7 @@ void loop() {
108108
// Triggers
109109
if (t - triggerTimeLast >= TriggerDuration) { // If enough time has passed, update the triggers
110110
XInput.setTrigger(TRIGGER_LEFT, triggerVal);
111-
XInput.setTrigger(TRIGGER_RIGHT, ~triggerVal); // Inverse
111+
XInput.setTrigger(TRIGGER_RIGHT, TriggerMax - triggerVal); // Inverse
112112

113113
// Increment trigger value based on direction
114114
if (triggerDirection == 0) { triggerVal++; }

src/XInput.cpp

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,21 +26,33 @@
2626

2727
#include "XInput.h"
2828

29-
#ifndef USB_XINPUT
30-
#warning "USB type is not set to XInput in boards menu! Board will not behave as an XInput device"
31-
#endif
32-
33-
// Teensy 3.1-3.2: __MK20DX256__
34-
// Teensy LC: __MKL26Z64__
35-
// Teensy 3.5: __MK64FX512__
36-
// Teensy 3.6: __MK66FX1M0__
37-
38-
#if defined(TEENSYDUINO) && \
39-
(defined(__MK20DX256__) || defined(__MKL26Z64__) || \
40-
defined(__MK64FX512__) || defined(__MK66FX1M0__))
29+
// AVR Board with USB support
30+
#if defined(USBCON)
31+
#ifndef USB_XINPUT
32+
#warning "Non-XInput version selected in boards menu! Using debug print - board will not behave as an XInput device"
33+
#endif
34+
35+
// Teensy 3 Boards
36+
#elif defined(TEENSYDUINO)
37+
// Teensy 3.1-3.2: __MK20DX256__
38+
// Teensy LC: __MKL26Z64__
39+
// Teensy 3.5: __MK64FX512__
40+
// Teensy 3.6: __MK66FX1M0__
41+
#if !defined(__MK20DX256__) && !defined(__MKL26Z64__) && \
42+
!defined(__MK64FX512__) && !defined(__MK66FX1M0__)
43+
#warning "Not a supported board! Must use Teensy 3.1/3.2, LC, 3.5, or 3.6"
44+
#elif !defined(USB_XINPUT)
45+
#warning "USB type is not set to XInput in boards menu! Using debug print - board will not behave as an XInput device"
46+
#endif /* if supported Teensy board */
47+
48+
// Everything else
4149
#else
42-
#warning "Not a supported board! Must use Teensy 3.1/3.2, LC, 3.5, or 3.6"
43-
#endif
50+
#ifdef USB_XINPUT
51+
#warning "Unknown board. XInput may not work properly."
52+
#else
53+
#error "This board does not support XInput!"
54+
#endif
55+
#endif /* if supported board */
4456

4557
// --------------------------------------------------------
4658
// XInput Button Maps |
@@ -332,7 +344,6 @@ int XInputGamepad::send() {
332344
newData = false;
333345
return XInputUSB::send(tx, sizeof(tx));
334346
#else
335-
#warning "Using debug output for XInput send()"
336347
printDebug();
337348
return sizeof(tx);
338349
#endif
@@ -449,7 +460,7 @@ void XInputGamepad::reset() {
449460

450461
// Reset received data (rx)
451462
player = 0; // Not connected, no player
452-
memset(rumble, 0x00, sizeof(rumble)); // Clear rumble values
463+
memset((void*) rumble, 0x00, sizeof(rumble)); // Clear rumble values
453464
ledPattern = XInputLEDPattern::Off; // No LEDs on
454465

455466
// Reset rescale ranges

0 commit comments

Comments
 (0)