Skip to main content
Version: FILS English

Home Environment Station

A touchscreen dashboard that monitors temperature, humidity, light and air quality in real time

info

Author: Bogdan Danila
GitHub Project Link: https://github.com/UPB-PMRust-Students/project-2026-bgdanila-1

Description

The Home Environment Station is built around an STM32 Nucleo-U545RE-Q that reads data from multiple sensors: BME280 for temperature and humidity, TSL2561 for ambient light, MQ135 for air quality, and HC-SR501 for motion. Everything is shown on a 2.4" TFT LCD touchscreen where you can swipe between sensor pages. Values are color-coded green (optimal), orange (caution) or red (critical) so you can tell at a glance if something is off. An ESP8266 handles WiFi for remote logging, and a buzzer + RGB LED give alerts when things go out of range.

Motivation

I wanted to build something that actually uses all the protocols we learned (SPI, I2C, ADC, PWM) together in one project, and have a nice UI on top of it. Air quality is something that affects you every day but you never really see the numbers. This project let me combine that practical idea with learning Embassy async, writing display drivers from scratch, and figuring out touch input on a real board.

Architecture

The STM32 talks to everything through different interfaces:

  • SPI Bus (shared): the ST7789 display and XPT2046 touch controller both sit on SPI1. Display runs at 20 MHz, touch at 1 MHz, switched via software chip selects.
  • I2C Bus: BME280 (temperature + humidity) and TSL2561 (light) share the same I2C bus with different addresses.
  • ADC: MQ135 air quality sensor gives an analog voltage that gets read through the STM32's ADC.
  • PWM: drives the buzzer and RGB LED for alerts.
  • GPIO: HC-SR501 PIR sensor outputs a digital high when it detects motion.
  • UART: ESP8266 WiFi module for sending data remotely.

The firmware uses Embassy's async executor. The main loop polls touch input, detects swipe gestures, and handles page transitions. Sensor tasks will run concurrently and update shared state.

Component Connections:

ComponentInterfaceSTM32 Pins
ST7789 DisplaySPI1 (20 MHz)MOSI: PA7 (D11), SCK: PA5 (D13), MISO: PA6 (D12), CS: PC9 (D10), DC: PC6 (D9), RST: PC7 (D8), LED: 3V3
XPT2046 TouchSPI1 (1 MHz, shared)T_CLK: PA5 (D13), T_DIN: PA7 (D11), T_DO: PA6 (D12), T_CS: PA8 (D7), T_IRQ: PB10 (D6)
BME280 SensorI2C1 (shared)SCL: PB6 (D15), SDA: PB7 (D14), VCC: 3V3
TSL2561 SensorI2C1 (shared)SCL: PB6 (D15), SDA: PB7 (D14), INT: not connected
MQ135 SensorADC1 + GPIOAOUT: PA0 (A0), DOUT: PA10 (D2), VCC: 5V
HC-SR501 PIRGPIO inputOUT: PB5 (D4), VCC: 5V
ESP8266 WiFi (NodeMCU)USART1 TX (one-way)STM32 PA9 (TX) -> NodeMCU D5 (GPIO14 RX), common GND
Passive BuzzerPWM (planned)PB4 (D5), via series resistor to buzzer
RGB LEDPWM x3 (planned)PA1 (A1), PA2 (D1), PA3 (D0), each color through resistor

System Schematic (Text)

+---------------------+       +--------------------------------------+
| 5V / 3V3 / GND rails|------>| STM32 NUCLEO-U545RE-Q (central node) |
+---------------------+ +--------------------------------------+
|
+-------------------------------+-------------------------------+
| | | | |
v v v v v
+----------------+ +-------------+ +-------------+ +-------------+ +--------------+
| ST7789 + | | BME280 | | TSL2561 | | MQ-135 | | HC-SR501 PIR |
| XPT2046 LCD | | Temp/Hum/P | | Light | | Air quality | | Motion |
| SPI1 + GPIO | | I2C1 | | I2C1 | | ADC + GPIO | | GPIO input |
+----------------+ +-------------+ +-------------+ +-------------+ +--------------+
| | | | |
+---------------+---------------+---------------+---------------+
|
v
+----------------------+
| ESP8266 NodeMCU v0.1|
| UART RX + common GND|
+----------------------+
|
+-----------------+-----------------+
| |
v v
+-------------------+ +-------------------+
| Passive buzzer | | RGB LED |
| PWM output (PB4) | | PWM R/G/B |
+-------------------+ +-------------------+

