Skip to main content
Version: FILS English

PlantGuard Node

Embedded Rust smart plant care system with automatic watering and Wi-Fi monitoring.

info

Author: Andrei-Ştefan FLOREA
GitHub Project Link: https://github.com/UPB-PMRust-Students/fils-project-2026-Andrei-20

Description

PlantGuard Node is a compact embedded plant monitoring and watering system built around the STMicroelectronics NUCLEO-U545RE-Q development board. The firmware is written in Rust for a no_std embedded environment using the Embassy asynchronous framework.

The system monitors soil moisture and environmental conditions, including temperature, relative humidity, and atmospheric pressure. When the measured soil moisture drops below a configured threshold and the water reservoir is not empty, the system activates a small 5V water pump for a controlled interval. A reservoir level sensor prevents the pump from running dry. Local status is shown on an SSD1306 display, while live measurements and manual watering control are exposed through a Wi-Fi-based browser interface.

The network part of the project uses an ESP32-class Wi-Fi module as an external Wi-Fi coprocessor connected to the STM32 over UART. This avoids the need for a LAN cable during the presentation and makes the project easier to demonstrate in a real environment. The Wi-Fi module can either connect to an existing network, such as a phone hotspot, or expose a local access point that allows a phone or laptop to connect directly to the PlantGuard Node.

Motivation

I chose this project because plant care is a practical problem where embedded systems can provide clear value. Manual watering is often inconsistent and based on estimation, which can lead to both underwatering and overwatering. PlantGuard Node solves this by using measured soil and environmental data instead of guesswork.

From an engineering perspective, the project combines multiple embedded topics in one coherent system: analog sensing through ADC, digital sensor communication over I2C, UART communication with an external Wi-Fi coprocessor, GPIO-based actuation, local display rendering, and asynchronous task coordination in Rust. The change from Ethernet to Wi-Fi also makes the project more realistic for a live demo, because the system can be presented without depending on wired LAN infrastructure. It can be powered, connected from a phone or laptop, and demonstrated as a standalone smart plant-care node.

The project also has a small but important safety aspect: the pump must not run when the reservoir is empty. For that reason, the watering control logic always checks the tank level sensor before activating the pump.

Architecture

Main software and system components:

  • Sensor Acquisition Module: periodically reads the capacitive soil moisture sensor through ADC and the BME280 environmental sensor over I2C.
  • Reservoir Safety Module: reads the float switch or water level sensor and reports whether the water reservoir is available or empty.
  • Shared Application State: stores the latest soil moisture, temperature, humidity, pressure, reservoir state, pump state, Wi-Fi state, and fault status.
  • Watering Control Module: compares soil moisture against a configured threshold and activates the pump only when watering is needed and the reservoir contains water.
  • Pump Driver Module: controls the 5V mini water pump through a logic-level N-channel MOSFET and protects the microcontroller side from direct motor current.
  • Display Module: renders live measurements and system status on the SSD1306 display using embedded graphics.
  • Wi-Fi Communication Module: communicates with the ESP32 Wi-Fi coprocessor over UART and exchanges live measurements, pump state, warnings, and manual control commands.
  • Web Control Interface: provides a simple browser-accessible interface for reading live values and triggering manual watering.
  • Alert Module: drives a status LED and optional buzzer for local indication of normal, watering, warning, or fault states.
  • Timing and Scheduling Layer: uses Embassy tasks and timers to run sensor sampling, display updates, pump control, UART communication, and command handling concurrently.

The planned communication split is:

  • STM32 NUCLEO-U545RE-Q: real-time embedded controller, sensor acquisition, watering decision, pump safety logic, local display.
  • ESP32 Wi-Fi module: wireless connectivity, browser-accessible web page, HTTP/WebSocket-style interface or simple TCP/serial bridge.
  • UART link: structured data exchange between STM32 and ESP32.

This split keeps the safety-critical part on the STM32 and lets the ESP32 handle Wi-Fi, which is a more complex and less deterministic communication subsystem.

How components connect:

                         +--------------------------------+
| Phone / Laptop Browser |
| Live Data + Manual Watering |
+---------------^----------------+
|
| Wi-Fi
|
+---------------+----------------+
| ESP32 Wi-Fi Module |
| AP Mode / Station Mode |
| Web Interface / Serial Bridge |
+---------------^----------------+
|
| UART
|
+------------------+ ADC +-----+------+
| Capacitive Soil |-------------> | |
| Moisture Sensor | | |
+------------------+ | |
| |
+------------------+ I2C | |
| BME280 Sensor |<------------->| |
| Temp/Hum/Press | | |
+------------------+ | |
| |
+------------------+ I2C | STM32 |
| SSD1306 Display |<------------->| NUCLEO- |
| Local Status | | U545RE-Q |
+------------------+ | |
| |
+------------------+ GPIO IN | |
| Tank Level |-------------> | |
| Sensor / Switch | | |
+------------------+ | |
| |
+------------------+ GPIO OUT | |
| Status LED |<------------- | |
+------------------+ | |
| |
+------------------+ GPIO OUT | |
| Optional Buzzer |<------------- | |
+------------------+ | |
+-----+------+
|
| GPIO OUT
v
+----------+----------+
| Logic-Level |
| N-Channel MOSFET |
+----------+----------+
|
| Switched 5V pump current
v
+------------------+ +-------------+-------------+ +------------------+
| External 5V PSU |----->| 5V Mini Water Pump |----->| Tube to Plant |
| Pump Supply | | Flyback Diode Protection | | Soil |
+------------------+ +---------------------------+ +------------------+

