This builds on the example BlinkyADC and adds support for transmitting data over Bluetooth to be received by some other device such as a computer or a mobile phone. Download the example BLE.zip which contains a readme describing each file in the package.
What is BLE
BLE stands for Bluetooth Low Energy (BLE and sometimes referred to as Bluetooth Smart) and is a short range radio communications protocol. There are two distinct types of nodes in a BLE network. A given node can be one or the other type or in some instances can act as both.
- Peripheral. A server in client/server terminology that has data to share with other nodes.
- Central. A client in client/server terminology that is interested in data from certain peripherals. Typically your mobile phone or tablet would act as a central.
In addition, peripherals can be connectable or non-connectable. A connectable peripheral is one where a central can connect and establish a session with the peripheral and maybe issue instructions to it. A non-connectable peripheral operates like a beacon and can broadcast its data to any number of listening centrals.
This example is to build a simple non-connectable peripheral that constantly broadcasts a few items of information to listening centrals
- The fixed string ‘Hello’
- A 16 bit value representing the last sample voltage on the analog input
- A 32 bit value representing the number of times the analog input has been sampled
Code
Unlike the previous examples, the code to add BLE support is a little too large to post here but is available in its entirety in the file BLE.cpp in the example package <SimpleBLE.zip>
In lieu of posting the code, each function in the source file BLE.cpp is listed here with a brief explanation of its purpose.
One Time Initialisation Functions
- InitialiseBLE. This is a wrapper function that handles all the individual initialisation functions.
- InitialiseBLEStack. This provides basic initialisation of the BLE stack (Nordic softdevice)
- InitialiseGAP. Initialise the Generic Access Profile. This defines how BLE devices discover and connect with one another.
- InitialiseGATT. Initialise the Generic Attribute Profile. This defines how data is exchanged between nodes.
Advertising Functions
Advertising is how BLE peripherals notify BLE centrals that they are present and how they can be communicated with.
- InitialiseAndStartAdvertsing. This function is called by the application when it wants to update the advertising packet with new data and (re)start advertising. This calls the function InitialiseAdvertising.
- InitialiseAdvertising. Configures advertising; What is present in the advertising packet, how frequently the packet is broadcast, how long the broadcast continues for, whether any scan response packets will be sent etc.
- StartAdvertising. Start broadcasting advertising packets. While broadcasting, the peripheral makes itself visible to nearby centrals.
- StopAdvertising. Stop broadcasting advertising packets. Stops broadcasting and is no longer visible to centrals.
Event Handlers
Invoked by the BLE stack (soft device) to notify the application code of BLE events.
- OnAdvertisingEvent. Called when an advertising event occurs.
- OnGATTEvent. Called when a GATT event occurs.
- OnBLEEvent. Called when a general BLE event occurs. This is used primarily when a central connects to manage connection/disconnection and data flow between the two nodes.
main.cpp
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include "nrf_delay.h"
#include "boards.h"
#include "main.h"
//
// Main entry point
//
int main()
{
//
// Initialise the board.
//
nrf_gpio_cfg_output(LED_A);
//
// Initialise logging over the SWO pin
//
ret_code_t retCode;
SWOInit();
//
// Enable ADC and immediately start a calibration
//
InitADC();
StartADCCalibration();
//
// Initilaise BLE
//
SWOPrintString("Initialise BLE");
if((retCode = InitialiseBLE("NSD123")) != NRF_SUCCESS)
{
HandleAppErrorCheck(retCode,"InitialiseBLE");
}
//
// Loop forever toggling the led ON/OFF
//
bool setOn = true,initialiseAdvertising = true;
uint32_t lastSampleNumber = 0;
while (true)
{
//
// If requested, (re)initialise advertising
//
if(initialiseAdvertising)
{
if((retCode = InitialiseAndStartAdvertising()) != NRF_SUCCESS)
{
HandleAppErrorCheck(retCode,"InitialiseBLE");
}
initialiseAdvertising = false;
}
//
// Toggle the LED
//
if(setOn)
{
nrf_gpio_pin_set(LED_A);
}
else
{
nrf_gpio_pin_clear(LED_A);
}
setOn = setOn ? false : true;
//
// Before going to sleep, start a sample
//
StartADCSample();
nrf_delay_ms(500);
//
// See if since StartADCSample a new sample value
// has become available
//
uint32_t currentSampleNumber;
uint32_t currentSampleValue = GetLastADCSampleValueRaw(¤tSampleNumber);
if(currentSampleNumber > lastSampleNumber)
{
//
// Sample number has changed therefore there
// must be a new sample available
//
float vSample = GetLastADCSampleValueVoltage(NULL);
SWOPrintString("Sample[%4u]: %u. %fV",currentSampleNumber,currentSampleValue,vSample);
lastSampleNumber = currentSampleNumber;
initialiseAdvertising = true;
}
}
}
Building and Flashing the Program
Any toolchain/programmer can be used for these steps. All the examples here are built using make and gcc. The binary is flashed using the Raspberry Pi networked programmer. See here for how to set up make, gcc and the Raspberry Pi networked programmer.
Building
From the terminal type:
C:\Projects\BLE> "c:\Program Files (x86)\GnuWin32\bin\make.exe" -f makefile CONFIG=Debug all
If there are no errors then the binary ble.elf should be output to the sub-folder bin\debug
Flashing the Binary to the Microcontroller
Hooking up the Programmer to the Microcontroller
See here for how to connect the programmer to the microcontroller.
Flashing
From a terminal type to flash both the softdevice (bluetooth stack) and the application code to the microcontroller:
C:\Projects\BLE> "C:\Program Files\NoSMD\SWorD\bin\SWorDProgrammer.exe" -program:C:\SDK\NordicSDK\nRF5_SDK_17.0.0_9d13099\components\softdevice\s132\hex\s132_nrf52_7.0.1_softdevice.hex,bin\debug\ble.elf -probe:rpi4programmer -pagesize:4096
Attempting to connect to rpi4programmer on 192.168.0.26::33332...
Connected to rpi4programmer on 192.168.0.26::33332...
Progress 100%
Completed with success
C:\Projects\BLE>
As with previous projects, the LED should be blinking and there should be printf like output on the SWO pin.
Testing BLE
Download an app to your smartphone or tablet. Some good options are:
- LightBlue
- nRF Connect
- BLE Laboratory
In this example I am using BLE Laboratory as you can see the advertising data changing in real time. The image below shows our device NSD123 and the data it is advertising.

0 Comments