In the realm of IoT projects, finding a reliable and efficient host hardware solution is important. The Adafruit Feather RP2040 is an excellent solution for that. It comes equipped with a comprehensive ecosystem, including an IDE and libraries tailored for your new projects. With this setup, you get to keep the main USB port for uploading, debugging, and data communication, while at the same time sending and receiving data to just-about-any USB device, like the BleuIO.
In this first blog with the Adafruit Feather board, we are going to show how you can setup the USB stack and communicate with BleuIO using the Adafruit Feather RP2040 board. Later in next project we will show how to read a Temperature and Humidity sensor and display the data help of the Bluetooth Low Energy (BLE) interface.
In the Arduino IDE, click on Tools > Board > Boards Manager. If you have previously selected a board, the Board menu item may have a board name after it.
In the Boards Manager, search for RP2040. Scroll down to the Raspberry Pi Pico/RP2040 by Earle F Philhower, III entry. Click Install to install it.
Choose Your Board
In the Tools > Boards menu, you should now see Raspberry Pi RP2040 Boards (possibly followed by a version number).
Navigate to the Raspberry Pi RP2040 Boards menu and choose Adafruit Feather RP2040 USB Host.
Now you’re ready to begin using Arduino with your RP2040 board! The main use case for this Feather is to act as a USB host.
Library Installation
Install Adafruit_TinyUSB Library
To use your Feather as a USB host, you’ll need to install the Adafruit TinyUSB library. It can be installed using the Library Manager in the Arduino IDE.
Click the Manage Libraries > menu item, search for Adafruit TinyUSB, and select the Adafruit TinyUSBLibrary
Install Pico PIO USB Library
Additionally, you’ll need to install the Pico PIO USB library.
Click the Manage Libraries > menu item again, search for PIO USB, and select the Pico PIO USB library.
Configuration and Deployment
Board Upload Settings
In the Tools menu, select Adafruit Feather RP2040 USB Host under Board.
For CPU Speed, you’ll need to select 120 MHz or240 MHz.
Finally, under USB Stack, select Adafruit TinyUSB.
Serial Host Bridge Example
Load the example code onto your Feather after following the library installation instructions on the Arduino Library Install page.
Navigate to the Adafruit TinyUSB Library Examples and select DualRole – CDC – serial_host_bridge
Now you can control the BleuIO USB Dongle via the Adafruit Feather board.
With these steps completed, you’re now ready to start integrating BleuIO with your Adafruit Feather RP2040 board. This setup lays the foundation for exciting IoT projects, and we’ll explore more functionalities in future tutorials where we will show how to make the BleuIO USB Dongle advertise data from a Temperature and Humidity sensor.
Stay tuned for further guides on applying BleuIO and Adafruit Feather RP2040 for your projects!
In this tutorial, we will explore how to use BleuIO, a Bluetooth Low Energy (BLE) USB dongle, for developing BLE applications with C++. We’ll demonstrate how to connect to BleuIO via a serial port, send AT commands, and receive responses. Additionally, we’ll discuss the benefits of using BleuIO and provide some use cases for BLE application development with C++.
Introduction to BleuIO
BleuIO is a BLE USB dongle designed to simplify and accelerate the development of BLE applications. It provides a set of AT commands that allow developers to interact with BLE devices and services without having to write extensive code. By leveraging these AT commands, developers can quickly prototype and develop BLE applications with minimal effort.
Prerequisites
Before getting started, ensure you have the following:
Serial communication library for C++ (e.g., <iostream>, <unistd.h>, <fcntl.h>, <termios.h>)
Basic knowledge of C++ programming
Setting Up the Environment
First, connect the BleuIO dongle to your computer via USB. Then, (for MAC operating system) determine the serial port assigned to the dongle using the ls /dev/cu.* command in the terminal. Note down the serial port name (e.g., /dev/cu.usbmodem4048FDE52DAF1) as we’ll need it to establish a serial connection.
Writing the C++ Program
Below is a C++ program that connects to BleuIO, sends an AT command, and retrieves the response.
#include <iostream>
#include <string>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <chrono>
#include <thread>
int main() {
// Open the serial port
const char* portname = "/dev/cu.usbmodem4048FDE52DAF1"; // Change this to match your serial port
int serial_port = open(portname, O_RDWR);
if (serial_port < 0) {
std::cerr << "Error opening serial port" << std::endl;
return 1;
}
// Configure the serial port settings
struct termios tty;
tcgetattr(serial_port, &tty);
cfsetospeed(&tty, B9600); // Set baud rate to 9600
cfsetispeed(&tty, B9600);
tty.c_cflag &= ~PARENB; // No parity
tty.c_cflag &= ~CSTOPB; // 1 stop bit
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8; // 8 bits per byte
tty.c_cflag &= ~CRTSCTS; // Disable hardware flow control
tty.c_cflag |= CREAD | CLOCAL; // Enable reading and ignore control lines
tty.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // Raw input
tcsetattr(serial_port, TCSANOW, &tty);
// Write data to the serial port to put the dongle in central role
const char* m1 = "AT+CENTRAL\r";
write(serial_port, m1, strlen(m1));
// Wait for 1 second to receive the response
std::this_thread::sleep_for(std::chrono::seconds(1));
// Write data to the serial port to scan for nearby device for three seconds
const char* m2 = "AT+GAPSCAN=3\r";
write(serial_port, m2, strlen(m2));
// Wait for 1 second to receive the response
std::this_thread::sleep_for(std::chrono::seconds(1));
// Read response from the serial port with timeout
char buf[1024];
std::string response;
int nbytes;
fd_set fds;
struct timeval timeout;
FD_ZERO(&fds);
FD_SET(serial_port, &fds);
timeout.tv_sec = 3; // Timeout after 3 second
timeout.tv_usec = 0;
while (select(serial_port + 1, &fds, NULL, NULL, &timeout) > 0) {
nbytes = read(serial_port, buf, sizeof(buf));
if (nbytes < 0) {
std::cerr << "Error reading from serial port" << std::endl;
close(serial_port);
return 1;
}
if (nbytes > 0) {
response.append(buf, nbytes);
}
}
// Display the response
std::cout << "Response: " << response << std::endl;
// Close the serial port
close(serial_port);
return 0;
}
Understanding the Code
We start by opening the serial port corresponding to BleuIO.
Next, we configure the serial port settings (baud rate, parity, stop bits, etc.) to match BleuIO’s communication parameters.
We then send the AT+CENTRAL command to BleuIO, which puts the dongle into central role.
After sending the command, we wait for 1 second to receive the response.
Then we send AT+GAPSCAN=3 to scan for nearby BLE devices for 3 seconds.
We read the response from the serial port with a timeout of 3 second.
Finally, we display the response received from BleuIO and close the serial port.
Output
Use Cases
BleuIO, with its AT command interface, presents an excellent starting point for developers looking to delve into Bluetooth Low Energy (BLE) application development with C++ across various domains.
Embedded Systems Development: BleuIO simplifies BLE application development in C++ for embedded systems. Developers can quickly prototype IoT devices, smart sensors, and wearables with BleuIO’s AT command interface, enabling features like remote control and wireless connectivity.
Cross-Platform Mobile Applications: Integrating BLE features into C++ mobile apps becomes seamless with BleuIO. Developers using frameworks like Qt or cross-platform tools can leverage BleuIO’s AT commands for device discovery, data exchange, and configuration across different platforms.
Industrial Automation and Control: C++ developers in industrial settings can enhance control systems and monitoring tools with BLE connectivity using BleuIO. Its AT command support enables communication with BLE-enabled equipment for tasks like remote monitoring and real-time data acquisition.
Educational Projects and Prototyping: BleuIO serves as an accessible platform for learning BLE technology with C++. Students and hobbyists can experiment with Bluetooth communication, protocol implementation, and IoT development, turning ideas into reality with minimal overhead.
In this tutorial, we’ve demonstrated how to use BleuIO for BLE application development with C++. By leveraging BleuIO’s AT commands, developers can streamline the development process and accelerate time-to-market for BLE-enabled projects. With the provided code and insights, you can now begin exploring BLE application development using BleuIO and C++ in your own projects.
With the rise of IoT devices, Bluetooth Low Energy (BLE) technology has emerged as a convenient solution for wireless data transmission. In this tutorial, we’ll explore how to read real-time air quality data from a BLE air quality monitoring device called HibouAir, and plot it using MATLAB. To accomplish this, we’ll utilize the BleuIO BLE USB dongle, which simplifies BLE application development with its AT command interface.
Project Components:
BleuIO BLE USB Dongle: The BleuIO dongle serves as our BLE interface, allowing us to communicate with BLE devices using simple AT commands. Its plug-and-play nature and versatile features make it an ideal choice for BLE application development.
HibouAir Air Quality Monitoring Device: HibouAir is a BLE-enabled air quality monitoring device that measures various parameters such as CO2, temperature, humidity, VOCs, and more. It provides real-time data transmission via BLE, making it suitable for IoT applications.
MATLAB: MATLAB is a powerful computing environment widely used for data analysis, visualization, and algorithm development. We’ll leverage MATLAB’s capabilities to read data from the BleuIO dongle, decode BLE advertisements from HibouAir, and plot the air quality data in real-time.
Project Implementation:
Step 1: Setting up the Hardware
Connect the BleuIO BLE USB dongle to your computer’s USB port.
Power on the HibouAir air quality monitoring device.
Step 2: Writing MATLAB Code
Define the serial port parameters in MATLAB to establish communication with the BleuIO dongle.
Scan for a specific HibouAir device with its MAC address to get air quality advertised data.
Implement functions to decode BLE advertisement data from HibouAir, including parsing CO2, temperature, humidity, and other relevant parameters.
Write code to continuously scan for BLE advertisements, extract air quality data, and plot co2 value real-time using MATLAB’s plotting functions.
How This Project Can Be Helpful for Engineers, Developers, and Analysts
Environmental Monitoring: Engineers and analysts can use this project to create efficient environmental monitoring systems. By integrating BLE air quality monitors with MATLAB’s data analysis tools, they can assess air quality, detect anomalies, and optimize environmental control systems.
Use Case: A civil engineering firm employs this setup to monitor indoor air quality in commercial buildings, identifying areas needing ventilation improvements.
IoT Development: Developers can leverage this project to build IoT applications across various industries. By connecting BLE monitors with cloud platforms and mobile apps, they enable remote monitoring and predictive maintenance.
Use Case: A startup develops a mobile app for real-time air quality monitoring in urban environments, using BLE devices and MATLAB for data analysis.
Research and Analysis: Analysts and researchers can utilize this project to study air quality’s impact on human health and the environment. BLE monitors and MATLAB enable them to collect data, perform statistical analysis, and communicate research findings effectively.
Use Case: Environmental scientists deploy BLE monitors to measure traffic-related air pollution in urban areas, using MATLAB to analyze data and inform urban planning decisions.
Complete MATLAB Code:
% Define the serial port parameters
portName = 'COM8'; % Change this to match your dongle's port identifier
baudRate = 57600; % Change this to match your dongle's baud rate
macaddress = '220069'; % Change this to match the desired MAC address
% Define adv_data_decode function if not defined already
function env_data = adv_data_decode(data)
% Initialize output structure
env_data = struct();
% Find the position of the start of advertisement data
pos = strfind(data, '5B070');
% Convert hexadecimal data to decimal values
temp_hex = convertNumber(data, pos+22, 4);
if temp_hex > 1000
temp_hex = (temp_hex - (65535 + 1)) / 10;
else
temp_hex = temp_hex / 10;
end
% Decode the advertisement data
env_data.boardID = data(pos + 8 : pos + 8 + 5);
env_data.type = hex2dec(data(pos + 6 : pos + 6 + 1));
env_data.light = convertNumber(data, pos + 14, 4);
env_data.pressure = convertNumber(data, pos + 18, 4) / 10;
env_data.temperature = temp_hex;
env_data.humidity = convertNumber(data, pos + 26, 4) / 10;
env_data.voc = convertNumber(data, pos + 30, 4);
env_data.co2 = hex2dec(data(pos + 46 : pos + 46 + 3));
env_data.ts = datetime('now', 'Format', 'yyyy-MM-dd HH:mm:ss');
end
function num = convertNumber(data, start, len)
% Convert hexadecimal string to decimal number
hex_str = data(start : start + len - 1);
num = typecast(uint32(hex2dec(hex_str)), 'int32');
end
% Create a function to handle the scanning and decoding
function scanAndDecode(~, ~, s, macaddress, hObject)
try
% Retrieve stored data from the figure's appdata
fig = ancestor(hObject, 'figure');
storedData = guidata(fig);
timeArray = storedData.timeArray;
co2Array = storedData.co2Array;
% Send the commands
writeline(s, "AT+CENTRAL");
write(s,13,"char");
writeline(s, "AT+FINDSCANDATA="+macaddress+"=4");
write(s,13,"char");
% Pause for 4 seconds (assuming this is the time needed for scanning)
pause(4);
% Read the response
response = '';
while s.NumBytesAvailable > 0
response = response + readline(s);
end
% Extract advertisement data from the last string
lastLine = strsplit(response, newline);
lastLine = lastLine{end}; % Get the last line
advData = regexp(lastLine, '\[ADV\]:\s+(\w+)', 'tokens');
% Display the advertisement data
if ~isempty(advData)
theData = adv_data_decode(advData{1}{1});
disp(theData.co2); % Display CO2 data for example
% Append new data points to arrays
timeArray = [timeArray, datenum(theData.ts)]; % Convert datetime to serial date number
co2Array = [co2Array, theData.co2];
% Update stored data in the figure's appdata
storedData.timeArray = timeArray;
storedData.co2Array = co2Array;
guidata(fig, storedData);
% Update plot with new data points
set(hObject, 'XData', timeArray, 'YData', co2Array);
% Set x-axis to display time in the format of hours, minutes, and seconds
datetick('x', 'HH:MM:SS');
drawnow;
else
disp('No advertisement data found.');
end
catch e
% Display any errors that occur
disp("An error occurred: " + e.message);
end
end
try
% Create a serial port object
s = serialport(portName, baudRate,"Timeout",2);
configureTerminator(s, "LF");
% Create a figure for plotting
fig = figure;
plotHandle = plot(NaN, NaN, 'o-');
xlabel('Time');
ylabel('CO2 Value');
title('CO2 Value vs. Time');
% Store data in the figure's appdata
storedData.timeArray = [];
storedData.co2Array = [];
guidata(fig, storedData);
% Create a timer object to run scanAndDecode every 10 seconds
t = timer('ExecutionMode', 'fixedRate', 'Period', 10, ...
'TimerFcn', {@scanAndDecode, s, macaddress, plotHandle});
% Set the closerequestfcn callback to stop the timer and clear the serial port
set(fig, 'closerequestfcn', {@stopScript, t, s});
% Start the timer
start(t);
catch e
% Display any errors that occur
disp("An error occurred: " + e.message);
% Stop and delete the timer
if exist('t', 'var') && isvalid(t)
stop(t);
delete(t);
end
% Close the serial port
if exist('s', 'var') && isvalid(s)
clear s;
end
end
% Enable data cursors
dcm = datacursormode(gcf);
set(dcm, 'UpdateFcn', @customDataCursor);
% Custom data cursor function
function output_txt = customDataCursor(~, event_obj)
% Get the data cursor position
pos = get(event_obj, 'Position');
% Convert the x-coordinate (time) to a formatted string
timeString = datestr(pos(1), 'HH:MM:SS');
% Create the output text to display
output_txt = {['X: ', timeString], ['Y: ', num2str(pos(2))]}; % Customize as needed
end
function stopScript(~, ~, t, s)
% Stop and delete the timer
if exist('t', 'var') && isvalid(t)
stop(t);
delete(t);
end
% Close the serial port
if exist('s', 'var') && isvalid(s)
% Close the serial port
delete(s);
end
% Close the figure
delete(gcf);
end
Output
In this tutorial, we demonstrated how to read real-time air quality data from a BLE air quality monitoring device, such as HibouAir, using the BleuIO BLE USB dongle and MATLAB. By following the steps outlined in this tutorial, engineers, developers, and analysts can develop applications for monitoring air quality in various environments. This project has numerous potential applications, including indoor air quality monitoring in smart buildings, environmental monitoring in industrial settings, and health monitoring in healthcare facilities. By leveraging the power of BLE technology and MATLAB’s data analysis capabilities, users can gain valuable insights into air quality trends and make informed decisions to improve environmental conditions and human health.
In this tutorial, we’ll explore how to utilize BleuIO, a Bluetooth Low Energy (BLE) USB dongle, with Node.js for BLE application development. We’ll use the serialport library to communicate with BleuIO, enabling us to send AT commands and interact with BLE devices.
Node.js Backend (server.js): This file sets up an Express server to serve the HTML file and handles BLE interactions using BleuIO and serialport.
// server.js
const express = require('express');
const { SerialPort } = require('serialport');
const app = express();
const port = 3000;
// Serve the HTML file (optional)
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html');
});
// Endpoint to scan for BLE devices using BleuIO
app.get('/scanbledevice', (req, res) => {
// Replace the following code with your BLE scanning logic
const bleDevices = ['Device 1', 'Device 2', 'Device 3'];
res.json(bleDevices);
});
// Start the server
app.listen(port, () => {
console.log(`Server is running on http://localhost:${port}`);
});
BLE Scanning Logic: Implement BLE scanning logic using BleuIO and serialport in the server file (server.js). This module contains the function to scan for BLE devices using BleuIO.
// scanble.js
const { SerialPort } = require('serialport');
function scanBLE() {
return new Promise((resolve, reject) => {
// Use SerialPort to list available ports
SerialPort.list()
.then((ports) => {
// Filter ports to find BleuIO device
const blePorts = ports.filter((port) =>
port.manufacturer.includes('Smart Sensor Devices')
);
if (blePorts.length === 0) {
reject(new Error('BleuIO device not found'));
}
// Connect to the first found BleuIO device
const blePort = new SerialPort({
path: blePorts[0].path,
baudRate: 115200
});
// Perform BLE scan
blePort.write('AT+CENTRAL\r', (err) => {
if (err) {
reject(new Error('Error setting central role: ' + err.message));
} else {
blePort.write('AT+GAPSCAN=3\r', (err) => {
if (err) {
reject(new Error('Error initiating scan: ' + err.message));
} else {
setTimeout(() => {
// Read and parse scan results
const scanResults = blePort.read();
resolve(scanResults.split('\n'));
}, 3500);
}
});
}
});
})
.catch((err) => {
reject(new Error('Error listing serial ports: ' + err.message));
});
});
}
module.exports = { scanBLE };
HTML Frontend (index.html): This file provides a user interface (UI) to trigger BLE device scanning and display the results.
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Include necessary meta tags and stylesheets -->
<title>Scan BLE Device</title>
</head>
<body>
<div class="container">
<br />
<br />
<button class="btn btn-success" id="scanBtn">Scan for Devices</button>
<div id="listScan"></div>
</div>
<!-- Include JavaScript for button click event -->
<script>
// JavaScript to handle button click event
</script>
</body>
</html>
Running the Application
Ensure your BleuIO dongle is connected to your computer.
Run the Node.js server
npm start
Open your web browser and navigate to http://localhost:3000.
Click the “Scan for Devices” button.
The list of nearby BLE devices will be displayed on the web page.
Output
In this tutorial, we’ve explored how to use BleuIO with Node.js via serial communication using the serialport library. You can extend this project by integrating more BLE functionalities and building a robust BLE application.
Feel free to customize and expand upon this project according to your requirements and explore the vast possibilities of BLE application development with Node.js and BleuIO!
In this project, we’ll create a system to monitor air quality in real-time using BleuIO (A Bluetooth Low Energy USB dongle). We’ll scan for an air quality monitoring device called HibouAir and decode the advertised data. The decoded air quality data will then be sent to the ThingsBoard cloud platform for visualization and monitoring.
Introduction to BleuIO
For this project, we’ll utilize a BLE USB dongle called BleuIO. BleuIO is a versatile Bluetooth low energy USB dongle that simplifies the development of BLE applications. It offers a range of AT commands, making it easy to interact with the dongle and create applications. BleuIO supports multiple platforms and programming languages. In our case, we’ll be using Python with the BleuIO Python library, available on PyPI.
About HibouAir
HibouAir is an advanced air quality monitoring device, HibouAir offers real-time data on various critical parameters including CO2 levels, particulate matter (PM 1.0, PM 2.5, PM 10), pressure, temperature, humidity, volatile organic compounds (VOCs), and noise levels. With its plug-and-play setup helps users to take immediate control of their indoor air quality.
About ThingsBoard
ThingsBoard is an open-source IoT platform that enables users to collect, store, visualize, and analyze data from connected devices in real-time. It provides a comprehensive set of features for building scalable and customizable IoT applications, including device management, data processing, rule engine, and customizable dashboards. With ThingsBoard, users can easily connect their devices, monitor their performance, and take actions based on real-time data insights. Its user-friendly interface and flexible architecture make it suitable for a wide range of IoT use cases, from industrial automation and smart cities to agriculture and healthcare. Additionally, ThingsBoard offers seamless integration with various third-party platforms and services, allowing users to leverage existing technologies and expand the capabilities of their IoT solutions.
Install the BleuIO Python library: First, we need to install the BleuIO Python library, which allows us to interact with the BleuIO USB dongle. You can install it using pip: pip install bleuio
Scan for nearby BLE devices: from bleuio_lib.bleuio_funcs import BleuIO import time my_dongle = BleuIO() my_dongle.at_central() my_dongle.at_findscandata('220069') # Replace '220069' with the device ID time.sleep(3) my_dongle.stop_scan()
Decode the advertised data last_element = my_dongle.scan_data[-1] data_part = json.loads(last_element[0])['data'] last_part = data_part.split(',')[-1].strip('"}') decoded_env_data = adv_data_decode(last_part)
Send data to ThingsBoard import requests api_endpoint = 'https://thingsboard.cloud/api/v1/YOUR_API_KEY/telemetry' response = requests.post(api_endpoint, json=decoded_env_data) if response.status_code == 200: print("Data sent successfully to ThingsBoard.") else: print("Failed to send data to ThingsBoard. Status code:", response.status_code)
Decoding Advertised Data
The advertised data contains encoded air quality data. We’ve implemented a function called adv_data_decode to decode this data based on the HibouAir datasheet. The decoded data includes parameters such as temperature, humidity, CO2 levels, etc.
Integration with ThingsBoard
We use the ThingsBoard cloud platform to visualize and monitor the air quality data. We send the decoded data to ThingsBoard via a POST request to the Telemetry API endpoint. If the request is successful, we receive a confirmation message.
ThingsBoard setup
We have created a device called HibouAir and added pressure , temperature , co2, humidity widget attribute on my dashboard and this is how my dashboard looks. we can see latest data ( data updated 1 mins ago)
Code
Complete code is available on the following repository
With BleuIO and ThingsBoard integration, we’ve built a robust system for monitoring air quality in real-time. This project demonstrates the BleuIO can be used in ThingsBoard integrationto create IoT solutions for environmental monitoring.
When it comes to creating Bluetooth Low Energy (BLE) applications, simplicity is key. That’s where BleuIO comes in – a handy USB dongle designed to make BLE development easier. With BleuIO, you can say goodbye to complicated programming because of its rich and user-friendly AT command interface. Instead of diving into complex programming languages, you can simply use AT commands to configure BleuIO as a central or peripheral device. This not only speeds up development but also makes BLE accessible to everyone, regardless of their programming background.
Autonomous Execution
One of BleuIO’s amazing features is its ability to execute commands automatically when it boots up. With the latest firmware updates, BleuIO can store up to 10 commands in its flash memory. So, when you power it up, it’ll jump into action, performing tasks like initializing as a beacon , setting specific characteristics and many more without needing a host computer.
Imagine the convenience of having BleuIO handle essential tasks on its own – it’s like having a trusty assistant for all your BLE needs!
Example of Auto Execution
BleuIO isn’t just limited to basic BLE functions – it can also emulate beacons with ease. With a simple command, you can turn BleuIO into a powerful beacon, broadcasting custom data effortlessly. Moreover, with its flash memory capabilities, your configurations persist through power cycles, eliminating the need for repeated setup. Additionally, you can easily set specific characteristics to tailor BleuIO’s behavior to your exact requirements.
To clear the auto execution commands type AT+CLRAUTOEXEC. BleuIO puts you in control, so you can focus on bringing your ideas to life.
Whether you’re a seasoned developer or a newbie, BleuIO is the best choice for your BLE applicaiton development with its user-friendly interface, autonomous execution capabilities, and versatility.
Bluetooth Low Energy (BLE) is a powerful technology for connecting devices wirelessly, and developing applications for BLE devices can be both exciting and challenging. In this tutorial, we’ll explore how to create a simple BLE device scanner using Python, Flask, and the BleuIO USB dongle. The BleuIO dongle provides a convenient interface through AT commands, allowing developers to easily interact with BLE devices.
Prerequisites
Before we dive into the tutorial, make sure you have the following:
Let’s start by examining the Python Flask code provided in app.py. This code defines a Flask web application with two routes: the home route (/) and a route to run the BLE device scan (/run_scan). The app uses the serial library to communicate with the BleuIO dongle over the serial port.
from flask import Flask, render_template, request
import serial
import time
app = Flask(__name__)
def scan_ble_devices():
connecting_to_dongle = 0
print("Connecting to dongle...")
while connecting_to_dongle == 0:
try:
console = serial.Serial(
port='/dev/cu.usbmodem4048FDE52DAF1',
baudrate=57600,
parity="N",
stopbits=1,
bytesize=8,
timeout=0
)
if console.is_open.__bool__():
connecting_to_dongle = 1
except:
print("Dongle not connected. Please reconnect Dongle.")
time.sleep(5)
console.write(str.encode("AT+CENTRAL"))
console.write('\r'.encode())
time.sleep(0.1)
console.write(str.encode("AT+GAPSCAN=2"))
console.write('\r'.encode())
time.sleep(3)
json_responses = []
while console.inWaiting() > 0:
line = console.readline().decode().strip()
print(line)
if line.startswith('['):
json_responses.append(line)
console.close()
return json_responses
@app.route('/')
def home():
return render_template('index.html')
@app.route('/run_scan', methods=['POST'])
def run_scan():
if request.method == 'POST':
json_responses = scan_ble_devices()
return render_template('index.html', json_responses=json_responses)
if __name__ == '__main__':
app.run(debug=True,port=5001)
HTML Template (index.html)
The HTML template (index.html) defines a simple web page with a button to trigger the BLE device scan. The page displays the results of the scan in an unordered list. Make sure the index.html file should stay inside template folder. so the folder structure should be like this
├── app.py
└── templates
└── index.html
Code for index.html is provided below
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Flask BLE Device Scanner</title>
<link
href="//cdn.muicss.com/mui-0.10.3/css/mui.min.css"
rel="stylesheet"
type="text/css"
/>
</head>
<body>
<div class="mui-container">
<br /><br />
<div class="mui-panel">
<img
src="https://flask.palletsprojects.com/en/3.0.x/_images/flask-horizontal.png"
alt=""
height="100"
/>
<img
src="https://1000logos.net/wp-content/uploads/2020/08/Python-Logo.png"
alt=""
height="100"
/>
<h1>Hello, Python BLE programmer!</h1>
<p>
This is a simple web page created with Flask to interact with BLE
devices nearby.
</p>
<form action="/run_scan" method="post">
<button
type="submit"
class="mui-btn mui-btn--primary mui-btn--raised"
>
Scan for BLE Devices
</button>
</form>
<br />
{% if json_responses %}
<ul class="mui-list--unstyled">
{% for json_response in json_responses %}
<li style="margin-bottom: 10px">
✓ {{ json_response | safe }}
</li>
{% endfor %}
</ul>
{% endif %}
</div>
</div>
</body>
</html>
Explaining the Code
Let’s dive into the connection part of the code and explain how the serial port is specified and why it is essential.
In this code snippet, the serial.Serial function is used to create a serial port object (console) for communication with the BleuIO dongle. Let’s break down the parameters used in this function:
port: Specifies the name or address of the port to which the BleuIO dongle is connected. In this case, it is set to '/dev/cu.usbmodem4048FDE52DAF1'. On macOS, /dev/cu.* represents serial ports, and by running ls /dev/cu.* in the terminal, you can see a list of connected devices. The specific port for the BleuIO dongle is copied from this list and pasted into the code.
For windows the COM port information can be found here. Here the path for the dongle is COM14
baudrate: Sets the baud rate for communication. The BleuIO dongle communicates at a baud rate of 57600, so it is set accordingly.
parity: Specifies the parity checking scheme. In this case, it is set to “N” for no parity.
stopbits: Defines the number of stop bits. It is set to 1, which is a common configuration.
bytesize: Sets the number of data bits. It is set to 8, which is standard for most serial communication.
timeout: Sets the timeout for read operations. It is set to 0, meaning no timeout, allowing the code to wait indefinitely for responses from the BleuIO dongle.
It’s crucial to accurately specify the port to establish a successful connection between the Flask application and the BleuIO dongle. Incorrect port information will result in a failure to establish communication.
Connecting to BleuIO Dongle: The scan_ble_devices function attempts to establish a connection with the BleuIO dongle over the serial port. It retries until the connection is successful.
Sending AT Commands: The function sends specific AT commands to the dongle to set it in central mode (AT+CENTRAL) and initiate a BLE device scan for two seconds (AT+GAPSCAN=2).
Parsing JSON Responses: The function reads and parses the JSON responses received from the dongle. It collects the responses in a list (json_responses).
Flask Routes: The Flask app has two routes – the home route (/) renders the index.html template, and the /run_scan route triggers the BLE device scan and displays the results
To run the script simply run the following code on the terminal.
python app.py
Output
In this tutorial, we’ve explored how to create a simple BLE device scanner using Python, Flask, and the BleuIO USB dongle. The combination of Flask and BleuIO’s AT commands provides a straightforward way for Python developers to interact with BLE devices, making BLE application development more accessible and efficient. You can further extend this project by adding features like connecting to specific BLE devices, reading characteristics, or even controlling devices. Details of the AT commands available on the BleuIO documentation.
To get started, make sure to have your BleuIO dongle, install Flask, and run the provided Python script. Happy BLE programming!
Bluetooth Low Energy (BLE) technology has become increasingly popular for creating wireless applications with low power consumption. In this tutorial, we’ll explore the process of scanning for nearby BLE devices, connecting to a specific device, and reading characteristics using the BleuIO BLE USB dongle. The tutorial is designed for Linux/MacOS environments.
Introduction to BleuIO
BleuIO is a versatile Bluetooth Low Energy USB dongle that simplifies BLE application development. It supports the AT command set, allowing developers to interact with the dongle using familiar commands. Whether you’re a seasoned BLE developer or just getting started, BleuIO offers a convenient and efficient way to work with BLE applications.
Forget complex libraries and complicated programming. Develop BLE applications effortlessly through simple AT commands.
Setting Up the Development Environment
Before diving into the tutorial, ensure you have the following prerequisites:
Python: Ensure that Python is installed on your system.
Writing the BLE Application Script
The provided Python script demonstrates the process of connecting to the BleuIO dongle, scanning for nearby BLE devices, and reading characteristics. Let’s break down the key components of the script:
# Importing necessary modules
import serial
import time
# Establishing connection to the BleuIO dongle
connecting_to_dongle = 0
print("Connecting to dongle...")
while connecting_to_dongle == 0:
try:
# Configuring the serial connection
console = serial.Serial(
port='/dev/cu.usbmodem4048FDE52CF21',
baudrate=57600,
parity="N",
stopbits=1,
bytesize=8,
timeout=0
)
if console.is_open.__bool__():
connecting_to_dongle = 1
except:
print("Dongle not connected. Please reconnect Dongle.")
time.sleep(5)
# Sending commands to the BleuIO dongle
console.write(str.encode("AT+CENTRAL"))
console.write('\r'.encode())
time.sleep(0.1)
console.write(str.encode("AT+GAPSCAN=3"))
console.write('\r'.encode())
time.sleep(3.5)
console.write(str.encode("AT+GAPCONNECT=[1]D1:79:29:DB:CB:CC"))
console.write('\r'.encode())
console.write(str.encode("AT+GATTCREAD=0013"))
console.write('\r'.encode())
# Waiting for the dongle to respond
time.sleep(1)
out = ""
while console.inWaiting() > 0:
out += console.read(console.inWaiting()).decode()
else:
if not out.isspace():
print(out + " ")
out = " "
Explanation:
1. Connecting to BleuIO:
Download and install a serial terminal emulator like screen or minicom.
Ensure your dongle is connected and note its port (e.g., /dev/cu.usbmodem4048FDE52CF21).
Run the script with the correct port and baudrate (57600) in your terminal.
The script attempts connection until successful, then sends essential AT commands:
AT+CENTRAL: Configures BleuIO as a central device (scanning/connecting).
AT+GAPSCAN=3: Starts scanning for BLE devices for 3 seconds.
2. Selecting and Connecting:
The scan results will appear in your terminal.
Identify the desired device, usually by name or MAC address.
Replace D1:79:29:DB:CB:CC in the script with your device’s MAC address.
Send AT+GAPCONNECT=[1]D1:79:29:DB:CB:CC to connect to the device (replace the mac address with your desired device if needed).
3. Reading a Characteristic:
Every BLE device exposes characteristics containing specific data.
Replace 0013 in AT+GATTCREAD with the characteristic’s UUID to read its value.
This script reads the characteristic with UUID 0013 and prints its value. Currently its showing the device type.
The outout
The output will be shown on the screen as
Value read: SSD002/2B
Hex: 0x5353443030322F3242
Size: 9
Understanding the Code:
The script uses serial library to communicate with BleuIO via AT commands.
While loops ensure connection success and read all available data.
The script parses output and filters empty space to avoid repetitive printing.
In this tutorial, we’ve covered the basics of working with the BleuIO BLE USB dongle on Linux/MacOS systems. The simplicity of the AT command interface and cross-platform compatibility make BleuIO an excellent choice for BLE application development. Experiment with the provided script, explore additional AT commands from BleuIO, and unlock the full potential of BLE applications with BleuIO. Happy coding!
In this tutorial, we will walk you through the process of creating a Home Assistant integration to read air quality data from a BLE air quality monitor called HibouAir. To accomplish this, we’ll be using BleuIO, a BLE USB dongle, to read data via the serial port. BleuIO comes equipped with a Python library that simplifies the project significantly. This integration provides real-time updates of various air quality parameters, such as pressure, temperature, humidity, VOC, CO2 and Particle Matters.
Prerequisites
Before we dive into the implementation, make sure you have the following prerequisites in place:
HibouAir Air Quality Monitor: Ensure you have a HibouAir air quality monitor. You can obtain it from the official source.
BleuIO BLE USB Dongle: Acquire a BleuIO BLE USB dongle to facilitate communication with the HibouAir monitor.
Host Computer: We’ll use a Windows-based host computer in this example.
Home Assistant: Install Home Assistant and have it up and running. You can run Home Assistant within a virtual machine using VirtualBox, as demonstrated in this tutorial.
Implementation
Let’s start by setting up the Home Assistant integration for HibouAir and BleuIO. You can find the complete code for this project on the following GitHub repository:
platform: Specifies the integration to use, which is hibouair_ble in this case.
scan_interval: Sets the interval for scanning and updating data. The example uses 120 seconds (2 minutes) for real-time data updates. Adjust this value according to your preference.
3. Restart Home Assistant
After updating the configuration, save the file and restart your Home Assistant instance. This will enable the integration.
4. Monitor Air Quality Data
Once Home Assistant is restarted, you should be able to see entities representing various air quality parameters with the hibouair_ble prefix. These parameters may include pressure, temperature, humidity, VOC, CO2, and more. The air quality data will update every 2 minutes, providing real-time information about your environment.
After setting up the dashboard with the Hibouair_ble entities , the dashboard looks like this
This integration is a simple example, and you can further customize and automate your smart home based on the data collected from the HibouAir monitor. Feel free to adapt the code to your specific requirements and enhance the capabilities of your Home Assistant setup.
With the combination of HibouAir and BleuIO, you can effortlessly create a home automation system that ensures your environment remains healthy and comfortable.
Bluetooth Low Energy (BLE) is a wireless communication technology commonly used in various IoT and wearable devices. With the right tools and libraries, working with BLE devices on Linux becomes easy and efficient. In this tutorial, we’ll explore how to use the BleuIO dongle and the associated Python library to scan for nearby BLE devices, connect to a device, and read its characteristics, specifically the device name.
Prerequisites
Before we begin, ensure you have the following:
BleuIO Dongle: You’ll need a BleuIO dongle, a versatile BLE device capable of working on any platform.
BleuIO Python Library: Install the BleuIO Python library, which provides the necessary tools for interacting with the BleuIO dongle. You can install it using pip:
pip install bleuio
Now that you have the prerequisites in place, let’s dive into the process.
Step 1: Setting up the Python Script
First, let’s set up a Python script to work with the BleuIO dongle. Here’s a script that demonstrates how to scan for nearby BLE devices, connect to one of them, and read characteristics.
import time
from datetime import datetime
from bleuio_lib.bleuio_funcs import BleuIO
# Creating a callback function for scan results
def my_scan_callback(scan_input):
print("\n\nmy_scan_callback: " + str(scan_input))
# Creating a callback function for events
def my_evt_callback(evt_input):
cbTime = datetime.now()
currentTime = cbTime.strftime("%H:%M:%S")
print("\n\n[" + str(currentTime) + "] my_evt_callback: " + str(evt_input))
# Initiating the BleuIO dongle
my_dongle = BleuIO()
# Registering the callback functions
my_dongle.register_evt_cb(my_evt_callback)
my_dongle.register_scan_cb(my_scan_callback)
# Switch to Central or Dual Gap Role
my_dongle.at_dual()
# Start scanning for devices
my_dongle.at_gapscan(3)
# Wait for a few seconds to allow devices to be discovered
time.sleep(4)
# Connect to a device using its MAC address
my_dongle.at_gapconnect('[1]D1:79:29:DB:CB:CC')
# Wait for the connection to establish
time.sleep(4)
# Read characteristics with handle '0003', which contains the device name
my_dongle.at_gattcread('0003')
# Wait briefly
time.sleep(1)
Step 2: Running the Script
Save the script to a Python file, for example, bleuio_ble_tutorial.py. Then, run the script using your Python interpreter.
The script performs the following actions:
Initiates the BleuIO dongle and sets up callback functions for scan results and events.
Switches to Central or Dual Gap Role.
Scans for nearby BLE devices for a specified duration (3 seconds in this example).
Connects to a specific device using its MAC address.
Waits for the connection to establish.
Reads the characteristics with handle ‘0003’, which typically contains the device name.
Waits briefly before exiting.
The scan results and characteristic data will be displayed on the terminal.
Output :
Working with BLE devices on Linux using the BleuIO dongle and Python library is a straightforward process. You can use this script as a starting point to interact with BLE devices and further develop your BLE applications. Remember to customize the script to suit your specific needs, and explore the wealth of possibilities that BLE technology offers in the world of IoT and wireless communication.