Introducing Auto Execution Loop in BleuIO

BleuIO, a leading Bluetooth Low Energy (BLE) USB dongle, continues to evolve with its latest firmware updates —version 2.7.8 for BleuIO and version 1.0.3 for BleuIO Pro. This new release builds upon the Auto Execution feature introduced in our previous firmware release by adding a powerful Auto Execution Loop, allowing users to automate repetitive tasks seamlessly. With this enhancement, developers can set up loops in the AUTOEXEC list, enabling continuous execution of commands without manual intervention.

What is Auto Execution Loop?

The Auto Execution feature allows users to store and run AT commands automatically upon startup, making BLE development faster and more efficient. With the new Auto Execution Loop, you can now create loops within the AUTOEXEC list, All auto-execute commands between the loop start and loop end will continue running indefinitely until manually stopped by clearing the auto-execute list using AT+CLRAUTOEXEC.

This feature is particularly useful for scenarios where continuous execution of BLE tasks is required, such as:

  • Beacon advertising with dynamic data updates
  • Changing BLE characteristics periodically
  • Automated device-to-device communication
  • Repeating sensor data transmission

How to Use the Auto Execution Loop

Setting up a loop in the AUTOEXEC list is simple and requires only a few steps:

  1. (Optional) Add any commands that should run once before the loop starts using AT+AUTOEXEC=*command*.
  2. Define the start of the loop using AT+AUTOEXECLOOP=START.
  3. Add the commands that should execute repeatedly with AT+AUTOEXEC=*command*.
  4. Mark the end of the loop using AT+AUTOEXECLOOP=END.
  5. Restart the BleuIO dongle to see the commands execute automatically on startup. Alternatively, plug it into any power source, like a power bank or USB adapter, and let it run autonomously.

To clear the AUTOEXEC list and stop an ongoing loop, simply use AT+CLRAUTOEXEC. This ensures that any active command sequence is halted.

Real-World Use Cases

1. Dynamic BLE Beacon

Start-up: Disables scan response message and starts advertising.

In loop: Sets the advertising name in advertising data to ‘BleuIO’, waits 10 seconds, sets advertising name to ‘CAT’, waits 10 seconds.

Test: Scan the dongle to see the name change every 10 seconds.

Commands:

AT+AUTOEXEC=AT+ADVRESP=00
AT+AUTOEXEC=AT+ADVSTART
AT+AUTOEXECLOOP=START
AT+AUTOEXEC=AT+ADVDATA=04:09:42:6C:65:75:49:4F  // Name: BleuIO
AT+AUTOEXEC=AT+WAIT=10
AT+AUTOEXEC=AT+ADVDATA=04:09:43:41:54  // Name: CAT
AT+AUTOEXEC=AT+WAIT=10
AT+AUTOEXECLOOP=END

2. BLE Peripheral with Notify Characteristic

Start-up: Creates a custom service with a characteristic with the notify property. Starts advertising.

In loop: Changes the characteristic value to ‘First Value’, waits 10 seconds, changes the value to ‘Second Value’, waits 10 seconds.

Test: Connect to the dongle and subscribe to the notification characteristic to see it toggle between the two values every 10 seconds.

Commands:

AT+AUTOEXEC=AT+CUSTOMSERVICE=0=UUID=72013640-2f23-49bb-8edd-6636969a2545
AT+AUTOEXEC=AT+CUSTOMSERVICE=1=UUID=72013641-2f23-49bb-8edd-6636969a2545
AT+AUTOEXEC=AT+CUSTOMSERVICE=1=PROP=RWN
AT+AUTOEXEC=AT+CUSTOMSERVICE=1=PERM=RW
AT+AUTOEXEC=AT+CUSTOMSERVICE=1=LEN=20
AT+AUTOEXEC=AT+CUSTOMSERVICE=1=VALUE=Value
AT+AUTOEXEC=AT+CUSTOMSERVICESTART
AT+AUTOEXEC=AT+ADVSTART
AT+AUTOEXECLOOP=START
AT+AUTOEXEC=AT+CUSTOMSERVICE=1=VALUE=First Value
AT+AUTOEXEC=AT+WAIT=10
AT+AUTOEXEC=AT+CUSTOMSERVICE=1=VALUE=Second Value
AT+AUTOEXEC=AT+WAIT=10
AT+AUTOEXECLOOP=END

