BleuIO Firmware Update V2.1.4

BleuIO released a new firmware version 2.1.4 on March 24, 2022, introducing new features and enhancements to improve productivity. You can download the updated firmware from

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

Following features and AT commands has been added to this release 

Added features:

  • BleuIO can now toggle on/off the written data echo after a gattcwrite command.
  • It is now possible to set a timer for AT+FINDSCANDATA & AT+SCANTARGET scans just like with AT+GAPSCAN. Just end the command with “=<scan_time>”. Like AT+FINDSCANDATA=123456=5.

Added Commands

  • Added a new command ATEW to Turn WRITTEN DATA echo on/off after GATTCWRITE commands. (On per default).

To meet the demands of users, the BleuIO team will continue to update and add new features. To find out more about the updates of the dongles new firmware 2.0.7, please visit our Getting Started Guide

Share this post on :

BLE USB dongle throughput measurement

Introduction

Here we will describe two quick ways of measuring the data throughput of the BleuIO Dongle.
For both examples we are going to need a BleuIO Dongle, another Bluetooth device (like another Bleuio Dongle) and a computer with Python (minimum version: 3.6) installed.

For the first measurement example, measuring the BLE data throughput, you will need one of the following supported development kits from Nordic Semiconductor:

  • nRF52840 DK (PCA10056)
  • nRF52840 Dongle (PCA10059)
  • nRF52833 DK (PCA10100)
  • nRF52 DK (PCA10040)
  • nRF51 DK (PCA10028)
  • nRF51 Dongle (PCA10031)