HARDWARE CONNECTIONS (pin-level):
LCD+Touch: PA5/PA6/PA7, PC9, PC6, PC7, PA8, PB10
BME280: PB6 (SCL), PB7 (SDA), 3V3, GND
TSL2561: PB6 (SCL), PB7 (SDA), 3V3, GND
MQ-135: PA0 (AOUT), PA10 (DOUT), 5V, GND
PIR: PB5 (OUT), 5V, GND
ESP8266: PA9 (USART1_TX) -> D5 (GPIO14 RX), GND <-> GND
Buzzer (planned): PB4 (PWM) -> buzzer +
RGB LED (planned): PA1/PA2/PA3 (PWM) -> R/G/B

Log

Week 2 - 4

Documentation for both software and hardware part of the project. Set up the Rust embedded toolchain and prepared the STM32 workflow.

Week 5 - 6

Ordered all the hardware. Soldered the TSL2561 sensor and the MQ135 sensor. Debugged the STM32 Nucleo-U545RE-Q and prepared it for the project.

Week 7

Connected the ST7789 display to the STM32 Nucleo-U545RE-Q. Sorted out visual and touchscreen parts. Tweaked the UI and swipe animations with static values before adding all sensors.

Week 8

Integrated BME280, TSL2561, and PIR into the runtime UI, then added the ESP8266 NodeMCU web dashboard path over UART JSON streaming.

Week 9

Improved refresh responsiveness and synchronized motion behavior between board display and web dashboard. Finalized project documentation updates and KiCad schematic integration.

Hardware

The core is an STM32 Nucleo-U545RE-Q running at 160 MHz (PLL from HSI). The display is a 2.4" TFT with an ST7789V controller and XPT2046 resistive touch, both sharing SPI1 with separate chip selects. For sensors I'm using a BME280 (temp + humidity over I2C), TSL2561 (light over I2C), MQ135 (air quality, analog), and HC-SR501 (PIR motion, digital GPIO). An ESP8266 NodeMCU handles WiFi over UART. Alerts come from a passive buzzer and an RGB LED, both driven by PWM. All the small stuff (breadboard, wires, resistors, LEDs) came from a component kit.

Schematics

KiCad schematic

Bill of Materials

DeviceUsagePrice
STM32 Nucleo-U545RE-QThe microcontroller125 RON
2.4" TFT LCD Touchscreen (ST7789V + XPT2046)Display + touch for the dashboard UI54.86 RON
Set 3x BME280Temperature, humidity, pressure (I2C)76.74 RON
TSL2561 (GY-2561)Light sensor, 0.1 to 40k+ lux (I2C)29.84 RON
MQ-135Air quality, detects CO2/NH3/benzene (analog)28.62 RON
HC-SR501 PIRMotion detection23.27 RON
ESP8266 NodeMCU V3WiFi for remote logging39.14 RON
Electronics Kit (Duueyct)Breadboard, wires, resistors, LEDs, buzzer65.50 RON
TotalComplete hardware cost442.97 RON

Software

LibraryDescriptionUsage
embassy-stm32Embassy HAL for STM32GPIO, SPI, I2C, ADC, PWM drivers
embassy-executorAsync task executorRuns sensor and UI tasks concurrently
embassy-timeTimers and delaysSplash screen, polling intervals, debouncing
embassy-syncSync primitivesMutex for the shared SPI bus
embassy-embedded-halShared bus abstractionsSpiDeviceWithConfig for display/touch multiplexing
mipidsiMIPI display driverST7789 init, orientation, color inversion
embedded-graphics2D graphics libraryText, shapes, dots on the dashboard
embedded-halHAL traitsSpiDevice for XPT2046 touch transfers
defmtLogging frameworkDebug output over RTT
panic-probePanic handlerShows panics via probe-rs
cortex-mCortex-M supportCritical sections, inline asm
  1. Embassy async framework
  2. Embedded Rust 101 course labs
  3. mipidsi docs
  4. embedded-graphics docs
  5. Nucleo-U545RE-Q user manual
  6. BME280 datasheet
  7. TSL2561 datasheet