BLE enabled Smart Bulb with STM32 & Javascript
Make a BLE enabled Smart Bulb with STM32 Microcontroller & Javascript for controlling AC Bulb or Home Automation using Bluetooth Low Energy
- Suitable forB.Tech/Diploma STM32 students
- Build time1-2 weeks
- LevelBeginner
- Available atAjvika Labs, Kakinada
About this project
Overview: BLE enabled Smart Bulb with STM32 & Javascript
In this project, we will learn how to make a BLE enabled Smart Bulb with STM32 & Javascript. Home automation involves automating household environment equipment. To achieve that, we have created a smart bulb that is easy to install, and the attached equipment can be controlled over a web browser or smartphone app. The aim of this project is to control different home appliances using a web browser or smartphone.
The project is showcasing a simple way of using the BLE BleuIO Dongle to turn on and off a Smart light bulb that is connected to the STM32 Nucleo-144 via a 5V Relay.
You will need two dongles, one connected to the Nucleo board and one connected to a computer, running the web script.
When the BleuIO Dongle is connected to the Nucleo board 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:
input
result
Send ATI (Request device information) command to BlueIO Dongle.
Manually turn the light bulb on
Manually turn the light bulb off
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.
If you want to use another setup you will have to make sure it supports USB Host and beware that the GPIO setup might be different and may need to be reconfigured in the .ioc file.
WARNING – THIS PROJECT INVOLVES HIGH VOLTAGES THAT CAN CAUSE SERIOUS INJURY OR DEATH. PLEASE TAKE ALL NECESSARY PRECAUTIONS, AND TURN OFF ALL POWER TO A CIRCUIT BEFORE WORKING ON IT.
Connecting the relay
Beware:
Always be very careful when experimenting with AC, electrical shock can result in serious injuries!
NOTICE OF RISK; DISCLAIMER OF LIABILITY
Pinout and Connection to STM32
For the DC part of the Relay circuit connect S (signal) to pin PE4 on the STM32 NUCLEO board, also connect the Power supply (+) and ground (-) to +5V and GND respectively.
About the Code
You can get the project
HERE
https://github.com/smart-sensor-devices-ab/stm32_bleuio_lightbulb_example
This project-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 pinout view, we set the GPIO PE4 to OUTPUT and labeled it to ‘lightbulb’.
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
)
;
memset
(
CDC_RX_Buffer
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
/**
* @brief Simple dongle interpreter
* @retval None
*/
void
dongle_interpreter
(
uint8_t *
input
)
{
if
(
strlen
(
(
char
*
)
input
)
!=
)
{
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
)
;
writeToDongle
(
(
uint8_t*
)
DONGLE_SEND_LIGHT_OFF
)
;
uart_buf_len
=
sprintf
(
uart_tx_buf
"\r\nLight bulb is %s\r\n"
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
"\r\nLight bulb is %s\r\n"
isLightBulbOn
?
"on"
:
"off"
)
;
HAL_UART_Transmit
(
&
huart3
(
uint8_t *
)
uart_tx_buf
uart_buf_len
HAL_MAX_DELAY
)
;
}
}
memset
(
&
dongle_response
RSP_SIZE
)
;
}
We
also
update
the
handleUartInput
function
so
we
can
have
manual
control
over
the
light
bulb
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 light bulb on!)\r\n"
)
;
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
"\r\n(2 pressed light bulb off!)\r\n"
)
;
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
put
the
intepreter
function
inside
the
main
loop
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while
(
)
{
/* 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
(
)
;
writeToDongle
(
(
uint8_t*
)
DONGLE_CMD_AT_ADVSTART
)
;
isAdvertising
=
true
;
}
}
/* USER CODE END 3 */
Using the example project
What you will need
Two BleuIO dongles (
https://www.bleuio.com/
)
The script for the dongle (available on the source code inside the web script folder)
A board with an STM32 Microcontroller with a USB port. (A Nucleo-144 development board: NUCLEO-H743ZI2, was used to develop this example. (
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
)
A 5V Relay
A light bulb
How to setup project
Downloading the project from GitHub
Get project Here
https://github.com/smart-sensor-devices-ab/stm32_bleuio_lightbu
In this project, we will learn how to make a BLE enabled Smart Bulb with STM32 & Javascript. Home automation involves automating household environment equipment. To achieve that, we have created a smart bulb that is easy to install, and the attached equipment can be controlled over a web browser or smartphone app. The aim of this project is to control different home appliances using a web browser or smartphone.
The project is showcasing a simple way of using the BLE BleuIO Dongle to turn on and off a Smart light bulb that is connected to the STM32 Nucleo-144 via a 5V Relay.
You will need two dongles, one connected to the Nucleo board and one connected to a computer, running the web script.
When the BleuIO Dongle is connected to the Nucleo board 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:
input
result
Send ATI (Request device information) command to BlueIO Dongle.
Manually turn the light bulb on
Manually turn the light bulb off
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.
If you want to use another setup you will have to make sure it supports USB Host and beware that the GPIO setup might be different and may need to be reconfigured in the .ioc file.
WARNING – THIS PROJECT INVOLVES HIGH VOLTAGES THAT CAN CAUSE SERIOUS INJURY OR DEATH. PLEASE TAKE ALL NECESSARY PRECAUTIONS, AND TURN OFF ALL POWER TO A CIRCUIT BEFORE WORKING ON IT.
Connecting the relay
Beware:
Always be very careful when experimenting with AC, electrical shock can result in serious injuries!
NOTICE OF RISK; DISCLAIMER OF LIABILITY
Pinout and Connection to STM32
For the DC part of the Relay circuit connect S (signal) to pin PE4 on the STM32 NUCLEO board, also connect the Power supply (+) and ground (-) to +5V and GND respectively.
About the Code
You can get the project
HERE
https://github.com/smart-sensor-devices-ab/stm32_bleuio_lightbulb_example
This project-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 pinout view, we set the GPIO PE4 to OUTPUT and labeled it to ‘lightbulb’.
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
)
;
memset
(
CDC_RX_Buffer
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
/**
* @brief Simple dongle interpreter
* @retval None
*/
void
dongle_interpreter
(
uint8_t *
input
)
{
if
(
strlen
(
(
char
*
)
input
)
!=
)
{
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
)
;
writeToDongle
(
(
uint8_t*
)
DONGLE_SEND_LIGHT_OFF
)
;
uart_buf_len
=
sprintf
(
uart_tx_buf
"\r\nLight bulb is %s\r\n"
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
"\r\nLight bulb is %s\r\n"
isLightBulbOn
?
"on"
:
"off"
)
;
HAL_UART_Transmit
(
&
huart3
(
uint8_t *
)
uart_tx_buf
uart_buf_len
HAL_MAX_DELAY
)
;
}
}
memset
(
&
dongle_response
RSP_SIZE
)
;
}
We
also
update
the
handleUartInput
function
so
we
can
have
manual
control
over
the
light
bulb
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 light bulb on!)\r\n"
)
;
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
"\r\n(2 pressed light bulb off!)\r\n"
)
;
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
put
the
intepreter
function
inside
the
main
loop
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while
(
)
{
/* 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
(
)
;
writeToDongle
(
(
uint8_t*
)
DONGLE_CMD_AT_ADVSTART
)
;
isAdvertising
=
true
;
}
}
/* USER CODE END 3 */
Using the example project
What you will need
Two BleuIO dongles (
https://www.bleuio.com/
)
The script for the dongle (available on the source code inside the web script folder)
A board with an STM32 Microcontroller with a USB port. (A Nucleo-144 development board: NUCLEO-H743ZI2, was used to develop this example. (
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
)
A 5V Relay
A light bulb
How to setup project
Downloading the project from GitHub
Get project Here
https://github.com/smart-sensor-devices-ab/stm32_bleuio_lightbu
Technologies used
Hardware components
- STM32
- Relay
Software & tools
- Arduino IDE
What you get
- Working project / hardware kit, tested before delivery
- Complete source code with explanation
- Project demo and guidance for your viva
- Project report, PPT and IEEE paper support (on request)
Delivery & Payment
Delivery takes a minimum of two weeks from the date your inquiry is confirmed.
Payment is in two parts:
• 50% advance to start the project
• Remaining 50% before delivery
Note:
• Documentation and PPT are not included by default
• If you need documentation/PPT, it can be arranged for extra time and cost
We'll confirm the exact timeline and cost with you after reviewing your requirements.