Control flow:

Sensor Task
|
| reads ADC + I2C sensors
v
Shared Application State
|
+--> Display Task -> SSD1306 local status
|
+--> Wi-Fi UART Task -> ESP32 -> Browser interface
|
+--> Control Task
|
| if soil is dry AND reservoir is not empty
v
Pump Driver Task
|
| activates pump for limited interval
v
Stabilization Delay
|
v
Re-check soil moisture

Wi-Fi communication flow:

Browser
|
| HTTP request / Web UI action
v
ESP32 Wi-Fi Module
|
| UART command, for example:
| GET_STATE
| WATER_NOW
| SET_THRESHOLD=45
v
STM32 NUCLEO-U545RE-Q
|
| UART response, for example:
| STATE,soil=38,temp=24.1,hum=51,press=1008,tank=OK,pump=OFF
v
ESP32 Wi-Fi Module
|
| updates browser page
v
Browser

The pump is never driven directly from a microcontroller pin. The STM32 GPIO controls only the MOSFET gate. The pump uses an external 5V supply, and the flyback diode protects the switching circuit from inductive voltage spikes generated when the motor is turned off.

Log

Week 5 - 11 May

  • Finalized the PlantGuard Node project idea and defined the main functional requirements.
  • Selected the STM32 NUCLEO-U545RE-Q as the main controller.
  • Chose the core peripherals: capacitive soil moisture sensor, BME280 environmental sensor, SSD1306 display, ESP32 Wi-Fi module, water level sensor, and 5V pump.
  • Replaced the original Ethernet-based communication plan with a Wi-Fi-based approach to make the project easier to demonstrate without a LAN cable.
  • Defined the first version of the system architecture and separated the project into sensing, control, display, Wi-Fi communication, and actuation modules.
  • Studied the required peripheral interfaces: ADC for soil moisture, I2C for BME280/SSD1306, UART for the ESP32 Wi-Fi module, and GPIO for pump, LED, buzzer, and tank level sensing.

Week 12 - 18 May

  • Planned the hardware wiring and power separation between the STM32 board, the ESP32 Wi-Fi module, and the external 5V pump supply.
  • Designed the pump switching circuit using a logic-level N-channel MOSFET and a flyback diode.
  • Planned the UART communication protocol between the STM32 and the ESP32 module.
  • Planned the shared application state structure for sensor values, pump state, threshold configuration, Wi-Fi status, and fault status.
  • Started firmware structure planning with separate Embassy tasks for sensor sampling, display refresh, pump control, UART communication, and command processing.
  • Defined the automatic watering algorithm: read soil moisture, compare with threshold, check tank level, activate pump for a fixed interval, wait for stabilization, then re-check.

Week 19 - 25 May

  • Planned the first bring-up tests for each hardware block independently.
  • Prepared the expected test order: GPIO LED test, ADC soil sensor test, I2C BME280 test, I2C SSD1306 display test, UART ESP32 communication test, Wi-Fi browser interface test, then pump MOSFET test with external power.
  • Planned the local display layout for showing soil moisture, temperature, humidity, pressure, pump state, reservoir status, and Wi-Fi connection state.
  • Planned the Wi-Fi browser interface with live readings and a manual watering command.
  • Defined safety behavior for the empty reservoir condition: disable pump activation, show a warning locally, and report the fault through Wi-Fi.
  • Planned a fallback demo mode where the ESP32 creates its own Wi-Fi access point, allowing a phone or laptop to connect directly to the PlantGuard Node without relying on classroom network access.

Hardware

The hardware platform is based on the STM32 NUCLEO-U545RE-Q development board. The system reads soil moisture using an analog capacitive sensor connected to an ADC input. Environmental data is acquired from a BME280 sensor over I2C. A small SSD1306 OLED display shares the I2C bus and provides local system feedback.

Wi-Fi connectivity is provided by an ESP32-class module connected to the STM32 over UART. This module is responsible for wireless communication and the browser-accessible interface. The STM32 remains responsible for sensor acquisition, pump control, safety checks, and local status display.

The watering actuator is a 5V mini water pump controlled through a logic-level N-channel MOSFET. The pump is powered from an external 5V supply, not directly from the STM32 board. A flyback diode is placed across the pump terminals for inductive load protection. A float switch or water level sensor is used as a GPIO input to detect an empty reservoir and prevent unsafe pump operation.

Schematics

