Close Menu
  • Articles
    • Learn Electronics
    • Product Review
    • Tech Articles
  • Electronics Circuits
    • 555 Timer Projects
    • Op-Amp Circuits
    • Power Electronics
  • Microcontrollers
    • Arduino Projects
    • STM32 Projects
    • AMB82-Mini IoT AI Camera
    • BLE Projects
  • IoT Projects
    • ESP8266 Projects
    • ESP32 Projects
    • ESP32 MicroPython
    • ESP32-CAM Projects
    • LoRa/LoRaWAN Projects
  • Raspberry Pi
    • Raspberry Pi Projects
    • Raspberry Pi Pico Projects
    • Raspberry Pi Pico W Projects
  • Electronics Calculator
Facebook X (Twitter) Instagram
  • About Us
  • Disclaimer
  • Privacy Policy
  • Contact Us
  • Advertise With Us
Facebook X (Twitter) Instagram Pinterest YouTube LinkedIn
How To Electronics
  • Articles
    • Learn Electronics
    • Product Review
    • Tech Articles
  • Electronics Circuits
    • 555 Timer Projects
    • Op-Amp Circuits
    • Power Electronics
  • Microcontrollers
    • Arduino Projects
    • STM32 Projects
    • AMB82-Mini IoT AI Camera
    • BLE Projects
  • IoT Projects
    • ESP8266 Projects
    • ESP32 Projects
    • ESP32 MicroPython
    • ESP32-CAM Projects
    • LoRa/LoRaWAN Projects
  • Raspberry Pi
    • Raspberry Pi Projects
    • Raspberry Pi Pico Projects
    • Raspberry Pi Pico W Projects
  • Electronics Calculator
How To Electronics
Home » Nordic nRF52840 Advanced Bluetooth 5 with Arduino IDE – Getting Started
BLE Projects

Nordic nRF52840 Advanced Bluetooth 5 with Arduino IDE – Getting Started

Mamtaz AlamBy Mamtaz AlamUpdated:July 20, 20235 Comments11 Mins Read
Share Facebook Twitter LinkedIn Telegram Reddit WhatsApp
NRF52840 Arduino IDE
Share
Facebook Twitter LinkedIn Pinterest Email Reddit Telegram WhatsApp

Overview: Getting Started with Nordic nRF52840 using Arduino IDE

In this article we will learn about Bluetooth Low Energy 5.0 & its application using Nordic nRF52840 with Arduino IDE. The nRF52840 SoC is a flexible, efficient Bluetooth 5 designed and developed by Nordic Semiconductor. The nRF52840 SoC is built around a 32-bit ARM® Cortex®-M4F processor optimized for ultra-low power operation. It has protocol support for Bluetooth 5, Bluetooth mesh, ANT and 2.4 GHz proprietary stacks.

The NRF52840 BLE 5.0 has a wide range of applications like Mesh Networking, For example, switching off an entire building of lights from a single smartphone. Similarly, it is used in healthcare applications like BPM, SP02, Thermometer & others. The other areas of applications include Fitness & Sports area for Athletes, Internet Connectivity, Generic sensors, HID connectivity over GATT Profiles, Proximity Sensing, audio hardware, Alert System, wireless keyboards, mice, and game controllers.

In this getting started tutorial, we will program the NRF52832 Development Board from Makerfabs. We will learn all about the GPIO Pins, architecture & Pin Mapping. We will also lear about the Bluefruit App from Adafruit. Using the Bluefruit App, we can control various devices through a wireless connectivity between Android App & NRF52840 Board.



What is Bluetooth Low Energy (BLE 5.0)?

Bluetooth 5.0 is the latest version of the Bluetooth wireless communication standard. Bluetooth 5 is the most significant advancement in the Bluetooth standard since the introduction of Bluetooth Low Energy in Bluetooth 4.0. It’s commonly used for wireless headphones and other audio hardware, as well as wireless keyboards, mice, and game controllers. Bluetooth is also used for communication between various smart home and Internet of Things (IoT) devices.

There are four significant new features of Bluetooth 5 compared to BLE 4.0:
1. A higher bit rate of 2 Mbps.
2. A long-range mode with better sensitivity at two new lower bit rates of 500 kbps and 125 kbps.
3. An 8 x improvement in broadcast capability with advertising extensions.
4. An improved channel selection algorithm


