I2C Sensor Data to MQTT

MCU: ESP32-WROOM-32-N4

Code can be found here for Adafruit STEMMA Soil Sensor. Code can be found here for Adafruit Si7021 Humidity & Temp Sensor.

I’ve combined these two projects into one post, because they are essentially doing the same thing, just for different sensors. The point of this project was to help automate my indoor gardening system, and ensure that when I traveled my plants would no longer die.

I wanted two different sensors for two different purposes: 1) A humidity sensor that would measure the level of humidity in my apartment. When it dropped below a certain level, the humidifier would be turned on. This would help ensure plant health, and also my health in avoiding dry air. 2) A soil moisture sensor that would measure the volumetric water content in the soil. This would be used to automate watering of the plant when the soil got below a certain level. Luckily, Adafruit sold both of these sensors and they were in stock at my local Micro Center! So I went ahead and made a purchase.

After buying these sensors, I initially wired them up to the ESP32 on a breadboard, and used the pre-written Arduino code to test whether my physical wiring abilities were working as expected. This was mainly to rule out any wiring errors so that I wouldn’t have to debug this later on, saving me the trouble. Once that was sorted out, it was code implementation time.

I’ll be honest–I had a hard time figuring out next steps. I was at a crossroads between two different approaches:

1) Automate locally using embedded logic alone. This path would have deepened my hands-on experience with soldering and low-level hardware control, and it was the direction I initially planned to take purely for the learning opportunity. However, as I continued researching, I began to question whether this was the best long-term implementation. Having only worked with bare-metal code, I looked into reverse-engineering Adafruit’s Arduino C++ abstractions. I dug into how Arduino handles I²C, starting with Wire.h and working down to twi.h, even considering reusing the TWI layer directly. The experience revealed just how deep the abstraction stack really was. Beyond complexity, reproducibility became a concern. If I added another plant to the garden, I’d have to rework the embedded logic. I couldn’t help but think–there’s got to be a better option than this, leading to my next approach:

2) Automate using a Home Assistant server. This option offered greater long-term reliability and scalability. Adding more plants would simply involve introducing new devices wired identically and running the same code, making future expansion straightforward. I’d also get to experiment with IoT concepts, and use the ESP32 devices I already had lying around to their advantage. Plus, I’d be able to check humidity and soil sensor stats on my phone, which was honestly very convenient.

As I researched further, I realized I could pair this approach with ESP-IDF, allowing me to work closer to the hardware without reinventing everything from scratch. Reviewing the ESP-IDF APIs and documentation made me realize I had been overcomplicating the problem. This approach aligned naturally with the Home Assistant architecture, supported scalability, and still allowed me to deepen my understanding of IoT systems. It also gave me the opportunity to finally build a Home Assistant server—something I had been wanting to do for a while.

With the direction clear, I moved forward with implementation. I chose TAPO smart plugs for the Home Assistant automation setup due to their reliability and ease of integration. I then deployed a Home Assistant server on my local network using Proxmox, which turned out to be relatively straightforward following an existing installation (guide)[https://community.home-assistant.io/t/installing-home-assistant-os-using-proxmox-8/201835]. I’m so grateful for the internet!

With the server ready, I began writing firmware using ESP-IDF and discovered PlatformIO as an alternative to the Arduino IDE. Its tooling and workflow were a clear improvement, and I don’t see myself going back. Access to clear ESP32 documentation and ESP-IDF APIs also made it significantly easier to develop the project and understand how the individual code segments fit together. With tutorials and online resources, I was able to figure it out and get it working (after various days of debugging, as any project calls for)!

Through the project, I learned:

Now that my code works, it’s onto the next step, which is to design a more portable system, either through 3d printing a case or designing my own PCB for the ESP32 & sensors (no more breadboard!). This definitely opens up a whole new can of worms, but I’m sure I’ll learn a lot and have fun along the way :)

A lot of helpful documentation I used:

MQTT & Home Assistant ESP-IDF MQTT Example ESP32 MQTT Client Tutorial Home Assistant MQTT Sensor Configuration MQTT Broker Set Up via Home Assistant

Wifi ESP-IDF Wifi Station Example

I2C ESP-IDF I2C Example

Si7021 I2C Protocol - SI7021 Example Adafruit Si7021 Docs

STEMMA Soil Sensor Adafruit Seesaw I2C Driver Adafruit Seesaw Docs

Other ESP32 PlatformIO Configurations