The first measurement example is the actual BLE data throughput. For this we will use a BleuIO Dongle and Wireshark. (For help on how to setup Wireshark and requirements go to this link: https://infocenter.nordicsemi.com/topic/ug_sniffer_ble/UG/sniffer_ble/intro.html ).
We will also utilize a simple python script that sends a set amount of data. For this measurement you can ignore the throughput print at the end of the script.

The second measurement example is for measuring the actual data being transferred over the USB as a Virtual COM port (via the CDC protocol).
We will be using the same simple script that will send a set amount of data and time when the transfer starts and then stops. Then divide the amount of data with the time the transfer took to get the throughput.

Notice : Interference can be caused by other wireless networks, other 2.4 GHz frequency devices, and high voltage devices that generate electromagnetic interference. This have impact on the measurement of throughput. To avoid interference, select wireless free space or use a shield box.

Instructions for BLE data throughput

  • For best result place the nRF Dev Kit between the BleuIO Dongle and your target device.
  • Open Wireshark and double-click the ‘nRF Sniffer for Bluetooth LE’.
  • Make sure the target Bluetooth device is advertising and find in the the scroll-down list.
  • Choose ‘IO/Data’ under the ‘Analysis’ menu tab.
  • Click the ‘+’ button to add new graphs. Add ‘bytes per seconds’ and/or ‘bit per seconds’.
  • Modify the script by filling in the relevant information into the variables ‘your_com_port’‘target_mac_addr’ and ‘write_handle’.
  • Run the python script.
  • You can now observe the graph showing the BLE Data throughput!

Instructions for USB port data throughput

This is the second measurement example for measuring the actual point to point data transfer between the two USB ports.

  • Connect the dongle to your computer. (Look up the COM port your dongle uses and paste it in the script in the variable ‘your_com_port’)
  • Scan (Using AT+GAPSCAN) after the device you wish to send the data to. Copy the mac address of the device into the script in the variable ‘target_mac_addr’.
  • Connect to the device and look up the handle of the characteristic you want to write to and paste into the script in the variable ‘write_handle’.
  • Finally just run python script and the throughput will be displayed at the end!

The script

import datetime
import serial
import time
import string
import random

connecting_to_dongle = True
trying_to_connect = False

# Change this to the com port your dongle is connected to.
your_com_port = "COM20"
# Change this to the mac address of your target device.
target_mac_addr = "[0]40:48:FD:E5:2C:F2"
# Change this to the handle of the characteristic on your target device.
write_handle = "0011"

# You can experiment with the packet length, increasing or decreasing it and see how that effect the throughput
packet_length = 150
# 1 Megabytes = 1000000 Bytes
file_size = 0.5 * 1000000
end_when = file_size / packet_length
send_counter = 0

# Random data string generator
def random_data_generator(size=packet_length, chars=string.digits + string.digits):
    return "".join(random.choice(chars) for _ in range(size))


print("Connecting to dongle...")
while connecting_to_dongle:
    try:
        console = serial.Serial(
            port=your_com_port,
            baudrate=115200,
            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+GAPDISCONNECT\r"))
start = input("Press Enter to start.\n\r>> ")

console.write(str.encode("ATE0\r"))
console.write(str.encode("AT+DUAL\r"))
connected = "0"
while connected == "0":
    time.sleep(0.5)
    if not trying_to_connect:
        # change to Mac address of the device you want to connect to
        console.write(str.encode("AT+GAPCONNECT=" + target_mac_addr + "\r"))
        trying_to_connect = True
    dongle_output2 = console.read(console.in_waiting)
    time.sleep(2)
    print("Trying to connect to Peripheral...")
    if not dongle_output2.isspace():
        if dongle_output2.decode().__contains__("\r\nCONNECTED."):
            connected = "1"
            print("Connected!")
            time.sleep(8)
        if dongle_output2.decode().__contains__("\r\nDISCONNECTED."):
            connected = "0"
            print("Disconnected!")
            trying_to_connect = False
        dongle_output2 = " "

start2 = input("Press Enter to sending.\n\r>> ")
start_time = time.mktime(datetime.datetime.today().timetuple())
console.write(
    str.encode(
        "AT+GATTCWRITEWRB=" + write_handle + " " + random_data_generator() + "\r"
    )
)
while 1:
    dongle_output = console.read(console.in_waiting)
    if send_counter > end_when:
        end_time = time.mktime(datetime.datetime.today().timetuple())
        break
    # Change to the handle of the characteristic you want to write to
    if "handle_evt_gattc_write_completed" in str(dongle_output):
        console.write(
            str.encode(
                "AT+GATTCWRITEWR=" + write_handle + " " + random_data_generator() + "\r"
            )
        )
        send_counter = send_counter + 1
    try:
        if not dongle_output.decode() == "":
            print(dongle_output.decode())
    except:
        print(dongle_output)

time_elapsed = end_time - start_time
time.sleep(0.1)

print("*" * 25)
print("Transfer Complete in: " + str(time_elapsed) + " seconds")
print(str(packet_length * send_counter) + "bytes sent.")
print("*" * 25)
print(
    "Throughput via USB (Virtual COM port): "
    + str((packet_length * send_counter) / time_elapsed)
    + " Bytes per seconds"
)
print("*" * 25)
Share this post on :

Show Bluetooth LE Sensor readings on LCD screen connected to STM32

The aim of this Bluetooth LE project is to read air quality sensor data and show it on an LCD display which is connected to STM32 board. A web browser will read the sensor data and pass it to STM32 board using BleuIO.

1. Introduction

The project is based on STM32 Nucleo-144 which controls LCD display using BleuIO.

For this project, we will need two BleuIO USB dongles, one connected to the Nucleo board and the other to a computer running the web script and a HibouAir – Air quality monitoring device .
When the BleuIO Dongle is connected to the Nucleo boards USB port the STM32 will recognize it and directly start advertising. This allows the Dongle on the computer port connect with the web script.

With the web script on the computer, we can scan and get air quality sensor data from HibouAir. Then we send these data to LCD screen connected to STM32 using Bluetooth.

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) for this example. This development board has a USB host where we connect the BleuIO dongle.

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.

About the Code

The project source code is available at Github.

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

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

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

Connect the SDA to PF0 on the Nucleo board and SCL to PF1.

Then setup I2C2 in the STM32Cube ioc file as follows. (Make sure to change the I2C speed frequency to 50 KHz as per LCD display requirements.)

In the USBH_CDC_ReceiveCallback function in USB_HOST\usb_host.c we copy the CDC_RX_Buffer into a external variable called dongle_response that is accessable from the main.c file.

void USBH_CDC_ReceiveCallback(USBH_HandleTypeDef *phost)
{
  	if(phost == &hUsbHostFS)
  	{
  		// Handles the data recived from the USB CDC host, here just printing it out to UART
  		rx_size = USBH_CDC_GetLastReceivedDataSize(phost);
		HAL_UART_Transmit(&huart3, CDC_RX_Buffer, rx_size, HAL_MAX_DELAY);

		// Copy buffer to external dongle_response buffer
		strcpy((char *)dongle_response, (char *)CDC_RX_Buffer);

		// Reset buffer and restart the callback function to receive more data
		memset(CDC_RX_Buffer,0,RX_BUFF_SIZE);
		USBH_CDC_Receive(phost, CDC_RX_Buffer, RX_BUFF_SIZE);
  	}

  	return;
}

In main.c we create a simple intepreter so we can react to the data we are recieving from the dongle.

void dongle_interpreter(uint8_t * input)
{

	if(strlen((char *)input) != 0)
	{
		if(strstr((char *)input, "\r\nADVERTISING...") != NULL)
		{
			isAdvertising = true;
		}
		if(strstr((char *)input, "\r\nADVERTISING STOPPED") != NULL)
		{
			isAdvertising = false;
		}
		if(strstr((char *)input, "\r\nCONNECTED") != NULL)
		{
			isConnected = true;
			HAL_GPIO_WritePin(GPIOE, GPIO_PIN_1, GPIO_PIN_SET);
		}
		if(strstr((char *)input, "\r\nDISCONNECTED") != NULL)
		{
			isConnected = false;
			HAL_GPIO_WritePin(GPIOE, GPIO_PIN_1, GPIO_PIN_RESET);
		}


		if(strstr((char *)input, "L=0") != NULL)
		{

			isLightBulbOn = false;
			//HAL_GPIO_WritePin(Lightbulb_GPIO_Port, Lightbulb_Pin, GPIO_PIN_RESET);
			lcd_clear();

			writeToDongle((uint8_t*)DONGLE_SEND_LIGHT_OFF);

			uart_buf_len = sprintf(uart_tx_buf, "\r\nClear screen\r\n");
			HAL_UART_Transmit(&huart3, (uint8_t *)uart_tx_buf, uart_buf_len, HAL_MAX_DELAY);
		}

		if(strstr((char *)input, "L=1") != NULL)
		{
				isLightBulbOn = true;
				writeToDongle((uint8_t*)DONGLE_SEND_LIGHT_ON);


				lcd_clear();

				lcd_write(input);

		}

	}
	memset(&dongle_response, 0, RSP_SIZE);
}

We put the intepreter function inside the main loop.

/* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
    MX_USB_HOST_Process();

    /* USER CODE BEGIN 3 */
    // Simple handler for uart input
    handleUartInput(uartStatus);

    // Inteprets the dongle data
    dongle_interpreter(dongle_response);

	// Starts advertising as soon as the Dongle is ready.
	if(!isAdvertising && !isConnected && isBleuIOReady)
	{
		HAL_Delay(200);
		writeToDongle((uint8_t*)DONGLE_CMD_AT_ADVSTART);
		isAdvertising = true;
	}
  }
  /* USER CODE END 3 */

