Bluetooth Low Energy (BLE)
The original specification was developed by Nokia in 2006 under the name Wibree. Later on, this technology became part ofBluetooth 4.0 in 2009 as Bluetooth Low Energy (BLE). As the name suggests, the power consumption is very low, at around 0.01 watts, compared to traditional Bluetooth which is around 1W.
Payload Concept
Long story short, is important that you know how efficient is the information that you are sending. For example, it is easier to turn on a LED with a “1”, than sending the complete phrase “turn on the LED“.
Product list- RAK5005-O | WisBlock Base Board x1
- RAK4631 | nRF52840 SX1262 | Module for LoRaWAN x1
- A Smartphone with BLE capability (Bluetooth 4.0 or higher) x1
In this tutorial, we are going to learn how to make a bidirectional communication via BLE and USB serial. Also, how to control your first object wirelessly, in this case, a green LED. With these concepts and examples, later on, you will be able to build more amazing things and even automate something, like your own house!
The first thing to do is to connect the BLE antenna to the RAK4631 Core. To do this press straight and firmly the connector until you hear a click.
Then connect the WisBlock to your PC or Laptop via USB.
Now you need to upload the firmware (code), that will allow bidirectional communication between the serial monitor and your phone, for this matter you can search it in the examples for the WisBlock. The complete path on your Arduino IDE is File>Examples> RAK WisBlock examples> RAK4631> Communications> BLE> ble_uart.
You need to have installed the RAKwireless BSP. If you don't have it, you can check it out on our GitHub.
If you cannot find the code here is the same code to copy, and also explained for you to learn how it works.
/**
@file ble_uart.ino
@author Bernd Giesecke (bernd.giesecke@rakwireless.com)
@brief BLE example shows how to implement UART over BLE
@version 0.1
@date 2020-07-27
@copyright Copyright (c) 2020
@note RAK4631 GPIO mapping to nRF52840 GPIO ports
RAK4631 <-> nRF52840
WB_IO1 <-> P0.17 (GPIO 17)
WB_IO2 <-> P1.02 (GPIO 34)
WB_IO3 <-> P0.21 (GPIO 21)
WB_IO4 <-> P0.04 (GPIO 4)
WB_IO5 <-> P0.09 (GPIO 9)
WB_IO6 <-> P0.10 (GPIO 10)
WB_SW1 <-> P0.01 (GPIO 1)
WB_A0 <-> P0.04/AIN2 (AnalogIn A2)
WB_A1 <-> P0.31/AIN7 (AnalogIn A7)
*/
#include <Arduino.h>
#include <bluefruit.h>
// Forward declarations for functions
void ble_connect_callback(uint16_t conn_handle);
void ble_disconnect_callback(uint16_t conn_handle, uint8_t reason);
/**
@brief BLE UART service
@note Used for BLE UART communication
*/
BLEUart g_BleUart;
/** Flag if BLE UART client is connected */
bool g_BleUartConnected = false;
/**
@brief Arduino setup function. Called once after power on or reset
*/
void setup()
{
// Initialize built in green LED
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, HIGH);
// Initialize Serial for debug output
Serial.begin(115200);
// Wait for USB Serial to be ready or terminal to be connected
time_t timeout = millis(); // Timeout in case the system runs on its own
// Waiting for Serial
while (!Serial)
{
if ((millis() - timeout) < 5000)
{
// Blink the LED to show that we are alive
delay(100);
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
}
else
{
// Timeout while waiting for USB Serial
break;
}
}
// prints in the Serial monitor the message
Serial.println("================================");
Serial.println("RAK4631 BLE UART example");
Serial.println("================================");
// Note: All config***() function must be called before begin()
Bluefruit.configPrphBandwidth(BANDWIDTH_MAX);// Config the peripheral connection with maximum bandwidth
Bluefruit.configPrphConn(92, BLE_GAP_EVENT_LENGTH_MIN, 16, 16);// more SRAM required by SoftDevice
Bluefruit.begin(1, 0);
// Set max power. Accepted values are: -40, -30, -20, -16, -12, -8, -4, 0, 4
Bluefruit.setTxPower(4);
// Set the BLE device name
Bluefruit.setName("RAK4631_UART_test");
// Callbacks for Peripheral
Bluefruit.Periph.setConnectCallback(ble_connect_callback);
Bluefruit.Periph.setDisconnectCallback(ble_disconnect_callback);
// Configure and Start BLE Uart Service
g_BleUart.begin();
// Set up and start advertising
// Advertising packet
Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE);
Bluefruit.Advertising.addTxPower();
Bluefruit.Advertising.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 Callback when client connects
@param conn_handle: Connection handle id
*/
void ble_connect_callback(uint16_t conn_handle)
{
(void)conn_handle;
g_BleUartConnected = true;
Serial.println("BLE client connected");
}
/**
@brief Callback invoked when a connection is dropped
@param conn_handle: connection handle id
@param reason: disconnect reason
*/
void ble_disconnect_callback(uint16_t conn_handle, uint8_t reason)
{
(void)conn_handle;
(void)reason;
g_BleUartConnected = false;
Serial.println("BLE client disconnected");
}
/**
@brief Arduino loop. Runs forever until power off or reset
*/
void loop()
{
// Forward anything received from USB Serial to BLE UART
if (Serial.available() && g_BleUartConnected)
{
g_BleUart.print(Serial.readString());
}
// Forward anything received from BLE UART to USB Serial
if (g_BleUart.available())
{
Serial.print(g_BleUart.readString());
}
}
After uploading the code you should see the following message on the Arduino serial monitor.
Now it's time to configure your phone. For that matter we are going to use the Serial Bluetooth terminal application for Android.
The serial monitor on the Arduino shows the same messages as the app on the phone.
This is fine for a communication example, but let's make a practical exercise. For that matter, we are going to use the same application of serial monitor UART, but we need to modify the firmware for the WisBlock core.
We’re going to turn on and off the built-in LED, which is the green one. But we are not going to send a large command such as “turn on the green led“; it's more efficient and a better practice only send “1“ or “0”, so the number 1 will turn on the LED and 0 will turn it off. In the serial monitor you will see a message “LED turn on
“or “LED turn off
“ depending on if you send a 1 or a 0.
The code is as follows:
/**
@file ble_uart.ino
@author Bernd Giesecke (bernd.giesecke@rakwireless.com)
@Modifications Made by Harold Duarte (harold.duarte@rakwireless.com) for the How to send data via Bluetooth - using WisBlock Starter Kit Tutorial
@brief BLE example shows how to implement UART over BLE
@version 0.1
@date 2020-07-27
@copyright Copyright (c) 2020
@note RAK4631 GPIO mapping to nRF52840 GPIO ports
RAK4631 <-> nRF52840
WB_IO1 <-> P0.17 (GPIO 17)
WB_IO2 <-> P1.02 (GPIO 34)
WB_IO3 <-> P0.21 (GPIO 21)
WB_IO4 <-> P0.04 (GPIO 4)
WB_IO5 <-> P0.09 (GPIO 9)
WB_IO6 <-> P0.10 (GPIO 10)
WB_SW1 <-> P0.01 (GPIO 1)
WB_A0 <-> P0.04/AIN2 (AnalogIn A2)
WB_A1 <-> P0.31/AIN7 (AnalogIn A7)
*/
#include <Arduino.h>
#include <bluefruit.h>
// Forward declarations for functions
void ble_connect_callback(uint16_t conn_handle);
void ble_disconnect_callback(uint16_t conn_handle, uint8_t reason);
/**
@brief BLE UART service
@note Used for BLE UART communication
*/
BLEUart g_BleUart;
/** Flag if BLE UART client is connected */
bool g_BleUartConnected = false;
int byteRecive;
/**
@brief Arduino setup function. Called once after power on or reset
*/
void setup()
{
// Initialize built in green LED
pinMode(LED_BUILTIN, OUTPUT);
//digitalWrite(LED_BUILTIN, HIGH);
// Initialize Serial for debug output
Serial.begin(115200);
// Wait for USB Serial to be ready or terminal to be connected
time_t timeout = millis(); // Timeout in case the system runs on its own
// Waiting for Serial
while (!Serial)
{
if ((millis() - timeout) < 5000)
{
// Blink the LED to show that we are alive
//delay(100);
//digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
}
else
{
// Timeout while waiting for USB Serial
break;
}
}
Serial.println("================================");
Serial.println("RAK4631 BLE");
Serial.println("================================");
// Config the peripheral connection with maximum bandwidth
// more SRAM required by SoftDevice
// Note: All config***() function must be called before begin()
Bluefruit.configPrphBandwidth(BANDWIDTH_MAX);
Bluefruit.configPrphConn(92, BLE_GAP_EVENT_LENGTH_MIN, 16, 16);
Bluefruit.begin(1, 0);
// Set max power. Accepted values are: -40, -30, -20, -16, -12, -8, -4, 0, 4
Bluefruit.setTxPower(4);
// Set the BLE device name
Bluefruit.setName("RAK4631_LED_EXAMPLE");
Bluefruit.Periph.setConnectCallback(ble_connect_callback);
Bluefruit.Periph.setDisconnectCallback(ble_disconnect_callback);
// Configure and Start BLE Uart Service
g_BleUart.begin();
// Set up and start advertising
// Advertising packet
Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE);
Bluefruit.Advertising.addTxPower();
Bluefruit.Advertising.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 Callback when client connects
@param conn_handle: Connection handle id
*/
void ble_connect_callback(uint16_t conn_handle)
{
(void)conn_handle;
g_BleUartConnected = true;
Serial.println("BLE client connected");
}
/**
@brief Callback invoked when a connection is dropped
@param conn_handle: connection handle id
@param reason: disconnect reason
*/
void ble_disconnect_callback(uint16_t conn_handle, uint8_t reason)
{
(void)conn_handle;
(void)reason;
g_BleUartConnected = false;
Serial.println("BLE client disconnected");
}
/**
@brief Arduino loop. Runs forever until power off or reset
*/
void loop()
{
// Forward anything received from USB Serial to BLE UART
if (Serial.available() && g_BleUartConnected)
{
g_BleUart.print(Serial.readString());
}
// Forward anything received from BLE UART to USB Serial
if (g_BleUart.available())
{
byteRecive = g_BleUart.read();
if ( byteRecive == '1')// if the input is 1 turn on the LED
{
digitalWrite(LED_BUILTIN, HIGH);
Serial.println("LED turn on");
}
if ( byteRecive == '0')// if the input is turn off the led
{
digitalWrite(LED_BUILTIN, LOW);
Serial.println("LED turn off");
}
Serial.print(g_BleUart.readString());
}
}
The setup is ready: The WisBlock with the respective firmware, the serial Bluetooth terminal application running and connected to the WisBlock, and your PC to see the serial monitor.
Now we perform the same steps as before with the Serial Bluetooth terminal application, connect to the device and send the value for turning on/off the LED.
It works! As you can see, when it sends the number 1, the green led turns on. If the 0 is sent, it turns off. In the serial monitor also show the message if the led was ON or OFF.
With this knowledge and example you can do many things, such as turn on a big AC motor with a relay, control the light of your house, open the door for your pet and many more things. Your imagination is the limit, and remember #IoTMadeEasy, as we always say.
ConclusionsAfter following all these steps, you will have managed to send bidirectional data and control your first object, in this case, a LED. But this is just the beginning. If you want to continue this journey, check the next tutorial: How to connect two WisBlock starter Kit using LoRaWAN
Also, follow us on our Hackster profile and be part of our community, to keep updated with more projects and news.
Please share with us, write on your doubts and interact with us in the comment section.
Resources
Comments
Please log in or sign up to comment.