BleuIO Node.js Library available on NPM

BleuIO, a leading provider of Bluetooth Low Energy (BLE) solutions, has recently released a new Node.js library for developers. This library is available on NPM, making it easy for developers to access and use it for their projects. With this library, developers can create BLE applications quickly and easily.

The BleuIO Node.js library provides a simple and straightforward way for developers to communicate with BLE devices. It supports a range of BLE protocols. This library is designed to work seamlessly with Node.js, making it easy to integrate into existing projects.

One of the primary advantages of using the BleuIO Node.js library is its ease of use. Developers do not need to have extensive knowledge of Bluetooth technology to use this library. The library provides a high-level API that simplifies the communication process, allowing developers to focus on their application’s functionality rather than the underlying BLE protocols.

Another advantage of the BleuIO Node.js library is its flexibility. The library can be used to create a range of BLE applications, from simple IoT devices to complex mobile applications. This flexibility is made possible by the library’s support for a range of BLE devices and protocols.

The BleuIO Node.js library is also highly customizable. Developers can configure the library to meet their specific requirements, such as setting up a custom scan interval or configuring the advertising payload. This flexibility allows developers to create applications that are tailored to their specific needs.

To use the BleuIO Node.js library, developers must have a BleuIO device or module. BleuIO devices are small, low-cost modules that can be integrated into a range of applications, from simple IoT devices to complex mobile applications. These devices provide a reliable and secure way to communicate with BLE devices.

Installation and how to use this library can be found on BleuIO’s getting started guide.

https://www.bleuio.com/getting_started/docs/nodejsLibScan/

Share this post on :

Create a real-time desktop CO2 widget using Javascript and Bluetooth

Creating a small real-time desktop CO2 widget using JavaScript and Bluetooth is a fun and engaging project that can help you understand how to work with Bluetooth communication and sensor data processing.

In this project we will use BleuIO to communicate with air quality monitoring sensor to read CO2 data. BleuIO is a bluetooth low energy usb dongle that helps to create BLE application easily. The AT command available on this device makes the development faster and easier.

There are many air quality sensor available but one popular choice is the HibouAir.

We will use electron js and node serial to connect with BleuIO. After that we will use AT commands to scan for nearby Bluetooth device that is advertising with a given board ID which is the air quality monitoring sensor.

Requirments :

  1. BleuIO
  2. HibouAir – air quality monitoring sensor

Note: both BleuIO and HibouAir are available at digikey.

Here are the steps you can follow to create your own widget:

Hardware setup :

Connect BleuIO to the computer and wait for the device to recognize it. This usually takes 10 seconds. Connect the air quality monitoring sensor HibouAir to a power cable. Make sure the device is within 50 meters.

Write the code :

Clone this repository from Github using

git clone https://github.com/smart-sensor-devices-ab/bluetooth-co2-desktop-widget.git

After that go inside the directory and write

npm install 

on terminal. This will install necessary libraries.

Inside this folder we will find three .js files and one html file. The index.html file is the frontend where we will see the real-time CO2 values.

The main.js file initialize the application and creates an window of 200px X 200px

render.js is the file which has all the logic go connect to BleuIO via serial port , gets real-time air quality data, decode it and finally print it on the screen.

Code explanation :

On render.js file, at first we make a list of devices connected to serial port. Then we filter out only the BleuIO devices by filtering with vendorID which is 2dcf. After that we pick the first item of the list.

Once we know the path of the BleuIO device , we connect to it.

ports = ports.filter((x) => x.vendorId == "2dcf");
      if (ports && ports.length > 0) {
        port = new SerialPort({
          path: ports[0].path,
          baudRate: 57600,
        });
}

Now that we are connected to the BleuIO dongle, we can write AT commands to it and get the response.

At first we write AT+DUAL to the dongle to put the dongle in dual role. So that we can scan for nearby devices and advertised data.

to put the dongle in dual role we write