BLE 5.0 Terms

1. Central
The Central is the host computer that is often a mobile device such as a phone or tablet, or maybe desktop or laptop.

2. Peripheral
The Peripheral is the connected devices such as heart rate monitor, smartwatch, or fitness tracker.

3. Advertising
The term Advertising means the information sent by the peripheral during connection set up. When a device advertises, it is transmitting the name of the device and describing its capabilities. The central looks for advertising peripheral to connect to, and uses that information to determine what the peripheral is capable of.

4. Service
It is the function that peripheral device provides. The peripheral advertises its services. A really common service that we use is the UART service, which acts like a hardware UART and is a way of bidirectionally sending information to and from devices.

5. Packet
The data transmitted by a device is called a Packet. BLE devices and host computers transmit and receive data in small bursts called packets.


Nordic nRF52840 System on Chip

NRF52840 Chip

The nRF52840 System on Chip is built around a 32-bit ARM® Cortex®-M4F processor optimized for ultra-low power operation, combining Bluetooth 5, Bluetooth Mesh, Thread, IEEE 802.15.4, ANT and 2.4GHz proprietary. It is also featured with an on-chip NFC-A tag and an on-chip USB 2.0 (Full speed) controller. The SoC is developed with 1 MB FLASH and 256 kB RAM.

Features & Specifications

1. Advanced Single-chip 2.4 GHz multi-protocol SoC
2. 32-bit ARM Cortex-M4F Processor
3. 1.7v to 5.5v operation
4. 1MB flash + 256kB RAM
5. Support for long-range and high throughput
6. 802.15.4 radio Support
7. On-chip NFC
8. PPI –Programmable Peripheral Interconnect
9. Automated power management system
10. Configurable Analog/Digital I/O mapping
11. 48 GPIO, 1 QSPI, 4 SPI, 2 I2C, I²S, 2 UART, 4 PWM
12. USB 2.0 controller
13. Digital microphone interface (PDM)
14. Quadrature decoder
15. 12-bit ADC
16. Low power comparator
17. On-air compatible with nRF52, nRF51 & nRF24 Series

To learn more about the features and specification of the NRF52840 Chip, you can follow the following Datasheet: nRF52840 Datasheet


Nordic nRF52840 Development Board

There are various manufacturer of Nordic nRF52840 Development Board. The board are usually programmed using Segger Embedded Studio. But some of the boards do have support for CircuitPython & Arduino IDE. In this guide we will program nRF52840 Development Board using Arduino IDE.

Now we need to select a board to get started. There are multiple boards available in the market from different vendors as shown in the image below.

Most of the boards shown in the image are quite expensive and range from 30$ price to 70$. So I selected the best board which can be purchased at a reasonable price. The criteria for selection is that the board should have all the best features of nRF52840 Chip. The board should support CircuitPython as well as Arduino IDE. The board should also have support for various Bootloaders.

So I selected MakePython nRF52840 board from Makerfabs whcih costs only 20$. The board has an additional 1.3″ I2C OLED Display which is an extra advantage for begineers like us. The MakePython nRF52840 Board supports both Arduino & Python Code.

MakePython NRF52840 Boards

You can purchase this board from this link: MakePython nRF52840 Board




MakePython nRF52840 Board

MakePython nRF52840 is a powerful, generic BLE MCU module target to CircuitPython/MicroPython learners & developers. It is true “breadboard compatible”, with the very detailed pins explanation, it is easy to learn& use.

This MakePython nRF52840 leads out all pins of Nordic nRF52840, programmed with CircuitPython by default, users can begin the CircuitPython developing as getting them on hand. It is also compatible with the Arduino making it easy to get started if the correct bootloader downloaded.

MakePython nRF52840 Board

Let us learn about the MakePython nRF52840 Pins. The board has 20 Outer Left PIN, 8 Inner Left PIN, 12 Outer Right PIN & 9 Inner Right PIN. The SSD1306/SSD1315 OLED Display SDA & SCL Pin is Pin P0.26 and P0.27 on the board. The onboard LED is at Pin. The board has 2 micro-USB Port. The top side of board(OLED side) MicroUSB is USB 2.0 port and the bottom side of board USB-to-UART(CP2102) port.

NRF52840 Pins Description


Getting Started with Nordic nRF52840 using Arduino IDE

