Skip to content

Commit b65e4a4

Browse files
authored
Merge pull request #688 from adafruit/ble-gamepad
Ble gamepad
2 parents 80297bb + eb3beca commit b65e4a4

File tree

10 files changed

+517
-25
lines changed

10 files changed

+517
-25
lines changed

libraries/Bluefruit52Lib/examples/Peripheral/hid_camerashutter/hid_camerashutter.ino renamed to libraries/Bluefruit52Lib/examples/Peripheral/blehid_camerashutter/blehid_camerashutter.ino

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,23 @@ BLEHidAdafruit blehid;
2929
uint8_t pinShutter = A0;
3030
#endif
3131

32+
// Circuit Play Bluefruit has button active state = high
33+
#ifdef ARDUINO_NRF52840_CIRCUITPLAY
34+
#define BTN_ACTIVE HIGH
35+
#else
36+
#define BTN_ACTIVE LOW
37+
#endif
38+
3239
void setup()
3340
{
3441
pinMode(pinShutter, INPUT_PULLUP);
3542

3643
Serial.begin(115200);
44+
45+
#if CFG_DEBUG
46+
// Blocking wait for connection when debug mode is enabled via IDE
3747
while ( !Serial ) delay(10); // for nrf52840 with native usb
48+
#endif
3849

3950
Serial.println("Bluefruit52 HID Camera Shutter Example");
4051
Serial.println("--------------------------------------\n");
@@ -106,7 +117,7 @@ void startAdv(void)
106117
void loop()
107118
{
108119
// Skip if shutter pin is not Ground
109-
if ( digitalRead(pinShutter) == 1 ) return;
120+
if ( digitalRead(pinShutter) != BTN_ACTIVE ) return;
110121

111122
// Make sure we are connected and bonded/paired
112123
for (uint16_t conn_hdl=0; conn_hdl < BLE_MAX_CONNECTION; conn_hdl++)
Lines changed: 278 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,278 @@
1+
/*********************************************************************
2+
This is an example for our nRF52 based Bluefruit LE modules
3+
4+
Pick one up today in the adafruit shop!
5+
6+
Adafruit invests time and resources providing this open source code,
7+
please support Adafruit and open-source hardware by purchasing
8+
products from Adafruit!
9+
10+
MIT license, check LICENSE for more information
11+
All text above, and the splash screen below must be included in
12+
any redistribution
13+
*********************************************************************/
14+
15+
/* This sketch demonstrate how to use BLEHidGamepad to send
16+
* button, dpad, and joystick report
17+
*/
18+
19+
#include <bluefruit.h>
20+
21+
BLEDis bledis;
22+
BLEHidGamepad blegamepad;
23+
24+
// defined in hid.h from Adafruit_TinyUSB_Arduino
25+
hid_gamepad_report_t gp;
26+
27+
void setup()
28+
{
29+
Serial.begin(115200);
30+
31+
#if CFG_DEBUG
32+
// Blocking wait for connection when debug mode is enabled via IDE
33+
while ( !Serial ) delay(10);
34+
#endif
35+
36+
Serial.println("Bluefruit52 HID Gamepad Example");
37+
Serial.println("-------------------------------\n");
38+
39+
Serial.println();
40+
Serial.println("Go to your phone's Bluetooth settings to pair your device");
41+
Serial.println("then open an application that accepts gamepad input");
42+
43+
Bluefruit.begin();
44+
Bluefruit.setTxPower(4); // Check bluefruit.h for supported values
45+
46+
// Configure and Start Device Information Service
47+
bledis.setManufacturer("Adafruit Industries");
48+
bledis.setModel("Bluefruit Feather 52");
49+
bledis.begin();
50+
51+
/* Start BLE HID
52+
* Note: Apple requires BLE device must have min connection interval >= 20m
53+
* ( The smaller the connection interval the faster we could send data).
54+
* However for HID and MIDI device, Apple could accept min connection interval
55+
* up to 11.25 ms. Therefore BLEHidAdafruit::begin() will try to set the min and max
56+
* connection interval to 11.25 ms and 15 ms respectively for best performance.
57+
*/
58+
blegamepad.begin();
59+
60+
/* Set connection interval (min, max) to your perferred value.
61+
* Note: It is already set by BLEHidAdafruit::begin() to 11.25ms - 15ms
62+
* min = 9*1.25=11.25 ms, max = 12*1.25= 15 ms
63+
*/
64+
/* Bluefruit.Periph.setConnInterval(9, 12); */
65+
66+
// Set up and start advertising
67+
startAdv();
68+
}
69+
70+
void startAdv(void)
71+
{
72+
// Advertising packet
73+
Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE);
74+
Bluefruit.Advertising.addTxPower();
75+
Bluefruit.Advertising.addAppearance(BLE_APPEARANCE_HID_GAMEPAD);
76+
77+
// Include BLE HID service
78+
Bluefruit.Advertising.addService(blegamepad);
79+
80+
// There is enough room for the dev name in the advertising packet
81+
Bluefruit.Advertising.addName();
82+
83+
/* Start Advertising
84+
* - Enable auto advertising if disconnected
85+
* - Interval: fast mode = 20 ms, slow mode = 152.5 ms
86+
* - Timeout for fast mode is 30 seconds
87+
* - Start(timeout) with timeout = 0 will advertise forever (until connected)
88+
*
89+
* For recommended advertising interval
90+
* https://developer.apple.com/library/content/qa/qa1931/_index.html
91+
*/
92+
Bluefruit.Advertising.restartOnDisconnect(true);
93+
Bluefruit.Advertising.setInterval(32, 244); // in unit of 0.625 ms
94+
Bluefruit.Advertising.setFastTimeout(30); // number of seconds in fast mode
95+
Bluefruit.Advertising.start(0); // 0 = Don't stop advertising after n seconds
96+
}
97+
98+
void loop()
99+
{
100+
// nothing to do if not connected or
101+
if ( !Bluefruit.connected() ) return;
102+
103+
Serial.println("No pressing buttons");
104+
gp.x = 0;
105+
gp.y = 0;
106+
gp.z = 0;
107+
gp.rz = 0;
108+
gp.rx = 0;
109+
gp.ry = 0;
110+
gp.hat = 0;
111+
gp.buttons = 0;
112+
blegamepad.report(&gp);
113+
delay(1000);
114+
115+
//------------- DPAD / HAT -------------//
116+
Serial.println("Hat/DPAD UP");
117+
gp.hat = GAMEPAD_HAT_UP;
118+
blegamepad.report(&gp);
119+
delay(1000);
120+
121+
Serial.println("Hat/DPAD UP RIGHT");
122+
gp.hat = GAMEPAD_HAT_UP_RIGHT;
123+
blegamepad.report(&gp);
124+
delay(1000);
125+
126+
Serial.println("Hat/DPAD RIGHT");
127+
gp.hat = GAMEPAD_HAT_RIGHT;
128+
blegamepad.report(&gp);
129+
delay(1000);
130+
131+
Serial.println("Hat/DPAD DOWN RIGHT");
132+
gp.hat = GAMEPAD_HAT_DOWN_RIGHT;
133+
blegamepad.report(&gp);
134+
delay(1000);
135+
136+
Serial.println("Hat/DPAD DOWN");
137+
gp.hat = GAMEPAD_HAT_DOWN;
138+
blegamepad.report(&gp);
139+
delay(1000);
140+
141+
Serial.println("Hat/DPAD DOWN LEFT");
142+
gp.hat = GAMEPAD_HAT_DOWN_LEFT;
143+
blegamepad.report(&gp);
144+
delay(1000);
145+
146+
Serial.println("Hat/DPAD LEFT");
147+
gp.hat = GAMEPAD_HAT_LEFT;
148+
blegamepad.report(&gp);
149+
delay(1000);
150+
151+
Serial.println("Hat/DPAD UP LEFT");
152+
gp.hat = GAMEPAD_HAT_UP_LEFT;
153+
blegamepad.report(&gp);
154+
delay(1000);
155+
156+
Serial.println("Hat/DPAD CENTER");
157+
gp.hat = GAMEPAD_HAT_CENTERED;
158+
blegamepad.report(&gp);
159+
delay(1000);
160+
161+
//------------- Joystick 1 -------------//
162+
163+
Serial.println("Joystick 1 UP");
164+
gp.x = 0;
165+
gp.y = -127;
166+
blegamepad.report(&gp);
167+
delay(1000);
168+
169+
Serial.println("Joystick 1 DOWN");
170+
gp.x = 0;
171+
gp.y = 127;
172+
blegamepad.report(&gp);
173+
delay(1000);
174+
175+
Serial.println("Joystick 1 RIGHT");
176+
gp.x = 127;
177+
gp.y = 0;
178+
blegamepad.report(&gp);
179+
delay(1000);
180+
181+
Serial.println("Joystick 1 LEFT");
182+
gp.x = -127;
183+
gp.y = 0;
184+
blegamepad.report(&gp);
185+
delay(1000);
186+
187+
Serial.println("Joystick 1 CENTER");
188+
gp.x = 0;
189+
gp.y = 0;
190+
blegamepad.report(&gp);
191+
delay(1000);
192+
193+
194+
//------------- Joystick 2 -------------//
195+
Serial.println("Joystick 2 UP");
196+
gp.z = 0;
197+
gp.rz = 127;
198+
blegamepad.report(&gp);
199+
delay(1000);
200+
201+
Serial.println("Joystick 2 DOWN");
202+
gp.z = 0;
203+
gp.rz = -127;
204+
blegamepad.report(&gp);
205+
delay(1000);
206+
207+
Serial.println("Joystick 2 RIGHT");
208+
gp.z = 127;
209+
gp.rz = 0;
210+
blegamepad.report(&gp);
211+
delay(1000);
212+
213+
Serial.println("Joystick 2 LEFT");
214+
gp.z = -127;
215+
gp.rz = 0;
216+
blegamepad.report(&gp);
217+
delay(1000);
218+
219+
Serial.println("Joystick 2 CENTER");
220+
gp.z = 0;
221+
gp.rz = 0;
222+
blegamepad.report(&gp);
223+
delay(1000);
224+
225+
//------------- Analog Trigger 1 -------------//
226+
Serial.println("Analog Trigger 1 UP");
227+
gp.rx = 127;
228+
blegamepad.report(&gp);
229+
delay(1000);
230+
231+
Serial.println("Analog Trigger 1 DOWN");
232+
gp.rx = -127;
233+
blegamepad.report(&gp);
234+
delay(1000);
235+
236+
Serial.println("Analog Trigger 1 CENTER");
237+
gp.rx = 0;
238+
blegamepad.report(&gp);
239+
delay(1000);
240+
241+
//------------- Analog Trigger 2 -------------//
242+
Serial.println("Analog Trigger 2 UP");
243+
gp.ry = 127;
244+
blegamepad.report(&gp);
245+
delay(1000);
246+
247+
Serial.println("Analog Trigger 2 DOWN");
248+
gp.ry = -127;
249+
blegamepad.report(&gp);
250+
delay(1000);
251+
252+
Serial.println("Analog Trigger 2 CENTER");
253+
gp.ry = 0;
254+
blegamepad.report(&gp);
255+
delay(1000);
256+
257+
//------------- Buttons -------------//
258+
for (int i=0; i<16; ++i)
259+
{
260+
Serial.print("Pressing button "); Serial.println(i);
261+
gp.buttons = (1ul << i);
262+
blegamepad.report(&gp);
263+
delay(1000);
264+
}
265+
266+
// Random touch
267+
Serial.println("Random touch");
268+
gp.x = random(-127, 128);
269+
gp.y = random(-127, 128);
270+
gp.z = random(-127, 128);
271+
gp.rz = random(-127, 128);
272+
gp.rx = random(-127, 128);
273+
gp.ry = random(-127, 128);
274+
gp.hat = random(0, 9);
275+
gp.buttons = random(0, 0xffff);
276+
blegamepad.report(&gp);
277+
delay(1000);
278+
}

libraries/Bluefruit52Lib/examples/Peripheral/hid_keyscan/hid_keyscan.ino renamed to libraries/Bluefruit52Lib/examples/Peripheral/blehid_keyscan/blehid_keyscan.ino

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -22,23 +22,43 @@
2222
BLEDis bledis;
2323
BLEHidAdafruit blehid;
2424

25+
// use on-board button if available
26+
#ifdef PIN_BUTTON1
27+
#define BTN1 PIN_BUTTON1
28+
#else
29+
#define BTN1 A0
30+
#endif
31+
32+
#ifdef PIN_BUTTON2
33+
#define BTN2 PIN_BUTTON2
34+
#else
35+
#define BTN2 A1
36+
#endif
37+
38+
// Circuit Play Bluefruit has button active state = high
39+
#ifdef ARDUINO_NRF52840_CIRCUITPLAY
40+
#define BTN_ACTIVE HIGH
41+
#else
42+
#define BTN_ACTIVE LOW
43+
#endif
44+
2545
// Array of pins and its keycode
26-
// For keycode definition see BLEHidGeneric.h
27-
uint8_t pins[] = { A0, A1, A2, A3, A4, A5 };
28-
uint8_t hidcode[] = { HID_KEY_A, HID_KEY_B, HID_KEY_C ,HID_KEY_D, HID_KEY_E, HID_KEY_F };
46+
// For keycode definition: https://github.com/hathach/tinyusb/blob/master/src/class/hid/hid.h
47+
uint8_t pins[] = { BTN1, BTN2 };
48+
uint8_t hidcode[] = { HID_KEY_KEYPAD_0, HID_KEY_KEYPAD_1 };
2949

3050
uint8_t pincount = sizeof(pins)/sizeof(pins[0]);
3151

32-
// Modifier keys, only take cares of Shift
33-
// ATL, CTRL, CMD keys are left for user excersie.
34-
uint8_t shiftPin = 11;
35-
3652
bool keyPressedPreviously = false;
3753

3854
void setup()
3955
{
4056
Serial.begin(115200);
41-
while ( !Serial ) delay(10); // for nrf52840 with native usb
57+
58+
#if CFG_DEBUG
59+
// Blocking wait for connection when debug mode is enabled via IDE
60+
while ( !Serial ) delay(10);
61+
#endif
4262

4363
Serial.println("Bluefruit52 HID Keyscan Example");
4464
Serial.println("-------------------------------\n");
@@ -66,9 +86,6 @@ void setup()
6686
pinMode(pins[i], INPUT_PULLUP);
6787
}
6888

69-
// set up modifier key
70-
pinMode(shiftPin, INPUT_PULLUP);
71-
7289
/* Start BLE HID
7390
* Note: Apple requires BLE device must have min connection interval >= 20m
7491
* ( The smaller the connection interval the faster we could send data).
@@ -128,16 +145,10 @@ void loop()
128145
uint8_t count=0;
129146
uint8_t keycode[6] = { 0 };
130147

131-
// scan modifier key (only SHIFT), user implement ATL, CTRL, CMD if needed
132-
if ( 0 == digitalRead(shiftPin) )
133-
{
134-
modifier |= KEYBOARD_MODIFIER_LEFTSHIFT;
135-
}
136-
137148
// scan normal key and send report
138149
for(uint8_t i=0; i < pincount; i++)
139150
{
140-
if ( 0 == digitalRead(pins[i]) )
151+
if ( BTN_ACTIVE == digitalRead(pins[i]) )
141152
{
142153
// if pin is active (low), add its hid code to key report
143154
keycode[count++] = hidcode[i];

libraries/Bluefruit52Lib/src/bluefruit.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
#include "services/BLEBeacon.h"
6666
#include "services/BLEHidGeneric.h"
6767
#include "services/BLEHidAdafruit.h"
68+
#include "services/BLEHidGamepad.h"
6869
#include "services/BLEMidi.h"
6970
#include "services/EddyStone.h"
7071

0 commit comments

Comments
 (0)