port.write(Buffer.from("AT+DUAL\r"), function (err) {
          if (err) {
            document.getElementById("error").textContent =
              "Error writing at dual";
          } else {
            console.log('dongle in dual role')
}

In this project I am trying to get air quality data from a HibouAir device which has a board ID of 45840D. Therefore I look for advertised data that has this specific boardID. If i write AT+FINDSCANDATA=4584OD, BleuIO will filter out only advertise data from this board ID.

After writing this , we get a response from the dongle. To read the response from serial port we use

 port.on("readable", () => {
          let data = port.read();
console.log(data)
})

We can push the response in an array and later decide what to do with it.

When we do a AT+FINDSCANDATA=45840D

the response from the dongle looks something like this

Then we take the last response by using

resp = readDataArray[readDataArray.length - 2];

After that , get the advertised data from the string by

resp.split(" ").pop();

Now we have the advertised data in a variable. We can easily get the CO2 value from this string by selecting the position. The documentation from HibouAirs says , the CO2 value is right at the end of the string. In that case the value is 023A which is 570 is decimal.

We can print this value in our screen.

We can create a function that do the scanning every 20 seconds to get latest values.

Here is the complete code to render.js file

// This file is required by the index.html file and will
// be executed in the renderer process for that window.
// All of the Node.js APIs are available in this process.
const { SerialPort } = require("serialport");
var port;
var readDataArray = [];
async function listSerialPorts() {
  await SerialPort.list().then((ports, err) => {
    if (err) {
      document.getElementById("error").textContent = err.message;
      return;
    } else {
      document.getElementById("error").textContent = "";
    }
    console.log("ports", ports);

    if (ports.length === 0) {
      document.getElementById("error").textContent = "No ports discovered";
    } else {
      ports = ports.filter((x) => x.vendorId == "2dcf");
      if (ports && ports.length > 0) {
        port = new SerialPort({
          path: ports[0].path,
          baudRate: 57600,
        });
        port.write(Buffer.from("AT+DUAL\r"), function (err) {
          if (err) {
            document.getElementById("error").textContent =
              "Error writing at dual";
          } else {
            const myWriteFunc = () => {
              port.write(Buffer.from("AT+FINDSCANDATA=5B0705=3\r")),
                function (err) {
                  if (err) {
                    document.getElementById("error").textContent =
                      "Error writing findscandata";
                  } else {
                    console.log("here");
                  }
                };
            };
            myWriteFunc();
            setInterval(() => {
              myWriteFunc();
            }, 20000);
          }
        });
        // Read serial port data
        port.on("readable", () => {
          let data = port.read();
          let enc = new TextDecoder();
          let arr = new Uint8Array(data);
          let removeRn = enc.decode(arr).replace(/\r?\n|\r/gm, "");
          if (removeRn != null) readDataArray.push(removeRn);
          if (removeRn == "SCAN COMPLETE") {
            console.log(readDataArray);
            let resp = readDataArray[readDataArray.length - 2];

            let advData = resp.split(" ").pop();
            let pos = advData.indexOf("5B0705");
            console.log("advData", advData);
            console.log("c", advData.substr(pos + 46, 4));
            let co2 = parseInt("0x" + advData.substr(pos + 46, 4));
            console.log(co2);
            document.getElementById("co2Val").innerHTML = co2;
          }
        });
      } else {
        document.getElementById("error").innerHTML =
          "No device found. Please connect a BleuIO ongle to your computer and try again.";
      }
    }
  });
}

function listPorts() {
  listSerialPorts();
  setTimeout(listPorts, 20000);
}

// Set a timeout that will check for new serialPorts every 2 seconds.
// This timeout reschedules itself.
//setTimeout(listPorts, 2000);

listSerialPorts();

To build this app we need a library called electron-builder. To install this library we write on terminal
npm i electron-builder

Once the library is build , we need to update our package json file and add build option or mac.

"build": {
    "appId": "com.co2.widget",
    "productName": "co2-widget",
    "mac": {
      "category": "airquality.app.widget"
    }
  }

We can update our script on package json like this

"scripts": {
    "start": "electron .",
    "pack": "electron-builder --dir",
    "dist": "electron-builder"
  },

Once we are done, build the app with

npm run build

We will see a dmg file in our dist folder. Once we run the app, the widget will look like this.

The value will update every 20 seconds.

Creating a small desktop CO2 widget using JavaScript and BlueIO is a great way to learn about these technologies and create a useful tool for monitoring indoor air quality.

Share this post on :

BleuIO Python library v1.2.0 includes verbose mode with easier event handling features

BleuIO Python library is updated and supports firmware version 2.2.1 .This update utilizes the new Verbose mode of the dongle and make it a lot simpler to work with Bluetooth Low Energy with Python.
Now the AT commands returns an object with 4 members

  • Command
  • Acknowledge
  • Response
  • End

Each contains a JSON object, except Response. The Response contains a list of JSON objects since a command can have several responses.

This new update of the library makes it easier to get the relevant information without building your own parser.
Status variables : Helpful status variables has been added which helps to keep track of the dongle status ; whether it is scanning, advertising or connected along with the dongle role.
Callback function : A callback function should be registered for both scan results and events. The callback functions will run every time a new event or scan result is detected.

Using the library

List of AT commands are available at https://www.bleuio.com/getting_started/docs/commands/

and how to access these AT commands using python library can be found at
https://pypi.org/project/bleuio/

Before starting to install our library, make sure you have the latest python installed on your system.

If you have never installed a library from PyPI, you must install the pip tool enabling you to download and install a PyPI package. There are several methods that are described on this page.

Now Install the library by running

pip install bleuio

pip automatically downloads and installs the most recent library on your system in the correct directory. To check that the installation went well, you can launch a Python interpreter and run the following lines:

from bleuio_lib.bleuio_funcs import BleuIO
my_dongle = BleuIO()
print(my_dongle.ati().Rsp)

Good luck on creating amazing Bluetooth Low Energy application using BleuIO and Python.

Share this post on :

BleuIO’s new firmware version 2.2.1 increased MTU size to 512 bytes

What is the maximum transmission unit (MTU)?

In networking, maximum transmission unit (MTU) is a measurement representing the largest data packet that a network-connected device will accept.

BleuIO’s new firmware version 2.2.1 increased MTU size from 247 bytes to 512 bytes, which allows more data to fit into fewer packets. This generally results in a faster and more efficient transmission of data.

A new AT command AT+GETMAC is also added to the latest firmware. This will return the MAC address of the BleuIO dongle.

Added features:

  • Increased MTU to 512 bytes.
  • Added an MTU event that shows the negotiated MTU when connected or when changed: (MTU CHANGED: xxx) (using verbose mode: {779:”0000″,”evt”:{“action”:”mtu changed”,”mtu”:xxx}})
  • Added new AT command: AT+GETMAC for getting bleuio mac address.

Bugfixes

  • Fixed format errors of some messages when using verbose mode that doesn’t comform to JSON.

To find out more about the updates of the dongles new firmware 2.2.1, please visit our Getting Started Guide.

Share this post on :

Bluetooth Low Energy based RGB LED Strip color control from a web browser and STM32

1. Introduction

This project is about Bluetooth Low Energy based RGB LED Strip Color Control from a web browser and STM 32. The LEDs light strip can also be controlled wirelessly via a BLE scanning App using IOS or Android. With the received data, we decide which color of the RGB strip to activate.

You will need two dongles, one connected to the Nucleo board and one connected to a computer to control from web browser. The web script is also available on GitHub.

When the BleuIO Dongle is connected to the Nucleo boards USB port the STM32 will recognize it and directly start advertising. This allows the other Dongle to connect to it.

It will also accept 3 different inputs from the UART:

inputresult
0Send ATI (Request device information) command to BlueIO Dongle.
1Manually turn the LED on
2Manually turn the LED off

We have used a STM32 Nucleo-144 development board with STM32H743ZI MCU (STM32H743ZI micro mbed-Enabled Development Nucleo-144 series ARM® Cortex®-M7 MCU 32-Bit Embedded Evaluation Board) and the WS2812, a intelligent control LED light source, for this example.

Connect the LED to the Nucleo Board by connecting:

4-7 VDC to 5V

GND to any GND

DIN to PE9

On the Nucleo NUCLEO-H743ZI2:

Note : If you want to use another setup you will have to make sure it support USB Host and beware that the GPIO setup might be different and may need to be reconfigured in the .ioc file.

2. Project requirments

  • Two BleuIO dongles (https://www.bleuio.com/)
  • A board with a STM32 Microcontroller with a USB port. (A Nucleo-144 development board: NUCLEO-H743ZI2, is used for this project. (https://www.st.com/en/evaluation-tools/nucleo-h743zi.html)
  • To connect the dongle to the Nucleo board a “USB A to Micro USB B”-cable with a USB A female-to-female adapter can be used.)
  • STM32CubeIDE (https://www.st.com/en/development-tools/stm32cubeide.html)
  • An WS2812 RGB LED

3. About the Code

The source code is available at
https://github.com/smart-sensor-devices-ab/stm32_bleuio_rgb_led_example

This project is based on another STM32 project (https://github.com/smart-sensor-devices-ab/stm32_bleuio_example) with the interface to the WS2812 Interface WS2812 with STM32 by Controllers Tech

The DIN pin will be connected to TIM1 which need to be enabled in to the .ioc file:

Parameter Settings:

DMA for TIM1 will also be enabled:

In main.c we will need to add a callback for TIM PWM Pulse Finished:

void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{
    HAL_TIM_PWM_Stop_DMA(&htim1, TIM_CHANNEL_1);
    datasentflag=1;
}



In main.c there is also a functions for controlling the LED.

Set_LED() for changing the color of the individual LEDs.

Set_Brightness() for setting the brightness. A brightness value of 0 means the LED is turned off.

WS2812_Send() execute the changes we made to the LED.

void Set_LED (int LEDnum, int Red, int Green, int Blue)
{
    LED_Data[LEDnum][0] = LEDnum;
    LED_Data[LEDnum][1] = Green;
    LED_Data[LEDnum][2] = Red;
    LED_Data[LEDnum][3] = Blue;
}

#define PI 3.14159265

void Set_Brightness (int brightness)  // 0-45
{
#if USE_BRIGHTNESS

    if (brightness > 45) brightness = 45;
    for (int i=0; i<MAX_LED; i++)
    {
        LED_Mod[i][0] = LED_Data[i][0];
        for (int j=1; j<4; j++)
        {
            float angle = 90-brightness;  // in degrees
            angle = angle*PI / 180;  // in rad
            LED_Mod[i][j] = (LED_Data[i][j])/(tan(angle));
        }
    }

#endif

}

void WS2812_Send (void)
{
    uint32_t indx=0;
    uint32_t color;


    for (int i= 0; i<MAX_LED; i++)
    {
#if USE_BRIGHTNESS
        color = ((LED_Mod[i][1]<<16) | (LED_Mod[i][2]<<8) | (LED_Mod[i][3]));
#else
        color = ((LED_Data[i][1]<<16) | (LED_Data[i][2]<<8) | (LED_Data[i][3]));
#endif

        for (int i=23; i>=0; i--)
        {
            if (color&(1<<i))
            {
                pwmData[indx] = 60;  // 2/3 of 90
            }

            else pwmData[indx] = 30;  // 1/3 of 90

            indx++;
        }

    }

    for (int i=0; i<50; i++)
    {
        pwmData[indx] = 0;
        indx++;
    }

    HAL_TIM_PWM_Start_DMA(&htim1, TIM_CHANNEL_1, (uint32_t *)pwmData, indx);
    while (!datasentflag){};
    datasentflag = 0;
}



We also update the handleUartInput function so we can have manual control over the LED via the UART.

/**
  * @brief Simple uart input handler
  * @retval None
  */
void handleUartInput(UARTCommandTypeDef cmd)
{
    switch(cmd)
    {
        case UART_RX_0:
        {
            // 0
            uart_buf_len = sprintf(uart_tx_buf, "\r\n(0 pressed)\r\n");
            HAL_UART_Transmit(&huart3, (uint8_t *)uart_tx_buf, uart_buf_len, HAL_MAX_DELAY);
            if(isBleuIOReady)
            {
                writeToDongle((uint8_t*)DONGLE_CMD_ATI);
            } else
            {
                uart_buf_len = sprintf(uart_tx_buf, BLEUIO_NOT_READY_MSG);
                HAL_UART_Transmit(&huart3, (uint8_t *)uart_tx_buf, uart_buf_len, HAL_MAX_DELAY);
            }
            uartStatus = UART_RX_NONE;
            break;
        }
        case UART_RX_1:
        {
            // 1
            uart_buf_len = sprintf(uart_tx_buf, "\r\n(1 pressed LED on!)\r\n");
            HAL_UART_Transmit(&huart3, (uint8_t *)uart_tx_buf, uart_buf_len, HAL_MAX_DELAY);
              Set_Brightness(40);
              WS2812_Send();
            uartStatus = UART_RX_NONE;
            break;
        }
        case UART_RX_2:
        {
            // 2
            uart_buf_len = sprintf(uart_tx_buf, "\r\n(2 pressed LED off!)\r\n");
            HAL_UART_Transmit(&huart3, (uint8_t *)uart_tx_buf, uart_buf_len, HAL_MAX_DELAY);
              Set_Brightness(0);
              WS2812_Send();

            uartStatus = UART_RX_NONE;
            break;
        }
        case UART_RX_NONE:
        {
            break;
        }
        default:
        {
            uartStatus = UART_RX_NONE;
            break;
        }
    }
}

4. How to setup project

4.1 Downloading the project from GitHub

Get project HERE

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


Either clone the project, or download it as a zip file and unzip it, into your STM32CubeIDE workspace.

4.2 Importing as an Existing Project

  • From STM32CubeIDE choose File>Import…

  • Then choose General>Existing Projects into Workspace then click ‘Next >’

  • Make sure you’ve choosen your workspace in ‘Select root directory:’
  • You should see the project “stm32_bleuio_rgb_led_example”, check it and click ‘Finish’.

5. Running the example

  • In STMCubeIDE click the hammer icon to build the project.
  • Open up the ‘STMicroelectronics STLink Viritual COM Port’ with a serial terminal emulation program like TeraTerm, Putty or CoolTerm.

Serial port Setup:

Baudrate: 115200

Data Bits: 8

Parity: None

Stop Bits: 1

Flow Control: None

  • Connect the BleuIO Dongle before running the example
  • In STMCubeIDE click the green play button to flash and run it on your board. The first time you click it the ‘Run Configuration’ window will appear. You can just leave it as is and click run.
  • You should be greeted by this welcome message:
Welcome to STM32 BleuIO RGB LED Example!
Press 0 to run the ATI command
Press 1 to manually turn on LED
Press 2 to manually turn off LED

The LED will turn on briefly when starting up.

  • Wait until the message: “[BleuIO Dongle Ready]” is shown.

  • The LEDs should now turn off and you can now connect with the other dongle using the script.

You can also use the uart commands (0, 1 or 2):

  • Press 0 to get device information.
  • 1 to turn on LED.
  • 2 to turn off LED.

Dongle response will be printed to UART.

Control the colors from a web browser

Connect the BleuIO dongle to the computer. Run the web script to connect to the other BleuIO dongle on the STM32. The web script is available inside the source file. Now we can control the colors wirelessly.

For this script to work, we need

Create a simple Html file called index.html which will serve as the frontend of the script. This Html file contains some buttons that help connect and read advertised data from the remote dongle, which is connected to stm32.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link
      href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css"
      rel="stylesheet"
      integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3"
      crossorigin="anonymous"
    />
    <title>
      Bluetooth controlled RGB LED Strip - Control color from web browser
    </title>
  </head>
  <body class="mt-5">
    <div class="container mt-5">
      <img
        src="https://www.bleuio.com/blog/wp-content/themes/bleuio/images/logo.png"
      />
      <h1 class="mb-5">
        Bluetooth controlled RGB LED Strip - Control color from web browser
      </h1>

      <div class="row">
        <div class="col-md-4 pt-5">
          <button class="btn btn-success mb-2" id="connect">Connect</button>
          <form method="post" id="sendMsgForm" name="sendMsgForm">
            <div class="mb-3">
              <label for="msgToSend" class="form-label"
                >Select color option</label
              >
              <select
                class="form-select"
                aria-label="Default select example"
                name="msgToSend"
                id="msgToSend"
                required
              >
                <option selected>Open this select menu</option>
                <option value="L=0">LED Off</option>
                <option value="L=1">LED On</option>
                <option value="L=RED">Set LED lights red</option>
                <option value="L=GREEN">Set LED lights green</option>
                <option value="L=BLUE">Set LED lights blue</option>
                <option value="L=RAINBOW">
                  Set LEDs lights to different colors
                </option>
              </select>
            </div>

            <button type="submit" class="btn btn-primary">Submit</button>
          </form>
        </div>
        <div class="col-md-8">
          <img
            src="https://www.bleuio.com/blog/wp-content/uploads/2022/09/bluetooth-controlled-rgb-led-strip-collor-control.jpg"
          />
        </div>
      </div>
    </div>

    <script src="script.js"></script>
  </body>
</html>

Create a js file called script.js and include it at the bottom of the Html file. This js file uses the BleuIO js library to write AT commands and communicate with the other dongle.

import * as my_dongle from 'bleuio'
const dongleToConnect='[0]40:48:FD:E5:2F:17'
document.getElementById('connect').addEventListener('click', function(){
  my_dongle.at_connect()
  document.getElementById("connect").disabled=true;
  document.getElementById("sendMsgForm").hidden=false;
})

document.getElementById("sendMsgForm").addEventListener("submit", function(event){
    event.preventDefault()

    
    my_dongle.ati().then((data)=>{
        //make central if not
        if(JSON.stringify(data).includes("Peripheral")){
            console.log('peripheral')
            my_dongle.at_central().then((x)=>{
                console.log('central now')
            })
        }        
    })
    .then(()=>{
        // connect to dongle
        my_dongle.at_getconn().then((y)=>{
            if(JSON.stringify(y).includes(dongleToConnect)){
                console.log('already connected')
            }else{
                my_dongle.at_gapconnect(dongleToConnect).then(()=>{
                    console.log('connected successfully')
                })
            }
        })
        .then(()=>{
            var theVal = document.getElementById('msgToSend').value;
            console.log('Message Send  '+theVal)
            // send command to show data
            my_dongle.at_spssend(theVal).then(()=>{
                console.log('Message Send '+theVal)
            })
        })
        
    })
  });

The script has a button to connect to COM port on the computer. After connecting to the dongle , we should be able to control the colors of the LED strip.

To connect to the BleuIO dongle on the STM32, make sure the STM32 is powered up and a BleuIO dongle is connected to it.

Get the MAC address

Follow the steps to get the MAC address of the dongle that is connected to STM32

- Open this site https://bleuio.com/web_terminal.html and click connect to dongle.
- Select the appropriate port to connect.
- Once it says connected, type ATI. This will show dongle information and current status.
- If the dongle is on peripheral role, set it to central by typing AT+CENTRAL
- Now do a gap scan by typing AT+GAPSCAN
- Once you see your dongle on the list ,stop the scan by pressing control+c
- Copy the ID and paste it into the script (script.js) line #2

Run the web script

You will need a web bundler. You can use parcel.js

Once parcel js installed, go to the root directory of web script and type “parcel index.html”. This will start your development environment.

Open the script on a browser. For this example we opened http://localhost:1234

You can easily connect to the dongle and update the LED strip.

The web script looks like this

Share this post on :

Bluetooth based PIR motion detecting application using STM32 board

1. Introduction

In this project we will use a PIR sensor to detect motion. Once motion is detected, it will trigger an interrupt and the BleuIO dongle connected to the board will advertise for 25 seconds. You can expand the project based on your needs further.

A PIR (passive infrared) Sensor is an electronic device that  detects heats from human or animal body, giving a detection signal when movement happens in a given area or range of the sensor.

For this project, we will need one dongle and a PIR sensor (for example: https://www.digikey.com/short/4v12z2nw).
When the BleuIO Dongle is connected to the Nucleo boards USB port the STM32 will recognize it and set up a new device name for the dongle: BleuIO PIR Detected. This will show up when the dongle is advertising.

2. Using the example project

2.1 What we will need

2. How to setup project

2.1 Downloading the project from GitHub

Get project HERE

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


Either clone the project, or download it as a zip file and unzip it, into your STM32CubeIDE workspace.

2.2 Importing as an Existing Project

  • From STM32CubeIDE choose File>Import…
  • Then choose General>Existing Projects into Workspace then click ‘Next >’
  • Make sure you’ve choosen your workspace in ‘Select root directory:’
  • You should see the project “stm32_bleuio_pir_example”, check it and click ‘Finish’.

If you download the project as a zip file you will need to rename the project folder from ‘stm32_bleuio_pir_example-master’ to ‘stm32_bleuio_pir_example’

5. Connecting the sensor

Connect the PIR Sensor Gnd to ground and Vdd to power and Output to a pin of your choice on the Nucleo board (In the example we use PA0)

If you want a different PIN you will need to go into the STM32Cube ioc file and make some edits:

  • Click on PA0 and select Reset_State in the STM32Cube ioc file.
  • Click on your desired Pin and select EXTIO
  • Then go to GPIO under System Core and make sure you setup the pin as follows:

    GPIO mode: External Interrupt Mode with Rising edge trigger detection

    GPIO Pull-up/Pull-down: Pull-down
  • Then go to NVIC under System Core and make sure EXTI line0 interrupt is enabled

6. Running the example

  • In STMCubeIDE click the hammer icon to build the project.
  • Open up the ‘STMicroelectronics STLink Viritual COM Port’ with a serial terminal emulation program like TeraTerm, Putty or CoolTerm.

Baudrate: 115200

Data Bits: 8

Parity: None

Stop Bits: 1

Flow Control: None

  • In STMCubeIDE click the green play button to flash and run it on your board. The first time you click it the ‘Run Configuration’ window will appear. You can just leave it as is and click run.
  • Connect the BleuIO Dongle.

7. Output

When the PIR sensor detects movement it will trigger an interrupt that in turn will tell the BleuIO Dongle to advertise for 25 seconds. Just so the PIR Sensor will not trigger constantly we have put a 20 second timeout before it will trigger again. If no new interrupts have been detected after the 25 second advertising timer has run out the BleuIO Dongle will stop advertising and wait for a new interrupt to happen.

The yellow LED on the STM32 board also toggles if there is a movement.

Hope you found this article informative.

Share this post on :

Benefits and use cases of Bluetooth Low Energy technology

We live in a day where wireless data transfer is a rather common phenomenon. From offering location services or audio streaming to maintaining device networks and data transfers, all is made possible due to wireless communication technologies and Bluetooth is one of them. Bluetooth is a short-range wireless technology which helps exchange data between connected devices over short radiuses. 

Bluetooth Low Energy is essential for IoT networks due to its ability to preserve battery power on devices. Major use cases of Bluetooth Low Energy technology include:

Use Cases

  • Mobile payments at retail outlets.
  • Wireless charging for multiple devices.
  • Keep track of traveller luggage at the airport by using smart tags.
  • Monitor air quality of the indoor environment by using BLE-powered sensors.
  • Remote monitoring of patient’s health conditions
  • Autonomous vehicles with intelligent seats and steering wheels, intelligent proximity reporting etc
  • Smart Home automation systems with sensors for tracking fire breakouts, water leakages, or motion in case of robbery.

Advantages of Bluetooth Low Energy technology

  • Sends an ID number via BLE advertising channels
  • The 2.4 GHz frequency controls interference in signals.
  • Determines the location of users within its range
  • Longer battery life by keeping the radio off when not required
  • Uninterrupted broadcast using Bluetooth beacon 
  • The devices are able to establish connections and faster data transfer.
  • Small size (maximum up to 255 bytes) data transfer which is helpful for IoT-based applications
  • The 128-bit AES algorithm ensures the safety of data transfer.
  • Low power consumption compared to other wireless technologies.
  • Comparatively lower cost of deployment and maintenance of chipsets and modules.

The BleuIO is Bluetooth low energy USB dongle that can be used to create Bluetooth low energy application. Just use the AT Commands available on the device for faster development.
The BleuIO is a fully integrated solution, providing MCU and Bluetooth® radio in one chip, based on Dialog Semiconductor latest Bluetooth chip DA14683. The FLASH based device permits field or boot upgradable, while application is stored on FLASH memory.
Projects and tutorials with source code can be found at https://www.bleuio.com/blog/?bleprojects

Share this post on :

Integration of Bluetooth technology within Embedded Systems

Bluetooth Low Energy (BLE) is one of the most widely applicable low-power connectivity standards. Its purpose is to connect devices over a fairly short range. BLE was developed with IoT applications in mind, which has special implications for its design.

Integration of Bluetooth technology within Embedded Systems facilitates an expansive range of Application Domains to support devices at various design levels. Engaging Bluetooth into an embedded system creates value in device capability for specific needs, via the implementation of Bluetooth Profiles that can help the data transfer between compatible devices. Recent introductions to Bluetooth LE Audio in the SMART phone market deliver revolutions in Bluetooth audio capability, enabling users to share audio from a single device to multiple wireless headsets.

Bluetooth Low Energy is used almost everywhere, which is one of its core strengths compared to other low-power networks. This is one of the reasons why everyone looking into BLE when designing their solutions. Because of the well-established name of Bluetooth Classic, BLE had an easier time gaining trust among developers. All these factors combined made it the obvious choice for many consumer IoT applications and much more.

On the other hand, Bluetooth Low Energy is constantly being developed and perfected to meet the most current demands of the market, therefore, it is one of the top choices for embedded system developers to integrate BLE in their solutions.

The BleuIO is Bluetooth low energy USB dongle that can be used in embedded system solutuions. Just use the AT Commands available on the device for faster development.
The BleuIO is a fully integrated solution, providing MCU and Bluetooth® radio in one chip, based on Dialog Semiconductor latest Bluetooth chip DA14683. The FLASH based device permits field or boot upgradable, while application is stored on FLASH memory.
Projects and tutorials with source code can be found at https://www.bleuio.com/blog/?bleprojects

Share this post on :

Indoor Positioning Systems based on Close Beacons

A beacon is a Bluetooth Low Energy (BLE) transmitter, a “Thing” that is often talked about on the Internet of Things. The information can be received by devices with a Bluetooth connection (smartphones, computers, tablets or industrial gateways among others).

One of the biggest advantages of this wireless communication protocol, BLE, is its low energy consumption, which gives these beacons a long battery life.

Who uses beacons?

Beacons have so far and primarily been used in retail to attract customers to a loyal behaviour, by collecting points or by sending them a promotional offer, the customer experience can be improved. This type of connected object has been used for many years in a varied number of industries and the industry is really starting to adopt the technology. 

Indoor positioning

There are many use cases for Bluetooth Beacons. This article discusses the indoor positioning system. 

There are many reasons an individual or organisation would be interested in indoor positioning. From improving the ease of navigation, finding what you’re looking for, delivering/receiving targeted location-based information, improving accessibility, accruing valuable data insights and much more.

Bluetooth Low Energy (BLE) signals from battery-driven beacons are at the soul of indoor location technology. It’s one of the most recognised technologies that has appeared for indoor positioning and has become industry-standard available recently. It uses BLE beacons (or iBeacons) that are affordable, small, has a long battery life, and do not need an external energy source. The device (smartphone/ watch etc.) detects the signal from the beacon and can approximately calculate the distance to the beacon, therefore calculating a user’s indoor location.

A script on BLE beacons based indoor positioning system

Many manufacturers make compatible BLE Beacons because BLE is an open industry standard. Manufacturers do vary in terms of quality, battery life, signal stability, and how they package the beacons. For this Indoor positioning example project, we are going to use Close Beacon to determine users location.

Instructions

  • At first, we place Close Beacon in different rooms and note their mac address. 
  • When we do a GAP SCAN, we will notice the close beacons on the list along with other devices. 
  • We filter out the close beacons and sort them by RSSI. 
  • We pick the first device from the list and match it with the MAC address
  • Finally, we print out the name of the location of Close Beacon.

Requirements

Steps

  • First, we connect the BleuIO USB dongle to our computer.
  • Get the BleuIO JavaScript library from NPM.
  • Create a simple Html file that contains buttons to connect to the dongle using a serial port and show the response on the screen.
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Indoor positioning</title>
    <link
      href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/css/bootstrap.min.css"
      rel="stylesheet"
      integrity="sha384-0evHe/X+R7YkIZDRvuzKMRqM+OrBnVFBL6DOitfPri4tjfHxaWutUpFmBp4vmVor"
      crossorigin="anonymous"
    />
  </head>
  <body>
    <div class="container mt-5">
      <h2>Indoor Positioning</h2>

      <br />
      <div class="row">
        <div class="col-md-6">
          <button id="connect" class="btn btn-success">Connect</button>
          <button id="checkLocation" class="btn btn-warning ms-5" disabled>
            Get Location
          </button>
          <br />
          <br />
          <div id="loading" style="display: none">
            <img src="./loading.a13f9403.gif" alt="" width="20" /> Finding your
            location
          </div>
          <div id="theLocation"></div>
        </div>
        <div class="col-md-6">
          <img src="indoor positioning example bluetooth beacon.jpg" alt="" />
        </div>
      </div>

      <script src="./script.js"></script>
    </div>
  </body>
</html>
  • Create a js file that communicates with the dongle and processes the response to determine the user’s current location.
import * as my_dongle from 'bleuio'
document.getElementById('connect').addEventListener('click', function(){
  my_dongle.at_connect()
  document.getElementById('checkLocation').removeAttribute("disabled");

})
//List of Close Beacons and their name based on mac address
let beaconArray={
  "Conference Room":"[D0:76:50:80:00:3A]",
  "Entrance":"[D0:76:50:80:00:97]",
  "SSD lab":"[D0:76:50:80:0B:9D]",
  "IAD lab":"[D0:76:50:80:0F:49]",
  "Office":"[D0:76:50:80:02:30]",
}
document.getElementById('checkLocation').addEventListener('click', function(){ 
  document.getElementById("loading").style.display = "block";
  document.getElementById('connect').setAttribute("disabled","");
// put the dongle on central role ,so that we can scan
  my_dongle.at_central().then(()=>{
    //enable rssi for the scan response
    my_dongle.at_showrssi(1).then(()=>{
      //filter advertised data , so it only shows close beacon on the response
      my_dongle.at_findscandata('9636C6F7',6).then((data)=>{
        //convert array string to array of object with key value
        const formated = data.map((item) => {
          if(item.length>30){
            const splitted= item.split(' ');
            let mac=splitted[2]
            let rssi=splitted[1]
            return { mac,rssi};
          }
        });
         //sort based on rssi value       
        formated.sort((a, b) => parseInt(b.rssi) > parseInt(a.rssi) && 1 || -1)
        // get the name of the close beacon by mac address
        let locationName=Object.keys(beaconArray).find(key => beaconArray[key] === formated[0]['mac']);
        document.getElementById("loading").style.display = "none";
        // print out the location
        document.getElementById("theLocation").innerHTML = "You are at <strong>"+locationName+"</strong";       
      })
    }) 
  })
})

Source code 

Source code is available on Github

https://github.com/smart-sensor-devices-ab/indoor_positioning.git

Output

Share this post on :

Python GUI Bluetooth Programming With Tkinter

Python has a lot of GUI frameworks, but Tkinter is the only framework that’s built into the Python standard library. Tkinter has several strengths. It’s cross-platform, so the same code works on Windows, macOS, and Linux. Visual elements are rendered using native operating system elements, so applications built with Tkinter look like they belong on the platform where they’re run.

Tkinter is lightweight and relatively painless to use compared to other frameworks. This makes it a compelling choice for building GUI applications in Python, especially for applications where a modern sheen is unnecessary, and the top priority is to quickly build something functional and cross-platform.

In this article, we will try to create a simple Python GUI application that can scan for nearby Bluetooth devices using Pyserial and shows the list on the screen.

Requirments 

Instructions

  • Connect the BleuIO to your computer. The script uses pyserial to connect to the Bluetooth USB dongle BleuIO.
  • Update the script and write the correct COM port (line 25), where the dongle is connected. 
  • After connecting to the dongle, we put the dongle into the central role using AT+CENTRAL so that it can scan for nearby Bluetooth devices. 
  • Then we do a simple Gap scan using AT+GAPSCAN=3 command to scan for nearby Bluetooth devices for 3 seconds.
  • After that, we read the output from the serial port and filter the device to get the unique number of devices.
  • Then we add a timestamp when the scan was completed. 
  • Finally, we sort the result by RSSI value before printing it out on screen.
  • ‘Scan again’ button will do the whole process again.

Here is the final script file. 

# Gjort av William 
# 2022-06-16 
# Smart Sensors Devices AB
# 
# libraries that is necessary for tkinter to work
import tkinter as tk
from tkinter import  ttk

# this is imported for the dongle and also for the "time.sleep()" commands
import serial
import time

# this is the library that is uesd to check the current time 
import datetime
now = datetime.datetime.now()

# this is what creates the main window
main_window = tk.Tk()

#changes the titel of the window
main_window.title('Scan for nearby Bluetooth devices')


# sets your port for the dongle
your_com_port = "COM18"  
connecting_to_dongle = True

#changes the size of the screens window
window_width = 900
window_height = 500

# get the screen dimension
screen_width = main_window.winfo_screenwidth()
screen_height = main_window.winfo_screenheight()
# find the center point
center_x = int(screen_width/2 - window_width / 2)
center_y = int(screen_height/2 - window_height / 2)
# set the position of the window to the center of the screen
main_window.geometry(f'{window_width}x{window_height}+{center_x}+{center_y}')

# apply the grid layout
main_window.grid_columnconfigure(1, weight=1)
main_window.grid_rowconfigure(1, weight=1)


# create the text widget
text = tk.Text(main_window, height=30, width=30)
text.grid(row=1, column=1, sticky=tk.EW)


# this is the part of the code that communicates whit the dongle
print("Connecting to dongle...")
while connecting_to_dongle:
    try:
        console = serial.Serial(
            port=your_com_port,
            baudrate=57600,
            parity="N",
            stopbits=1,
            bytesize=8,
            timeout=0,
        )
        if console.is_open.__bool__():
            connecting_to_dongle = False
    except:
        print("Dongle not connected. Please reconnect Dongle.")
        time.sleep(5)
print("Connected to Dongle.")

console.write(str.encode("AT+CENTRAL"))
console.write("\r".encode())
print("Putting dongle in Central role.")
time.sleep(0.1)

console.write(str.encode("AT+GAPSCAN=3"))
console.write("\r".encode())
time.sleep(0.1)
print("Looking for nearby Bluetooth devices ...")
dongle_output2 = console.read(console.in_waiting)
time.sleep(3)
print("Scan Complete!")
filtered = []

for dev in dongle_output2.decode().splitlines():
    if len(dev)>20:
        filtered.append(dev.split(maxsplit=1)[1])

seen = set()
out = []
for elem in filtered:
    prefix = elem.split(' ')[1]
    if prefix not in seen:
        seen.add(prefix)
        out.append(elem)

# sort list 
out.sort(key=lambda x:int(x.split()[3]), reverse=True)

# writes out the amount of bluetooth devices found on the main screen
text.insert('0.5', 'Amount of devices found: ' + str(len(out)) + '\n\n')

# funktion to get the current time
def get_time():
    return now.strftime('%H:%M:%S')

# prints out the time of the scan on the main screen
text.insert('1.0','The time of the scan: ' + str(get_time()) + '\n\n')

# writes out the results on the main screen
for i in range(0,len(out)):
    position = f'{i+5}.{len(out[i])}'
    tempStr = out[i] + "\n"
    text.insert(position,f' {tempStr}')

# is supposed to delet everyting on the list
out.clear()

#the funktion for the scan button
def button_clicked():
    # enables the programe to change the results on the main screen to the new ones after the user presses the scan button
    text['state'] = 'normal'
    # update the current time.
    now = datetime.datetime.now()
    # funktion to get the current time
    def get_time():
        return now.strftime('%H:%M:%S')
    # this simply puts a emty row betwen the results and the rest of the output on kommandotolken
    print()
    # this delets the previous output that is on the main screen
    text.delete('0.0', tk.END)

    # this is the part of the code that communicates whit the dongle 
    console.write(str.encode("AT+GAPSCAN=3"))
    console.write("\r".encode())
    time.sleep(0.1)
    
    dongle_output2 = console.read(console.in_waiting)
    time.sleep(3)
    filtered = []

    for dev in dongle_output2.decode().splitlines():
        if len(dev)>20:
            filtered.append(dev.split(maxsplit=1)[1])

    seen = set()
    out = []
    for elem in filtered:
        prefix = elem.split(' ')[1]
        if prefix not in seen:
            seen.add(prefix)
            out.append(elem)

    # sort list 
    out.sort(key=lambda x:int(x.split()[3]), reverse=True)

    
    #writes out the time of the scan on the main screen
    text.insert('1.0','The time of the scan: ' + str(get_time()) + '\n\n')

     # writes out the amount of bluetooth devices found on the main screen
    text.insert('0.0', 'Amount of devices found: ' + str(len(out)) + '\n\n')

    # writes out the results on the main screen
    for i in range(0,len(out)):
        position = f'{i+5}.{len(out[i])}'
        tempStr = out[i] + "\n" 
        text.insert(position,f' {tempStr}')

    # makes it so that you cant edite the results on the main screen
    text['state'] = 'disabled'

#what calls the function for the scan button. also fixes what the user will see as the buttons name.
main_button = ttk.Button(
    main_window,
    text='Scan again',
    command=lambda: button_clicked()
)
# creat the scan button 
main_button.grid(row=0, column=1, sticky=tk.EW)

# just an exit button.
exit_button = ttk.Button(
    main_window,
    text='Exit',
    command=lambda: main_window.quit()
)
# this determens were the exit button is located 
exit_button.grid(row=2, column=1, sticky=tk.EW)

# makes it so that you cant edite the results on the main screen
text['state'] = 'disabled'

# keeps the main window open
main_window.mainloop()

time.sleep(1)
console.close()

Source code is available at https://github.com/smart-sensor-devices-ab/python_gui_tkinter_bluetooth.git

Run the script

To run the script we use start

pythonw Scan_ble.pyw

Note : Scan_ble.pyw is the file name

Output

After running the script, we see a total 25 devices found nearby. We can scan again using the ‘Scan again’ button

Share this post on :