So thats all about the Hardware Part. Now let’t move to the Programming Part and Program nRF52840 using Arduino IDE. The best part about this board is, the board is having Pre-installed “CircuitPython Bootloader” as well as “Arduino Bootloader“.

If you want to learn how to flash Arduino bootloader to nRF52840 Board you can follow the following Guide below.


Downloading Arduino Bootloader to nRF52840 Board

Note: Skip this Step, if you are using the same nRF52840 Development Board, i.e MakePython nRF52840

In order to download Firmware to nRF52840 Board, you need to have a J-Link. If you don’t have J-Link then you can purchase it from the following link: https://amzn.to/3hRdvz7

These steps show how to download the Arduino firmware if you had an nrf52840 board not supported by Arduino Firmware.

Step 1: Download J-Link from the following Link: https://www.segger.com/downloads/jlink/JLink_Windows.exe

Step 2: Make the following connection between J-Link Connector & nRF52840 Board.

J-Link nRF52840 Connection

Step 3: Open J-Flash and select “Create a new Project“. Then Click on “Start J-Flash“.

On the new window Select “Cortex-M0 Board“. Select SWD for Interface & Speed at 4000. And click OK.

Step 4: Select nRF52840_xxAA

Step 5: Download nRF52840 Arduino Firmware from following Link: nRF5840 Arduino Bootloader

Step 6: Power the Board using MicroUSB Port. Open the file and select the firmware you just downloaded.

Step 7: Now Click on Target. Click on “Connect“. This will connect the Board with J-Link. Then Select Manual Programming. First Erase the chip by clicking on “Erase Chip“. Once the Chip is Erased, you can now program the device by clicking on “Program & Verify” option.

You have successfully flashed Arduino Bootloader to nrF52840 Development Board.


Adding nRF52840 to Board Manager of Arduino IDE

Now we need to install Boards to the Arduino IDE. So follow the following steps:

Step 1: Open your Arduino IDE. Click on File >>> Preference

Step 2: Copy the following Board Manager Url to the “Additional Board Manager URLs” Section. And after adding Click on OK.

1
https://adafruit.github.io/arduino-board-index/package_adafruit_index.json

Step 3: Now Go to Tools >>>> Boards >>>> Board Manager

Step 4: Now Search for NRF52840 in the Search Box.

So select nrf52 Adafruit Option & click on install. So after a while, the board will be successfully installed.



nRF52840 Arduino 1st Program – Blinking of LED

Now let us test the board by writing an LED Blink Code. This simple code is like writing the “Hello World” Command in the C program. This program will help you to know whether the Board is working or not. This also verifies whether the Bootloader is uploaded & working.

So take an LED of any color and connect the LED Positive Pin to P0.30 of MakePython nRF52840 Board. Connect the LED negative pin to GND.

nRF52840 Arduino Getting Started

Here is a Simple Arduino Code. Copy the following Arduino Code and Paste it in the Arduino IDE window.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#define LED_BUILTIN 30
 
// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);
}
 
// the loop function runs over and over again forever
void loop() {
  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);                       // wait for a second
}

Now compile the code. After compiling, Select the following Board and Port & Click on Upload. You can upload the code to nRF52840 Board using any of the USB Port, as it has 2 USB Ports. The CP2102 Driver needs to be installed on your PC in order to show the Port.

So the after the code is uploaded successfully the LED will start blinking. You can change the blink interval to check more. You can also try the same code with some other Input/Output Pins.

nRF52840 Arduino Getting Started LED Blink

Well that’s all about nRF52840 Arduino Getting Started Tutorial. Now let us move to the main part of the nRF52840 chip, i.e. Wireless Communication Part.




Adafruit Bluefruit LE Connect App

To interact with your board from your phone or tablet, you’ll use the Adafruit Bluefruit LE Connect App. Download or Simply Install the App from Apple App Store or Google Play App Store

This App only works if you have code running on nRF52840 Development Board. The device will only advertise when the code is running. The means the device will transmit/show the device name on Android/Apple Phone if the device is running.

So now lets run code on the board and check the working.


Arduino Code/Program to Communicate with Bluefruit LE Connect App

First we need to install “Bluefruit App Library” to the Arduino IDE. The Bluefruit App is supported by Adafruit_BusIO Library.

Download Adafruit_BusIO Library

