Running a HibouAir BLE Air Quality Scanner on Adafruit Fruit Jam with BleuIO

In this project, we will look at how the BleuIO SSD025 Bluetooth Low Energy USB dongle can add BLE communication to an Adafruit Fruit Jam powered by the RP2350.

The project takes an unusual software approach. Instead of running the HibouAir scanner as part of the native firmware, the Fruit Jam runs a custom real-time operating system called myRTOS .

A myRTOS application module, hibouair.c, written in C, communicates with the BleuIO dongle over USB, scans for nearby HibouAir air-quality sensors, decodes their Bluetooth Low Energy advertisements and displays the latest measurements in real time in a terminal window.

The result is a compact embedded BLE air-quality gateway running on the RP2350.

Requirements

For this project, we use:

The Fruit Jam is particularly suitable for this project because it has a built-in USB hub with two exposed USB host ports.

What does this project do?

1. HibouAir broadcasts sensor data

2. BleuIO receives the BLE advertisements

3. Fruit Jam receives the data over USB

4. myRTOS decodes and displays the measurements

The HibouAir sensor periodically broadcasts its measurements using BLE advertising packets. The SSD025 receives these packets and makes the information available to the RP2350 over USB.

The myRTOS application then scans for HibouAir devices, interprets the received information and maintains a live list of detected sensors.

The terminal provides an easy way to observe the air-quality information as it arrives.

Hardware

The project is built around three main pieces of hardware.

Adafruit Fruit Jam with the BleuIO SSD025 connected directly to the USB Type-A host port.

Adafruit Fruit Jam

The Fruit Jam is a compact computer based on the RP2350B microcontroller. Adafruit provides two USB Type-A host ports through an onboard USB hub, making it possible to connect USB peripherals directly to the board.

The board provides considerably more functionality than is required for this simple gateway. In addition to the RP2350B, it includes flash storage, PSRAM, USB host capability, microSD, DVI output, audio hardware and an ESP32-C6 for wireless connectivity.

For this project, however, the important feature is the USB host interface .

BleuIO SSD025

The BleuIO SSD025 is used as the Bluetooth Low Energy interface.

This means the RP2350 application does not need to implement the Bluetooth Low Energy stack itself.

The dongle supports Bluetooth 5.2 and USB Full Speed, can operate in Bluetooth central or peripheral roles, and is controlled through its USB interface.

The application can therefore access BLE functionality through BleuIO’s USB interface while leaving the Bluetooth communication to the dongle.

HibouAir SSD002

The HibouAir SSD002 is the wireless air-quality sensor.

HibouAir’s documentation describes the SSD002/2B as a CO2 air-quality monitor using an NDIR CO2 sensor, with wireless Bluetooth connectivity. The sensor family can provide environmental parameters including CO2, temperature, humidity, particulate matter and VOC-related measurements depending on the model.

www.hibouair.com

Why use BleuIO?

The BleuIO acts as the bridge between the USB host implemented by the Fruit Jam and the Bluetooth Low Energy devices in the surrounding environment.

The application processor can concentrate on:

  • USB communication
  • RTOS scheduling
  • data parsing
  • terminal output

while the BleuIO handles the Bluetooth side.

BleuIO’s own HibouAir gateway example similarly uses BleuIO to provide BLE communication to RP2040/RP2350 development boards through USB.

The Software Architecture

The software in this project is based on myRTOS , a small real-time operating system environment running on the Fruit Jam.

The HibouAir application is started from the RTOS command interface:

myrtos:/> hibouair

Once started, the application enters scanning mode:

scanning; ctrl-C to stop

The application then continuously processes incoming BLE data.

Conceptually, the software pipeline looks like this:

HibouAir → BLE advertisements → BleuIO SSD025 → USB → Fruit Jam / myRTOS → HibouAir packet decoding → Terminal display

The important point is that this is not simply a raw BLE packet monitor.

The application turns the incoming wireless data into a human-readable sensor table .

How to Run the Project

The complete project is available on GitHub:

https://github.com/smart-sensor-devices-ab/Adafruit-Fruit-Jam-with-BleuIO

  1. Connect the board: Connect the Adafruit Fruit Jam to your computer using a USB-C cable and turn the power switch ON.
  2. Hold down Button #1 (the UF2 BOOT button located on GPIO0), press and release the reset button while continuing to hold Button #1, and release Button #1 only after the bootloader drive appears.
  3. Drag the project’s .uf2 file onto the board’s bootloader drive. The image includes myRTOS and the hibouair.c application module.
  4. Press the reset button to reboot the board.
  5. Connect the BleuIO SSD025: Plug the BleuIO SSD025 into one of the Fruit Jam’s USB Type-A host ports.
  6. Power the HibouAir sensor: Make sure one or more HibouAir sensors are powered on and within Bluetooth range of the BleuIO dongle.

Button Locations on the Adafruit Fruit Jam

To enter UF2 bootloader mode, this project uses two buttons on the Fruit Jam:

  • Button #1 (UF2 BOOT) — located on GPIO0 towards the bottom-right edge of the board.
  • Reset button — located on the left edge of the board.

The image below shows the location of both buttons.

After rebooting, open a terminal window and connect to the board.

Windows

After rebooting, open Device Manager and identify the COM port assigned to the Fruit Jam. Connect to this port using a serial terminal such as PuTTY.

macOS

To find the Fruit Jam’s serial port, open a terminal and run:

ls /dev/cu.usbmodem*

The command should return a device similar to:

/dev/cu.usbmodem2351xxxx

Connect to it using:

screen /dev/cu.usbmodem2351xxxx

Real-Time HibouAir Scanning

After connecting to the Fruit Jam, start the HibouAir application from the myRTOS command interface:

myrtos:/> hibouair
scanning; ctrl-C to stop

The program then prints a table containing the detected HibouAir devices.

This gives the user an immediate overview of all the HibouAir sensors currently being received.

Expected Output

For example, the output below shows several HibouAir devices detected during a scan. The table shows each detected device’s board identifier, Bluetooth address, sensor type and latest environmental measurements.

Where Could This Go Next?

The current application concentrates on the essential task: receiving HibouAir advertisements and presenting the decoded measurements in real time.

Logging the data to the Fruit Jam’s microSD card would also make it possible to create long-term air-quality datasets without requiring a permanently connected computer.

The Fruit Jam’s USB host capability, microSD storage and RP2350B processor make this type of expansion practical.