Using the example project

What we will need

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_SHT85_example”, check it and click ‘Finish’.

Running the example

Upload the the code to STM32 and run the example. The USB dongle connect to STM32 will start advertising automatically.

Send Sensor data to LCD screen 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. Now you can send sensor data to the LCD screen.

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, read advertised data from the HibouAir to get air quality sensor data, and send this data to the LCD screen 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 LE Air quality sensor data to LCD screen</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 LE Air quality sensor data to LCD screen</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="sendDataForm" name="sendMsgForm" hidden>
            <div class="mb-3">
              <label for="sensorID" class="form-label">Sensor ID</label>
              <input
                type="text"
                class="form-control"
                name="sensorID"
                id="sensorID"
                required
                maxlength="60"
                value="0578E0"
              />
            </div>

            <button type="submit" class="btn btn-primary">Get Data</button>
          </form>
          <br />
          <button class="btn btn-danger" id="clearScreen" disabled>
            Clear screen
          </button>
        </div>
        <div class="col-md-8">
          <img src="air_quality_lcd.jpg" class="img-fluid" />
        </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'
import 'regenerator-runtime/runtime'

const dongleToConnect='[0]40:48:FD:E5:2F:17'
//const sensorID = '0578E0'
document.getElementById('connect').addEventListener('click', function(){
  my_dongle.at_connect()
  document.getElementById("clearScreen").disabled=false;
  document.getElementById("connect").disabled=true;
  document.getElementById("sendDataForm").hidden=false;
})

document.getElementById("sendDataForm").addEventListener("submit", function(event){
    event.preventDefault()
    const sensorID = document.getElementById('sensorID').value
    getSensorData(sensorID)
    setInterval(function () {getSensorData(sensorID)}, 10000);

   
  });

  const getSensorData =((sensorID)=>{
    my_dongle.ati().then((data)=>{
        //make central if not
        if(JSON.stringify(data).includes("Peripheral")){
            console.log('peripheral')
            my_dongle.at_dual().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(async()=>{
           return my_dongle.at_findscandata(sensorID,6).then((sd)=>{
                console.log('scandata',sd)
                let advData = sd[sd.length - 1].split(" ").pop()
                let positionOfID= advData.indexOf(sensorID);
                let tempHex = advData.substring(positionOfID+14, positionOfID+18)
                let temp = parseInt('0x'+tempHex.match(/../g).reverse().join(''))/10;

                let co2Hex = advData.substring(positionOfID+38, positionOfID+42)
                let co2 = parseInt('0x'+co2Hex);
                //console.log(temp,co2)
                return {
                    'CO2' :co2,
                    'Temp' :temp,                       
                  }
            })
        })
        .then((x)=>{
            console.log(x.CO2)
            console.log(x.Temp)
            var theVal = "L=1 SENSOR ID "+sensorID+"    TEMPERATURE " + x.Temp + ' °c    CO2 '+ x.CO2+' ppm';
            console.log('Message Send 1 ')
            // send command to show data
            my_dongle.at_spssend(theVal).then(()=>{
                console.log('Message Send '+theVal)
            })
        })
        
    })
})

document.getElementById('clearScreen').addEventListener('click', function(){
    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(()=>{
            // send command to clear the screen
            my_dongle.at_spssend('L=0').then(()=>{
                console.log('Screen Cleared')
            })
        })
        
    })
})

