MKR WiFi 1010 Bluetooth® Low Energy
Learn how to access your board from your phone via Bluetooth®.
Enabling Bluetooth® Low Energy
Bluetooth® Low Energy separates itself from what is now known as “Bluetooth® Classic” by being optimized to use low power with low data rates. There are two different types of Bluetooth® devices: central or peripheral. A central Bluetooth® device is designed to read data from peripheral devices, while the peripheral devices are designed to do the opposite. Peripheral devices continuously post data for other devices to read, and it is precisely what we will be focusing on today.
This tutorial is a great starting point for any maker interested in creating their own Bluetooth® projects.
Hardware & Software Needed
- Arduino IDE (online or offline).
- ArduinoBLE library installed.
- Arduino MKR WiFi 1010 (link to store).
- Micro USB cable
- LED
- 220 ohm resistor
- Breadboard
- Jumper wires
Service & Characteristics
A service can be made up of different data measurements. For example, if we have a device that measures wind speed, temperature and humidity, we can set up a service that is called “Weather Data”. Let’s say the device also records battery level and energy consumption, we can set up a service that is called “Energy information”. These services can then be subscribed to central Bluetooth® devices.
Characteristics are components of the service we mentioned above. For example, the temperature or battery level are both characteristics, which record data and update continuously.
Unique Universal Identifier (UUID)
When we read data from a service, it is important to know what type of data we are reading. For this, we use UUIDs, who basically give a name to the characteristics. For example, if we are recording temperature, we want to label that characteristic as temperature, and to do that, we have to find the UUID, which in this case is “2A6E”. When we are connecting to the device, this service will then appear as “temperature”. This is very useful when tracking multiple values.
If you want to read more about UUIDs, services, and characteristics, check the links below:
Circuit
Follow the wiring diagram below to connect the LED to the MKR WiFi 1010 board.
Schematic
Follow the wiring diagram below to connect the LED to the MKR WiFi 1010 board.
Creating the Program
The goal with this tutorial is to be able to access our MKR WiFi 1010 board via Bluetooth®, and control an LED onboard it. We will also retrieve the latest readings from an analog pin. We will then use UUIDs from the official Bluetooth® page, that are compliant with GATT (Generic Attribute Profile). This way, when we access our device later, the service and characteristics can be recognized!
We will go through the following steps in order to create our sketch:
- Create a new service.
- Create an LED characteristic.
- Create an analog pin characteristic.
- Set the name for our device.
- Start advertising the device.
- Create a conditional that works only if an external device is connected (smartphone).
- Create a conditional that turns on an LED over Bluetooth®.
- Read an analog pin over Bluetooth®.
1. First, let's make sure we have the drivers installed. If we are using the Web Editor, we do not need to install anything. If we are using an offline editor, we need to install it manually. This can be done by navigating to Tools > Board > Board Manager.... Here we need to look for the Arduino SAMD boards (32-bits Arm® Cortex®-M0+) and install it.
2. Now, we need to install the library needed. If we are using the Web Editor, there is no need to install anything. If we are using an offline editor, simply go to Tools > Manage libraries.., and search for ArduinoBLE and install it.
With the dependencies installed, we will now move on to the programming part.
Code Explanation
NOTE: This section is optional, you can find the complete code further down on this tutorial.
First, we need to include the ArduinoBLE library, and create a new service. We will name the service "180A" which is translated to "Device Information". We will then create two characteristics, one for the LED, and one for the analog pin. The name "2A57" is translated to "Digital Output" and "2A58 is translated to "Analog".
1#include <ArduinoBLE.h>2BLEService newService("180A"); // creating the service3
4BLEUnsignedCharCharacteristic randomReading("2A58", BLERead | BLENotify); // creating the Analog Value characteristic5BLEByteCharacteristic switchChar("2A57", BLERead | BLEWrite); // creating the LED characteristic6
7const int ledPin = 2;8long previousMillis = 0;
In the
setup()
, we will start by initializing serial communication, define both the in-built LED and the LED we connected to pin 2, and initialize the ArduinoBLE library.We then set the name for our device, using the command
BLE.setLocalName("MKR WiFi 1010");
, then add the characteristics we defined previously to the service created earlier, newService
. After they have been added, we will also add the service, using the command BLE.addService(newService);
.The final steps we will take is to set the starting value of 0 for both characteristics. This is mostly important for the LED, since 0 means it will be OFF from the start.
The setup is finished by using the command
BLE.advertise();
, which makes it visible for other devices to connect to.1void setup() {2 Serial.begin(9600); // initialize serial communication3 while (!Serial); //starts the program if we open the serial monitor.4
5 pinMode(LED_BUILTIN, OUTPUT); // initialize the built-in LED pin to indicate when a central is connected6 pinMode(ledPin, OUTPUT); // initialize the built-in LED pin to indicate when a central is connected7
8 //initialize ArduinoBLE library9 if (!BLE.begin()) {10 Serial.println("starting Bluetooth® Low Energy failed!");11 while (1);12 }13
14 BLE.setLocalName("MKR WiFi 1010"); //Setting a name that will appear when scanning for Bluetooth® devices15 BLE.setAdvertisedService(newService);16
17 newService.addCharacteristic(switchChar); //add characteristics to a service18 newService.addCharacteristic(randomReading);19
20 BLE.addService(newService); // adding the service21
22 switchChar.writeValue(0); //set initial value for characteristics23 randomReading.writeValue(0);24
25 BLE.advertise(); //start advertising the service26 Serial.println(" Bluetooth® device active, waiting for connections...");27}
In the
loop()
we will use the command BLEDevice central = BLE.central();
to start waiting for a connection. When a device connects, the address of the connecting device (the central) will be printed in the Serial Monitor, and the in-built LED will turn ON. After this, we use a
while
loop that only runs as long as a device is connected. Here, we do a reading of Analog pin 1, which will record random values between 0 and 1023. We then use a conditional to check if there's an incoming value: if any value other than 0 comes in, the LED turns ON, but if 0 comes in, it turns it OFF.If our device (smartphone) disconnects, we exit the
while
loop. Once it exits, it turns off the in-built LED and the message "Disconnected from central" prints in the Serial Monitor. 1void loop() {2 3 BLEDevice central = BLE.central(); // wait for a Bluetooth® Low Energy central4
5 if (central) { // if a central is connected to the peripheral6 Serial.print("Connected to central: ");7 8 Serial.println(central.address()); // print the central's BT address9 10 digitalWrite(LED_BUILTIN, HIGH); // turn on the LED to indicate the connection11
12
13 14 while (central.connected()) { // while the central is connected:15 long currentMillis = millis();16 17 if (currentMillis - previousMillis >= 200) { 18 previousMillis = currentMillis;19
20 int randomValue = analogRead(A1);21 randomReading.writeValue(randomValue);22
23 if (switchChar.written()) {24 if (switchChar.value()) { // any value other than 025 Serial.println("LED on");26 digitalWrite(ledPin, HIGH); // will turn the LED on27 } else { // a 0 value28 Serial.println(F("LED off"));29 digitalWrite(ledPin, LOW); // will turn the LED off30 }31 }32
33 }34 }35 36 digitalWrite(LED_BUILTIN, LOW); // when the central disconnects, turn off the LED37 Serial.print("Disconnected from central: ");38 Serial.println(central.address());39 }40}
Complete Code
If you choose to skip the code building section, the complete code can be found below:
1#include <ArduinoBLE.h>2BLEService newService("180A"); // creating the service3
4BLEUnsignedCharCharacteristic randomReading("2A58", BLERead | BLENotify); // creating the Analog Value characteristic5BLEByteCharacteristic switchChar("2A57", BLERead | BLEWrite); // creating the LED characteristic6
7const int ledPin = 2;8long previousMillis = 0;9
10
11void setup() {12 Serial.begin(9600); // initialize serial communication13 while (!Serial); //starts the program if we open the serial monitor.14
15 pinMode(LED_BUILTIN, OUTPUT); // initialize the built-in LED pin to indicate when a central is connected16 pinMode(ledPin, OUTPUT); // initialize the built-in LED pin to indicate when a central is connected17
18 //initialize ArduinoBLE library19 if (!BLE.begin()) {20 Serial.println("starting Bluetooth® Low Energy failed!");21 while (1);22 }23
24 BLE.setLocalName("MKR WiFi 1010"); //Setting a name that will appear when scanning for Bluetooth® devices25 BLE.setAdvertisedService(newService);26
27 newService.addCharacteristic(switchChar); //add characteristics to a service28 newService.addCharacteristic(randomReading);29
30 BLE.addService(newService); // adding the service31
32 switchChar.writeValue(0); //set initial value for characteristics33 randomReading.writeValue(0);34
35 BLE.advertise(); //start advertising the service36 Serial.println(" Bluetooth® device active, waiting for connections...");37}38
39void loop() {40 41 BLEDevice central = BLE.central(); // wait for a Bluetooth® Low Energy central42
43 if (central) { // if a central is connected to the peripheral44 Serial.print("Connected to central: ");45 46 Serial.println(central.address()); // print the central's BT address47 48 digitalWrite(LED_BUILTIN, HIGH); // turn on the LED to indicate the connection49
50 // check the battery level every 200ms51 // while the central is connected:52 while (central.connected()) {53 long currentMillis = millis();54 55 if (currentMillis - previousMillis >= 200) { // if 200ms have passed, we check the battery level56 previousMillis = currentMillis;57
58 int randomValue = analogRead(A1);59 randomReading.writeValue(randomValue);60
61 if (switchChar.written()) {62 if (switchChar.value()) { // any value other than 063 Serial.println("LED on");64 digitalWrite(ledPin, HIGH); // will turn the LED on65 } else { // a 0 value66 Serial.println(F("LED off"));67 digitalWrite(ledPin, LOW); // will turn the LED off68 }69 }70
71 }72 }73 74 digitalWrite(LED_BUILTIN, LOW); // when the central disconnects, turn off the LED75 Serial.print("Disconnected from central: ");76 Serial.println(central.address());77 }78}
Testing It Out
Once we are finished with the coding, we can upload the sketch to the board. When it has been successfully uploaded, open the Serial Monitor. In the Serial Monitor, the text " Bluetooth® device active, waiting for connections..." will appear.
We can now discover our MKR WiFi 1010 board in the list of available Bluetooth® devices. To access the service and characteristic we recommend using the LightBlue application. Follow this link for iPhones or this link for Android phones.
Once we have the application open, follow the image below for instructions:
To control the LED, we simply need to write any value other than 0 to turn it on, and 0 to turn it off. This is within the "Digital Output" characteristic, which is located under "Device Information". We can also go into the "Analog" characteristic, where we need to change the data format to "Unsigned Little-Endian", and click the "Read Again" button. Once we click the button, we will retrieve the latest value.
Troubleshoot
If the code is not working, there are some common issues we can troubleshoot:
- We haven't updated the latest firmware for the board.
- We haven't installed the Board Package required for the board.
- We haven't installed the ArduinoBLE library.
- We haven't opened the Serial Monitor to initialize the program.
- The device you are using to connect has its Bluetooth® turned off.
Conclusion
In this tutorial we have created a basic Bluetooth® peripheral device. We learned how to create services and characteristics, and how to use UUIDs from the official Bluetooth® documentation. In this tutorial, we did two practical things: turning an LED, ON and OFF, and reading a value from an analog pin. You can now start experimenting with this code, and create your own amazing Bluetooth® applications!
Now that you have learned a little bit how to use the ArduinoBLE library, you can try out some of our other tutorials for the MKR WiFi 1010 board. You can also check out the ArduinoBLE library for more examples and inspiration for creating Bluetooth® projects!
Suggest changes
The content on docs.arduino.cc is facilitated through a public GitHub repository. If you see anything wrong, you can edit this page here.
License
The Arduino documentation is licensed under the Creative Commons Attribution-Share Alike 4.0 license.