Exhibit F
UBC AgroBot
Embedded systems work on UBC's autonomous hydroponics engineering team -- IoT sensor network, MQTT communication, and a time-series observability stack.
- C++
- Raspberry Pi
- ESP32
- MQTT
- QuestDB
- Grafana
- Linux
Why I joined
Most of my projects up to this point had been pure software. I wanted to work with actual hardware for once, and UBC’s engineering design teams seemed like the right way to do that without waiting for a course to cover it. AgroBot had an automation subteam that sat right at the intersection of hardware and software, which felt like a natural fit.
What the team is building
AgroBot is building a fully autonomous hydroponic system. The team has three subteams: automation, structure, and plants. The structure team handles the physical enclosure and water system; the plants team runs experiments on crop growth. The automation subteam is what connects those pieces. Without it you just have a box of water and some plants. With it, the system can monitor itself, keep conditions within range, and give the rest of the team data to make decisions with.
The IoT backbone
The core of the automation system is a Raspberry Pi running Linux, which acts as the central hub. Around it are several ESP32 microcontrollers placed throughout the hydroponic setup, each reading sensor data: temperature, humidity, water levels, and other plant variables.
Getting these devices talking reliably took some thought about protocol choice. HTTP would work in theory, but for a sensor network where multiple devices are publishing readings frequently, it’s the wrong fit. Every HTTP request opens a connection, sends data, and closes the connection. Do that dozens of times per second across several sensors and you’re wasting a lot of overhead on connection management.
MQTT is designed for exactly this kind of network. It uses a publish-subscribe model: each ESP32 publishes its readings to a topic on a central broker, and the Raspberry Pi subscribes to those topics and receives the data. The connection stays open, the messages are small, and the broker handles routing. The communication layer on both ends is written in C++.
Making it observable
Collecting sensor data is only useful if someone can actually read and act on it. Raw readings from a sensor network don’t tell you much on their own. What matters is the trend over time: is the temperature creeping up overnight? Did a pH reading spike after a water top-up? That kind of question needs time-series data, not a single snapshot.
QuestDB stores the stream of incoming readings. It’s purpose-built for time-series workloads, so querying ranges of data by timestamp is fast. Grafana sits on top of it and renders the dashboards the team actually looks at – charts, thresholds, and recent readings for each plant variable.
The last piece was making the dashboards accessible outside the lab. Rather than opening ports or setting up a VPN, I used a Cloudflare tunnel. The tunnel establishes an outbound connection from our machine to Cloudflare’s network and assigns a stable public URL. Anyone on the team can open the dashboard from their laptop or phone, from anywhere, without us exposing the Pi directly to the internet.
Where things stand
The sensor network and observability stack are running. The team can monitor the hydroponic system remotely and the data is being collected continuously. The next phase on the automation side is closing the control loop: using the sensor readings to trigger actuators that actually adjust the system, like dosing nutrients or turning on ventilation, rather than just surfacing the data for humans to act on. That work is ongoing.