STM32 NUCLEO-U545RE-QMain ControllerRust + EmbassyCapacitive SoilMoisture SensorADCBME280Temp / Hum / PressureI2CSSD1306 OLEDLocal DisplayI2CTank Level SensorFloat SwitchGPIO INESP32 Wi-Fi ModuleAP / Station ModeWeb UI / Serial BridgeUART TX/RXPhone / LaptopBrowser InterfaceWi-FiStatus LED + BuzzerGPIO OUTLogic-LevelN-MOSFET DriverGPIO OUT5V Mini Water Pumpswitched 5VExternal 5V PSUPump Power5V + GNDFlyback diode across pumpLocal Button OptionalGPIO IN

Bill of Materials

DeviceUsagePrice
STM32 NUCLEO-U545RE-QMain microcontroller development board~125 RON
ESP32-C3 / ESP32-WROOM Wi-Fi ModuleWi-Fi coprocessor for browser interface and wireless monitoring~25 RON
Capacitive Soil Moisture SensorMeasures soil moisture through ADC~10 RON
BME280 Environmental Sensor ModuleMeasures temperature, humidity, and pressure over I2C~25 RON
SSD1306 OLED DisplayLocal display for measurements and system state~20 RON
5V Mini Water PumpWatering actuator~20 RON
Logic-Level N-Channel MOSFETSwitches pump current from GPIO control~5 RON
Flyback DiodeProtects switching circuit from pump inductive kickback~1 RON
Float Switch / Water Level SensorDetects empty water reservoir~10 RON
Status LED + ResistorLocal visual system indication~2 RON
Buzzer Module (optional)Acoustic warning for empty reservoir or fault state~5 RON
BreadboardPrototype assembly~15 RON
Jumper WiresElectrical connections between modules~10 RON
External 5V Power SupplySeparate supply for pump current~25 RON
Tubing for Water DeliveryCarries water from pump to plant~10 RON
Small Water Container / ReservoirStores water for the pump~10 RON
Misc. Connectors and Mounting MaterialsIntegration and mechanical support~20 RON

Estimated total: ~338 RON

The prices are approximate component estimates and will be updated until the project is finalized.

Software

Library / ToolDescriptionUsage
embassy-executorAsynchronous embedded task executorRuns concurrent firmware tasks such as sensing, display, UART communication, and pump control
embassy-stm32STM32 hardware abstraction layerAccess to ADC, I2C, UART, GPIO, interrupts, DMA, and clocks on the STM32U545RE-Q
embassy-timeEmbassy timers and delaysPeriodic sensor sampling, pump activation interval, stabilization delay, and display refresh timing
embassy-syncSynchronization primitivesShared application state between asynchronous tasks
embedded-halCommon embedded HAL traitsHardware abstraction for drivers and peripheral access
embedded-hal-asyncAsync embedded HAL traitsAsynchronous I2C/UART-style driver interfaces where supported
embedded-io-asyncAsync I/O traitsUART stream abstraction for communication with the ESP32 module
heaplessFixed-capacity collections for no_std RustBuffers, strings, and command frames without dynamic allocation
defmtEmbedded logging frameworkCompact firmware logs during development and debugging
defmt-rttRTT transport for defmt logsSends debug logs from the target board to the host
panic-probePanic handler for embedded debuggingReports panics during firmware development
ssd1306SSD1306 OLED display driverControls the local OLED display over I2C
embedded-graphics2D graphics library for embedded displaysRenders text, values, and status indicators on the SSD1306 display
bme280BME280-compatible Rust sensor driverReads temperature, humidity, and atmospheric pressure over I2C
static-cellSafe static initialization helperStores long-lived Embassy driver state without a heap
portable-atomicAtomic operations support for embedded targetsUseful dependency for some async/shared-state embedded crates
cortex-mLow-level Cortex-M supportCore ARM Cortex-M functionality
cortex-m-rtCortex-M runtimeStartup/runtime support for bare-metal Rust firmware
ESP32 AT firmware or custom ESP32 firmwareWi-Fi-side firmwareProvides AP/station mode, browser interface, and UART bridge to STM32
Simple UART text protocolApplication protocol between STM32 and ESP32Transfers state updates and commands such as GET_STATE, WATER_NOW, and SET_THRESHOLD

The previous Ethernet-specific items are intentionally removed:

  • W5500 Ethernet module is replaced by an ESP32 Wi-Fi module.
  • SPI W5500 communication is replaced by UART communication.
  • embassy-net-wiznet is removed because it is specific to Wiznet Ethernet controllers.
  • embassy-net is no longer mandatory on the STM32 side if the ESP32 handles the Wi-Fi and web server. The STM32 can remain focused on deterministic sensing, control, and UART communication.
  1. Embassy framework
  2. Embassy GitHub repository
  3. STM32 NUCLEO-U545RE-Q product page
  4. Espressif ESP32 Modules
  5. ESP-AT Firmware Documentation
  6. BME280 Environmental Sensor
  7. SSD1306 OLED Display Datasheet
  8. embedded-graphics documentation
  9. Rust Embedded Book
  10. Capacitive Soil Moisture Sensor Reference
  11. Mini Water Pump Reference