Since we are using OLED Display to display the events happening. So we need to install Libraries for OLED Display. Download the following Library and add it to the Library Folder.

Download SSD1306 Library & Download Adafruit GFX Library

Now open a New Sketch in your Arduino IDE and copy the following code as shown below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
#include <bluefruit.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
 
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
 
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
 
 
// OTA DFU service
BLEDfu bledfu;
 
// Uart over BLE service
BLEUart bleuart;
 
// Function prototypes for packetparser.cpp
uint8_t readPacket (BLEUart *ble_uart, uint16_t timeout);
float   parsefloat (uint8_t *buffer);
void    printHex   (const uint8_t * data, const uint32_t numBytes);
 
// Packet buffer
extern uint8_t packetbuffer[];
 
void setup(void)
{
  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D/0x3C for 128x64
    Serial.println(F("SSD1306 allocation failed"));
    for(;;) // Don't proceed, loop forever
    {
        Serial.println("Now Loop!");
        delay(500);
    }
  }
  Serial.println(F("SSD1306 init success"));
  display.clearDisplay();
  
  Serial.begin(115200);
  while ( !Serial ) delay(10);   // for nrf52840 with native usb
 
  Serial.println(F("Adafruit Bluefruit52 Controller App Example"));
  Serial.println(F("-------------------------------------------"));
 
   display.clearDisplay();
   display.setTextSize(2);             // Normal 1:1 pixel scale
   display.setTextColor(WHITE);        // Draw white text
   display.setCursor(0,0);             // Start at top-left corner
   display.print("Bluefruit52");
   display.setCursor(0,30);  
   display.print("Controller");
   display.display();  
 
  Bluefruit.begin();
  Bluefruit.setTxPower(4);    // Check bluefruit.h for supported values
  Bluefruit.setName("Bluefruit52");
 
  // To be consistent OTA DFU should be added first if it exists
  bledfu.begin();
 
  // Configure and start the BLE Uart service
  bleuart.begin();
 
  // Set up and start advertising
  startAdv();
 
  Serial.println(F("Please use Adafruit Bluefruit LE app to connect in Controller mode"));
  Serial.println(F("Then activate/use the sensors, color picker, game controller, etc!"));
  Serial.println();  
 
  display.clearDisplay();
   display.setTextSize(2);             // Normal 1:1 pixel scale
   display.setTextColor(WHITE);        // Draw white text
   display.setCursor(0,0);             // Start at top-left corner
   display.print("Activate");
   display.setCursor(0,30);  
   display.print("Controls");
   display.display();  
}
 
void startAdv(void)
{
  // Advertising packet
  Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE);
  Bluefruit.Advertising.addTxPower();
  
  // Include the BLE UART (AKA 'NUS') 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.5 ms
   * - Timeout for fast mode is 30 seconds
   * - Start(timeout) with timeout = 0 will advertise forever (until connected)
   *
   * For recommended advertising interval
   * https://developer.apple.com/library/content/qa/qa1931/_index.html  
   */
  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.start(0);                // 0 = Don't stop advertising after n seconds  
}
 
