Skip to content

Commit 4a5b114

Browse files
committed
add hid_keyscan
1 parent 34d68dd commit 4a5b114

File tree

1 file changed

+170
-0
lines changed

1 file changed

+170
-0
lines changed
Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
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 demonstate how to use BLE HID to scan an array of pin
16+
* and send its keycode. It is essentially an implementation of hid keyboard,
17+
* useful reference if you want to make an BLE keyboard.
18+
*/
19+
20+
#include <bluefruit.h>
21+
22+
BLEHidAdafruit blehid;
23+
24+
// Array of pins and its keycode
25+
// For keycode definition see BLEHidGeneric.h
26+
uint8_t pins[] = { A0, A1, A2, A3, A4, A5 };
27+
uint8_t hidcode[] = { HID_KEY_A, HID_KEY_B, HID_KEY_C ,HID_KEY_D, HID_KEY_E, HID_KEY_F };
28+
29+
uint8_t pincount = sizeof(pins)/sizeof(pins[0]);
30+
31+
// Modifier keys, only take cares of Shift
32+
// ATL, CTRL, CMD keys are left for user excersie.
33+
uint8_t shiftPin = 11;
34+
35+
bool keyPressedPreviously = false;
36+
37+
void setup()
38+
{
39+
Serial.begin(115200);
40+
41+
Serial.println("Bluefruit52 HID Keyscan Example");
42+
Serial.println("-------------------------------\n");
43+
44+
Serial.println();
45+
Serial.println("Go to your phone's Bluetooth settings to pair your device");
46+
Serial.println("then open an application that accepts keyboard input");
47+
48+
Serial.println();
49+
Serial.println("Wire configured Pin to GND to send key");
50+
Serial.println("Wire Shift Keky to GND if you want to send it in upper case");
51+
Serial.println();
52+
53+
Bluefruit.begin();
54+
// Set max power. Accepted values are: -40, -30, -20, -16, -12, -8, -4, 0, 4
55+
Bluefruit.setTxPower(4);
56+
Bluefruit.setName("Bluefruit52");
57+
58+
// set up pin as input
59+
for (uint8_t i=0; i<pincount; i++)
60+
{
61+
pinMode(pins[i], INPUT_PULLUP);
62+
}
63+
64+
// set up modifier key
65+
pinMode(shiftPin, INPUT_PULLUP);
66+
67+
/* Start BLE HID
68+
* Note: Apple requires BLE device must have min connection interval >= 20m
69+
* ( The smaller the connection interval the faster we could send data).
70+
* However for HID and MIDI device, Apple could accept min connection interval
71+
* up to 11.25 ms. Therefore BLEHidAdafruit::begin() will try to set the min and max
72+
* connection interval to 11.25 ms and 15 ms respectively for best performance.
73+
*/
74+
blehid.begin();
75+
76+
/* Set connection interval (min, max) to your perferred value.
77+
* Note: It is already set by BLEHidAdafruit::begin() to 11.25ms - 15ms
78+
* min = 9*1.25=11.25 ms, max = 12*1.25= 15 ms
79+
*/
80+
/* Bluefruit.setConnInterval(9, 12); */
81+
82+
// Set up and start advertising
83+
startAdv();
84+
}
85+
86+
void startAdv(void)
87+
{
88+
// Advertising packet
89+
Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE);
90+
Bluefruit.Advertising.addTxPower();
91+
Bluefruit.Advertising.addAppearance(BLE_APPEARANCE_HID_KEYBOARD);
92+
93+
// Include BLE HID service
94+
Bluefruit.Advertising.addService(blehid);
95+
96+
// There is enough room for the dev name in the advertising packet
97+
Bluefruit.Advertising.addName();
98+
99+
/* Start Advertising
100+
* - Enable auto advertising if disconnected
101+
* - Interval: fast mode = 20 ms, slow mode = 152.5 ms
102+
* - Timeout for fast mode is 30 seconds
103+
* - Start(timeout) with timeout = 0 will advertise forever (until connected)
104+
*
105+
* For recommended advertising interval
106+
* https://developer.apple.com/library/content/qa/qa1931/_index.html
107+
*/
108+
Bluefruit.Advertising.restartOnDisconnect(true);
109+
Bluefruit.Advertising.setInterval(32, 244); // in unit of 0.625 ms
110+
Bluefruit.Advertising.setFastTimeout(30); // number of seconds in fast mode
111+
Bluefruit.Advertising.start(0); // 0 = Don't stop advertising after n seconds
112+
}
113+
114+
void loop()
115+
{
116+
/*-------------- San Pin Array and send report ---------------------*/
117+
bool anyKeyPressed = false;
118+
119+
uint8_t modifier = 0;
120+
uint8_t count=0;
121+
uint8_t keycode[6] = { 0 };
122+
123+
// scan mofidier key (only SHIFT), user implement ATL, CTRL, CMD if needed
124+
if ( 0 == digitalRead(shiftPin) )
125+
{
126+
modifier |= KEYBOARD_MODIFIER_LEFTSHIFT;
127+
}
128+
129+
// scan normal key and send report
130+
for(uint8_t i=0; i < pincount; i++)
131+
{
132+
if ( 0 == digitalRead(pins[i]) )
133+
{
134+
// if pin is active (low), add its hid code to key report
135+
keycode[count++] = hidcode[i];
136+
137+
// 6 is max keycode per report
138+
if ( count == 6)
139+
{
140+
blehid.keyboardReport(modifier, keycode);
141+
142+
// reset report
143+
count = 0;
144+
memset(keycode, 0, 6);
145+
}
146+
147+
// used later
148+
anyKeyPressed = true;
149+
keyPressedPreviously = true;
150+
}
151+
}
152+
153+
// Send any remaining keys (not accumulated up to 6)
154+
if ( count )
155+
{
156+
blehid.keyboardReport(modifier, keycode);
157+
}
158+
159+
// Send All-zero report to indicate there is no keys pressed
160+
// Most of the time, it is, though we don't need to send zero report
161+
// every loop(), only a key is pressed in previous loop()
162+
if ( !anyKeyPressed && keyPressedPreviously )
163+
{
164+
keyPressedPreviously = false;
165+
blehid.keyRelease();
166+
}
167+
168+
// Poll interval
169+
delay(10);
170+
}

0 commit comments

Comments
 (0)