Conclusion

This project demonstrates how the Adafruit Fruit Jam, BleuIO SSD025 and HibouAir SSD002 can be combined to create a compact RP2350-based Bluetooth Low Energy air-quality gateway.

HibouAir sensors broadcast their environmental measurements over BLE. BleuIO receives these advertisements and transfers the data to the Fruit Jam over USB, where the myRTOS hibouair application decodes the sensor data and presents the latest measurements in real time.

The project shows how BleuIO can add BLE communication to an RP2350-based embedded system while keeping the Bluetooth interface separate from the main application.

Share this post on :

Build a Cloud Air Quality Dashboard with HibouAir, BleuIO, and TagoIO

Air quality and environmental monitoring are common IoT use cases where Bluetooth Low Energy sensors can provide useful real-time information without requiring complex infrastructure.

In this project, we will use HibouAir as our air quality monitoring sensor, BleuIO as the Bluetooth Low Energy interface, and a Python application to collect and decode the advertised sensor data. The decoded measurements will then be sent to TagoIO, where we can store and visualize the data using an online dashboard.

The goal is to keep the project simple. There is no need to install an IoT server, MQTT broker, database, or dashboard software locally. BleuIO handles the BLE communication, the Python application processes the sensor data collected from HibouAir, and TagoIO handles the cloud side.

Why TagoIO?

TagoIO is an IoT platform that provides tools for connecting devices, storing sensor data, and creating dashboards for visualization.

For this project, one of the main reasons for choosing TagoIO is that it is easy to get started. It provides a free plan, which is suitable for experimenting with a small number of devices and building proof-of-concept IoT applications.

This makes it particularly useful for projects such as environmental monitoring where we simply want to send sensor measurements to the cloud and visualize them without setting up our own backend infrastructure.

If the project grows later, TagoIO also provides paid subscription options with additional resources and capabilities. This means we can start with the free option while developing and testing the project, and move to a larger plan later if necessary.

Another useful feature is its dashboard builder. Once our sensor variables reach TagoIO, we can create cards, displays, gauges, and time-series charts directly from the web interface.

For our HibouAir project, this allows us to visualize measurements such as:

  • Temperature
  • Relative humidity
  • CO2

Project Requirements

For this project, we need the following hardware and software.

Hardware

BleuIO

BleuIO is a USB Bluetooth Low Energy dongle that allows us to control BLE communication using simple AT commands over a serial connection.

In this project, BleuIO scans for the BLE advertisements transmitted by HibouAir and passes the received advertisement data to our Python application.

HibouAir

HibouAir is the environmental BLE sensor used in this example.

For this project, we are using a HibouAir device advertising with the board ID:

220069

Software Requirements

Install Python 3 if it is not already available.

The project uses the following Python packages:

pyserial
requests

Install them using:

python3 -m pip install pyserial requests

You will also need a free TagoIO account.

Create an account and then create a new device in the TagoIO console.

For example:

Device Name: HibouAir Air Quality Sensor

After creating the device, TagoIO generates a Device Token.

The Device Token is used by the Python application to authenticate when sending measurements to TagoIO.

Keep this token private and do not publish it in a public GitHub repository.

How the Project Works

The project consists of three main stages.

1. Collect BLE Advertisements from HibouAir

HibouAir continuously broadcasts environmental data using Bluetooth Low Energy advertisements.

BleuIO is connected to the computer through USB and appears as a serial device.

On macOS, for example, the BleuIO dongle may appear as:

/dev/cu.usbmodemxxxxxxx

The Python application opens this serial port and communicates with BleuIO.

To locate our specific HibouAir device, the application asks BleuIO to search for advertisements containing the HibouAir board ID:

220069

Conceptually, the command looks like:

AT+FINDSCANDATA=220069=3

BleuIO scans for matching BLE advertisements and returns the advertisement data to the Python application.

The data received from BleuIO contains the raw BLE advertisement in hexadecimal format.

The Python application identifies the HibouAir environmental advertisement and extracts the relevant bytes from the payload.

The values are then decoded into useful environmental measurements.

For example:

Temperature : 24.6 °C
Humidity    : 48.2 %
CO2         : 612 ppm

Sending the Data to TagoIO

Once the HibouAir advertisement has been decoded, the Python application prepares the measurements in the format expected by TagoIO.

For example:

[
  {
    "variable": "temperature",
    "value": 24.6,
    "unit": "°C"
  },
  {
    "variable": "humidity",
    "value": 48.2,
    "unit": "%"
  },
  {
    "variable": "co2",
    "value": 612,
    "unit": "ppm"
  }
]

The application then sends the data to the TagoIO API using HTTPS.

The TagoIO Device Token is included with the request so that TagoIO knows which device the measurements belong to.

After the first successful upload, the variables automatically become available for the device in TagoIO.

In this example, the variables are:

temperature
humidity
co2

The application continues scanning for new HibouAir advertisements and periodically uploads new measurements.

Creating the TagoIO Dashboard

Once the sensor data starts appearing in TagoIO, we can create a dashboard.

In the TagoIO console, go to:

Dashboards

Create a new dashboard and give it a name such as:

HibouAir Air Quality Dashboard

We can then add widgets using the variables sent by our Python application.

For example, we can create current-value widgets for:

Temperature
Humidity
CO2

We can also add line charts to display how each measurement changes over time.

Because TagoIO stores timestamps with the measurements, the line-chart widgets can display the sensor data as a time series.

This gives us a simple cloud-based air-quality monitoring dashboard without having to maintain our own database or web application.

Source Code

The complete source code for this project is available on GitHub:

GitHub:
https://github.com/smart-sensor-devices-ab/BleuIO-hibouair-tagoio

Configure the Application

Before running the application, update the configuration with your BleuIO serial port and TagoIO Device Token.

For example:

BLEUIO_PORT = "/dev/cu.usbmodem4048FDE52CF21"

HIBOUAIR_ID = "220069"

You will also need your TagoIO Device Token.

For development, the token can be supplied through the application configuration.

The TagoIO API endpoint also needs to match the region used by your TagoIO account.

Running the Application

Make sure:

  1. BleuIO is connected to the computer.
  2. HibouAir is powered on and advertising.
  3. Your computer has an Internet connection.
  4. Your TagoIO Device Token has been configured.

Then run:

python3 script.py

The application should first connect to BleuIO.

You should see output similar to:

