Skip to content

Commit 0e160f2

Browse files
committed
implement Nordic led button service example
close #59
1 parent f4781e3 commit 0e160f2

File tree

1 file changed

+221
-0
lines changed

1 file changed

+221
-0
lines changed
Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
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 implement part of Nordic custom LED Button Service (LBS).
16+
* Install "nRF Blinky" app on your Android/iOS to control the on-board LED
17+
* - https://apps.apple.com/us/app/nrf-blinky/id1325014347
18+
* - https://play.google.com/store/apps/details?id=no.nordicsemi.android.nrfblinky
19+
*/
20+
21+
#include <bluefruit.h>
22+
23+
// max concurrent connections supported by this example
24+
#define MAX_PRPH_CONNECTION 2
25+
uint8_t connection_count = 0;
26+
27+
/* HRM Service Definitions
28+
* Heart Rate Monitor Service: 0x180D
29+
* Heart Rate Measurement Char: 0x2A37
30+
* Body Sensor Location Char: 0x2A38
31+
*/
32+
BLEService hrms = BLEService(UUID16_SVC_HEART_RATE);
33+
BLECharacteristic hrmc = BLECharacteristic(UUID16_CHR_HEART_RATE_MEASUREMENT);
34+
BLECharacteristic bslc = BLECharacteristic(UUID16_CHR_BODY_SENSOR_LOCATION);
35+
36+
/* LBS Service: 00001523-1212-EFDE-1523-785FEABCD123
37+
* LBS Button : 00001524-1212-EFDE-1523-785FEABCD123
38+
* LBS LED : 00001525-1212-EFDE-1523-785FEABCD123
39+
*/
40+
41+
const uint8_t LBS_UUID_SERVICE[] =
42+
{
43+
0x23, 0xD1, 0xBC, 0xEA, 0x5F, 0x78, 0x23, 0x15,
44+
0xDE, 0xEF, 0x12, 0x12, 0x23, 0x15, 0x00, 0x00
45+
};
46+
47+
const uint8_t LBS_UUID_CHR_BUTTON[] =
48+
{
49+
0x23, 0xD1, 0xBC, 0xEA, 0x5F, 0x78, 0x23, 0x15,
50+
0xDE, 0xEF, 0x12, 0x12, 0x24, 0x15, 0x00, 0x00
51+
};
52+
53+
const uint8_t LBS_UUID_CHR_LED[] =
54+
{
55+
0x23, 0xD1, 0xBC, 0xEA, 0x5F, 0x78, 0x23, 0x15,
56+
0xDE, 0xEF, 0x12, 0x12, 0x25, 0x15, 0x00, 0x00
57+
};
58+
59+
BLEService lbs(LBS_UUID_SERVICE);
60+
BLECharacteristic lsbButton(LBS_UUID_CHR_BUTTON);
61+
BLECharacteristic lsbLED(LBS_UUID_CHR_LED);
62+
63+
// Use on-board button if available, else use A0 pin
64+
#ifdef PIN_BUTTON1
65+
uint8_t button = PIN_BUTTON1;
66+
#else
67+
uint8_t button = A0;
68+
#endif
69+
70+
uint8_t buttonState;
71+
72+
void setup()
73+
{
74+
pinMode(LED_BUILTIN, OUTPUT);
75+
digitalWrite(LED_BUILTIN, 1-LED_STATE_ON); // led off
76+
77+
pinMode(button, INPUT_PULLUP);
78+
buttonState = (uint8_t) (1-digitalRead(button)); // button is active LOW
79+
80+
Serial.begin(115200);
81+
//while ( !Serial ) delay(10); // for nrf52840 with native usb
82+
83+
Serial.println("Bluefruit52 nRF Blinky Example");
84+
Serial.println("------------------------------\n");
85+
86+
// Initialize Bluefruit with max concurrent connections as Peripheral = MAX_PRPH_CONNECTION, Central = 0
87+
Serial.println("Initialise the Bluefruit nRF52 module");
88+
Bluefruit.begin(MAX_PRPH_CONNECTION, 0);
89+
Bluefruit.Periph.setConnectCallback(connect_callback);
90+
Bluefruit.Periph.setDisconnectCallback(disconnect_callback);
91+
92+
// Setup the LED-Button service using
93+
Serial.println("Configuring the LED-Button Service");
94+
95+
// Note: You must call .begin() on the BLEService before calling .begin() on
96+
// any characteristic(s) within that service definition.. Calling .begin() on
97+
// a BLECharacteristic will cause it to be added to the last BLEService that
98+
// was 'begin()'ed!
99+
lbs.begin();
100+
101+
// Configure Button characteristic
102+
// Properties = Read + Notify
103+
// Permission = Open to read, cannot write
104+
// Fixed Len = 1 (button state)
105+
lsbButton.setProperties(CHR_PROPS_READ | CHR_PROPS_NOTIFY);
106+
lsbButton.setPermission(SECMODE_OPEN, SECMODE_NO_ACCESS);
107+
lsbButton.setFixedLen(1);
108+
lsbButton.begin();
109+
lsbButton.write8(buttonState);
110+
111+
// Configure the LED characteristic
112+
// Properties = Read + Write
113+
// Permission = Open to read, Open to write
114+
// Fixed Len = 1 (LED state)
115+
lsbLED.setProperties(CHR_PROPS_READ | CHR_PROPS_WRITE);
116+
lsbLED.setPermission(SECMODE_OPEN, SECMODE_OPEN);
117+
lsbLED.setFixedLen(1);
118+
lsbLED.begin();
119+
lsbLED.write8(0x00); // led = off
120+
121+
lsbLED.setWriteCallback(led_write_callback);
122+
123+
// Setup the advertising packet(s)
124+
Serial.println("Setting up the advertising");
125+
startAdv();
126+
}
127+
128+
void startAdv(void)
129+
{
130+
// Advertising packet
131+
Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE);
132+
Bluefruit.Advertising.addTxPower();
133+
134+
// Include HRM Service UUID
135+
Bluefruit.Advertising.addService(lbs);
136+
137+
// Secondary Scan Response packet (optional)
138+
// Since there is no room for 'Name' in Advertising packet
139+
Bluefruit.ScanResponse.addName();
140+
141+
/* Start Advertising
142+
* - Enable auto advertising if disconnected
143+
* - Interval: fast mode = 20 ms, slow mode = 152.5 ms
144+
* - Timeout for fast mode is 30 seconds
145+
* - Start(timeout) with timeout = 0 will advertise forever (until connected)
146+
*
147+
* For recommended advertising interval
148+
* https://developer.apple.com/library/content/qa/qa1931/_index.html
149+
*/
150+
Bluefruit.Advertising.restartOnDisconnect(true);
151+
Bluefruit.Advertising.setInterval(32, 244); // in unit of 0.625 ms
152+
Bluefruit.Advertising.setFastTimeout(30); // number of seconds in fast mode
153+
Bluefruit.Advertising.start(0); // 0 = Don't stop advertising after n seconds
154+
}
155+
156+
void led_write_callback(uint16_t conn_hdl, BLECharacteristic* chr, uint8_t* data, uint16_t len)
157+
{
158+
(void) conn_hdl;
159+
(void) chr;
160+
(void) len; // len should be 1
161+
162+
// data = 1 -> LED = On
163+
// data = 0 -> LED = Off
164+
digitalWrite(LED_BUILTIN, data[0] ? LED_STATE_ON : (1-LED_STATE_ON));
165+
}
166+
167+
void loop()
168+
{
169+
delay(10); // poll button every 10 ms
170+
171+
uint8_t newState = (uint8_t) (1-digitalRead(button)); // button is active LOW
172+
173+
// only notify if button state chagnes
174+
if ( newState != buttonState)
175+
{
176+
buttonState = newState;
177+
lsbButton.write8(buttonState);
178+
179+
// notify all connected clients
180+
for (uint16_t conn_hdl=0; conn_hdl < MAX_PRPH_CONNECTION; conn_hdl++)
181+
{
182+
if ( Bluefruit.connected(conn_hdl) && lsbButton.notifyEnabled(conn_hdl) )
183+
{
184+
lsbButton.notify8(conn_hdl, buttonState);
185+
}
186+
}
187+
}
188+
}
189+
190+
// callback invoked when central connects
191+
void connect_callback(uint16_t conn_handle)
192+
{
193+
(void) conn_handle;
194+
195+
connection_count++;
196+
Serial.print("Connection count: ");
197+
Serial.println(connection_count);
198+
199+
// Keep advertising if not reaching max
200+
if (connection_count < MAX_PRPH_CONNECTION)
201+
{
202+
Serial.println("Keep advertising");
203+
Bluefruit.Advertising.start(0);
204+
}
205+
}
206+
207+
/**
208+
* Callback invoked when a connection is dropped
209+
* @param conn_handle connection where this event happens
210+
* @param reason is a BLE_HCI_STATUS_CODE which can be found in ble_hci.h
211+
*/
212+
void disconnect_callback(uint16_t conn_handle, uint8_t reason)
213+
{
214+
(void) conn_handle;
215+
(void) reason;
216+
217+
Serial.println();
218+
Serial.print("Disconnected, reason = 0x"); Serial.println(reason, HEX);
219+
220+
connection_count--;
221+
}

0 commit comments

Comments
 (0)