The script has a button to connect to COM port on the computer. There is a text field where you can write sensor ID of the air quality monitor device. Once connected, the script will try to get advertised data from the sensor and convert it to a meaningful data. After that it will send this data to the STM32 board which then display on the LCD screen.

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 #4

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 see air quality data on the LCD screen. The response will show on browser console screen.

The web script looks like this

Output

The message will show on the LCD screen.

Share this post on :

Develop Bluetooth LE application easily with JAVA and BleuIO

This article is a guide for creating Java applications that can write AT commands to BleuIO and access nearby Bluetooth Low Energy devices. This example project will be helpful to create BLE application easily.

Requirments

  1. BleuIO. (Bluetooth Low Energy USB dongle)
  2. NetBean

About the Project

The script has a COM port settings section. This section shows connected devices to the COM port. Using jSerialComm we get the list of COM ports and show it on a dropdown menu to select.

The connect and disconnect buttons manages the connection of the dongle.

Once we are connected to the BleuIO dongle, we will be able to write AT commands to the dongle using serial port write command.

We have a button at the bottom right to stop on going process. This button is effective when we write AT+GAPSCAN. The BleuIO dongle will keep scanning for nearby BLE devices unless we stop the process.

The response will be available on the output panel.

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

Step 1: Clone the project

Step 2 : Run the project

Connect BleuIO dongle into the computer.

Run the project using NetBean play button.

Alternatively we can open the project using command line interface by going to the root folder of the project and type

java -jar "dist/JavaBleuIO.jar"

The output will look like this.

Lets select a COM port where the BleuIO dongle is connected and click connect.

Now we will be able to write AT commands and see the response from the dongle on output screen.

Share this post on :

Bluetooth LE based LCD messenger using STM32 and BleuIO

The aim of this project is to send message via Bluetooth using a web browser or smartphone to a LCD display which is connected to STM32 board.

1. Introduction

The project is based on STM32 Nucleo-144 which controls LCD display using BleuIO.

For this project, we will need two BleuIO USB dongles, one connected to the Nucleo board and the other to a computer, running the web script.
When the BleuIO Dongle is connected to the Nucleo boards USB port the STM32 will recognize it and directly start advertising. This allows the Dongle on the computer port connect with the web script.

With the web script on the computer, we can send message to LCD screen connected to STM32 using BleuIO.

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) for this example. This development board has a USB host where we connect the BleuIO dongle.

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.

About the Code

The project source code is available at Github.

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

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

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

Connect the SDA to PF0 on the Nucleo board and SCL to PF1.

Then setup I2C2 in the STM32Cube ioc file as follows. (Make sure to change the I2C speed frequency to 50 KHz as per LCD display requirements.)

In the USBH_CDC_ReceiveCallback function in USB_HOST\usb_host.c we copy the CDC_RX_Buffer into a external variable called dongle_response that is accessable from the main.c file.

void USBH_CDC_ReceiveCallback(USBH_HandleTypeDef *phost)
{
  	if(phost == &hUsbHostFS)
  	{
  		// Handles the data recived from the USB CDC host, here just printing it out to UART
  		rx_size = USBH_CDC_GetLastReceivedDataSize(phost);
		HAL_UART_Transmit(&huart3, CDC_RX_Buffer, rx_size, HAL_MAX_DELAY);

		// Copy buffer to external dongle_response buffer
		strcpy((char *)dongle_response, (char *)CDC_RX_Buffer);

		// Reset buffer and restart the callback function to receive more data
		memset(CDC_RX_Buffer,0,RX_BUFF_SIZE);
		USBH_CDC_Receive(phost, CDC_RX_Buffer, RX_BUFF_SIZE);
  	}

  	return;
}