BleuIO + HibouAir + TagoIO
==========================

BleuIO port: /dev/cu.usbmodem4048FDE52CF21
BleuIO responded OK

Looking for HibouAir 220069

When a valid HibouAir advertisement is received, the decoded sensor measurements will be displayed:

----------------------------------
HibouAir detected
----------------------------------

Temperature   : 24.6 °C
Humidity      : 48.2 %
CO2           : 612 ppm

----------------------------------

TagoIO upload: OK

The application will continue scanning and uploading new readings until it is stopped.

Use:

Ctrl + C

to stop the application.

Output

After the application has been running for a while, the sensor measurements will be available from the TagoIO device page and dashboard.

The dashboard can display the latest HibouAir measurements as well as their historical changes.

In this project, we created a simple cloud-connected environmental monitoring system using HibouAir, BleuIO, Python, and TagoIO.

This project should be considered a starting point rather than a finished monitoring product.

The code can be modified or expanded in many ways. Feel free to modify, extend, or reuse the code in your own BLE and IoT applications as needed.

Share this post on :

Turn an RP2040 or RP2350 Board into a HibouAir Gateway with BleuIO

In this tutorial, we will look at how the BleuIO USB dongle can add Bluetooth Low Energy communication to an RP2040 or RP2350 development board.

The project uses the open-source Pico I/O Bridge firmware. It allows a supported development board to work as a USB host for BleuIO. BleuIO scans nearby HibouAir sensors, and the board displays the latest sensor data through a simple browser interface.

The board also creates a small USB network connection with the computer. This means the dashboard can be opened directly in a web browser without installing a desktop application or connecting the board to Wi-Fi. The firmware is written in Rust and exposes its interfaces through a local .local address.

This project is a useful example of how BleuIO can provide BLE communication to development boards that do not have built-in Bluetooth. The board handles USB hosting and networking, while BleuIO handles Bluetooth scanning.

Requirements

You will need:

What Does This Project Do?

The project creates a simple connection between HibouAir sensors, BleuIO and your computer.

1. HibouAir broadcasts sensor data

HibouAir sensors regularly broadcast their measurements using Bluetooth Low Energy advertising packets.

Depending on the HibouAir model, these broadcasts can contain parameters such as: Temperature, Humidity, Pressure, CO2, VOC, Noise, PM1.0, PM2.5, PM10, Ambient light

Because the project reads BLE advertising data, the HibouAir sensors do not need to be paired with the development board.

2. BleuIO receives the BLE advertisements

BleuIO is connected to the USB-A host port of the development board.

After BleuIO is detected, the firmware manages the scanning process automatically. BleuIO searches for nearby HibouAir advertisements and sends the received data to the board.

This is an important part of the project: the RP2040 or RP2350 board does not need its own Bluetooth radio. BleuIO provides the Bluetooth Low Energy functionality through USB.

3. The board decodes the HibouAir data

The firmware reads the BLE scan results from BleuIO and decodes the HibouAir manufacturer data.

It identifies the HibouAir sensor ID and sensor type before extracting the measurements supported by that particular model.

The firmware keeps the latest readings for up to eight HibouAir sensors in memory. When no sensor filter has been configured, sensors are discovered automatically.

4. The results appear in a web browser

The development board appears on the computer as a small USB Ethernet device. It provides its own local IP network and advertises a unique .local hostname.

The browser dashboard shows: BleuIO connection status, USB transfer status, Number of HibouAir sensors discovered, HibouAir sensor IDs, Sensor types, Latest measurements, Time since the last advertisement, Number of reports received

The dashboard updates automatically while BleuIO continues scanning.

How to Run the Project

The complete project is available on GitHub:

Pico I/O Bridge GitHub repository

There are two ways to run it:

  1. Flash a pre-built firmware file.
  2. Build the firmware from the Rust source code.

Using a pre-built firmware file is the easiest method.

Method 1: Use the Pre-Built Firmware

Step 1: Download the firmware

Open the project’s release page:

Pico I/O Bridge v0.2.0 release

The release contains pre-built UF2 firmware files for the supported board profiles, together with a checksum file.

Download the UF2 file that matches your board.

For this project, select the firmware for either:

Adafruit Feather RP2040 USB Host

or:

Waveshare RP2350 USB-A

Do not flash firmware intended for a different board model.

Step 2: Put the board into bootloader mode

Disconnect the board from the computer.

Put the board into its normal UF2 or BOOTSEL flashing mode. The exact button combination depends on the board, so follow the normal bootloader procedure for your development board.

When the board enters bootloader mode, it should appear on the computer as a removable USB drive.

Step 3: Flash the UF2 file

Copy the downloaded UF2 file to the board’s removable drive.

The board should restart automatically after the file has been copied.

Wait a few seconds for the firmware to start and for the USB network connection to become available.

Step 4: Connect BleuIO

Insert the BleuIO USB dongle into the USB-A host port of the development board.

The physical connection should look like this:

Do not connect BleuIO directly to the computer for this setup. It needs to be connected to the USB host port on the development board.

Step 5: Power the HibouAir sensors

Make sure your HibouAir sensors are powered on and located within Bluetooth range of BleuIO.

No Bluetooth pairing process is required. The sensors simply need to be broadcasting their normal BLE advertisement data.

Step 6: Find the board hostname

Each board creates a unique .local hostname.

For the Adafruit Feather RP2040 USB Host, it will follow this format:

pico-io-usb-host-xxxxxx.local

For the Waveshare RP2350 USB-A, it will follow this format:

pico-io-waveshare-rp2350-xxxxxx.local

Replace xxxxxx with the unique identifier assigned to your board.

On macOS, the board can also be discovered through the built-in dns-sd utility:

dns-sd -B _http._tcp

The project advertises its web interface through mDNS and DNS Service Discovery.

On Windows, the optional mDNS Discovery utility can be used to view available mDNS and DNS-SD services.

Step 7: Open the web interface

Open a browser and enter the board hostname.

For example:

http://pico-io-usb-host-244c29.local/usb-host.html

Use your board’s actual hostname rather than the example above.

The USB-host-enabled profiles expose the USB status page at:

/usb-host.html

The web interface and the USB-host API are included whenever the firmware is built with the pio-usb-host feature.

Step 8: Wait for BleuIO to become ready

After opening the page, check the USB section.

You should see a status similar to:

BleuIO Ready

You should also see:

BleuIO HibouAir scanner ready