3. Device-to-Device Communication

Start-up: Enables verbose mode.

In loop: Connects to another dongle, waits 10 seconds to ensure connection, sends an SPS message ‘HELLO’, waits 10 seconds before disconnecting, then waits 60 seconds.

Test: Set up a second dongle to advertise and run AT+GETMAC on it to obtain the MAC address. Use that address in the first dongle’s AUTOEXEC list when adding the AT+GAPCONNECT command. Monitor the terminal on the second dongle to see the first dongle connecting and sending ‘HELLO’ every minute.

Commands:

AT+AUTOEXEC=ATV1
AT+AUTOEXECLOOP=START
AT+AUTOEXEC=AT+GAPCONNECT=[0]*MAC_ADDRESS*
AT+AUTOEXEC=AT+WAIT=10
AT+AUTOEXEC=AT+SPSSEND=HELLO
AT+AUTOEXEC=AT+WAIT=10
AT+AUTOEXEC=AT+GAPDISCONNECT
AT+AUTOEXEC=AT+WAIT=60
AT+AUTOEXECLOOP=END

Why Auto Execution Loop Matters

The introduction of Auto Execution Loop in BleuIO v2.7.8 brings a new level of automation and efficiency to BLE development. With this feature, you can:

  • Reduce manual intervention by automating repetitive tasks
  • Increase reliability by ensuring commands execute consistently
  • Enable standalone BLE applications without needing a host device
  • Enhance development workflow by quickly testing different BLE behaviors

For developers building BLE applications, this feature opens up exciting possibilities, from autonomous sensor monitoring to seamless device interactions.

BleuIO’s Auto Execution Loop is a game-changer for BLE automation, making it easier than ever to set up continuous execution of commands. Whether you’re developing a smart beacon, a data-logging device, or a BLE-based automation system, this feature allows you to achieve more with less effort.

How to Upgrade:

To take advantage of these enhancements, make sure to update your BleuIO dongle to firmware version 2.7.8. You can find the firmware update and detailed instructions on the official BleuIO website. Click here to know more about firmware updates.

Share this post on :

Monitoring Air Quality with BleuIO and Renesas RRH62000 on EK-RA4M2

In this tutorial, we demonstrate how to use the Renesas EK-RA4M2 MCU, the Renesas RRH62000 All-in-One Air Quality Sensor Module, and the BleuIO Bluetooth Low Energy (BLE) USB Dongle to collect and transmit air quality data wirelessly. The RRH62000 sensor module measures key environmental parameters such as:

  • eCO₂ (Equivalent Carbon Dioxide)
  • Humidity (%)
  • Temperature (°C)
  • Particulate Matter (PM1, PM2.5, PM10) (µm/cm³)
  • Total Volatile Organic Compounds (TVOC) (mg/m³)
  • Indoor Air Quality Index (IAQ)

The EK-RA4M2 MCU reads data from the sensor via I²C, processes the information, and transmits it over BLE using the BleuIO USB dongle. The advertised data can be monitored using BLE scanning applications, and the sensor values can also be displayed in RTTViewer on a connected PC.

Requirements

Before getting started, ensure you have the following hardware and software:

Hardware

Software

You can download the complete example project here:
➡️ GitHub Repository

Hardware Setup

Connecting EK-RA4M2 and BleuIO Dongle

  1. Connect EK-RA4M2 to your PC using a micro-USB cable via the J10 (Debug1) port.
  2. Plug the BleuIO dongle into a USB OTG cable and connect it to J11 (USB Full Speed) on the EK-RA4M2 board.
  3. Set jumpers:
    • Place J12 on pins 1-2.
    • Remove J15 completely.

Reference Diagram:

Connecting RRH62000 Air Quality Sensor

