Story
The hardware choice was obvious: ESP32. It gives us BLE, WiFi, deep sleep modes, and enough GPIOs to handle multiple sensors — all on a chip that costs under $5 in volume.
Here’s how we built it, what we learned, and why you might want to **hire ESP32 developer** for your next IoT project instead of wrestling with this yourself.
The Hardware Stack
Our BOM was straightforward:
- ESP32-WROOM-32 as the main MCU
- BME280 sensor for temperature (±1°C), humidity (±3% RH), and pressure (±1 hPa)
- CR2032 coin cell battery (we wanted to see how low we could push power consumption)
- 3D-printed enclosure (we designed it in Fusion 360, printed on a Bambu Lab X1)
The BME280 communicates over I2C. We used the default address 0x76, pulled SDA to GPIO21 and SCL to GPIO22. No level shifting needed — the BME280 runs at 3.3V natively.
Firmware Architecture
We wrote the firmware in C using ESP-IDF v5.1. No Arduino libraries — we wanted direct control over BLE advertising intervals and sleep cycles.
The core loop:
```c
void app_main() {
bme280_init();
ble_init();
while(1) {
read_sensor_data();
update_ble_characteristics();
esp_deep_sleep(30000000); // 30 seconds
}
}
```
The BLE GATT server exposes three characteristics under a custom service UUID: temperature (2 bytes, signed integer scaled by 100), humidity (2 bytes, unsigned integer scaled by 100), and pressure (4 bytes, unsigned integer in Pascals). We set the BLE advertising interval to 100ms — fast enough for responsive app updates, slow enough to keep power draw reasonable.
Power Optimization: What Actually Worked
We tested three configurations:
1. No sleep, continuous BLE advertising — battery lasted 4 hours
2. Deep sleep with 30-second wake cycle — battery lasted 11 days
3. Deep sleep + RTC memory + sensor power gating — battery lasted 23 days
The trick was power-gating the BME280. We connected its VDD pin to GPIO26 and pulled it low during deep sleep. The BME280 draws 3.6 µA in sleep mode, but with the power rail cut entirely, that drops to zero. We also disabled the ESP32 internal pull-ups on the I2C lines and used external 4.7kΩ resistors instead — the internal ones add about 45 µA per pin.
The Elecrow PCB Design
For the production run, we designed a custom PCB through Elecrow. The board is 40mm x 30mm, 2-layer, with ENIG finish. Key design decisions:
- Castellated holes on the edge for the BME280 module — saves space and eliminates a connector
- 0.5mm trace width for power lines, 0.3mm for signals
- Ground plane on bottom layer with thermal reliefs on the battery pad
- No antenna tuning required — the ESP32 module has its own ceramic antenna
We routed the BLE antenna trace with a 50-ohm impedance match using KiCad's built-in calculator. The trace is 1.2mm wide on a 1.6mm FR4 board with 0.035mm copper thickness. That's a standard 50-ohm microstrip on 4.5 dielectric constant material.
BLE Connection Stability
During testing, we noticed that the BLE connection would drop after about 3 minutes of no data transmission. That's expected — the ESP32's BLE stack goes into a power-saving mode after 30 seconds of inactivity. We fixed it by sending a keepalive notification every 10 seconds, even when sensor data hadn't changed. The payload is just a single byte (0x00) that the app ignores, but it keeps the connection alive.
We also set the BLE connection interval to 30ms with a slave latency of 4. That means the ESP32 can skip up to 4 connection events (120ms) before the master assumes the connection is dead. This gives us more flexibility in scheduling sensor reads without losing the link.
Why You Might Want to Hire ESP32 Developer
This project seems simple on paper — read a sensor, send data over BLE. But the details matter. Power optimization alone took us three iterations. The BLE stack on ESP32 has quirks: the advertising data length is limited to 31 bytes, the connection parameters need careful tuning for battery life, and the deep sleep wake-up sources can be finicky if you don't map them correctly.
If you're building a production IoT device, the difference between a prototype that works for an hour and a product that runs for weeks is in the firmware and hardware integration. That's where experience pays off. When you **hire ESP32 developer** from a team that's shipped dozens of BLE products, you skip the trial-and-error phase.
We shipped 500 units of this weather station to a client in the UK. The final cost per unit was $4.80 in components and $1.20 for the Elecrow PCB. Assembly was done in-house with a reflow oven — about 15 minutes per board for a single operator.
Where We'd Improve Next Time
If we were doing this again, we'd use the ESP32-C3 instead of the original ESP32. It's cheaper ($1.50 vs $2.80), has a built-in RISC-V core that's more power-efficient, and supports BLE 5.0. The C3 also has a dedicated low-power coprocessor that can handle BLE advertising while the main core sleeps — something the original ESP32 can't do cleanly.
We'd also add a DS3231 RTC for timestamping sensor data. The ESP32's internal RTC drifts by about 5 seconds per day, which adds up over a month-long deployment. The DS3231 is accurate to ±2ppm — about 1 second per month.
And we'd switch to **Matter** instead of raw BLE for the next revision. Matter over BLE gives us a standardized data model that works with Apple HomeKit, Google Home, and Amazon Alexa out of the box. No custom app required. The ESP32-C3 supports Matter natively through the ESP-Matter SDK.
Final Thoughts
The ESP32 is a workhorse for BLE sensor projects. It's cheap, well-documented, and the toolchain (ESP-IDF) is mature. But the difference between a working prototype and a shippable product is in the details — power gating, BLE parameter tuning, PCB layout for antenna performance.
If you need to get from concept to production quickly, hire ESP32 developer who's already been through the debugging process. Our team has done this exact project for clients in agriculture, smart home, and industrial monitoring. We know where the traps are, and we know how to avoid them.
The weather station we built is now deployed in 12 greenhouses across the Netherlands, sending data every 30 seconds over BLE to a Raspberry Pi gateway. The batteries last 28 days in real-world conditions. That's the difference between hobbyist code and production firmware.