/**************************************************************************/
/*!
    @brief  Constantly poll for new command or response data
*/
/**************************************************************************/
void loop(void)
{
  // Wait for new data to arrive
  uint8_t len = readPacket(&bleuart, 500);
  if (len == 0) return;
 
  // Got a packet!
  // printHex(packetbuffer, len);
 
  // Color
  if (packetbuffer[1] == 'C') {
    uint8_t red = packetbuffer[2];
    uint8_t green = packetbuffer[3];
    uint8_t blue = packetbuffer[4];
    Serial.print ("RGB #");
    if (red < 0x10) Serial.print("0");
    Serial.print(red, HEX);
    if (green < 0x10) Serial.print("0");
    Serial.print(green, HEX);
    if (blue < 0x10) Serial.print("0");
    Serial.println(blue, HEX);
 
    display.clearDisplay();
    display.setTextSize(2);             // Normal 1:1 pixel scale
    display.setTextColor(WHITE);        // Draw white text
    display.setCursor(0,0);             // Start at top-left corner
    display.print("RGB Color");
    display.setCursor(10,30);  
    display.print("#");
    display.print(red, HEX);
    display.print(green, HEX);
    display.println(blue, HEX);
    display.display();
  
  }
 
  // Buttons
  if (packetbuffer[1] == 'B') {
    uint8_t buttnum = packetbuffer[2] - '0';
    boolean pressed = packetbuffer[3] - '0';
    Serial.print ("Button "); Serial.print(buttnum);
    if (pressed) {
      Serial.println(" pressed");
      display.clearDisplay();
      display.setTextSize(1);             // Normal 1:1 pixel scale
      display.setTextColor(WHITE);        // Draw white text
      display.setCursor(0,0);             // Start at top-left corner
      display.print("Button Status");
      display.setCursor(0,20);  
      display.print("pressed ");
      display.print(buttnum);
      display.display();
    }
    else
    {
      Serial.println(" released");
      display.clearDisplay();
      display.setTextSize(1);             // Normal 1:1 pixel scale
      display.setTextColor(WHITE);        // Draw white text
      display.setCursor(0,0);             // Start at top-left corner
      display.print("Button Status");
      display.setCursor(0,20);  
      display.print("Released ");
      display.print(buttnum);
      display.display();
    }
  }
 
  // GPS Location
  if (packetbuffer[1] == 'L') {
    float lat, lon, alt;
    lat = parsefloat(packetbuffer+2);
    lon = parsefloat(packetbuffer+6);
    alt = parsefloat(packetbuffer+10);
    Serial.print("GPS Location\t");
    Serial.print("Lat: "); Serial.print(lat, 4); // 4 digits of precision!
    Serial.print('\t');
    Serial.print("Lon: "); Serial.print(lon, 4); // 4 digits of precision!
    Serial.print('\t');
    Serial.print(alt, 4); Serial.println(" meters");
 
    display.clearDisplay();
    display.setTextSize(1);             // Normal 1:1 pixel scale
    display.setTextColor(WHITE);        // Draw white text
    display.setCursor(0,0);             // Start at top-left corner
    display.print("GPS Location");
    display.setCursor(0,20);  
    display.print("Lat:");
    display.print(lat, 4);
    display.setCursor(0,30);  
    display.print("Lon:");
    display.print(lon, 4);
    display.setCursor(0,40);  
    display.print("Alt:");
    display.print(alt, 4);
    display.display();    
  }
 
  // 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();
 
    display.clearDisplay();
    display.setTextSize(1);             // Normal 1:1 pixel scale
    display.setTextColor(WHITE);        // Draw white text
    display.setCursor(0,0);             // Start at top-left corner
    display.print("Accelerometer");
    display.setCursor(0,20);  
    display.print("X: ");
    display.print(x);
    display.setCursor(0,30);  
    display.print("Y: ");
    display.print(y);
    display.setCursor(0,40);  
    display.print("Z: ");
    display.print(z);
    display.display();
    
  }
 
  // 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');
    Serial.print(y); Serial.print('\t');
    Serial.print(z); Serial.println();
 
    display.clearDisplay();
    display.setTextSize(1);             // Normal 1:1 pixel scale
    display.setTextColor(WHITE);        // Draw white text
    display.setCursor(0,0);             // Start at top-left corner
    display.print("Magnetometer");
    display.setCursor(0,20);  
    display.print("X: ");
    display.print(x);
    display.setCursor(0,30);  
    display.print("Y: ");
    display.print(y);
    display.setCursor(0,40);  
    display.print("Z: ");
    display.print(z);
    display.display();
  }
 
  // Gyroscope
  if (packetbuffer[1] == 'G') {
    float x, y, z;
    x = parsefloat(packetbuffer+2);
    y = parsefloat(packetbuffer+6);
    z = parsefloat(packetbuffer+10);
    Serial.print("Gyro\t");
    Serial.print(x); Serial.print('\t');
    Serial.print(y); Serial.print('\t');
    Serial.print(z); Serial.println();
 
    display.clearDisplay();
    display.setTextSize(1);             // Normal 1:1 pixel scale
    display.setTextColor(WHITE);        // Draw white text
    display.setCursor(0,0);             // Start at top-left corner
    display.print("Gyroscope");
    display.setCursor(0,20);  
    display.print("X: ");
    display.print(x);
    display.setCursor(0,30);  
    display.print("Y: ");
    display.print(y);
    display.setCursor(0,40);  
    display.print("Z: ");
    display.print(z);
    display.display();
  }
 
  // Quaternions
  if (packetbuffer[1] == 'Q') {
    float x, y, z, w;
    x = parsefloat(packetbuffer+2);
    y = parsefloat(packetbuffer+6);
    z = parsefloat(packetbuffer+10);
    w = parsefloat(packetbuffer+14);
    Serial.print("Quat\t");
    Serial.print(x); Serial.print('\t');
    Serial.print(y); Serial.print('\t');
    Serial.print(z); Serial.print('\t');
    Serial.print(w); Serial.println();
 
    display.clearDisplay();
    display.setTextSize(1);             // Normal 1:1 pixel scale
    display.setTextColor(WHITE);        // Draw white text
    display.setCursor(0,0);             // Start at top-left corner
    display.print("Quaternions");
    display.setCursor(0,20);  
    display.print("X: ");
    display.print(x);
    display.setCursor(0,30);  
    display.print("Y: ");
    display.print(y);
    display.setCursor(0,40);  
    display.print("Z: ");
    display.print(z);
    display.setCursor(0,50);  
    display.print("W: ");
    display.print(w);
    display.display();
  }
}