In main.c we create a simple intepreter so we can react to the data we are recieving from the dongle.

void dongle_interpreter(uint8_t * input)
{

	if(strlen((char *)input) != 0)
	{
		if(strstr((char *)input, "\r\nADVERTISING...") != NULL)
		{
			isAdvertising = true;
		}
		if(strstr((char *)input, "\r\nADVERTISING STOPPED") != NULL)
		{
			isAdvertising = false;
		}
		if(strstr((char *)input, "\r\nCONNECTED") != NULL)
		{
			isConnected = true;
			HAL_GPIO_WritePin(GPIOE, GPIO_PIN_1, GPIO_PIN_SET);
		}
		if(strstr((char *)input, "\r\nDISCONNECTED") != NULL)
		{
			isConnected = false;
			HAL_GPIO_WritePin(GPIOE, GPIO_PIN_1, GPIO_PIN_RESET);
		}


		if(strstr((char *)input, "L=0") != NULL)
		{

			isLightBulbOn = false;
			//HAL_GPIO_WritePin(Lightbulb_GPIO_Port, Lightbulb_Pin, GPIO_PIN_RESET);
			lcd_clear();

			writeToDongle((uint8_t*)DONGLE_SEND_LIGHT_OFF);

			uart_buf_len = sprintf(uart_tx_buf, "\r\nClear screen\r\n");
			HAL_UART_Transmit(&huart3, (uint8_t *)uart_tx_buf, uart_buf_len, HAL_MAX_DELAY);
		}

		if(strstr((char *)input, "L=1") != NULL)
		{
				isLightBulbOn = true;
				writeToDongle((uint8_t*)DONGLE_SEND_LIGHT_ON);


				lcd_clear();

				lcd_write(input);

		}

	}
	memset(&dongle_response, 0, RSP_SIZE);
}

We put the intepreter function inside the main loop.

/* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
    MX_USB_HOST_Process();

    /* USER CODE BEGIN 3 */
    // Simple handler for uart input
    handleUartInput(uartStatus);

    // Inteprets the dongle data
    dongle_interpreter(dongle_response);

	// Starts advertising as soon as the Dongle is ready.
	if(!isAdvertising && !isConnected && isBleuIOReady)
	{
		HAL_Delay(200);
		writeToDongle((uint8_t*)DONGLE_CMD_AT_ADVSTART);
		isAdvertising = true;
	}
  }
  /* USER CODE END 3 */

Using the example project

What we will need

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_SHT85_example”, check it and click ‘Finish’.

Running the example

Upload the the code to STM32 and run the example. The USB dongle connect to STM32 will start advertising automatically.

Send Messages to LCD screen 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. Now you can send messages to the LCD screen.

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>Send message to STM32 LCD display using Bluetooth LE</title>
  </head>
  <body class="mt-5">
    <div class="container mt-5">
      <h1 class="mb-5">Send message to STM32 LCD display using Bluetooth LE</h1>
      <button class="btn btn-success" id="connect">Connect</button>
      <div class="row">
        <div class="col-md-4">
          <form method="post" id="sendMsgForm" name="sendMsgForm">
            <div class="mb-3">
              <label for="msgToSend" class="form-label">Your Message</label>
              <input
                type="text"
                class="form-control"
                name="msgToSend"
                id="msgToSend"
                required
                maxlength="60"
              />
            </div>

            <button type="submit" class="btn btn-primary">Submit</button>
          </form>
        </div>
      </div>

      <br />
      <button class="btn btn-danger" id="clearScreen" disabled>
        Clear screen
      </button>
    </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("clearScreen").disabled=false;
  document.getElementById("connect").disabled=true;
  document.getElementById("sendMsgForm").hidden=false;
})

document.getElementById("sendMsgForm").addEventListener("submit", function(event){
    event.preventDefault()
    console.log('here')

    
    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 = "L=1 " + document.getElementById('msgToSend').value;
            console.log('Message Send 1 '+theVal)
            // send command to show data
            my_dongle.at_spssend(theVal).then(()=>{
                console.log('Message Send '+theVal)
            })
        })
        
    })
  });



document.getElementById('clearScreen').addEventListener('click', function(){
    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(()=>{
            // send command to clear the screen
            my_dongle.at_spssend('L=0').then(()=>{
                console.log('Screen Cleared')
            })
        })
        
    })
})

The script has a button to connect to COM port on the computer. There is a text field where you can write your message. Your messages will be displayed on LCD screen connected to STM32 board.

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 send your message to the LCD screen. The response will show on browser console screen.

The web script looks like this

Output

The message will show on the LCD screen.

Video of working project

Share this post on :