Once BleuIO is ready, the managed HibouAir scan begins automatically.

Nearby HibouAir sensors should start appearing as individual cards. The first results may take a few seconds, depending on the sensors’ advertisement intervals.

Expected Output

The page should show each discovered HibouAir sensor with its sensor ID, sensor model and latest measurements.

Method 2: Build the Firmware from Source

Developers can also clone the complete project and build the firmware using Rust.

Clone the repository:

git clone https://github.com/ulso/pico-io-bridge.git
cd pico-io-bridge

Build for the Adafruit Feather RP2040 USB Host

cargo build --locked --release \
  --no-default-features \
  --features board-adafruit-rp2040-usb-host

Build for the Waveshare RP2350 USB-A

cargo build --locked --release \
  --target thumbv8m.main-none-eabihf \
  --no-default-features \
  --features board-waveshare-rp2350-usb-a

The RP2040 and RP2350 profiles use different Rust target configurations, so it is important to use the command intended for your board.

With the board in BOOTSEL mode, the project can also be built and flashed using the appropriate cargo run command. The repository contains the full toolchain and flashing details for developers who want to modify the firmware.

The complete source code, build instructions and examples are available in the Pico I/O Bridge GitHub repository. Additional project screenshots can be found in the Pico I/O Bridge Wiki.

Share this post on :

Send HibouAir Temperature and Humidity Data to openSenseMap Using BleuIO

In this project, we are going to build a simple air quality data-sharing system using a BleuIO USB dongle, a HibouAir sensor, Python, and openSenseMap.

The goal of this project is to collect temperature and humidity data from a HibouAir sensor over Bluetooth Low Energy and publish the values online using openSenseMap. Once the data is uploaded to openSenseMap, it can be viewed publicly and shared with others.

This is a minimal project designed to show how BleuIO can be used as a BLE gateway for collecting environmental sensor data and sending it to an online platform. The same idea can later be expanded to include other air quality parameters such as CO2, VOC, particulate matter, pressure, or other sensor values.

What is openSenseMap?

openSenseMap is an open data platform for environmental sensor data. It allows users to create a virtual sensor station, called a senseBox, and upload measurements from different sensors.

By using openSenseMap, we can make our air quality data public and easy to access. This is useful for projects related to environmental monitoring, smart cities, classrooms, research, and IoT demonstrations.

In this project, we will create a senseBox on openSenseMap and add two sensors:

  • Temperature
  • Relative humidity

The Python script will read these values from the HibouAir BLE advertisement and upload them to the correct openSenseMap sensor IDs.

Project Requirements

To complete this project, we need the following hardware and software:

No extra microcontroller, BLE pairing, database, or web server is required. BleuIO connects directly to the computer through USB and is controlled using AT commands from the Python script.

Setting Up openSenseMap

First, create an account on openSenseMap. After logging in, create a new senseBox. This senseBox will represent the sensor station where our HibouAir measurements will be uploaded.

Inside the senseBox, create two sensors:

  • Temperature with unit °C
  • Relative humidity with unit %RH

After creating the senseBox and sensors, openSenseMap will provide different IDs. We need to copy and save the following values:

  • senseBox ID
  • Temperature sensor ID
  • Humidity sensor ID

These IDs are important because the Python script uses them to know where to upload each measurement. The senseBox ID identifies the box, while each sensor ID identifies the individual measurement field.

Configuring the Project

The project uses an info.txt file to store the required IDs and configuration values.

If info.txt does not already exist, copy the example file:

cp info.example.txt info.txt

Then add the openSenseMap IDs and the HibouAir board ID:

OPENSENSEMAP_BOX_ID=your_box_id_here
SENSOR_ID_TEMPERATURE=your_temperature_sensor_id_here
SENSOR_ID_HUMIDITY=your_humidity_sensor_id_here
HIBOUAIR_SENSOR_ID=220069

# Optional on macOS:
# BLEUIO_PORT=/dev/cu.usbmodemXXXX

The HIBOUAIR_SENSOR_ID is the board ID printed on the HibouAir sensor. The script uses this ID to filter BLE advertisements and make sure it is reading data from the correct device.

Normally, the script automatically finds the BleuIO serial port on macOS by checking /dev/cu.usbmodem* and /dev/cu.usbserial*. If needed, the port can also be added manually in info.txt.

The info.txt file is excluded from Git using .gitignore, so private box IDs and sensor IDs are not committed to the repository.

Installing Dependencies

Open Terminal, go to the project directory, and run:

python3 -m venv .venv
source .venv/bin/activate
python3 -m pip install -r requirements.txt

The project uses only two Python packages:

  • pyserial
  • requests

pyserial is used to communicate with the BleuIO dongle over the serial port, and requests is used to upload data to openSenseMap.

How the Project Works

The BleuIO USB dongle is connected directly to the Mac. The Python script opens the BleuIO serial port and sends AT commands to scan for BLE advertisements from the HibouAir sensor.

The script uses the HibouAir board ID to filter the scan result. For example:

AT+FINDSCANDATA=220069=5

This command asks BleuIO to search for advertised data containing the board ID 220069 for five seconds.

When the scan response is received, the script decodes the latest valid HibouAir advertisement. It extracts only two values. Temperature and Relative humidity,

After decoding the values, the script uploads them to the configured openSenseMap senseBox using the temperature and humidity sensor IDs.

The upload process repeats every 60 seconds.

Only temperature and humidity are uploaded. Bluetooth addresses, raw advertising payloads, and other sensor values are not sent to openSenseMap or saved to a file.

Running the Script

Connect BleuIO to the Computer and run:

python3 main.py

Press Ctrl+C to stop the logger.

Example output:

## BleuIO HibouAir openSenseMap Logger

Using port: /dev/cu.usbmodem4048FDE52CF21
Checking BleuIO...
BleuIO responded OK

Scanning for HibouAir sensor ID: 220069
Scan command: AT+FINDSCANDATA=220069=5
Waiting for BleuIO scan response...

Decoded HibouAir data:
Temperature: 24.3 °C
Humidity: 42.8 %RH

Uploading to openSenseMap...
Temperature uploaded successfully
Humidity uploaded successfully

Waiting 60 seconds before next scan...

The script reads the BleuIO response, decodes the temperature and humidity values, uploads them to openSenseMap, and then waits before starting the next scan.

Outputs

Source Code

The full source code for this project is available on GitHub.

