Embedded Project
LoRa Greenhouse Monitoring System
In this project, I designed and deployed an IoT monitoring system to collect, transmit, store, and visualize environmental data from a remote greenhouse using long-range, low-power wireless communication.
This system integrates embedded firmware, LoRa radio communication, a data ingestion pipeline, a web-based monitoring dashboard, and is automated to run automatically on boot/reboot.
Key Features and Technologies Used
- Programmed two ESP32-S3 microcontroller boards (Heltec WiFi LoRa 32 V3) in C++ to read DHT22 sensor data, transmit, and receive the data over a LoRa radio, providing real-time temperature and humidity readings
- Built a Python ingestion service that reads serial data from the receiver and stores it in SQLite.
- Developed a web dashboard using Flask and Chart.js for real-time monitoring, including time-series visualizations and an alert classification system
- Automated deployment using systemd services on a Raspberry Pi 5, ensuring automatic startup on boot/reboot
- Exposed the dashboard publicly using secure tunneling with Tailscale Funnel
System Diagram
Embedded Sensor Sender
Using a Heltec WiFi LoRa 32 V3 board (containing ESP32-S3 microcontroller and LoRa radio) connected to a DHT22 temperature and humidity sensor, I built:
- C++ firmware using Arduino
- a sensor reading loop
- OLED display output
- LoRa packet transmission
This node is stationed in the greenhouse to send environmental readings. Example transmitted packet (node, temperature, humidity):
GH0,73.2,49.3
Receiver
A second Heltec board acts as the receiver.
- receives LoRa packets
- displayes received data on its OLED
- outputs structured data to the Raspberry Pi
Example output:
Received from GH0: GH0,73.2,49.3 | RSSI: -25
3D Printing the Heltec Cases
Using simon.muzi’s (muzi.works) 3D model “H1 - Case for Heltec V3 running Meshtastic,” I printed cases for both boards, drilling a hole in the back of the case for the sender to make room for the sensor.
Data Ingestion
On a Raspberry Pi 5, I built a Python ingestion service that:
- reads serial data continuously from the receiver
- parses messages into structured values
- timestamps each reading
- inserts records into SQLite
Web Dashboard
Using Flask and Chart.js, I built a dashboard to visualize and monitor the data.
- Latest reading panel
- time-series charts with color-coded zones for readability (normal, warning, and critical temperatures).
- Alerting classification and alert history panel
Accessing the Dashboard
To make the dashboard accessible outside the local network, I used Tailscale Funnel to securely expose the dashboard over HTTPS, allowing remote access when off-site.
Deployment and Automation
To ensure the system operates continuously, I created systemd service unit files for both the ingestion service and the dashboard, as well as running the Tailscale Funnel in the background. This allows the system to automatically start on boot, restart if a service crashes, and run without manual intervention.
Running Tailscale Funnel in background:
sudo tailscale funnel --bg localhost:5000
greenhouse-ingest.service (also very similar to greenhouse-dashboard.service):
[Unit]
Description=Greenhouse Ingestion Service
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=teletraanx
WorkingDirectory=/home/teletraanx/greenhouse-monitor
ExecStart=/home/teletraanx/greenhouse-monitor/venv/bin/python /home/teletraanx/greenhouse-monitor/ingest.py
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
Open Source Contribution
Developed LoRa-based sensor communication examples (DHT22) and submitted an open-source contribution to ropg’s heltec_esp32_lora_v3 repo, including debugging and resolving OLED initialization issues on Heltec ESP32 LoRa v3 hardware.
Future Improvements and Expansion
- Email alerting
- Multi-node/greenhouse support
- More sensors and readings!