BLUETOOTH LE BASED LCD MESSENGER USING STM32

Summary of BLUETOOTH LE BASED LCD MESSENGER USING STM32


Summary: This project shows how to send messages from a web browser or smartphone via Bluetooth LE (using BleuIO dongles) to an LCD connected to an STM32 Nucleo-144 (STM32H743ZI). A BleuIO dongle on the Nucleo advertises over USB host; a second dongle on the PC runs a web script (using BleuIO JS) to connect and send AT commands that the STM32 interprets to update or clear the LCD.

Parts used in the Bluetooth LE based LCD Messenger:

  • STM32 Nucleo-144 development board (NUCLEO-H743ZI2 with STM32H743ZI MCU)
  • Two BleuIO USB dongles
  • USB A to Micro USB B cable with USB A female-to-female adapter
  • Liquid Crystal Display Module – NHD-0420D3Z-NSW-BBW-V3
  • Computer with Chrome 78 or later
  • BleuIO javascript library
  • Web bundler (parcel js)
  • STM32CubeIDE

The aim of this project is to send messages via Bluetooth using a web browser or smartphone to an LCD display that is connected to the STM32 board.

BLUETOOTH LE BASED LCD MESSENGER USING STM32

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 board’s USB port the STM32 will recognize it and directly start advertising. This allows the Dongle on the computer port to connect with the web script.

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

We have used an 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 on GitHub.

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’

pin configuration

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.)

Connect the SDA to PF0

lcd stm32 web bluetooth

In the USBH_CDC_ReceiveCallback function in USB_HOST\usb_host.c we copy the CDC_RX_Buffer into an external variable called dongle_response that is accessible 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 interpreter so we can react to the data we are receiving 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 interpreter 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…

Importing As An Existing Project

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

Existing Projects into Workspace

Make sure you’ve chosen your workspace in ‘Select root directory:’

You should see the project “stm32_bleuio_SHT85_example”, check it, and click ‘Finish’.

Select root directory

Running The Example

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

Send Messages To The 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/[email protected]/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 the COM port on the computer. There is a text field where you can write your message. Your messages will be displayed on an LCD screen connected to the 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 the 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

Source: BLUETOOTH LE BASED LCD MESSENGER USING STM32

Quick Solutions to Questions related to Bluetooth LE based LCD Messenger:

  • What hardware is required to run the example?
    Two BleuIO dongles, an STM32 board with USB host (example NUCLEO-H743ZI2), a NHD-0420D3Z-NSW-BBW-V3 LCD, a USB A to Micro USB B cable and USB A female-to-female adapter, and a computer.
  • How does the STM32 communicate with the BleuIO dongle connected to it?
    The BleuIO dongle is connected to the STM32 USB host; the STM32 reads CDC data from the dongle via USBH_CDC_ReceiveCallback and processes it in the main loop.
  • Can I send messages from a web browser to the LCD?
    Yes; the web script uses the BleuIO javascript library and a BleuIO dongle on the computer to connect to the dongle on the STM32 and send AT commands to display messages.
  • What software is needed on the computer to run the web script?
    Chrome 78 or later with enable-experimental-web-platform-features enabled, a web bundler like parcel js, and the BleuIO javascript library.
  • How does the STM32 detect commands from the dongle?
    CDC_RX_Buffer is copied to dongle_response in USBH_CDC_ReceiveCallback; dongle_interpreter in main.c parses dongle_response for commands like L=1 and L=0.
  • What commands does the interpreter respond to for LCD control?
    The interpreter checks for L=1 to write text to the LCD and L=0 to clear the screen, and it also monitors advertising and connection status messages.
  • How do I configure I2C for the LCD on the Nucleo board?
    Connect SDA to PF0 and SCL to PF1, configure I2C2 in the STM32Cube ioc file, and set the I2C speed to 50 KHz as required by the LCD.
  • How do I get the MAC address of the dongle connected to STM32?
    Use the BleuIO web terminal, connect to the dongle, run ATI, set to central if peripheral, run AT+GAPSCAN, copy the ID from the scan results and paste it into script.js.
  • Does the project repository provide the code?
    Yes; the project source code is available on GitHub and can be cloned or downloaded and imported into STM32CubeIDE.
  • What should I rename if I download the project zip?
    If downloaded as zip, rename the project folder from stm32_bleuio_lcd-master to stm32_bleuio_lcd.

About The Author

Muhammad Bilal

I am a highly skilled and motivated individual with a Master's degree in Computer Science. I have extensive experience in technical writing and a deep understanding of SEO practices.