Users can download the project, configure their own openSenseMap IDs, add their HibouAir board ID, and run the script on their own system.

GitHub URL:

https://github.com/smart-sensor-devices-ab/bleuio_opensensemap

Expanding the Project

This project currently uploads only temperature and humidity, but it can be expanded easily.

Users can modify the script to decode and upload more environmental parameters, such as: CO2, VOC, Particulate matter, Air pressure, Light level etc.

Additional sensors can also be created in openSenseMap, and their sensor IDs can be added to the configuration file. This makes the project flexible for different air quality monitoring and IoT applications.

With only a BleuIO USB dongle, a HibouAir sensor, and a Python script, we can collect temperature and humidity data and make it publicly available. The project is easy to set up, requires no BLE pairing, and can be extended for more advanced air quality monitoring applications.

Share this post on :

Build a BLE RSSI Heatmap Visualizer Using BleuIO

Bluetooth Low Energy devices are everywhere, from smart sensors and beacons to IoT devices and proximity-based applications. When working with BLE, developers often need a quick way to scan nearby advertising devices and understand their signal strength.

In this project, we build a simple BLE RSSI Heatmap Visualizer using the BleuIO USB dongle. The application runs directly in the browser and connects to BleuIO through the serial port. It performs a BLE scan, reads nearby advertising devices, extracts their RSSI values, and displays them in a visual heatmap.

This is helpful because raw BLE scan output can be difficult to read, especially when many devices are advertising at the same time. With this visualizer, developers can quickly see which devices have strong, medium, or weak signal strength.

BleuIO makes this project simple because it handles the BLE scanning through easy AT commands. Instead of writing low-level Bluetooth code, we can send commands from JavaScript and focus on building the visualization.

Requirements

To try this project, you need:

How It Works

The application connects to the BleuIO dongle using the browser’s Web Serial API. Once connected, it sends BleuIO AT commands to put the dongle into central scanning mode and start a BLE GAP scan.

The main commands used are:

AT+CENTRAL
AT+SHOWRSSI=1
AT+GAPSCAN=5

AT+CENTRAL prepares BleuIO for scanning. AT+SHOWRSSI=1 enables RSSI values in the scan output. AT+GAPSCAN=5 scans nearby BLE devices for 5 seconds.

The browser app then reads the serial output and looks for device information such as MAC address, RSSI value, and device name if available. Each device is grouped based on RSSI strength.

The signal categories are simple:

Strong signal: RSSI >= -50
Medium signal: RSSI between -51 and -70
Weak signal: RSSI <= -71

The heatmap places BleuIO at the center and displays nearby BLE devices around it. Stronger devices appear closer to the center, while weaker devices appear farther away. The device bubbles are also color-coded, making it easier to understand the BLE environment at a glance.

A table below the heatmap shows the detected devices with MAC address, RSSI, name, signal category, and last seen time.

GitHub Project Code

The full source code is available here:

https://github.com/smart-sensor-devices-ab/ble-rss-heatmap-visualizer

You can download or clone the project and open it in a supported browser.

Live Testing

You can also try the live version here:

https://smart-sensor-devices-ab.github.io/ble-rss-heatmap-visualizer/

To test it:

  1. Plug in the BleuIO USB dongle.
  2. Open the live page in your browser.
  3. Click Connect.
  4. Select the BleuIO serial port.
  5. Click Scan.
  6. View the BLE RSSI heatmap and detected device table.

Output Screenshot

Add output screenshot here.

This is an example project showing how BleuIO can be used with the Web Serial API to build a practical BLE scanning and visualization tool. Developers can use the source code as a starting point and modify it for their own use cases.

For example, the project can be extended to scan for a longer period of time, change the RSSI threshold values, filter specific devices, highlight known BLE sensors, or integrate the scan results into a larger web dashboard.

Because BleuIO works with simple AT commands over serial, it is easy to integrate with different programming languages, platforms, and browser-based tools like this one.

Share this post on :

Using BleuIO with Fortran to Scan and Decode BLE Advertising Data

Bluetooth Low Energy development is often associated with languages like C, Python, JavaScript, or mobile frameworks. But with BleuIO, BLE communication becomes accessible from almost any programming language that can work with a serial port. In this tutorial, we will build a simple Fortran terminal application that connects to a BleuIO USB dongle, sends AT commands, scans for nearby HibouAir BLE advertisements, decodes the advertising data, and prints the sensor values directly in the terminal.

This project is intentionally small and beginner-friendly. The goal is not to build a full production BLE application, but to demonstrate how Fortran can communicate with BLE devices through BleuIO using simple serial communication.

Why Fortran for a BLE Example?

Fortran is one of the oldest programming languages still actively used today, especially in scientific computing, engineering, numerical modelling, and high-performance applications. While Fortran is not normally the first language people think of for BLE development, this example shows an interesting advantage of using BleuIO.

What We Are Building

The application does the following:

It connects to a BleuIO USB dongle using serial terminal. Then it configures the serial port and sends BleuIO AT commands. After that, it starts a filtered BLE scan for HibouAir advertisements using the command:

AT+FINDSCANDATA=FF5B07

The program then reads the incoming scan data, extracts the advertising payload, decodes the HibouAir manufacturer data, and prints values such as sensor ID, light or noise, pressure, temperature, humidity, CO2, and particulate matter values where available. The README also notes that the program automatically searches for a BleuIO dongle using VID 0x2dcf and PID 0x6002.

Project Requirements

Before running the project, install the required packages on macOS using Homebrew:

brew install gcc libserialport pkg-config

You will also need the following hardware:

1. BleuIO USB dongle
2. HibouAir CO2 Sensor

Getting the Project

The full source code is available on GitHub:

https://github.com/smart-sensor-devices-ab/bleuio-fortran

Building the Project

Build the project with:

make

This creates the executable:

./bleuio_fortran_scanner

The README confirms that the project is built using make and creates the bleuio_fortran_scanner binary.

Running the Project

Run the scanner from the terminal:

./bleuio_fortran_scanner

Once started, the program searches for the connected BleuIO dongle, opens the serial port, prepares the dongle, and starts scanning for HibouAir BLE advertisements.

You can stop the program at any time using:

Ctrl-C

How It Works

The project is split into small Fortran source files to keep the example easy to understand.