Connect the RRH62000 sensor module to EK-RA4M2 as follows:

  • Power: Connect 5V and GND from RRH62000 to 5V and GND on EK-RA4M2.
  • I²C Communication:
    • SCL (Clock) → SCL on EK-RA4M2
    • SDA (Data) → SDA on EK-RA4M2
    • GND → GND on EK-RA4M2

Reference Diagrams:


Importing the Project into e² Studio

  1. Open e² Studio IDE and choose a workspace. Click Launch.
  2. Download or clone the project from GitHub and place the “bleuio_ra4m2_rrh62000_example” folder inside your workspace.
  3. Go to File → Import and select Existing Projects into Workspace under the General tab.
  4. Click Browse… and locate the project folder.
  5. Select the project and click Finish to import it.

Importing Example Project:

Building and Running the Example

  1. Build the project by clicking the build icon.
  2. Set up debugging:
    • Click the down arrow next to the Debug icon and select Debug Configurations…
    • Under Renesas GDB Hardware Debugging, choose bleuio_ra4m2_sensor_rrh62000_example Debug_Flat and click Debug.


  3. Run the program:
    • Open RTTViewer and connect using the following settings:
      • Connection to J-Link: USB
      • Target Device: R7FA4M2AD
      • Interface & Speed: SWD, 4000 kHz
      • RTT Control Block Address: 0x200009dc
  4. In e² Studio, click Resume twice to start execution.
  5. The program starts running:
    • All LEDs turn on for 1 second, then only the red LED remains on.
    • The red LED turns off when BleuIO is initialized.
    • The green LED turns on when advertising starts.
  6. Sensor data is displayed in RTTViewer.

Scanning and Decoding BLE Advertising Data

Scan the Dongle using nRF Connect

Use a BLE scanning app like nRF Connect to view the advertised data:

Decoding the Advertising Message

Example raw BLE advertisement:

02010619FF3600016491803010300030105060306080192

All air quality sensor values except eCO2 is split into two bytes. The first byte is the whole number and the second byte is the decimal. For example
1649 is the temperature value. The whole number is 16 and the decimal is 49. Converting it from hex gives
us: 23.73 °C

The eCO2 value is 2 bytes, big endian.

Breaking it down:

DataDescriptionDecoded Value
020106Advertising flag (connectable)
19Message size
FFManufacturer Specific Data
3600Renesas Manufacturer ID (Little Endian)
Air Quality Advertised Data
1649Temperature (°C)23.73°C
1803Humidity (%RH)24.3% RH
0103IAQ Index1.3
0003TVOC (mg/m³)0.3 mg/m³
0105PM1 (µm/cm³)1.5
0603PM2.5 (µm/cm³)6.3
0608PM10 (µm/cm³)6.8
0192eCO₂ (ppm)402 ppm

This project successfully demonstrates how to use the BleuIO Bluetooth dongle, EK-RA4M2 MCU, and Renesas RRH62000 sensor to wirelessly monitor air quality. The BLE advertisements can be scanned and decoded to extract real-time air quality data.

For the full source code and updates, visit:
➡️ GitHub Repository

Share this post on :

Chat with HibouAir using BleuIO: Smart Air Quality Analysis with Google Technologies 

Indoor air quality is crucial for maintaining a healthy living and working environment. HibouAir is a powerful air quality monitoring device that provides real-time data on CO2 levels, temperature, humidity, and air pressure.  

This project demonstrates how BleuIO enables communication with HibouAir, allowing real-time environmental data to be retrieved, while Google’s Gemma model processes and analyzes the data to provide meaningful, easy-to-understand responses through a chat interface.

Users can interact with HibouAir’s smart assistant and ask questions such as:

  • “What is my room temperature?”
  • “What is the humidity level?”
  • “How is the air quality in my room?”

The system retrieves real-time sensor data from HibouAir and provides contextual recommendations based on environmental conditions.

By leveraging Google’s lightweight Gemma model, this project ensures efficient and intelligent analysis of air quality data, making it accessible for various applications, from smart homes to research.