Similarly open another Tab on the Arduino IDE and paste the following code below. Save the file with the name “packetParser.cpp” as shown in the image below.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#include <string.h>
#include <Arduino.h>
#include <bluefruit.h>
 
 
#define PACKET_ACC_LEN                  (15)
#define PACKET_GYRO_LEN                 (15)
#define PACKET_MAG_LEN                  (15)
#define PACKET_QUAT_LEN                 (19)
#define PACKET_BUTTON_LEN               (5)
#define PACKET_COLOR_LEN                (6)
#define PACKET_LOCATION_LEN             (15)
 
//    READ_BUFSIZE            Size of the read buffer for incoming packets
#define READ_BUFSIZE                    (20)
 
 
/* Buffer to hold incoming characters */
uint8_t packetbuffer[READ_BUFSIZE+1];
 
/**************************************************************************/
/*!
    @brief  Casts the four bytes at the specified address to a float
*/
/**************************************************************************/
float parsefloat(uint8_t *buffer)
{
  float f;
  memcpy(&f, buffer, 4);
  return f;
}
 
/**************************************************************************/
/*!
    @brief  Prints a hexadecimal value in plain characters
    @param  data      Pointer to the byte data
    @param  numBytes  Data length in bytes
*/
/**************************************************************************/
void printHex(const uint8_t * data, const uint32_t numBytes)
{
  uint32_t szPos;
  for (szPos=0; szPos < numBytes; szPos++)
  {
    Serial.print(F("0x"));
    // Append leading 0 for small values
    if (data[szPos] <= 0xF)
    {
      Serial.print(F("0"));
      Serial.print(data[szPos] & 0xf, HEX);
    }
    else
    {
      Serial.print(data[szPos] & 0xff, HEX);
    }
    // Add a trailing space if appropriate
    if ((numBytes > 1) && (szPos != numBytes - 1))
    {
      Serial.print(F(" "));
    }
  }
  Serial.println();
}
 