The libserialport_bindings.f90 file contains the small ISO_C_BINDING interface required to call libserialport. The serial_utils.f90 file handles finding, opening, configuring, reading from, writing to, and closing the serial port. The bleuio_commands.f90 file contains helper procedures for sending BleuIO AT commands. The simple_json.f90 file extracts the predictable fields needed from the BleuIO scan response. The hibouair_decoder.f90 file decodes HibouAir manufacturer data and prints the sensor values. Finally, main.f90 contains the main scanner flow.

The main idea is simple. BleuIO receives BLE advertising data and returns it through the serial port. The Fortran application reads each line, checks whether it contains valid scan data, extracts the advertisement payload, and decodes the bytes according to the HibouAir data format.

Because BleuIO handles the BLE communication, the Fortran code does not need to manage Bluetooth scanning directly. It only sends AT commands and reads the response.

Example Output

When a HibouAir CO₂ sensor is found, the terminal output looks like this:

BleuIO Fortran HibouAir Scanner
--------------------------------
Searching for BleuIO dongle...
Connected: /dev/tty.usbmodemXXXX

Sensor ID: 123ABC
Light: 52 Lux
Pressure: 1012.4 hPA
Temperature: 23.6 C
Humidity: 45.1 %rh
CO2: 612 ppm

For a PM sensor board, the output includes particulate matter values:

  Sensor ID: 456DEF
Light: 38 Lux
Pressure: 1011.8 hPA
Temperature: 22.9 C
Humidity: 47.2 %rh
PM 1.0: 2.1 ug/m3
PM 2.5: 4.8 ug/m3
PM 10: 7.3 ug/m3
CO2: 0 ppm

These sample outputs are also included in the project README.

Output Screenshot

Add a screenshot here showing the terminal running the Fortran application and printing decoded HibouAir sensor values.

Further Development

This project is a simple example showing how BleuIO can be used with Fortran when building BLE applications. It demonstrates the basic workflow: connect to BleuIO through a serial port, send AT commands, scan for BLE advertisements, read the response, and decode the data.

Developers can use this example as a starting point and expand it for their own projects. For example, the script could be extended to save sensor readings to a file, export data as CSV, monitor multiple HibouAir devices, trigger alerts when CO₂ or PM values are high, or integrate the data with scientific and engineering workflows where Fortran is already used.

Share this post on :

Building a BLE Application with Zig and BleuIO: Reading Sensor Data from HibouAir

In this tutorial, we will build a lightweight command-line application that interacts with Bluetooth Low Energy (BLE) devices using Zig and a BleuIO USB dongle. The application will scan for nearby BLE advertisements and decode sensor data broadcast by a HibouAir device. While HibouAir is used here as a test case, the main goal is to demonstrate how BleuIO simplifies BLE application development and how Zig can be used to build efficient, low-level tools for working with wireless data. By the end of this guide, you will have a working example of a BLE-powered CLI tool that reads, processes, and displays real-time data directly in your terminal.

About ZipLang (Zig)

Zig is a modern systems programming language designed with a focus on simplicity, performance, and control over hardware resources. It is particularly well-suited for applications that require direct interaction with devices, such as serial communication and embedded systems. In this project, Zig is used to communicate with the BleuIO dongle over a serial interface, process incoming BLE scan data, and decode raw payloads into meaningful values. Its minimal runtime and explicit design make it a strong choice for building reliable BLE tools without unnecessary abstraction.

Project Requirements

Hardware

Software

  • Zig installed
  • libserialport
  • pkg-config

How It Works

The application uses BleuIO as a bridge between the computer and BLE devices. When the program starts, it automatically detects the connected BleuIO dongle by matching its vendor and product ID, then opens a serial connection configured for communication. Once the connection is established, the program sends AT commands to initialize the dongle and begin scanning for BLE advertisement data that matches a specific identifier used by HibouAir devices.

As BLE data is received, the Zig application continuously reads the serial output, interprets the incoming JSON responses, and extracts the relevant payload. This payload is then decoded into human-readable sensor values such as temperature, humidity, pressure, particulate matter, and CO2 levels. The decoded information is printed directly in the terminal, allowing real-time monitoring without requiring any additional tools or manual decoding steps. When the program is stopped, it gracefully sends commands to halt scanning and reset the dongle before closing the connection.

Source Code

You can find the complete source code for this project on GitHub:

https://github.com/smart-sensor-devices-ab/bleuio-ziglang

Install and Run the Project

Follow the readme file inside the project to install and run. Once dependencies are installed, follow these steps:

Build the project

zig build

Run the application

zig build run

Make sure your BleuIO dongle is connected before running the program.

Example Output

When the application is running, it prints decoded BLE sensor data directly to the terminal. Each detected broadcast from a matching device is processed and displayed in a readable format, making it easy to observe environmental data in real time.

About BleuIO

BleuIO plays a central role in this project by abstracting the complexity of BLE communication. Instead of implementing a full Bluetooth stack within the application, developers can interact with BLE devices using simple AT commands over a serial interface. This approach allows BLE functionality to be integrated into applications written in virtually any programming language and run on any major operating system. By handling scanning, filtering, and communication at the hardware level, BleuIO enables developers to focus on application logic, making BLE development faster and more accessible.

This tutorial demonstrates how Zig and BleuIO can be combined to build a practical BLE application with minimal overhead. While HibouAir is used here as a sample device for testing, the same approach can be applied to a wide range of BLE-enabled sensors and devices. The combination of a lightweight programming language and a simple BLE interface creates a powerful development workflow that is both efficient and easy to extend for real-world use cases.

Share this post on :

Building a BLE Sensor Scanner with Nim and BleuIO

Working with Bluetooth Low Energy devices often means dealing with multiple layers—hardware, protocols, and data decoding. In this tutorial, we are going to simplify that process by building a small command-line application using Nim and a BleuIO USB Dongle.

The goal is simple: scan nearby BLE devices, detect HibouAir sensors, decode their broadcast data, and display readable environmental values directly in the terminal.

By the end, you will have a working local tool that reads real-time air quality data without needing cloud connectivity.

What We Are Building

In this project, we build a lightweight desktop utility that connects to a BleuIO dongle and continuously scans for BLE advertisement data. When a compatible HibouAir device is detected, the application decodes the raw hex payload and prints meaningful values such as temperature, humidity, pressure, CO2, and particulate matter levels.

This is not a heavy application or a full dashboard. It is intentionally simple. The idea is to give developers a clean starting point to understand how BLE data flows from a device to a readable format.

Why Nim with BleuIO?