Features of This Project

  • Live CO2, Temperature, Humidity, and Pressure Monitoring
  • Google-Powered Analysis for Meaningful Insights
  • Conversational Chat Interface (“Chat with HibouAir”)
  • Completely Local – No Internet Required
  • Lightweight & Efficient Processing with Gemma

Step-by-Step Guide: How It Works

Install Required Software

We need:

  • BleuIO for Bluetooth communication.
  • Ollama to run Google’s Gemma model locally.
  • HibouAir for air quality monitoring
  • Gemma for efficient data analysis and meaningful responses.

Install Python Dependencies

pip install flask bleuio

Install Ollama (For Local Processing)
For Mac/Linux:

curl -fsSL https://ollama.com/install.sh | sh

For Windows, download it from Ollama’s official site.

Install Google’s Gemma Model

ollama pull gemma

Why Gemma? What Are the Alternatives?

For this project, we chose Gemma, a lightweight, open-source model developed by Google, because it aligns with Google’s ecosystem and provides efficient, real-time insights for environmental data.

Why Use Google’s Gemma?

  • Optimized for Efficiency – Runs well on low-power machines without requiring cloud resources.
  • Google-Backed & Open Source – Developed by Google DeepMind, ensuring high-quality performance with full transparency.
  • No API Costs & Fully Local – No need for an internet connection or paid APIs, making it a cost-effective solution.
  • Designed for Meaningful Responses – Processes real-time air quality data and provides insightful, structured feedback.

Other Model Alternatives

  • Phi-2 – Even lighter but lacks detailed contextual understanding.
  • Llama3 – More powerful but requires more computational resources.
  • Mistral – Previously used, efficient, but not part of the Google ecosystem.

Connecting HibouAir via Bluetooth (BleuIO)

HibouAir continuously broadcasts CO2, temperature, humidity, and pressure via Bluetooth. We use BleuIO to scan and retrieve these values in real-time.

Setting Up the Chat Interface

Users can type questions like:

  • “What is the temperature?”
  • “What is my CO2 level?”
  • “How is the air quality?”

The system fetches real-time sensor data from HibouAir and provides Google-powered analysis and recommendations.

app.py (Backend)

  • This script:
  • Scans for HibouAir data
  • Extracts CO2, temperature, humidity, and pressure
  • Uses Google’s Gemma model for intelligent responses
  • Serves the chat interface via Flask
def chat():
    """Handles user input, fetches air quality data if needed, and returns response."""
    user_input = request.json.get("message", "").lower()

    with Manager() as manager:
        air_data = manager.dict({"co2": 0, "pressure": 0, "temperature": 0, "humidity": 0})
        process = Process(target=scan_for_air_quality_process, args=(air_data,))
        process.start()
        process.join()

        # Check for specific sensor queries
        if "temperature" in user_input:
            if air_data["temperature"] > 0:
                response = f"The current temperature in your room is {air_data['temperature']}°C."
            else:
                response = "⚠️ Unable to retrieve temperature data. Ensure HibouAir is in range."
            return jsonify({"response": response})

        elif "humidity" in user_input:
            if air_data["humidity"] > 0:
                response = f"The current humidity level in your room is {air_data['humidity']}%."
            else:
                response = "⚠️ Unable to retrieve humidity data. Ensure HibouAir is in range."
            return jsonify({"response": response})

        elif "pressure" in user_input:
            if air_data["pressure"] > 0:
                response = f"The current air pressure in your room is {air_data['pressure']} hPa."
            else:
                response = "⚠️ Unable to retrieve air pressure data. Ensure HibouAir is in range."
            return jsonify({"response": response})
        elif "co2" in user_input:
            if air_data["co2"] > 0:
                response = f"The current CO2 in your room is {air_data['co2']} ppm."
            else:
                response = "⚠️ Unable to retrieve co2 data. Ensure HibouAir is in range."
            return jsonify({"response": response})

        elif "air quality" in user_input :
            if air_data["co2"] > 0:
                prompt = (
                    f"The current air quality readings are:\n"
                    f"- CO2 Level: {air_data['co2']} ppm\n"
                    f"- Temperature: {air_data['temperature']}°C\n"
                    f"- Humidity: {air_data['humidity']}%\n"
                    f"- Pressure: {air_data['pressure']} hPa\n"
                    f"First give all the data. This is my room data. Give me short analysis on this data. and give me short suggestions "
                )
            else:
                return jsonify({"response": "⚠️ Unable to retrieve air quality data. Ensure HibouAir is in range and try again."})
        else:
            # Normal response for non-air quality queries
            prompt = user_input

    ai_response = subprocess.run(
        ["ollama", "run", "gemma", prompt],
        capture_output=True,
        text=True
    ).stdout.strip()

    return jsonify({"response": ai_response})

