How to make a BLE-enabled smart light bulb using STM32
Source: InternetPublisher:清宁时光 Keywords: STM32 BLE smart bulb Updated: 2024/05/24
This article will teach you how to make a BLE-enabled smart light bulb using STM32.
Home Automation involves automating the home environment devices. For this purpose, we have developed a smart light bulb which is easy to install and the connected devices can be controlled through a web browser or smartphone application. The aim of this project is to control different home appliances using a web browser or smartphone.
1. Introduction
This project shows a simple way to use a BleuIO Dongle to turn on and off a light bulb connected to an STM32 Nucleo-144 via a 5V relay.
You will need two dongles, one to connect to the Nucleo board and one to connect to the computer running the web script.
When the BleuIO Dongle is connected to the USB port of the Nucleo board, the STM32 recognizes it and starts advertising directly. This allows another dongle to be connected to it.
It will also accept 3 different inputs from the UART:
Input results
0 Sends an ATI (Request Device Information) command to the BlueIO Dongle.
1 Turn on the lamp manually
2 Turn off the lamp manually
We used the STM32 Nucleo-144 development board and the STM32H743ZI MCU (STM32H743ZI micro mbed-Enabled Development Nucleo-144 series ARM? Cortex?-M7 MCU 32-Bit Embedded Evaluation Board) as an example.
If you want to use another setup, you must make sure it supports USB host, and be aware that the GPIO setup may be different and may need to be reconfigured in the .ioc file.
WARNING – This project involves high voltages that could cause serious injury or death. Take all necessary precautions and turn off all power to the circuit before working on it.
2. Connect the relay
guard against:
Please be careful when testing AC power. Electric shock can cause serious injury! Risk Notice; Disclaimer
Pinout and Connection to STM32 For the DC portion of the relay circuit, connect S (signal) to pin PE4 on the STM32 NUCLEO board, while connecting power (+) and ground (-) to +5V and GND respectively.
3. About the Code
This project is based on our previous STM32 project (https://github.com/smart-sensor-devices-ab/stm32_bleuio_example) with these changes in the .ioc file:
In the Pins View, we set GPIO PE4 to OUTPUT and labeled it "Light Bulb".
In the USBH_CDC_ReceiveCallback function in USB_HOSTusb_host.c, we copy the CDC_RX_Buffer into an external variable called dongle_response which is accessible from the main.c file.
In main.c we create a simple interpreter so that we can react to the data we receive from the dongle.
void dongle_interpreter ( uint8_t * input)
{
if ( strlen (( char *)input) != 0 )
{
if ( strstr (( char *)input, "
广告..." ) != NULL )
{
isAdvertising = true ;
}
if ( strstr (( char *)input, "
广告已停止。" ) != NULL )
{
isAdvertising = false ;
}
if ( strstr (( char *)input, "
CONNECTED" ) != NULL )
{
isConnected =真;
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_1, GPIO_PIN_SET);
}
if ( strstr (( char *)input, "
DISCONNECTED" ) != 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);
writeToDongle(( uint8_t *)DONGLE_SEND_LIGHT_OFF);
uart_buf_len = sprintf (uart_tx_buf, "
灯泡是 %s
" , isLightBulbOn ? "on" : "off" );
HAL_UART_Transmit(&huart3, ( uint8_t *)uart_tx_buf, uart_buf_len, HAL_MAX_DELAY);
}
if ( strstr (( char *)input, "L=1" ) != NULL )
{
isLightBulbOn = true ;
HAL_GPIO_WritePin(Lightbulb_GPIO_Port, Lightbulb_Pin, GPIO_PIN_SET);
writeToDongle(( uint8_t *)DONGLE_SEND_LIGHT_ON);
uart_buf_len = sprintf (uart_tx_buf, "
灯泡是 %s
" , isLightBulbOn ? "on" : "off" );
HAL_UART_Transmit(&huart3, ( uint8_t *)uart_tx_buf, uart_buf_len, HAL_MAX_DELAY);
}
}
memset (&dongle_response, 0 , RSP_SIZE);
}
We also updated the handleUartInput function so that we can manually control the bulb over the UART.
void handleUartInput (UARTCommandTypeDef cmd)
{
switch (cmd)
{
case UART_RX_0:
{
// 0
uart_buf_len = sprintf (uart_tx_buf, " (0 press ) " );
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, " (1 pressed bulb turned on!) " );
HAL_UART_Transmit(&huart3, ( uint8_t *)uart_tx_buf, uart_buf_len, HAL_MAX_DELAY);
HAL_GPIO_WritePin(Lightbulb_GPIO_Port, Lightbulb_Pin, GPIO_PIN_SET);
uartStatus = UART_RX_NONE;
break;
}
case UART_RX_2:
{
// 2
uart_buf_len = sprintf (uart_tx_buf, " (2 pressed bulb turned off!) " );
HAL_UART_Transmit(&huart3, ( uint8_t *)uart_tx_buf, uart_buf_len, HAL_MAX_DELAY);
HAL_GPIO_WritePin(Lightbulb_GPIO_Port, Lightbulb_Pin, GPIO_PIN_RESET);
uartStatus = UART_RX_NONE;
break;
}
case UART_RX_NONE:
{
break;
}
default:
{
uartStatus = UART_RX_NONE;
break;
}
}
}
We place the interpreter function inside the main loop.
4. Using the Example Project
4.1 What you need
Two BleuIO dongles
The dongle script (can be found in the source code in the web scripts folder)
A board with an STM32 microcontroller with a USB port. (Nucleo-144 development board: NUCLEO-H743ZI2, used to develop this example.
To connect the dongle to the Nucleo board, you can use a "USB A to Micro USB B" cable with a USB A female to female adapter. )
STM32CubeIDE
A 5V relay
A light bulb
5. How to set up a project
5.1 Download the project from below
Clone the project, or download it as a zip file and extract it into your STM32CubeIDE workspace.
5.2 Import as an existing project
From STM32CubeIDE, select File>Import.
Then select General>Existing Projects into Workspace and click "Next>"
Make sure you have your workspace selected in "Select root directory:"
You should see the project "stm32_bleuio_example", check it and click "Finish".
6. Run the Example
In STMCubeIDE, click the hammer icon to build the project.
Use a serial terminal emulation program such as TeraTerm, Putty, or CoolTerm to open the "STMicroelectronics STLink Virtual COM Port". Serial Port Settings:
Baud rate: 115200
Data bits: 8
Parity: None
Stop bits: 1
Flow Control: No
Connect the BleuIO Dongle before running the examples.
In STMCubeIDE, click the green play button to flash and run it on your board. The first time you click it, the Run Configurations window will appear. You can leave it as is and click Run.
You should receive the following welcome message:
Wait until the message "[BleuIO Dongle Ready]" is displayed.
You can now connect another dongle using the script.
You can also use the uart command (0, 1, or 2):
Press 0 to get device information.
1 Turn on the lamp.
2 Turn off the lamp.
The dongle response will be printed to the UART.
7. Control lights from a web browser
We wrote a simple script that connects to the dongle and sends a signal to toggle the light from a web browser.
In order for this script to work, we need
BleuIO USB dongle connected to your computer.
BleuIO javascript library
Chrome 78 or higher, and you need to enable the #enable-experimental-web-platform-features flag in chrome://flags
A network packager - (parcel js)
Create a simple Html file called index.html which will be used as the front end of the script. This Html file contains some buttons that help to connect to and send signals to the remote dongle, which is connected to the stm32.
< 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 > Control Light Using Bleutooth Low Energy
< body class = "mt-5" >
< div class = "container mt-5" >
< h1 class = "mb-5" > Control light using Bluetooth Low Energy
<button class = "btn btn-success" id = "connect" > Connect
<button class = "btn btn-warning" id = "lightOn" disabled > Turn On
<button class = "btn btn-danger" id = "lightOf" disabled > Turn Off
<div class = "container mt-5">
<image ID = "light" src = "light_off.png" alt = "" />
< script src = "script.js" >
Create a js file named 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 other dongles.
import * as my_dongle from "bleuio" ;
const dongleToConnect = "[0]40:48:FD:E5:35:A5" ;
import lightOnImg from "./light_on.png" ;
import lightOfImg from "./light_off.png" ;
document.getElementById( "connect" ).addEventListener( "click" , function () {
my_dongle.at_connect();
document.getElementById( "lightOn" ).disabled = false ;
document.getElementById( "lightOf" ).disabled = false ;
document.getElementById( "connect" ).disabled = true ;
});
document.getElementById( "lightOn" ) .addEventListener( "click" , function () {
my_dongle
.ati()
. then((data) => {
//
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 control the light my_dongle.at_spssend( "L=1" ).then( () => { console .log( "Turned on" ); document .getElementById( "light" ).src = lightOnImg; }); } );
}); });
document.getElementById( "lightOf" ) .addEventListener( "click" , function () {
my_dongle
.ati()
. then((data) => {
//
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 control the light my_dongle.at_spssend( "L=0" ).then( () => { console .log( "Turned off" ); document .getElementById( "light" ).src = lightOfImg; }); });
}); });
The script js file has three button actions; connect and control the light.
Now we need to know the ID of the other dongle connected to the STM32 so that we can connect to it. You can get the dongle ID using this web terminal.
- Open this site https://bleuio.com/web_terminal.html and click Connect to dongle.
- Select the appropriate port for connection.
- Once it says connected, type in **"ATI"**. This will display the dongle information and current status.
- If the dongle is in peripheral role, set it to central by typing **"AT+CENTRAL"**
- Now do a gap scan by typing **"AT+GAPSCAN"**
- Once you see your dongle in the list, press control+c to stop scanning
- Copy the ID and paste it into line 2 of the script (script.js)
You will need a web bundler. You can use parcel.js
After installing parcel js, go to the root directory and type "parcel index.html". This will launch your development environment.
Use parcel js to open the script on the browser.
You can easily connect to the dongle and turn the light on and off from there.
- Hardware interface circuit between CH375 and single chip microcomputer
- Interface circuit composed of 8255A and single chip microcomputer
- How to design a home computer using Arduino DUE
- Digital frequency meter made with ATmega8 microcontroller
- How to design an AirPlay speaker using Raspberry Pi Zero
- How to use ESP8266 to make a mini fully functional clock
- How to use ESP8266 to design a portable air quality monitoring station
- 3 IO scan 16 buttons
- Decoding infrared remote control using microcontroller
- Microcontroller test board circuit 2