Nim is a compiled programming language that feels lightweight but powerful. It combines the simplicity of scripting languages with the performance of C. For developers who want fast execution, low memory usage, and clean syntax, Nim is a very practical choice.

Using Nim with BleuIO makes the development process even smoother. The BleuIO dongle abstracts away complex BLE stack handling and exposes everything through simple AT commands over a serial interface. Instead of dealing with platform-specific BLE APIs, you can send commands and receive structured data in return.

This combination allows you to focus more on logic and less on low-level Bluetooth complexity.

Requirements

Before running the project, make sure you have the following:

How the Project Works

When the application starts, it first looks for the connected BleuIO dongle by checking the USB device identifiers. Once the dongle is found, the program opens the serial port and prepares the device for communication.

The setup phase uses a short sequence of AT commands:

ATV0
ATE0
ATV1

These commands are used to configure how the dongle responds over serial so that the application can read and process the output more reliably.

After setup, the application starts scanning for BLE advertisement data using this command:

AT+FINDSCANDATA=FF5B07

This tells BleuIO to scan and report advertisement packets that match the data pattern used by HibouAir devices.

As scan results come in, the program reads the serial output line by line. It looks for valid scan data entries and then extracts the raw advertisement payload. Once a matching payload is found, the Nim code decodes the hex data into readable sensor values such as temperature, humidity, pressure, CO2, and particulate matter values depending on the device type.

When you stop the program with Ctrl + C, it also sends a final reset command to close things down cleanly:

ATR

Example Output

Below is an example of how the data appears in the terminal when a device is detected and decoded.

You will see values like temperature, humidity, pressure, and CO2 being printed in real time as the device broadcasts data.

Source Code

You can access the full project source code here:

[GitHub Repository ]

The code is intentionally kept small and readable so it is easy to follow and modify.

Running the Project

Once the project is downloaded and the BleuIO dongle is plugged into your Mac, you can build and run it directly from Terminal.

First, move into the project folder:

cd ~/Downloads/bleuio-nim

If you have not already installed the required tools, install them with Homebrew:

brew install nim libserialport pkg-config

After that, build the project:

nimble build

Once the build is complete, run it with:

nimble run

If everything is set up correctly, the application will detect the connected BleuIO dongle, initialize it, and begin scanning for HibouAir advertisement data. Within a few seconds, you should start seeing decoded sensor readings appear in the terminal.

When you want to stop the scanner, press:

Ctrl + C

The application will then stop scanning, send its cleanup command, and close the serial connection.

This project is best seen as a foundation rather than a finished product. It shows how to connect to a BLE device, scan for advertisement data, and decode it into something useful.
From here, you can take it in many directions. You might want to store the data locally, send it to a cloud service, build a graphical dashboard, or integrate it into a larger system. Since the core BLE communication is already handled through BleuIO, extending the project becomes much easier.

Share this post on :

Scanning BLE Devices with C++ and Boost Using the BleuIO Dongle

Bluetooth Low Energy (BLE) has become one of the most widely used wireless technologies for IoT devices, sensors, wearables, and industrial monitoring systems. Developers working with embedded systems, automation platforms, and hardware integration often rely on C++ because of its performance, low-level hardware access, and portability.

In this tutorial, we will create a simple command-line BLE scanning application using C++. The program connects to the BleuIO USB dongle through a serial port and sends AT commands to control Bluetooth operations. After starting the program, the user enters the number of seconds to scan, and the application instructs the BleuIO dongle to perform a BLE scan and print the detected devices directly in the terminal. This example demonstrates the basic workflow of communicating with BleuIO from a C++ application.

Why C++ and Boost Are Commonly Used for Bluetooth Development

C++ is widely used in Bluetooth and embedded development because it provides high performance and direct access to hardware interfaces such as serial communication. Many IoT gateways, embedded systems, and industrial applications rely on C++ to interact with sensors and wireless devices. To simplify development, developers often use the Boost libraries, which extend the C++ standard library with reliable cross-platform tools. In this tutorial we use Boost.Asio, which provides a portable and efficient way to handle serial communication and asynchronous input/output across different operating systems.

Requirements

Before starting this project, you should have the following:

Installing the Required Tools

macOS Setup

First install Xcode Command Line Tools, which provide the C++ compiler.

xcode-select --install

Next install Homebrew if it is not already installed.

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

Then install Boost:

brew install boost

You can verify the installation using:

brew --prefix boost

Windows Setup

On Windows you will need:

  • Visual Studio or MSVC compiler
  • Boost libraries

Steps:

  1. Install Visual Studio Community Edition
  2. Enable Desktop development with C++
  3. Download Boost from https://www.boost.org
  4. Extract Boost and configure it for your project.

Alternatively, Boost can be installed using vcpkg.

Have a look into the getting started guide on boost office page

https://www.boost.org/doc/user-guide/getting-started.html

Understanding How the Script Works

The example script uses Boost.Asio serial communication to interact with the BleuIO dongle.

The application works in several stages.

Serial Connection

The program opens a serial port connected to the BleuIO dongle.

serial_.open(port_name);

The serial port parameters are configured to match BleuIO’s default UART settings.

serial_.set_option(serial_port_base::baud_rate(57600));
serial_.set_option(serial_port_base::character_size(8));
serial_.set_option(serial_port_base::parity(serial_port_base::parity::none));
serial_.set_option(serial_port_base::stop_bits(serial_port_base::stop_bits::one));
serial_.set_option(serial_port_base::flow_control(serial_port_base::flow_control::none));

Asynchronous Serial Reader

The script uses an asynchronous reader to continuously listen for responses from the BleuIO dongle.

serial_.async_read_some(...)

Whenever the dongle sends data, the program prints the received information to the terminal.

This allows us to see scan results in real time.

Sending AT Commands

Commands are sent to BleuIO using the sendCommand() function.

bleuio.sendCommand("AT+CENTRAL");

The command is written to the serial port followed by a carriage return and newline.

Setting Central Role

BLE devices can operate in different roles.
Before scanning, the BleuIO dongle must be set to central mode.

bleuio.sendCommand("AT+CENTRAL");

Starting a BLE Scan

The scan command is then issued.

AT+GAPSCAN=<seconds>

For example:

AT+GAPSCAN=5

This instructs the BleuIO dongle to scan for nearby BLE devices for five seconds.

The dongle returns advertising data for detected devices during the scan.

Full Source Code