Get full source code from Github

index.html (Frontend – Chat Interface)

<div class="card">
        <div class="card-header">Chat with HibouAir</div>
        <div class="card-body">
          <div
            id="chatbox"
            class="border rounded p-3"
            style="height: 400px; overflow-y: auto; background: #f8f9fa"
          >
            <div class="alert alert-secondary">
              <b>HibouAir:</b> Ask me about air quality!
            </div>
          </div>
        </div>
      </div>

Expected Responses

You: “What is my CO2 level?”
HibouAir: “The current CO2 level is 850 ppm.”

You: “What is the air quality in my room?”
HibouAir:

CO2 Level: 850 ppm  
Temperature: 24°C  
Humidity: 55%  
Pressure: 1010 hPa  
Based on these readings, the air quality is good.

Using the Chat Interface

The web interface allows users to ask about specific values like temperature, humidity, pressure, CO2, or overall air quality.

Output

Get the Source Code

This project is open-source! You can access the full code and modify it for your own needs.

👉 [GitHub Repository]

This project showcases how HibouAir and BleuIO can be integrated to provide real-time air quality analysis in a way that is easy to understand. Instead of requiring users to interpret raw sensor data, the chat interface translates complex air quality values into clear, meaningful insights. Powered by Google’s Gemma model, it delivers simple and actionable responses—helping users understand their indoor air quality without needing to be experts.  

Share this post on :

Using BleuIO with Angular & TypeScript via Web Serial API

In modern web development, Bluetooth Low Energy (BLE) integration is becoming increasingly important for IoT applications. With the Web Serial API, we can now directly communicate with hardware devices like BleuIO using just a browser, eliminating the need for native drivers or middleware.

In this tutorial, we will demonstrate how to use Angular 19 and TypeScript to communicate with a BleuIO USB Dongle via Web Serial API. We will build a simple web application that connects to BleuIO, sends AT commands, and displays responses in real time.

This approach is beneficial because:

  • No additional backend services are required—everything runs directly in the browser.
  • Simplicity—Web Serial API allows communication with serial devices in JavaScript/TypeScript without native code.
  • Cross-platform compatibility—Works on any OS with Google Chrome or Microsoft Edge.

Why Use Angular & TypeScript?

Angular is a powerful framework for building scalable, maintainable, and modern web applications. TypeScript, which is the foundation of Angular, brings type safety and better tooling, making development smoother and reducing runtime errors.

By using Angular 19, we ensure that our application is built on the latest and most optimized framework version, taking advantage of standalone components and improved performance features.

Setting Up the Angular Project

To get started, ensure you have Node.js and Angular CLI installed.

Create an Angular Project

Run the following command to generate a new Angular 19 project:

new angular-bleuio --strict
cd angular-bleuio

Choose No for routing and CSS as the styling option.

add Bootstrap to styles.css:

@import url('https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css');

This ensures our application has a clean, professional UI.

Building the BleuIO Web Serial Connection

We will now implement the core functionality:

  1. Connect to BleuIO via Web Serial API.
  2. Send AT commands and receive responses.
  3. Display formatted responses using delimiters.

Creating the Angular Component

In src/app/app.component.ts, replace the contents with:

import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';

