Bluefruit nRF52 Feather Learning Guide Created by Kevin Townsend Last updated on 2018-12-14 04:38:51 AM UTC
Guide Contents Guide Contents Introduction nRF52832 Technical Details nRF51 or nRF52 Bluefruit Devices? Device Pinout Special Notes Power Pins Analog Inputs PWM Outputs I2C Pins Assembly Header Options! Soldering in Plain Headers Prepare the header strip: Add the breakout board: And Solder! 2 7 7 8 9 10 11 11 11 11 12 12 15 15 16 16 Soldering on Female Header 18 Tape In Place Flip & Tack Solder And Solder! 18 19 20 Arduino BSP Setup 1.
Advanced: Upgrading an Existing Bootloader Flashing the Bootloader 1. Updating the Bootloader with the DFU Bootloader 2. Updating the Bootloader with a Segger J-Link and Arduino IDE JLink Drivers and Tools Burning the Bootloader from the Arduino IDE 3. Manually Burning the Bootloader via nrfjprog 4.
AdafruitBluefruit API Examples BLEGap BLEAdvertising API Related Information Example BLEScanner API 92 92 93 94 95 95 97 97 99 99 setRxCallback(rx_callback_t fp) void useActiveScan(bool enable); void filterRssi(int8_t min_rssi); void filterMSD(uint16_t manuf_id); void filterUuid(BLEUuid ble_uuid); void filterUuid(BLEUuid ble_uuid1, BLEUuid ble_uuid2); void filterUuid(BLEUuid ble_uuid1, BLEUuid ble_uuid2, BLEUuid ble_uuid3); void filterUuid(BLEUuid ble_uuid1, BLEUuid ble_uuid2, BLEUuid ble_uuid3, BLEUuid b
Output BLEUart API Example BLEClientUart API Examples BLEBeacon API Example Testing BLEMidi 126 127 127 127 130 130 130 134 134 134 136 137 API Installing the Arduino MIDI Library Example Usage BLEHidAdafruit API Example Sketches Bonding HID Devices 137 137 138 141 142 142 142 143 Setting up your Bluefruit device for bonding Bonding on iOS Testing the HID Keyboard and Bonding BLEAncs API ANCS OLED Example 143 144 145 146 146 146 Sketch Requirements Loading the Sketch Pairing to your Mobile Device
BSP release & Bootloader version Flash Memory SRAM Layout 159 159 160 Functions affecting SoftDevice SRAM usage 161 Software Resources Bluefruit LE Client Apps and Libraries 163 163 Bluefruit LE Connect (https://adafru.it/f4G) (Android/Java) Bluefruit LE Connect (https://adafru.it/f4H) (iOS/Swift) 163 163 Bluefruit LE Connect for OS X (https://adafru.it/o9F) (Swift) Bluefruit LE Command Line Updater for OS X (https://adafru.it/pLF) (Swift) 164 164 Deprecated: Bluefruit Buddy (https://adafru.
Introduction The Adafruit Feather nRF52 Bluefruit is our latest easy-to-use all-in-one Bluetooth Low Energy board, with a nativebluetooth chip, the nRF52832! It's our take on an 'all-in-one' Arduino-compatible + Bluetooth Low Energy with built in USB and battery charging. This chip has twice the flash, SRAM and performance of the earlier nRF51-based Bluefruit modules. Best of all it has Arduino IDE support so there is no 'helper' chip like the ATmega32u4 or ATSAMD21.
nRF51 or nRF52 Bluefruit Devices? The Bluefruit nRF52 Feather (based on the nRF52832 (https://adafru.it/vaJ) SoC) is quite different from the earlier nRF51822 based Bluefruit products (Bluefruit M0 Feather (https://adafru.it/t6a), etc.), both of which will continue to exist. From a hardware perspective, the nRF52 Feather is based on a much more powerful ARM Cortex M4F processor, with 512KB flash, 64KB SRAM and hardware floating point acceleration ...
Device Pinout © Adafruit Industries https://learn.adafruit.
Please note that the nRF52832 uses a USB serial adapter to RXD/TXD are with respect to the nRF52 Special Notes The following pins have some restrictions that need to be taken into account when using them: PIN_DFU / P0.20: If this pin is detected to be at GND level at startup, the board will enter a special serial bootloader mode and will not execute any user code, going straight into bootloader mode.
during the bootloader phase. Power Pins 3.3V Output: This two pins are connected to the output of the on board 3.3V regulator. They can be used to supply 3.3V power to external sensors, breakouts or Feather Wings. LIPO Input (VBAT): This is the voltage supply off the optional LIPO cell that can be connected via the JST PH connector. It is nominally ~3.5-4.2V. VREG Enable: This pin can be set to GND to disable the 3.3V output from the on board voltage regulator.
Assembly We ship Feathers fully tested but without headers attached - this gives you the most flexibility on choosing how to use and configure your Feather Header Options! Before you go gung-ho on soldering, there's a few options to consider! The first option is soldering in plain male headers, this lets you plug in the Feather into a solderless breadboard © Adafruit Industries https://learn.adafruit.
Another option is to go with socket female headers. This won't let you plug the Feather into a breadboard but it will let you attach featherwings very easily © Adafruit Industries https://learn.adafruit.
We also have 'slim' versions of the female headers, that are a little shorter and give a more compact shape © Adafruit Industries https://learn.adafruit.
Finally, there's the "Stacking Header" option. This one is sort of the best-of-both-worlds. You get the ability to plug into a solderless breadboard and plug a featherwing on top. But its a little bulky Soldering in Plain Headers Prepare the header strip: Cut the strip to length if necessary. It will be easier to solder if you insert it into a breadboard - long pins down © Adafruit Industries https://learn.adafruit.
Add the breakout board: Place the breakout board over the pins so that the short pins poke through the breakout pads And Solder! Be sure to solder all pins for reliable electrical contact. (For tips on soldering, be sure to check out our Guide to Excellent Soldering (https://adafru.it/aTk)). © Adafruit Industries https://learn.adafruit.
Solder the other strip as well. © Adafruit Industries https://learn.adafruit.
You're done! Check your solder joints visually and continue onto the next steps Soldering on Female Header Tape In Place For sockets you'll want to tape them in place so when you flip over the board they don't fall out Flip & Tack Solder After flipping over, solder one or two points on each strip, to 'tack' the header in place © Adafruit Industries https://learn.adafruit.
© Adafruit Industries https://learn.adafruit.
And Solder! Be sure to solder all pins for reliable electrical contact. (For tips on soldering, be sure to check out our Guide to Excellent Soldering (https://adafru.it/aTk)). © Adafruit Industries https://learn.adafruit.
You're done! Check your solder joints visually and continue onto the next steps © Adafruit Industries https://learn.adafruit.
Arduino BSP Setup You can install the Adafruit Bluefruit nRF52 BSP in two steps: nRF52 support requires at least Arduino IDE version 1.6.12! Please make sure you have an up to date version before proceeding with this guide! Please consult the FAQ section at the bottom of this page if you run into any problems installing or using this BSP! 1. BSP Installation Recommended: Installing the BSP via the Board Manager Download and install the Arduino IDE (https://adafru.it/fvm) (At least v1.6.
It will take up to a few minutes to finish installing the cross-compiling toolchain and tools associated with this BSP. The delay during the installation stage shown in the image below is normal, please be patient and let the installation terminate normally: Once the BSP is installed, select 'Adafruit Bluefruit nRF52 Feather' from the Tools -> Board menu, which will update your system config to use the right compiler and settings for the nRF52: 2.
Adafruit nRF52 BSP via git (for core development and PRs only) 1. Install BSP via Board Manager as above to install compiler & tools. 2. Delete the core folder nrf52 installed by Board Manager in Adruino15, depending on your OS. It could be OS X: ~/Library/Arduino15/packages/adafruit/hardware/nrf52 Linux: ~/.arduino15/packages/adafruit/hardware/nrf52 Windows: %APPDATA%\Local\Arduino15\packages\adafruit\hardware\nrf52 3.
Arduino Board Setup Once you have the Bluefruit nRF52 BSP setup on your system, you need to select the appropriate board, which will determine the compiler and expose some new menus options: 1. Select the Board Target Go to the Tools menu Select Tools > Board > Adafruit Bluefruit nRF52 Feather 2.
To enable it go to System Preferences -> Security & Privacy and click allow if you see Silab in the developer name. Download & Install Adafruit Driver (nRF52840 Windows) For Feather nRF52840, If you are using Windows, you will need to follows Windows Driver Installation (https://adafru.it/D0H) to download and install driver. 3.
selected bootloader can only upload to board having the same version. In short, you need to upgrade/burn bootloader that come with the BSP using this guide © Adafruit Industries https://learn.adafruit.
Using the Bootloader This page is for information purposes only. Normally the bootloader will work transparently and automatically from the Arduino IDE, requiring no manual intervention on your behalf. The Bluefruit nRF52 Feather includes a customized version of the Nordic bootloader that enables serial support, over the air (OTA) DFU support, and various fail safe features like factory reset when the FRST pin is grounded at startup.
Factory Reset The Bluefruit nRF52 Feather has an optional FRST pad on the bottom of the PCB. If you brick your device, you can solder a wire to the FRST pad, connecting it to GND.
Select Tools->Burn Bootloader to start the upgrade. After receiving the new Bootloader over the serial connection, the old Bootloader will erase itself! The new bootloader will then be flashed. The process typically takes 30-60 seconds to complete. Make sure you see the "Device programmed" in the output log before launching Serial monitor or uploadinga new sketch. © Adafruit Industries https://learn.adafruit.
Flashing the Bootloader All Adafruit nRF52 boards chip with the bootloader pre-flashed. This page is provided for information purposes only! All Bluefruit nRF52 Feather boards and Bluefruit nRF52 modules ship with the serial bootloader pre-flashed, so this page is normally not required when setting your device and system up. The information provided here is only intended for for rare cases where you may want or need to reflash the bootloader yourself, and have access to the HW required to do so. 1.
3. Manually Burning the Bootloader via nrfjprog You can also manually burn the bootloader from the command line, using `nrfjprog` from Nordic. You can either download nRF5x-Command-Line-Tools (https://adafru.it/vaJ) for OSX/Linux/Win32, or use the version that ships with the BSP in the tools/nrf5x-command-line-tools folder. Run the folllwing commands, updating the path to the .hex file as appropriate: $ nrfjprog -e -f nrf52 $ nrfjprog --program bootloader_with_s132.
`nrfjprog` tool wherever you have added it. You can run the following command, for example: $ ln -s $HOME/prog/nordic/nrfjprog/nrfjprog /usr/local/bin/nrfjprog 4. Manually Burning the Bootloader via AdaLink Alternatively, you can use AdaLink (https://adafru.it/fPq) to flash the bootloader with a Segger J-Link: # First erase the device's flash contents $ adalink nrf52832 -p jlink -w # Then flash the bootloader and SoftDevice .hex file $ adalink nrf52832 -p jlink -h feather52_bootloader_v050_s132_v201.
Examples There are numerous examples available for the Bluefruit nRF52 Feather in the Examples menu of the nRF52 BSP, and these are always up to date. You're first stop looking for example code should be there: Example Source Code The latest example source code is always available and visible on Github, and the public git repository should be considered the definitive source of example code for this board. https://adafru.it/vaK https://adafru.
Advertising: Beacon This example shows how you can use the BLEBeacon helper class and advertising API to configure your Bluefruit nRF52 board as a 'Beacon'. Complete Code The code below may be out of sync with the latest examples on Github. You should always consult Github for the latest version. The latest version of this code is available on Github (https://adafru.it/vaM) and in the Examples menu. © Adafruit Industries https://learn.adafruit.
#include // Beacon uses the Manufacturer Specific Data field in the advertising // packet, which means you must provide a valid Manufacturer ID. Update // the field below to an appropriate value. For a list of valid IDs see: // https://www.bluetooth.
Output You can use the nRF Beacons application from Nordic Semiconductors to test this sketch: nRF Beacons for iOS (https://adafru.it/vaC) nRF Beacons for Android (https://adafru.it/vaD) Make sure that you set the UUID, Major and Minor values to match the sketch above, and then run the sketch at the same time as the nRF Beacons application. With the default setup you should see a Mona Lisa icon when the beacon is detected.
BLE UART: Controller This examples shows you you can use the BLEUart helper class and the Bluefruit LE Connect applications to send based keypad and sensor data to your nRF52. Setup In order to use this sketch, you will need to open Bluefruit LE Connect on your mobile device using our free iOS (https://adafru.it/f4H), Android (https://adafru.it/f4G) or OS X (https://adafru.it/o9F) applications. Load the Controller example sketch (https://adafru.
As you change the color (or as other data becomes available) you should receive the data on the nRF52, and see it in the Serial Monitor output: Complete Code The latest version of this code is always available on Github (https://adafru.it/vaN), and in the Examples folder of the nRF52 BSP. The code below is provided for convenience sake, but may be out of date! See the link above for the latest code. #include BLEUart bleuart; // Function prototypes for packetparser.
// There is no room for 'Name' in the Advertising packet // Use the optional secondary Scan Response packet for 'Name' instead Bluefruit.ScanResponse.
// Accelerometer if (packetbuffer[1] == 'A') { float x, y, z; x = parsefloat(packetbuffer+2); y = parsefloat(packetbuffer+6); z = parsefloat(packetbuffer+10); Serial.print("Accel\t"); Serial.print(x); Serial.print('\t'); Serial.print(y); Serial.print('\t'); Serial.print(z); Serial.println(); } // Magnetometer if (packetbuffer[1] == 'M') { float x, y, z; x = parsefloat(packetbuffer+2); y = parsefloat(packetbuffer+6); z = parsefloat(packetbuffer+10); Serial.print("Mag\t"); Serial.print(x); Serial.print('\t');
#define #define #define #define #define #define #define PACKET_ACC_LEN PACKET_GYRO_LEN PACKET_MAG_LEN PACKET_QUAT_LEN PACKET_BUTTON_LEN PACKET_COLOR_LEN PACKET_LOCATION_LEN // READ_BUFSIZE #define READ_BUFSIZE (15) (15) (15) (19) (5) (6) (15) Size of the read buffer for incoming packets (20) /* Buffer to hold incoming characters */ uint8_t packetbuffer[READ_BUFSIZE+1]; /**************************************************************************/ /*! @brief Casts the four bytes at the specified address to
/**************************************************************************/ /*! @brief Waits for incoming data and parses it */ /**************************************************************************/ uint8_t readPacket(BLEUart *ble_uart, uint16_t timeout) { uint16_t origtimeout = timeout, replyidx = 0; memset(packetbuffer, 0, READ_BUFSIZE); while (timeout--) { if (replyidx >= 20) break; if ((packetbuffer[1] == 'A') break; if ((packetbuffer[1] == 'G') break; if ((packetbuffer[1] == 'M') break; if ((pac
if (xsum != checksum) { Serial.print("Checksum mismatch in packet : "); printHex(packetbuffer, replyidx+1); return 0; } // checksum passed! return replyidx; } © Adafruit Industries https://learn.adafruit.
Custom: HRM The BLEService and BLECharacteristic classes can be used to implement any custom or officially adopted BLE service of characteristic using a set of basic properties and callback handlers. The example below shows how to use these classes to implement the Heart Rate Monitor (https://adafru.it/vaO) service, as defined by the Bluetooth SIG. HRM Service Definition UUID: 0x180D (https://adafru.
// a BLECharacteristic will cause it to be added to the last BLEService that // was 'begin()'ed! // Configure the Heart Rate Measurement characteristic // See: https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.
2. Next, you can configure the Heart Rate Measurement characteristic (hrmc above). The values that you set for this will depend on the characteristic definition, but for convenience sake we've documented the key information in the comments in the code above. ' hrmc.setProperties(CHR_PROPS_NOTIFY); ' - This sets the PROPERTIES value for the characteristic, which determines how the characteristic can be accessed.
void cccd_callback(BLECharacteristic& chr, uint16_t cccd_value) { // Display the raw request packet Serial.print("CCCD Updated: "); Serial.print(cccd_value); Serial.println(""); // Check the characteristic this CCCD update is associated with in case // this handler is used for multiple CCCD records. if (chr.uuid == hrmc.uuid) { if (chr.notifyEnabled()) { Serial.println("Heart Rate Measurement 'Notify' enabled"); } else { Serial.println("Heart Rate Measurement 'Notify' disabled"); } } } 4.
// Setup LED pins and reset blinky counter pinMode(STATUS_LED, OUTPUT); blinkyms = millis(); // Initialise the Bluefruit module Serial.println("Initialise the Bluefruit nRF52 module"); Bluefruit.begin(); // Set the advertised device name (keep it short!) Serial.println("Setting Device Name to 'Feather52 HRM'"); Bluefruit.setName("Feather52 HRM"); // Set the connect/disconnect callback handlers Bluefruit.setConnectCallback(connect_callback); Bluefruit.
// See: https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.service.heart_rate.xml // Supported Characteristics: // Name UUID Requirement Properties // ---------------------------- ------ ----------- ---------// Heart Rate Measurement 0x2A37 Mandatory Notify // Body Sensor Location 0x2A38 Optional Read // Heart Rate Control Point 0x2A39 Conditional Write <-- Not used here hrms.begin(); // // // // Note: You must call .begin() on the BLEService before calling .
Serial.println("Connected"); } void disconnect_callback(uint8_t reason) { (void) reason; Serial.println("Disconnected"); Serial.println("Advertising!"); } void cccd_callback(BLECharacteristic& chr, uint16_t cccd_value) { // Display the raw request packet Serial.print("CCCD Updated: "); //Serial.printBuffer(request->data, request->len); Serial.print(cccd_value); Serial.println(""); // Check the characteristic this CCCD update is associated with in case // this handler is used for multiple CCCD records.
break; } } } } © Adafruit Industries https://learn.adafruit.
BLE Pin I/O Firmata is a generic protocol for communicating with microcontrollers and controlling the board's pins such as setting the GPIO outputs and inputs, PWM output, analog reads, etc.... Setup In order to run this demo, you will need to open Bluefruit LE Connect on your mobile device using our free iOS (https://adafru.it/f4H), Android (https://adafru.it/f4G) or OS X (https://adafru.it/o9F) applications. Load the StandardFirmataBLE example sketch (https://adafru.
// Adafruit nRF52 Boards require Firmata at least 2.5.7 #include #include #include #include #define #define #define #define #define #define #define #define #define #define #define
/* pins configuration */ byte portConfigInputs[TOTAL_PORTS]; // each bit: 1 = pin in INPUT, 0 = anything else /* timer unsigned unsigned unsigned variables */ long currentMillis; // store the current value from millis() long previousMillis; // for comparison with currentMillis int samplingInterval = 19; // how often to run the main loop (in ms) /* i2c data */ struct i2c_device_info { byte addr; int reg; byte bytes; byte stopTX; }; /* for i2c read continuous more */ i2c_device_info query[I2C_MAX_QUERIES];
* FUNCTIONS *============================================================================*/ void attachServo(byte pin, int minPulse, int maxPulse) { if (servoCount < MAX_SERVOS) { // reuse indexes of detached servos until all have been reallocated if (detachedServoCount > 0) { servoPinMap[pin] = detachedServos[detachedServoCount - 1]; if (detachedServoCount > 0) detachedServoCount--; } else { servoPinMap[pin] = servoCount; servoCount++; } if (minPulse > 0 && maxPulse > 0) { servos[servoPinMap[pin]].
void disableI2CPins() { isI2CEnabled = false; // disable read continuous mode for all devices queryIndex = -1; } void // // // if readAndReportData(byte address, int theRegister, byte numBytes, byte stopTX) { allow I2C requests that don't require a register read for example, some devices using an interrupt pin to signify new data available do not always require the register read so upon interrupt you call Wire.requestFrom() (theRegister != I2C_REGISTER_NOT_SPECIFIED) { Wire.
* * if if if if if if if if if if if if if if if if The compiler will apply substantial optimizations if the inputs to readPort() are compile-time constants.
Firmata.setPinMode(pin, PIN_MODE_ANALOG); } break; case INPUT: // Adafruit: Input without pull up cause pin state changes randomly --> lots of transmission data // if (IS_PIN_DIGITAL(pin)) { // pinMode(PIN_TO_DIGITAL(pin), INPUT); // disable output driver //#if ARDUINO <= 100 // // deprecated since Arduino 1.0.1 - TODO: drop support in Firmata 2.6 // digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable internal pull-ups //#endif // Firmata.
break; default: Firmata.sendString("Unknown pin mode"); // TODO: put error msgs in EEPROM } // TODO: save status to EEPROM here, if changed } /* * Sets the value of an individual pin. Useful if you want to set a pin value but * are not tracking the digital port state. * Can only be used on pins configured as OUTPUT. * Cannot be used to enable pull-ups on Digital INPUT pins. */ void setPinValueCallback(byte pin, int value) { if (pin < TOTAL_PINS && IS_PIN_DIGITAL(pin)) { if (Firmata.
pinMode(pin, INPUT_PULLUP); #else // only write to the INPUT pin to enable pullups if Arduino v1.0.0 or earlier pinWriteMask |= mask; #endif } Firmata.
* SYSEX-BASED commands *============================================================================*/ void sysexCallback(byte command, byte argc, byte *argv) { byte mode; byte stopTX; byte slaveAddress; byte data; int slaveRegister; unsigned int delayTime; switch (command) { case I2C_REQUEST: mode = argv[1] & I2C_READ_WRITE_MODE_MASK; if (argv[1] & I2C_10BIT_ADDRESS_MODE_MASK) { Firmata.
} if (argc == 6) { // a slave register is specified slaveRegister = argv[2] + (argv[3] << 7); data = argv[4] + (argv[5] << 7); // bytes to read } else { // a slave register is NOT specified slaveRegister = (int)I2C_REGISTER_NOT_SPECIFIED; data = argv[2] + (argv[3] << 7); // bytes to read } queryIndex++; query[queryIndex].addr = slaveAddress; query[queryIndex].reg = slaveRegister; query[queryIndex].bytes = data; query[queryIndex].
} break; case SERVO_CONFIG: if (argc > 4) { // these vars are here for clarity, they'll optimized away by the compiler byte pin = argv[0]; int minPulse = argv[1] + (argv[2] << 7); int maxPulse = argv[3] + (argv[4] << 7); if (IS_PIN_DIGITAL(pin)) { if (servoPinMap[pin] < MAX_SERVOS && servos[servoPinMap[pin]].
} if (IS_PIN_I2C(pin)) { Firmata.write(PIN_MODE_I2C); Firmata.write(1); // TODO: could assign a number to map to SCL or SDA } #ifdef FIRMATA_SERIAL_FEATURE serialFeature.handleCapability(pin); #endif Firmata.write(127); } Firmata.write(END_SYSEX); break; case PIN_STATE_QUERY: if (argc > 0) { byte pin = argv[0]; Firmata.write(START_SYSEX); Firmata.write(PIN_STATE_RESPONSE); Firmata.write(pin); if (pin < TOTAL_PINS) { Firmata.write(Firmata.getPinMode(pin)); Firmata.write((byte)Firmata.
disableI2CPins(); } for (byte i = 0; i < TOTAL_PORTS; i++) { reportPINs[i] = false; // by default, reporting off portConfigInputs[i] = 0; // until activated previousPINs[i] = 0; } for (byte i = 0; i < TOTAL_PINS; i++) { // pins with analog capability default to analog input // otherwise, pins default to digital output if (IS_PIN_ANALOG(i)) { // turns off pullup, configures everything setPinModeCallback(i, PIN_MODE_ANALOG); } else if (IS_PIN_DIGITAL(i)) { // sets the output to 0, configures portConfigInputs
// Configure and Start BLE Uart Service // Firmata use several small write(1) --> buffering TXD is required to run smoothly // Enable buffering TXD bleuart.begin(); bleuart.bufferTXD(true); Firmata.setFirmwareVersion(FIRMATA_FIRMWARE_MAJOR_VERSION, FIRMATA_FIRMWARE_MINOR_VERSION); Firmata.attach(ANALOG_MESSAGE, analogWriteCallback); Firmata.attach(DIGITAL_MESSAGE, digitalWriteCallback); Firmata.attach(REPORT_ANALOG, reportAnalogCallback); Firmata.attach(REPORT_DIGITAL, reportDigitalCallback); Firmata.
Bluefruit.Advertising.restartOnDisconnect(true); Bluefruit.Advertising.setInterval(32, 244); // in unit of 0.625 ms Bluefruit.Advertising.setFastTimeout(30); // number of seconds in fast mode Bluefruit.Advertising.
© Adafruit Industries https://learn.adafruit.
Central BLEUART This example show you how to use Feather nRF52 as a Central to talk to other Bluefruit (nRF52 or nRF51) peripherals exposing the bleuart (AKA 'NUS') service. Client Services Since the Central role accesses the GATT server on the peripheral, we first need to declare a client bleuart instance using the BLEClientUart helper class. We can also conveniently read Device Information if BLEClientDis is also used.
void setup() { // Other set up ..... /* Start Central Scanning * - Enable auto scan if disconnected * - Interval = 100 ms, window = 80 ms * - Don't use active scan * - Start(timeout) with timeout = 0 will scan forever (until connected) */ Bluefruit.Scanner.setRxCallback(scan_callback); Bluefruit.Scanner.restartOnDisconnect(true); Bluefruit.Scanner.setInterval(160, 80); // in unit of 0.625 ms Bluefruit.Scanner.useActiveScan(false); Bluefruit.Scanner.
void connect_callback(uint16_t conn_handle) { Serial.println("Connected"); Serial.print("Dicovering DIS ... "); if ( clientDis.discover(conn_handle) ) { Serial.println("Found it"); char buffer[32+1]; // read and print out Manufacturer memset(buffer, 0, sizeof(buffer)); if ( clientDis.getManufacturer(buffer, sizeof(buffer)) ) { Serial.print("Manufacturer: "); Serial.println(buffer); } // read and print out Model Number memset(buffer, 0, sizeof(buffer)); if ( clientDis.
void setup() { Serial.begin(115200); Serial.println("Bluefruit52 Central BLEUART Example"); Serial.println("-----------------------------------\n"); // Initialize Bluefruit with maximum connections as Peripheral = 0, Central = 1 // SRAM usage required by SoftDevice will increase dramatically with number of connections Bluefruit.begin(0, 1); Bluefruit.setName("Bluefruit52 Central"); // Configure DIS client clientDis.begin(); // Init BLE Central Uart Serivce clientUart.begin(); clientUart.
*/ void connect_callback(uint16_t conn_handle) { Serial.println("Connected"); Serial.print("Dicovering DIS ... "); if ( clientDis.discover(conn_handle) ) { Serial.println("Found it"); char buffer[32+1]; // read and print out Manufacturer memset(buffer, 0, sizeof(buffer)); if ( clientDis.getManufacturer(buffer, sizeof(buffer)) ) { Serial.print("Manufacturer: "); Serial.println(buffer); } // read and print out Model Number memset(buffer, 0, sizeof(buffer)); if ( clientDis.
Serial.println("Disconnected"); } /** * Callback invoked when uart received data * @param uart_svc Reference object to the service where the data * arrived. In this example it is clientUart */ void bleuart_rx_callback(BLEClientUart& uart_svc) { Serial.print("[RX]: "); while ( uart_svc.available() ) { Serial.print( (char) uart_svc.read() ); } Serial.println(); } void loop() { if ( Bluefruit.Central.connected() ) { // Not discovered yet if ( clientUart.
Dual Roles BLEUART If you are not familiar with Central Role, it is advised to look at the "Central BLEUART" example first then continue with this afterwards. This example demonstrates how you can use a Feather nRF52 to connect to two other Bluefruit or BLE devices using the bleuart (AKA 'NUS') service concurrently, with the device running at both a peripheral and a central at the same time.
We are then ready to forward data from central to peripheral and vice versa using callbacks: void cent_bleuart_rx_callback(BLEClientUart& cent_uart) { char str[20+1] = { 0 }; cent_uart.read(str, 20); Serial.print("[Cent] RX: "); Serial.println(str); if ( bleuart.notifyEnabled() ) { // Forward data from our peripheral to Mobile bleuart.print( str ); }else { // response with no prph message clientUart.
// Callbacks for Central Bluefruit.Central.setConnectCallback(cent_connect_callback); Bluefruit.Central.setDisconnectCallback(cent_disconnect_callback); Advertising and Scanner It is possible to start both the scanner and advertising at the same time so that we can discover and be discovered by other BLE devices.
// Peripheral uart service BLEUart bleuart; // Central uart client BLEClientUart clientUart; void setup() { Serial.begin(115200); Serial.println("Bluefruit52 Dual Role BLEUART Example"); Serial.println("-------------------------------------\n"); // Initialize Bluefruit with max concurrent connections as Peripheral = 1, Central = 1 // SRAM usage required by SoftDevice will increase with number of connections Bluefruit.begin(1, 1); // Set max power.
Bluefruit.Advertising.addTxPower(); // Include bleuart 128-bit uuid Bluefruit.Advertising.addService(bleuart); // Secondary Scan Response packet (optional) // Since there is no room for 'Name' in Advertising packet Bluefruit.ScanResponse.addName(); /* Start Advertising * - Enable auto advertising if disconnected * - Interval: fast mode = 20 ms, slow mode = 152.
if ( clientUart.discovered() ) { clientUart.print(str); }else { bleuart.println("[Prph] Central role not connected"); } } /*------------------------------------------------------------------*/ /* Central *------------------------------------------------------------------*/ void scan_callback(ble_gap_evt_adv_report_t* report) { // Check if advertising contain BleUart service if ( Bluefruit.Scanner.checkReportForService(report, clientUart) ) { Serial.println("BLE UART service detected. Connecting ...
Serial.print("[Cent] RX: "); Serial.println(str); if ( bleuart.notifyEnabled() ) { // Forward data from our peripheral to Mobile bleuart.print( str ); }else { // response with no prph message clientUart.println("[Cent] Peripheral role not connected"); } } © Adafruit Industries https://learn.adafruit.
Custom: Central HRM The BLEClientService and BLEClientCharacteristic classes can be used to implement any custom or officially adopted BLE service of characteristic on the client side (most often is Central) using a set of basic properties and callback handlers. The example below shows how to use these classes to implement the Heart Rate Monitor (https://adafru.it/vaO) service, as defined by the Bluetooth SIG. To run this example, you will need an extra nRF52 running peripheral HRM sketch (https://adafru.
You MUST call .begin() on the BLEClientService before adding any BLEClientCharacteristics. Any BLEClientCharacteristic will automatically be added to the last BLEClientService that was `begin()'ed! 2. Since Heart Rate Measurement characteristic (clientMeasurement above) is notifiable. You need to set up callback for it ' hrmc.setNotifyCallback(hrm_notify_callback); ' This sets the callback that will be fired when we receive a Notify message from peripheral.
function return true if characteristics is found, and false otherwise. You could also check with .discovered() function. A service could contain more characteristics but we don't need to discover them all, only those that we want to interact with. Advanced: Alternatively, you could discover all the interested characteristics of a service within a function call by using Bluefruit.Discovery.discoverCharacteristic() (not used in the example).
// Connect Callback Part 3 void connect_callback(uint16_t conn_handle) { ....... // Reaching here means we are ready to go, let's enable notification on measurement chr if ( hrmc.enableNotify() ) { Serial.println("Ready to receive HRM Measurement value"); }else { Serial.println("Couldn't enable notify for HRM Measurement.
Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit! MIT license, check LICENSE for more information All text above, and the splash screen below must be included in any redistribution *********************************************************************/ /* This sketch show how to use BLEClientService and BLEClientCharacteristic * to implement a custom client that is used to talk with Gatt server on * peri
/* Start Central Scanning * - Enable auto scan if disconnected * - Interval = 100 ms, window = 80 ms * - Don't use active scan * - Filter only accept HRM service * - Start(timeout) with timeout = 0 will scan forever (until connected) */ Bluefruit.Scanner.setRxCallback(scan_callback); Bluefruit.Scanner.restartOnDisconnect(true); Bluefruit.Scanner.setInterval(160, 80); // in unit of 0.625 ms Bluefruit.Scanner.filterUuid(hrms.uuid); Bluefruit.Scanner.useActiveScan(false); Bluefruit.Scanner.
Serial.println("Measurement characteristic is mandatory but not found"); Bluefruit.Central.disconnect(conn_handle); return; } Serial.println("Found it"); // Measurement is found, continue to look for option Body Sensor Location // https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.body_sensor_lo // Body Sensor Location is optional, print out the location in text if present Serial.print("Discovering Body Sensor Location characteristic ... "); if ( bslc.
// https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.heart_rate_mea // Measurement contains of control byte0 and measurement (8 or 16 bit) + optional field // if byte0's bit0 is 0 --> measurement is 8 bit, otherwise 16 bit. Serial.print("HRM Measurement: "); if ( data[0] & bit(0) ) { uint16_t value; memcpy(&value, data+1, 2); Serial.println(value); } else { Serial.println(data[1]); } } © Adafruit Industries https://learn.adafruit.
Bluefruit nRF52 API The Adafruit nRF52 core defines a number of custom classes that aim to make it easy to work with BLE in your projects. The key classes are listed below, and examined in more detail elsewhere in this learning guide: AdafruitBluefruit is the main entry point to the Adafruit Bluefruit nRF52 API. This class exposes a number of essential functions and classes, such as advertising, the list of GATT services and characteristics defined on your device, and connection status.
AdafruitBluefruit The Bluefruit nRF52 Feather codebase is in an early BETA stage and is undergoing active development based on customer feedback and testing. As such, the class documentation here is incomplete, and you should consult the Github repo for the latest code and API developments: https://goo.gl/LdEx62 This base class is the main entry point to the Adafruit Bluefruit nRF52 API, and exposes most of the helper classes and functions that you use to configure your device.
bool setApperance uint16_t getApperance void void (uint16_t appear); (void); autoConnLed (bool enabled); setConnLedInterval (uint32_t ms); /*------------------------------------------------------------------*/ /* GAP, Connections and Bonding *------------------------------------------------------------------*/ bool connected (void); bool disconnect (void); bool bool setConnInterval (uint16_t min, uint16_t max); setConnIntervalMS (uint16_t min_ms, uint16_t max_ms); uint16_t connHandle bool connPaired ui
BLEGap This page is a work in progress as the API is changing as we migrate to S132v5 and add better Central mode support. This GAP API for Bluefruit is accessible via Bluefruit.Gap.
BLEAdvertising The Bluefruit nRF52 Feather codebase is in an early BETA stage and is undergoing active development based on customer feedback and testing. As such, the class documentation here is incomplete, and you should consult the Github repo for the latest code and API developments: https://goo.gl/LdEx62 'Advertising' is what makes your Bluetooth Low Energy devices visible to other devices in listening range.
/*------------- Adv Data -------------*/ bool addData(uint8_t type, const void* data, uint8_t len); bool addFlags(uint8_t flags); bool addTxPower(void); bool addName(void); bool addAppearance(uint16_t appearance); bool addManufacturerData(const void* data, uint8_t count); /*------------- UUID bool addUuid(BLEUuid bool addUuid(BLEUuid bool addUuid(BLEUuid bool addUuid(BLEUuid -------------*/ bleuuid); bleuuid1, BLEUuid bleuuid2); bleuuid1, BLEUuid bleuuid2, BLEUuid bleuuid3); bleuuid1, BLEUuid bleuuid2, BLE
typedef void (*stop_callback_t) (void); typedef void (*slow_callback_t) (void); void setType(uint8_t adv_type); void setFastTimeout(uint16_t sec); void setSlowCallback(slow_callback_t fp); void setStopCallback(stop_callback_t fp); void setInterval (uint16_t fast, uint16_t slow); void setIntervalMS(uint16_t fast, uint16_t slow); uint16_t getInterval(void); bool setBeacon(BLEBeacon& beacon); bool setBeacon(EddyStoneUrl& eddy_url); bool isRunning(void); void restartOnDisconnect(bool enable); bool start(uint16_
void setup(void) { // Other startup code here // ... // Set up Advertising Packet setupAdv(); // Start Advertising Bluefruit.Advertising.start(); } void startAdv(void) { // Advertising packet Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE); Bluefruit.Advertising.addTxPower(); // Include bleuart 128-bit uuid Bluefruit.Advertising.addService(bleuart); // Secondary Scan Response packet (optional) // Since there is no room for 'Name' in Advertising packet Bluefruit.ScanResponse.
BLEScanner The Bluefruit nRF52 Feather codebase is in an early BETA stage and is undergoing active development based on customer feedback and testing. As such, the class documentation here is incomplete, and you should consult the Github repo for the latest code and API developments: https://goo.gl/LdEx62 This documentation is based on BSP 0.7.0 and higher. Please make sure you have an up to date version before using the code below.
typedef void (*rx_callback_t) (ble_gap_evt_adv_report_t*); typedef void (*stop_callback_t) (void); BLEScanner(void); ble_gap_scan_params_t* getParams(void); bool isRunning(void); void void void void useActiveScan(bool enable); setInterval(uint16_t interval, uint16_t window); setIntervalMS(uint16_t interval, uint16_t window); restartOnDisconnect(bool enable); void filterRssi(int8_t min_rssi); void filterMSD(uint16_t manuf_id); void void void void void filterUuid(BLEUuid filterUuid(BLEUuid filterUuid(BLEUu
} else { /* This is a normal advertising packet */ Serial.printf("[ADV%9d] Packet received from ", millis()); } Serial.printBuffer(report->peer_addr.addr, 6, ':'); Serial.print("\n"); /* Raw buffer contents */ Serial.printf("%14s %d bytes\n", "PAYLOAD", report->dlen); if (report->dlen) { Serial.printf("%15s", " "); Serial.printBuffer(report->data, report->dlen, '-'); Serial.println(); } /* RSSI value */ Serial.printf("%14s %d dBm\n", "RSSI", report->rssi); /* Adv Type */ Serial.
information. By default active scanning is disabled, so no Scan Response packets will be received by BLEScanner unless this function is called and set to 1 before calling Bluefruit.Scanner.start(0) .
void restartOnDisconnect(bool enable); Setting this function to '1' will cause the scanning process to start again as soon as you disconnect from a peripheral device. The default behaviour is to automatically restart scanning on disconnect. Examples For an example that uses almost all of the BLEScanner and advertising API in Central mode, see central_scan_advanced.ino (https://adafru.it/y5a) in the Central examples folder. https://adafru.it/y5a https://adafru.
BLEService The Bluefruit nRF52 Feather codebase is in an early BETA stage and is undergoing active development based on customer feedback and testing. As such, the class documentation here is incomplete, and you should consult the Github repo for the latest code and API developments: https://goo.gl/LdEx62 This base class is used when defining custom BLE Gatt Services, such as the various service helper classes that make up the Adafruit Bluefruit nRF52 API described here.
BLEUuid uuid; static BLEService* lastService; BLEService(void); BLEService(uint16_t uuid16); BLEService(uint8_t const uuid128[]); void setUuid(uint16_t uuid16); void setUuid(uint8_t const uuid128[]); virtual err_t begin(void); Example The following example declares a HRM (Heart Rate Monitor) service, and assigns some characteristics to it: Note that this example code is incomplete.
// b1:2 = Sensor contact status (0+1 = Not supported, 2 = Supported but contact not detected, 3 = Supported an // b0 = Value format (0 = UINT8, 1 = UINT16) // B1 = UINT8 - 8-bit heart rate measurement value in BPM // B2:3 = UINT16 - 16-bit heart rate measurement value in BPM // B4:5 = UINT16 - Energy expended in joules // B6:7 = UINT16 - RR Internal (1/1024 second resolution) hrmc.setProperties(CHR_PROPS_NOTIFY); hrmc.setPermission(SECMODE_OPEN, SECMODE_NO_ACCESS); hrmc.setFixedLen(2); hrmc.
BLECharacteristic The Bluefruit nRF52 Feather codebase is in an early BETA stage and is undergoing active development based on customer feedback and testing. As such, the class documentation here is incomplete, and you should consult the Github repo for the latest code and API developments: https://goo.gl/LdEx62 This base class is used when defining custom BLE GATT characteristics, and is used throughput the Adafruit Bluefruit nRF52 API and helper classes.
maximum value it will hold (up to 20 bytes). .begin() will cause this characteristic to be added to the last BLEService that had it's .begin() method called. Order of Operations (Important!) One very important thing to take into consideration when working with BLEService and BLECharacteristic, is that any BLECharacteristic will automatically be added to the last BLEService that had it's `.begin()` function called. As such, you must call yourService.
virtual err_t begin(void); // Add Descriptor function must be called right after begin() err_t addDescriptor(BLEUuid bleuuid, void const * content, uint16_t len, BleSecurityMode read_perm = SECMODE_OPEN, Ble ble_gatts_char_handles_t handles(void); /*------------- Write -------------*/ uint16_t write(const void* data, uint16_t len); uint16_t write(const char* str); uint16_t uint16_t uint16_t uint16_t write8 write16 write32 write32 (uint8_t (uint16_t (uint32_t (int num); num); num); num); /*-------------
/* HRM Service Definitions * Heart Rate Monitor Service: 0x180D * Heart Rate Measurement Char: 0x2A37 * Body Sensor Location Char: 0x2A38 */ BLEService hrms = BLEService(UUID16_SVC_HEART_RATE); BLECharacteristic hrmc = BLECharacteristic(UUID16_CHR_HEART_RATE_MEASUREMENT); BLECharacteristic bslc = BLECharacteristic(UUID16_CHR_BODY_SENSOR_LOCATION); void setupHRM(void) { // Configure the Heart Rate Monitor service // See: https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.
// 5 = Ear Lobe // 6 = Foot // 7:255 = Reserved bslc.setProperties(CHR_PROPS_READ); bslc.setPermission(SECMODE_OPEN, SECMODE_NO_ACCESS); bslc.setFixedLen(1); bslc.begin(); bslc.write8(2); // Set the characteristic to 'Wrist' (2) } void cccd_callback(BLECharacteristic& chr, uint16_t cccd_value) { // Display the raw request packet Serial.print("CCCD Updated: "); //Serial.printBuffer(request->data, request->len); Serial.print(cccd_value); Serial.
BLEClientService The Bluefruit nRF52 Feather codebase is in an early BETA stage and is undergoing active development based on customer feedback and testing. As such, the class documentation here is incomplete, and you should consult the Github repo for the latest code and API developments: https://goo.gl/LdEx62 This base class is used when defining custom BLE Gatt Clients.
BLEUuid uuid; // Constructors BLEClientService(void); BLEClientService(BLEUuid bleuuid); virtual bool begin(void); virtual bool bool discover (uint16_t conn_handle); discovered(void); uint16_t connHandle(void); void setHandleRange(ble_gattc_handle_range_t handle_range); ble_gattc_handle_range_t getHandleRange(void); Example The following example declares a HRM (Heart Rate Monitor) service, and assigns some characteristics to it: /********************************************************************* Thi
Serial.println("Bluefruit52 Central Custom HRM Example"); Serial.println("--------------------------------------\n"); // Initialize Bluefruit with maximum connections as Peripheral = 0, Central = 1 // SRAM usage required by SoftDevice will increase dramatically with number of connections Bluefruit.begin(0, 1); Bluefruit.setName("Bluefruit52 Central"); // Initialize HRM client hrms.begin(); // Initialize client characteristics of HRM. // Note: Client Char will be added to the last service that is begin()ed.
* @param conn_handle */ void connect_callback(uint16_t conn_handle) { Serial.println("Connected"); Serial.print("Discovering HRM Service ... "); // If HRM is not found, disconnect and return if ( !hrms.discover(conn_handle) ) { Serial.println("Found NONE"); // disconect since we couldn't find HRM service Bluefruit.Central.disconnect(conn_handle); return; } // Once HRM service is found, we continue to discover its characteristic Serial.println("Found it"); Serial.
{ Serial.println("Couldn't enable notify for HRM Measurement. Increase DEBUG LEVEL for troubleshooting"); } } /** * Callback invoked when a connection is dropped * @param conn_handle * @param reason */ void disconnect_callback(uint16_t conn_handle, uint8_t reason) { (void) conn_handle; (void) reason; Serial.
BLEClientCharacteristic The Bluefruit nRF52 Feather codebase is in an early BETA stage and is undergoing active development based on customer feedback and testing. As such, the class documentation here is incomplete, and you should consult the Github repo for the latest code and API developments: https://goo.gl/LdEx62 This base class is used when defining custom client for BLE GATT characteristics, and is used throughout the Adafruit Bluefruit nRF52 API and helper classes.
/*--------- Callback Signatures ----------*/ typedef void (*notify_cb_t ) (BLEClientCharacteristic* chr, uint8_t* data, uint16_t len); typedef void (*indicate_cb_t) (BLEClientCharacteristic* chr, uint8_t* data, uint16_t len); BLEUuid uuid; // Constructors BLEClientCharacteristic(void); BLEClientCharacteristic(BLEUuid bleuuid); // Destructor virtual ~BLEClientCharacteristic(); void begin(BLEClientService* parent_svc = NULL); bool bool discover(void); discovered(void); uint16_t connHandle(void); uint16_t
/********************************************************************* This is an example for our nRF52 based Bluefruit LE modules Pick one up today in the adafruit shop! Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit! MIT license, check LICENSE for more information All text above, and the splash screen below must be included in any redistribution ******************************************************
// Increase Blink rate to different from PrPh advertising mode Bluefruit.setConnLedInterval(250); // Callbacks for Central Bluefruit.Central.setDisconnectCallback(disconnect_callback); Bluefruit.Central.setConnectCallback(connect_callback); /* Start Central Scanning * - Enable auto scan if disconnected * - Interval = 100 ms, window = 80 ms * - Don't use active scan * - Filter only accept HRM service * - Start(timeout) with timeout = 0 will scan forever (until connected) */ Bluefruit.Scanner.
Serial.print("Discovering Measurement characteristic ... "); if ( !hrmc.discover() ) { // Measurement chr is mandatory, if it is not found (valid), then disconnect Serial.println("not found !!!"); Serial.println("Measurement characteristic is mandatory but not found"); Bluefruit.Central.disconnect(conn_handle); return; } Serial.println("Found it"); // Measurement is found, continue to look for option Body Sensor Location // https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.
* @param chr Pointer client characteristic that even occurred, * in this example it should be hrmc * @param data Pointer to received data * @param len Length of received data */ void hrm_notify_callback(BLEClientCharacteristic* chr, uint8_t* data, uint16_t len) { // https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.
BLEDiscovery This page is a work in progress as the API is changing as we migrate to S132v5 and add better Central mode support. BLEDiscovery is a helper class to make finding characteristics on a Gatt server (hosted on a BLE peripheral) easier.
BLEDis The Bluefruit nRF52 Feather codebase is in an early BETA stage and is undergoing active development based on customer feedback and testing. As such, the class documentation here is incomplete, and you should consult the Github repo for the latest code and API developments: https://goo.gl/LdEx62 This helper class acts as a wrapper for the Bluetooth Device Information Service (https://adafru.it/q9E) (0x180A).
BLEDis(void); void void void void setModel(const char* model); setHardwareRev(const char* hw_rev); setSoftwareRev(const char* sw_rev); setManufacturer(const char* manufacturer); err_t begin(void); The individual characteristic values are set via the .set*() functions above, and when all values have been set you call the .begin() function to add the service to the device's internal GATT registry.
Output If you examine the device using the Bluefruit LE Connect app on iOS, Android or OS X you should see something resembling the following output: © Adafruit Industries https://learn.adafruit.
BLEUart The Bluefruit nRF52 Feather codebase is in an early BETA stage and is undergoing active development based on customer feedback and testing. As such, the class documentation here is incomplete, and you should consult the Github repo for the latest code and API developments: https://goo.
uint32_t blinkyms; void setup() { Serial.begin(115200); Serial.println("Bluefruit52 BLEUART Example"); // Setup LED pins and reset blinky counter pinMode(STATUS_LED, OUTPUT); blinkyms = millis(); // Setup the BLE LED to be enabled on CONNECT // Note: This is actually the default behaviour, but provided // here in case you want to control this manually via PIN 19 Bluefruit.autoConnLed(true); Bluefruit.begin(); Bluefruit.setName("Bluefruit52"); Bluefruit.setConnectCallback(connect_callback); Bluefruit.
blinkyms = millis(); digitalToggle(STATUS_LED); } // Forward from Serial to BLEUART if (Serial.available()) { // Delay to get enough input data since we have a // limited amount of space in the transmit buffer delay(2); uint8_t buf[64]; int count = Serial.readBytes(buf, sizeof(buf)); bleuart.write( buf, count ); } // Forward from BLEUART to Serial if ( bleuart.available() ) { uint8_t ch; ch = (uint8_t) bleuart.read(); Serial.write(ch); } } void connect_callback(void) { Serial.
BLEClientUart The Bluefruit nRF52 Feather codebase is in an early BETA stage and is undergoing active development based on customer feedback and testing. As such, the class documentation here is incomplete, and you should consult the Github repo for the latest code and API developments: https://goo.gl/LdEx62 BLEClientUart is a wrapper class for the client side of the NUS or 'Nordic UART Service' (aka 'BLE UART').
// Initialize Bluefruit with maximum connections as Peripheral = 0, Central = 1 // SRAM usage required by SoftDevice will increase dramatically with number of connections Bluefruit.begin(0, 1); Bluefruit.setName("Bluefruit52 Central"); // Configure DIS client clientDis.begin(); // Init BLE Central Uart Serivce clientUart.begin(); clientUart.setRxCallback(bleuart_rx_callback); // Increase Blink rate to different from PrPh advertising mode Bluefruit.setConnLedInterval(250); // Callbacks for Central Bluefruit.
Serial.println("Found it"); char buffer[32+1]; // read and print out Manufacturer memset(buffer, 0, sizeof(buffer)); if ( clientDis.getManufacturer(buffer, sizeof(buffer)) ) { Serial.print("Manufacturer: "); Serial.println(buffer); } // read and print out Model Number memset(buffer, 0, sizeof(buffer)); if ( clientDis.getModel(buffer, sizeof(buffer)) ) { Serial.print("Model: "); Serial.println(buffer); } Serial.println(); } Serial.print("Discovering BLE Uart Service ... "); if ( clientUart.
void bleuart_rx_callback(BLEClientUart& uart_svc) { Serial.print("[RX]: "); while ( uart_svc.available() ) { Serial.print( (char) uart_svc.read() ); } Serial.println(); } void loop() { if ( Bluefruit.Central.connected() ) { // Not discovered yet if ( clientUart.discovered() ) { // Discovered means in working state // Get Serial input and send to Peripheral if ( Serial.available() ) { delay(2); // delay a bit for all characters to arrive char str[20+1] = { 0 }; Serial.readBytes(str, 20); clientUart.
BLEBeacon The Bluefruit nRF52 Feather codebase is in an early BETA stage and is undergoing active development based on customer feedback and testing. As such, the class documentation here is incomplete, and you should consult the Github repo for the latest code and API developments: https://goo.gl/LdEx62 The BLEBeacon helper class allows you to easily configure the nRF52 as a 'Beacon', which uses the advertising packet to send out a specifically format chunk of data to any devices in listening range.
#include // Beacon uses the Manufacturer Specific Data field in the advertising // packet, which means you must provide a valid Manufacturer ID. Update // the field below to an appropriate value. For a list of valid IDs see: // https://www.bluetooth.
Testing If you test with the nRF Beacons application (iOS (https://adafru.it/vaC) or Android (https://adafru.it/vaD)) you can configure the app to look for the UUID, Manufacturer ID, Major and Minor values you provided, and you should be able to see the beacon, as shown in the two screenshots below: Make sure that the UUID, Major and Minor values match or the application won't detect your beacon node! © Adafruit Industries https://learn.adafruit.
BLEMidi The Bluefruit nRF52 Feather codebase is in an early BETA stage and is undergoing active development based on customer feedback and testing. As such, the class documentation here is incomplete, and you should consult the Github repo for the latest code and API developments: https://goo.gl/LdEx62 BLEMidi is a helper class that adds support for sending and receiving MIDI Messages using the MIDI over Bluetooth LE specification.
Example The blemidi example demonstrates how to use the BLEMidi helper class with the Arduino MIDI Library. The example sends a looping arpeggio, and prints any incoming MIDI note on and note off messages to the Arduino Serial Monitor.
int position = 0; // Store example melody as an array of note values byte note_sequence[] = { 74,78,81,86,90,93,98,102,57,61,66,69,73,78,81,85,88,92,97,100,97,92,88,85,81,78, 74,69,66,62,57,62,66,69,74,78,81,86,90,93,97,102,97,93,90,85,81,78,73,68,64,61, 56,61,64,68,74,78,81,86,90,93,98,102 }; void setup() { Serial.begin(115200); Serial.println("Adafruit Bluefruit52 MIDI over Bluetooth LE Example"); Bluefruit.begin(); Bluefruit.
} void handleNoteOff(byte channel, byte pitch, byte velocity) { // Log when a note is released. Serial.printf("Note off: channel = %d, pitch = %d, velocity - %d", channel, pitch, velocity); Serial.println(); } void loop() { // Don't continue if we aren't connected. if (! Bluefruit.connected()) { return; } // Don't continue if the connected device isn't ready to receive messages. if (! blemidi.notifyEnabled()) { return; } // Setup variables for the current and previous // positions in the note sequence.
} // read any new MIDI messages MIDI.read(); } Usage You will need to do a small bit of setup on your selected platform to connect to the BLE MIDI enabled Bluefruit52. Click on a platform below to view BLE MIDI setup instructions for your device: macOS (OS X) iOS Android Windows The arpeggio should automatically play once the Bluefruit52 is connected to your software synth. The video below shows the Bluefruit52 connected to Moog's Animoog on iOS.
BLEHidAdafruit The Bluefruit nRF52 Feather codebase is in an early BETA stage and is undergoing active development based on customer feedback and testing. As such, the class documentation here is incomplete, and you should consult the Github repo for the latest code and API developments: https://goo.gl/LdEx62 BLEHidAdafruit allows you to simulate a mouse or keyboard using the HID (Human Interface Device) profile that is part of the Bluetooth Low Energy standard.
hid_keyboard (https://adafru.it/vb8): This example will simulate an HID keyboard, waiting for data to arrive via the nRF52's serial port (via USB serial), and send that data over the air to the bonded Central device. hid_mouse (https://adafru.it/vb9): This example will simulate an HID mouse. To use it run the sketch and open the Serial Monitor, then enter the appropriate characters to move the mouse or trigger/release the mouse buttons.
Opening the Serial Monitor will give you the following output (though it may differ depending on the debug level you have selected): Bonding on iOS To bond to an iOS device, make sure the sketch is running (as described above) and go into your Settings app and Select Bluetooth. You should see a device at the bottom of this page called Bluefruit52 (this may vary depending on the version of the sketch you are using!): © Adafruit Industries https://learn.adafruit.
Click the device, and you will get a pairing request like this: Click the Pair button, and the devices will be paired and bonded, and will automatically connect to each other in the future. If everything went will, you will see the device in your MY DEVICES list, as follows: Testing the HID Keyboard and Bonding To test the HID keyboard sketch and bonding process, open the Serial Monitor (or your favorite terminal emulator), enter some text, and if you are using the Serial Monitor click the Send button.
BLEAncs The Bluefruit nRF52 Feather codebase is in an early BETA stage and is undergoing active development based on customer feedback and testing. As such, the class documentation here is incomplete, and you should consult the Github repo for the latest code and API developments: https://goo.gl/LdEx62 BLEAncs is a helper class that enables you to receive notifications from the Apple Notification Center Service (https://adafru.it/wfj) from devices such as an iPhone or iPad.
Make sure that the Adafruit_SSD1306.h file has the 'SSD1306_128_32' macro enabled. Running the sketch with 'SSD1306_128_64' set will cause corrupted data to appear on the OLED display. Once the sketch is running on the nRF52 Feather you can proceed with the one-time pairing process, described below. Pairing to your Mobile Device Before you can start receiving notifications, you will need to 'pair' the nRF52 Feather and the mobile device.
2. Scroll to the bottom of the list of 'My Devices' and click on Bluefruit52 under Other Devices: 3. When the pairing dialog box comes up, click the Pair button: 4. Wait for the pairing process to complete, at which point Bluefruit52 should appear in the My Devices list with the Connected status: Once two devices have been paired, they will automatically reconnect to each other whenever they are in range and have their Bluetooth radios enabled.
Certain alerts (such as incoming calls) can also have actions associated with them, making use of the three buttons on the left-hand side of the display to decide which action to take. In the ancs_oled example, we have a special section of code for incoming calls where you can accept or decline a call with an appropriate button press: // Check buttons uint32_t presedButtons = readPressedButtons(); if ( myNotifs[activeIndex].ntf.
BLEClientCts The Bluefruit nRF52 Feather codebase is in an early BETA stage and is undergoing active development based on customer feedback and testing. As such, the class documentation here is incomplete, and you should consult the Github repo for the latest code and API developments: https://goo.gl/LdEx62 BLEClientCts is a helper class that implements adopted Current Time Service (https://adafru.it/BiT) , which enables you to receive time from devices such as an iPhone or iPad.
Adafruit_GFX (https://adafru.it/xep) (Github source (https://adafru.it/aJa)) Adafruit_SSD1306 (https://adafru.it/xep) (Github source (https://adafru.it/aHq)) Loading the Sketch The client_cts_oled sketch can be loaded via the examples menu under Peripheral > client_cts_oled: With the sketch loaded, you can build the firmware and then flash it to your device via the Upload button or menu option.
3. When the pairing dialog box comes up, click the Pair button: 4. Wait for the pairing process to complete, at which point Bluefruit52 should appear in the My Devices list with the Connected status: Once two devices have been paired, they will automatically reconnect to each other whenever they are in range and have their Bluetooth radios enabled. Wait for Time Data At this point, time data from the mobile device will be read and display on the the OLED.
© Adafruit Industries https://learn.adafruit.
BLECentral This page is a work in progress as the API is changing as we migrate to S132v5 and add better Central mode support. The Central mode API is accessible via Bluefruit.Central.
nRF52 ADC The nRF52832 includes an adjustable 'successive-approximation ADC' which can be configured to convert data with up to 14-bit resolution (0..16383), and the reference voltage can be adjusted up to 3.6V internally. The default values for the ADC are 10-bit resolution (0..1023) with a 3.6V reference voltage, meaning every digit returned from the ADC = 3600mV/1024 = 3.515625mV. Analog Reference Voltage The internal reference voltage is 0.
int adcin = A5; int adcvalue = 0; float mv_per_lsb = 3600.0F/1024.0F; // 10-bit ADC with 3.6V input range void setup() { Serial.begin(115200); while ( !Serial ) delay(10); } // for nrf52840 with native usb void loop() { // Get a fresh ADC value adcvalue = analogRead(adcin); // Display the results Serial.print(adcvalue); Serial.print(" ["); Serial.print((float)adcvalue * mv_per_lsb); Serial.println(" mV]"); delay(100); } Advanced Example (12-bit, 3.
{ battery_level } else if (mvolts > { battery_level } else if (mvolts > { battery_level } else if (mvolts > { battery_level } else if (mvolts > { battery_level } else { battery_level } = 100; 2900) = 100 - ((3000 - mvolts) * 58) / 100; 2740) = 42 - ((2900 - mvolts) * 24) / 160; 2440) = 18 - ((2740 - mvolts) * 12) / 300; 2100) = 6 - ((2440 - mvolts) * 6) / 340; = 0; return battery_level; } void setup() { Serial.
delay(1000); } © Adafruit Industries https://learn.adafruit.
Memory Map This page applies to BSP 0.8.0 and higher, which introduced bootloader v5.1.0 and S132 v5.x.x. For earlier releases (BSP release < 0.8.0) see bootloader v0.5.0 and S132 v2.x.x at the bottom of this page. BSP release & Bootloader version The memory usage depends on the version of the Softdevice and/or bootloader (single/dual bank). Following is the Bootloader and Softdevice version included with BSP release - 0.9.x :nRF52832 S132 v6.1.0 single bank andnRF52840 S140 v6.1.0 single bank - 0.8.
SoftDevice: This section of flash memory contains the Soft Device, which is Nordic's black box Bluetooth Low Energy stack. Application: This section of flash memory stores the user sketches that you compile in the Arduino IDE. Reserved: This section of flash memory is kept empty to enable dual banks safe firmware updates.
thread stack, malloc() etc. The size, based on the variables shown below, is Y = 64 - 12.5 - X - 2 ( KB ), where 12.5KB will vary depending on the SoftDevice used. Stack Memory: Used by non RTOS thread code, this is mostly for Interrupt Service Routines (ISRs) and SoftDevice API calls. The current size is 2 KB. Functions affecting SoftDevice SRAM usage The Bluefruit nRF52 configNNN() functions set the behavior of SoftDevice, thus determining the total SRAM usage.
[CFG] SoftDevice config requires more SRAM than provided by the linker. App Ram Start must be at least 0x20004180 (provided 0x20003200). Please update linker file or re-config SoftDevice. © Adafruit Industries https://learn.adafruit.
Software Resources To help you get your Bluefruit LE module talking to other Central devices, we've put together a number of open source tools for most of the major platforms supporting Bluetooth Low Energy. Bluefruit LE Client Apps and Libraries Adafruit has put together the following mobile or desktop apps and libraries to make it as easy as possible to get your Bluefruit LE module talking to your mobile device or laptop, with full source available where possible: Bluefruit LE Connect (https://adafru.
Bluefruit LE Connect for OS X (https://adafru.it/o9F) (Swift) This OS X desktop application is based on the same V2.x codebase as the iOS app, and gives you access to BLE UART, basic Pin I/O and OTA DFU firmware updates from the convenience of your laptop or mac. This is a great choice for logging sensor data locally and exporting it as a CSV, JSON or XML file for parsing in another application, and uses the native hardware on your computer so no BLE dongle is required on any recent mac.
$ ./bluefruit bluefruit v0.3 Usage: bluefruit [options...] Commands: Scan peripherals: Automatic update: Custom firmware: Show this screen: Show version: Options: --uuid --enable-beta scan update [--enable-beta] [--uuid ] dfu --hex [--init ] [--uuid ] --help --version If present the peripheral with that uuid is used.
supported Bluetooth 4.0 USB dongles (http://adafru.it/1327) to emulate BLE on the system (though at this stage it's still in early BETA and drops the connection and takes more care to work with). This app allows you to collect sensor data or perform many of the same functionality offered by the mobile Bluefruit LE Connect apps, but on the desktop. The app is still in BETA, but full source (https://adafru.it/ijE) is available in addition to the easy to use pre-compiled binaries (https://adafru.it/ijB).
AdaLink (https://adafru.it/fPq) (Python) This command line tool is a python-based wrapper for programming ARM MCUs using either aSegger JLink (https://adafru.it/fYU) or an STLink/V2 (https://adafru.it/ijF). You can use it to reflash your Bluefruit LE module using the latest firmware from the Bluefruit LE firmware repo (https://adafru.it/edX). Details on how to use the tool are available in the readme.md file on the main Adafruit_Adalink (https://adafru.it/fPq) repo on Github.
$ python flash.py --jtag=jlink --board=blefriend32 --softdevice=8.0.0 --bootloader=2 --firmware=0.6.7 jtag : jlink softdevice : 8.0.0 bootloader : 2 board : blefriend32 firmware : 0.6.7 Writing Softdevice + DFU bootloader + Application to flash memory adalink -v nrf51822 --programmer jlink --wipe --program-hex "Adafruit_BluefruitLE_Firmware/softdevice/s110_nrf51_8.0.0 ... © Adafruit Industries https://learn.adafruit.
Downloads The following resources may be useful working with the Bluefruit nRF52 Feather: Adafruit_nRF52_Arduino (https://adafru.it/vaF): The core code for this device (hosted on Github) nRF52 Example Sketches (https://adafru.it/vaK): Browse the example code from the core repo on Github nRF52832 Product Specification (https://adafru.it/vaR): Key technical documentation for the nRF52832 SoC EagleCAD PCB files on GitHub (https://adafru.it/vbH) https://adafru.it/z4c https://adafru.
© Adafruit Industries https://learn.adafruit.
FAQs NOTE: For FAQs relating to the BSP, see the dedicated BSP FAQ list (https://adafru.it/vnF). What are the differences between the nRF51 and nRF52 Bluefruit boards? Which one should I be using? The two board families take very different design approaches. All of the nRF51 based modules are based on an AT command set (over UART or SPI), and require two MCUs to run: the nRF51 hosting the AT command parser, and an external MCU sending AT style commands.
line, and enter the following command: $ ./arm-none-eabi-gdb something.ino.elf ` something.ino.elf ` is the name of the .elf file generated when you built your sketch. You can find this by enabling 'Show verbose output during: [x] compilation' in the Arduino IDE preferences. You CAN run GDB without the .elf file, but pointing to the .elf file will give you all of the meta data like displaying the actual source code at a specific address, etc.
Next select the Attach to running program option in the top-left hand corner, or via the menu system, which will cause the debugger to connect to the nRF52 over SWD: © Adafruit Industries https://learn.adafruit.
At this point, you can click the PAUSE icon to stop program execution, and then analyze variables, or set breakpoints at appropriate locations in your program execution, and debug as you would with most other embedded IDEs! Clicking on the left-hand side of the text editor will set a breakpoint on line 69 in the image below, for example, and the selecting Debug > Reset > Reset & Run from the menu or icon will cause the board to reset, and you should stop at the breakpoint you set: © Adafruit Industries h
You can experiment with adding some of the other debug windows and options via the View menu item, such as the Call Stack which will show you all of the functions that were called before arriving at the current breakpoint: Can I make two Bluefruit nRF52's talk to each other? Yes, by running one board in peripheral mode and one board in central mode, where the central will establish a connection with the peripheral board and you can communicate using BLE UART or a custom service.