/**************************************************************************/
/*!
    @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') && (replyidx == PACKET_ACC_LEN))
      break;
    if ((packetbuffer[1] == 'G') && (replyidx == PACKET_GYRO_LEN))
      break;
    if ((packetbuffer[1] == 'M') && (replyidx == PACKET_MAG_LEN))
      break;
    if ((packetbuffer[1] == 'Q') && (replyidx == PACKET_QUAT_LEN))
      break;
    if ((packetbuffer[1] == 'B') && (replyidx == PACKET_BUTTON_LEN))
      break;
    if ((packetbuffer[1] == 'C') && (replyidx == PACKET_COLOR_LEN))
      break;
    if ((packetbuffer[1] == 'L') && (replyidx == PACKET_LOCATION_LEN))
      break;
 
    while (ble_uart->available()) {
      char c =  ble_uart->read();
      if (c == '!') {
        replyidx = 0;
      }
      packetbuffer[replyidx] = c;
      replyidx++;
      timeout = origtimeout;
    }
    
    if (timeout == 0) break;
    delay(1);
  }
 
  packetbuffer[replyidx] = 0;  // null term
 
  if (!replyidx)  // no data or timeout
    return 0;
  if (packetbuffer[0] != '!')  // doesn't start with '!' packet beginning
    return 0;
  
  // check checksum!
  uint8_t xsum = 0;
  uint8_t checksum = packetbuffer[replyidx-1];
  
  for (uint8_t i=0; i<replyidx-1; i++) {
    xsum += packetbuffer[i];
  }
  xsum = ~xsum;
 
  // Throw an error message if the checksum's don't match
  if (xsum != checksum)
  {
    Serial.print("Checksum mismatch in packet : ");
    printHex(packetbuffer, replyidx+1);
    return 0;
  }
  
  // checksum passed!
  return replyidx;
}


Communication Between nRF52840 Adafruit Bluefruit LE Connect App

Compile the above sketch and flash it to your nRF52840 Devleopment Board. Once you are done uploading, open the Serial Monitor (Tools > Serial Monitor). The Serial Monitor will show the following output.

Now Open the Bluefruit LE Connect application on your mobile device. Connect to the appropriate target ‘Bluefruit52‘.

Bluefruit52 Connect

Once connected switch to the Controller application inside the app.

Bluefruit App Controller

Now you can Enable an appropriate control surface. The following are the controls as shown in the image below.


Now you can check the control of each function. The Accelerometer, Gyroscope, Magnetometer, Color Picker, etc can be enabled and disabled by turning the ON/OFF virtual button. The SSD1306 I2C OLED Display will display the data obtained from your Phone.


Video Tutorial & Explanation

Nordic nRF52840 Advanced Bluetooth 5 SoC (BLE 5.2) with Arduino IDE – Getting Started Tutorial
Watch this video on YouTube.

So, that’s all from nRF52840 Development Board Arduino Tutorial. In some other Tutorial, you will see more projects using BLE 5.0 Chips. If you have any doubts or queries, you can comment down below. All the suggestions are appreciated.

You can check another BLE 5.0 version here from Texas Instrument: Reyax RYB080I.

Share. Facebook Twitter Pinterest LinkedIn Tumblr Email Reddit Telegram WhatsApp
Previous ArticleESP8266 NRF24L01 Wifi Gateway with Arduino NRF24L01 Node
Next Article ESP8266 to ESP8266 Communication : Ad hoc Networking

Related Posts

Building a Smart Sensor Node with a BLE Microcontroller

Building a Smart Sensor Node with a BLE Microcontroller

PIR Motion Detection using Bluetooth & STM32 Board

PIR Motion Detection using Bluetooth & STM32 Board

Updated:December 23, 20234K
Mobile App with XIAO BLE nRF52840 Sense

Send/Receive Data to Mobile App with XIAO BLE nRF52840 Sense

Updated:August 18, 20221110K
Using IMU & Microphone on XIAO BLE nRF52840 Sense

Using IMU & Microphone on XIAO BLE nRF52840 Sense

Updated:March 23, 202527K
Seeed XIAO BLE nRF52840 Sense

Getting Started with Seeed XIAO BLE nRF52840 Sense

Updated:November 26, 202412K
Home Automation Raspberry Pi

Smart Phone Controlled Home Automation with Raspberry Pi

Updated:October 21, 20222K
View 5 Comments

5 Comments

  1. Mitchell on November 9, 2020 10:48 AM

    Hey! I watched your video on youtube and you have a great tutorial. I am currently using the adafruit itsy bitsy nRF52840 using the Arduino IDE and i am a beginner. Ive gotten through the arduino examples on the adafruit website but am looking to do some coding one step further. I am wondering if you have any tutorials or articles on specifically advertising the microcontroller to the phone (through nrf connect or another bluetooth app) while being able to package and send data from an external sensor like a hall effect sensor reading rpm

    Reply
    • Mr. Alam on November 9, 2020 11:09 AM

      Hi Mitchell thank you for the comment. Meanwhile, I don’t have any such tutorial but I will be making the tutorial very soon.

      Reply
  2. Marcos Tadeo on November 4, 2021 9:17 PM

    Hi.

    I am beginner developer, what is the format for Firmware? .Bin?

    thanks and regards

    Reply
  3. Anish on April 1, 2022 11:15 PM

    Hey Mitchell, did you find any other sources? I am using the itsybitsy too and would like to send sensor data to an app or computer using bluetooth

    Reply
  4. Anson on April 29, 2022 6:38 PM

    Hi, I am using itsybitsy nrf52840. Is it possible if I want to send collected data from one of the pins of the board to the Bluefruit app using BLE? If so, may I have the instruction for coding?

    Reply

CommentsCancel reply

Latest Posts
ESP32 Fingerprint Attendance System with Live Web Dashboard

ESP32 Fingerprint Attendance System with Live Web Dashboard

June 21, 2026
IoT Based PM & Air Quality Monitoring System using ESP32

IoT Based PM & Air Quality Monitoring System using ESP32

June 14, 2026
DIY ESP32 MLX90640 IR Thermal Camera with Live Web Display

DIY ESP32 MLX90640 IR Thermal Camera with Live Web Display

May 10, 2026
IoT Activity Tracker with ESP32 & Accelerometer Gyroscope

IoT Activity Tracker with ESP32 & Accelerometer/Gyroscope

May 2, 2026
A Guide to Sourcing Obsolete ICs for Vintage Projects

Beyond AliExpress: A Guide to Sourcing Obsolete ICs for Vintage Projects

April 21, 2026

ESP32 IoT Vehicle Motion Analyzer with MPU6050 & LIS3MDL

April 27, 2026
Building a Smart Sensor Node with a BLE Microcontroller

Building a Smart Sensor Node with a BLE Microcontroller

February 26, 2026
High-Accuracy Pitch, Roll, Yaw with ESP32 & BNO08x IMU

High-Accuracy Pitch, Roll, Yaw with ESP32 & BNO08x IMU

April 27, 2026
Top Posts & Pages
  • ESP32 Fingerprint Attendance System with Live Web Dashboard
    ESP32 Fingerprint Attendance System with Live Web Dashboard
  • IoT AC Energy Meter with PZEM-004T & ESP32 WebServer
    IoT AC Energy Meter with PZEM-004T & ESP32 WebServer
  • ESP32 CAN Bus Tutorial | Interfacing MCP2515 CAN Module with ESP32
    ESP32 CAN Bus Tutorial | Interfacing MCP2515 CAN Module with ESP32
  • LD2410 Sensor with ESP32 - Human Presence Detection
    LD2410 Sensor with ESP32 - Human Presence Detection
  • 12V DC to 220V AC Inverter Circuit & PCB
    12V DC to 220V AC Inverter Circuit & PCB
  • IoT Based Patient Health Monitoring on ESP32 Web Server
    IoT Based Patient Health Monitoring on ESP32 Web Server
  • Buck Converter: Basics, Working, Design & Application
    Buck Converter: Basics, Working, Design & Application
  • Silicon Controlled Rectifier (SCR): Construction, Working & Applications
    Silicon Controlled Rectifier (SCR): Construction, Working & Applications
Categories
  • Arduino Projects (197)
  • Articles (60)
    • Learn Electronics (19)
    • Product Review (15)
    • Tech Articles (28)
  • Electronics Circuits (46)
    • 555 Timer Projects (21)
    • Op-Amp Circuits (7)
    • Power Electronics (13)
  • IoT Projects (205)
    • ESP32 MicroPython (7)
    • ESP32 Projects (82)
    • ESP32-CAM Projects (15)
    • ESP8266 Projects (76)
    • LoRa/LoRaWAN Projects (22)
  • Microcontrollers (38)
    • AMB82-Mini IoT AI Camera (4)
    • BLE Projects (18)
    • STM32 Projects (19)
  • Raspberry Pi (93)
    • Raspberry Pi Pico Projects (57)
    • Raspberry Pi Pico W Projects (12)
    • Raspberry Pi Projects (24)
Follow Us
  • Facebook
  • Twitter
  • Pinterest
  • Instagram
  • YouTube
About Us

“‘How to Electronics’ is a vibrant community for electronics enthusiasts and professionals. We deliver latest insights in areas such as Embedded Systems, Power Electronics, AI, IoT, and Robotics. Our goal is to stimulate innovation and provide practical solutions for students, organizations, and industries. Join us to transform learning into a joyful journey of discovery and innovation.

Copyright © How To Electronics. All rights reserved.
  • About Us
  • Disclaimer
  • Privacy Policy
  • Contact Us
  • Advertise With Us

Type above and press Enter to search. Press Esc to cancel.

Ad Blocker Enabled!
Ad Blocker Enabled!
Looks like you're using an ad blocker. Please allow ads on our site. We rely on advertising to help fund our site.