@Component({
  selector: 'app-root',
  standalone: true, //
  imports: [FormsModule],
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent {
  port: any | undefined;
  writer: WritableStreamDefaultWriter | undefined;
  reader: ReadableStreamDefaultReader | undefined;
  command: string = '';
  response: string = 'Not connected.';

  async connectToBleuIO() {
    try {
      if (!('serial' in navigator)) {
        this.response = 'Web Serial API not supported in this browser.';
        return;
      }

      this.port = await (navigator as any).serial.requestPort();
      await this.port.open({ baudRate: 115200 });

      this.response = 'Connected to BleuIO.';
      this.writer = this.port.writable?.getWriter();
      this.reader = this.port.readable?.getReader();

      this.readData();
    } catch (error) {
      console.error('Connection failed:', error);
      this.response = 'Failed to connect.';
    }
  }

  async sendCommand() {
    if (!this.port || !this.writer || !this.command) {
      this.response = 'Not connected or empty command.';
      return;
    }

    try {
      // Reset the response before sending a new command
      this.response = 'Waiting for response...';

      // Clear any old responses before sending new data
      if (this.reader) {
        await this.reader.cancel();
        this.reader.releaseLock();
        this.reader = this.port.readable?.getReader(); // Reinitialize reader
      }

      // Send the AT command
      const encoder = new TextEncoder();
      await this.writer.write(encoder.encode(this.command + '\r\n'));

      this.response = 'Command sent: ' + this.command;
      this.readData(); // Start reading the new response
    } catch (error) {
      console.error('Send error:', error);
      this.response = 'Error sending command.';
    }
  }

  async readData() {
    if (!this.reader) return;

    const decoder = new TextDecoder();
    let fullResponse = '';

    try {
      while (true) {
        const { value, done } = await this.reader.read();
        if (done) break;

        let textChunk = decoder.decode(value);
        fullResponse += textChunk; // Append new data to the response

        this.response = fullResponse
          .replace(/(\w)\.(\s[A-Z])/g, '$1.\n$2') // Add newline after full stops (but not inside numbers)
          .replace(
            /(BleuIO|Firmware Version|Peripheral role|Central role|Not Connected|Not Advertising)/g,
            '\n$1'
          ); // New line before keywords
      }
    } catch (error) {
      console.error('Read error:', error);
    }
  }
}

Creating the UI

Modify src/app/app.component.html:

<div class="container text-center mt-5">
  <h1 class="mb-4 text-primary">
    Angular & TypeScript: Connect to BleuIO via Serial port
  </h1>

  <!-- Connect Button -->
  <button class="btn btn-primary mb-3" (click)="connectToBleuIO()">
    Connect to BleuIO
  </button>

  <div class="input-group mb-3 w-50 mx-auto">
    <input
      type="text"
      [(ngModel)]="command"
      class="form-control"
      placeholder="Enter AT Command"
    />
    <button class="btn btn-success" (click)="sendCommand()">
      Send Command
    </button>
  </div>

  <h3 class="mt-4">Response:</h3>

  <div
    class="border p-3 w-75 mx-auto bg-light rounded shadow-sm"
    style="white-space: pre-line"
  >
    {{ response }}
  </div>
</div>

Update src/main.ts

Replace its contents with:

import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app/app.component';
import { importProvidersFrom } from '@angular/core';
import { FormsModule } from '@angular/forms';

bootstrapApplication(AppComponent, {
  providers: [importProvidersFrom(FormsModule)],
}).catch((err) => console.error(err));

Running the Project

Start the Angular app:

ng serve

Open Google Chrome and go to http://localhost:4200/.
Test by clicking “Connect to BleuIO”, entering an AT command, and clicking “Send Command”.

Complete Source Code

Find the full source code on GitHub:
🔗 GitHub Repository

Output

Use Cases: Why This is Helpful

  • This tutorial is beneficial for developers who:
  • Want a simple, browser-based way to communicate with BleuIO.
  • Need a cross-platform solution that works on Windows, macOS, and Linux.
  • Are building IoT applications that require BLE communication.
  • Want to use Angular & TypeScript for a scalable frontend solution.

This tutorial demonstrates how to use Angular 19, TypeScript, and the Web Serial API to communicate with BleuIO. The project is lightweight, scalable, and works entirely in the browser—perfect for IoT applications!

Share this post on :