You can find the full source code on GitHub.

GitHub repository

https://github.com/smart-sensor-devices-ab/bleuio-cpp-boost

The repository contains the complete C++ script used in this tutorial.

How to Run the Script

First compile the program.

clang++ -std=c++17 main.cpp -I$(brew --prefix boost)/include -o bleuio_scan

After compilation, run the program:

./bleuio_scan

The program will ask for the scan duration.

Example:

Enter scan duration in seconds: 5

The script will then:

Connect to the BleuIO serial port,Put the dongle into central mode,Start scanning for BLE devices,Print scan results in the terminal

Example output may look like this:

Locating the BleuIO Serial Port

Before running the program, you need to identify the serial port where the BleuIO dongle is connected.

On macOS, you can list available serial devices using the terminal command:

ls /dev/cu.*

The BleuIO device will typically appear with a name similar to:

/dev/cu.usbmodemXXXXXXXX

This value can then be used in the script as the serial port path.

On Windows, the serial port can be identified through Device Manager. After plugging in the BleuIO dongle, open Device Manager and expand the Ports (COM & LPT) section. The device will appear as a USB serial device with a COM port number, such as COM17.

Expanding This Example

The script in this tutorial is a basic example showing how to communicate with the BleuIO dongle using C++ and Boost.Asio. Although it only performs BLE scanning, the same approach can be used to send any AT command supported by BleuIO. Developers can extend this example to connect to devices, read GATT characteristics, parse advertisement data, or integrate BLE functionality into larger applications such as IoT gateways, monitoring tools, or automation systems.

Share this post on :

Integrating BleuIO with Teensy 4.1 – Scanning and Decoding HibouAir Sensor Data (Part 2)

In the previous project, we focused on getting Teensy 4.1 working as a USB Host for the BleuIO. The goal was simple: remove the PC from the equation and prove that a microcontroller could directly control BleuIO and communicate over BLE using AT commands.

This project builds on that foundation and does something practical with it. Instead of manually sending commands and observing responses, we now create a complete scanner that automatically detects nearby HibouAir sensors, reads their BLE advertisement data, decodes it, and prints meaningful environmental values in real time.

At this point, the system stops being a connectivity demo and becomes an actual application.

Hardware Requirements

Software Requirements

Install ArduinoJson

This project uses ArduinoJson to parse scan results from BleuIO.

In Arduino IDE:

  1. Open Library Manager
  2. Search for arduinojson
  3. Install version 7.x or compatible

ArduinoJson is required to deserialize the JSON scan data received from BleuIO.

How it Works

The architecture remains the same as in Part 1, but now it is used with purpose.

Teensy operates in USB Host mode and communicates directly with BleuIO. BleuIO handles all Bluetooth Low Energy scanning internally and outputs scan results as structured JSON strings over USB serial. Teensy receives those strings, parses the JSON content, extracts the manufacturer-specific payload, and decodes it into usable values.

Conceptually, the flow looks like this:

Teensy 4.1 (USB Host + Application Logic)
↓
BleuIO (BLE Scanning Engine)
↓
BLE Advertisement Data (JSON)
↓
HibouAir Decoder
↓
Readable Environmental Measurements

The important thing to notice here is that Teensy never deals with BLE packets directly. There is no radio handling, no GAP or GATT management, and no BLE stack integration. Everything related to Bluetooth stays inside BleuIO. The microcontroller simply receives structured scan results and processes them like any other data stream.

Automatic Startup and Scanning

When the firmware starts, it configures BleuIO automatically. It disables command echo, enables verbose mode, and then sends a filtered scan command:

AT+FINDSCANDATA=FF5B07

This tells BleuIO to report only devices containing the HibouAir manufacturer identifier. From that moment, scan results begin arriving continuously as JSON lines.

Each line contains fields such as the device address and a data field containing the manufacturer payload in hex format. That hex string is where the sensor readings are encoded.

Parsing the JSON Data

Since scan data arrives asynchronously, the project includes a small USB serial line reader. It buffers incoming characters until a newline is detected, ensuring that we always attempt to parse complete JSON messages.

The ArduinoJson library is used to deserialize each line into a JsonDocument. Once deserialized, we check that the expected scan fields are present. If so, we extract the hex-encoded manufacturer payload and pass it to the HibouAir decoder.

At this stage, the data is still raw — just a long hex string representing packed bytes from the BLE advertisement.

Decoding the HibouAir Advertisement Payload

The core of this project is the HibouAir structure. Instead of manually extracting bytes in the main loop, the decoding logic is encapsulated in a dedicated class.

The constructor receives the JSON document, extracts the data field, and interprets the hex string as a packed binary structure. Using offsetof() ensures that the correct byte offsets are used, and helper functions convert the hex pairs into integers. Because the BLE advertisement uses little-endian ordering, some fields require byte swapping before they become meaningful.

Once decoded, the class provides clean accessor functions such as:

  • getTemp()
  • getHum()
  • getBar()
  • getCo2()
  • getPM2_5()

These functions already return properly scaled values. For example, temperature is divided by 10 to convert from raw integer format to degrees Celsius.

This separation keeps the application logic simple. The main loop only needs to create a HibouAir object and call show_sensor() to print the values.

Example Output

When running the project with a nearby HibouAir sensor, the Serial Monitor shows structured environmental readings like this:

Sensor ID: 22008C
Light: 14 Lux
Pressure: 1007.3 hPA
Temperature: 22.9 C
Humidity: 14.1 %rh
CO2: 508 ppm

For particulate matter devices, additional values appear:

PM 1.0: 0.0 ug/m3
PM 2.5: 1.2 ug/m3
PM 10: 2.5 ug/m3

This output is generated directly from BLE advertisements without establishing a connection to the sensor. The sensors simply broadcast their measurements, and the system passively collects and decodes them.

GitHub Repository

The complete source code for this project is available here:

https://github.com/smart-sensor-devices-ab/bleuio-teensy-hibouair-scanner

You can clone the repository, install the ArduinoJson library through the Arduino IDE Library Manager, upload the sketch to Teensy 4.1, and run it immediately. The code is modular and organized so you can reuse the USB line reader, the HibouAir decoder, or the scanning logic in your own applications.

With this foundation in place, several natural extensions become possible. You could store measurements on an SD card, publish them via MQTT, expose them through a REST interface, or even build a complete air-quality gateway. The BLE side does not need to change.

Share this post on :