Key takeaway: IC1 should hold ~3.3 V for light loads deep into AA discharge, but high-current WiFi bursts become risky below ~0.9–1.0 V because the boost converter can hit current limit and VOUT collapses.
Keep in mind that in code I set wifi power to lowest level WIFI_POWER_8_5dBm. Wifi Connect last about 2500ms in average. also do not forget about C2, C4 and C5
Now update the graph
Updated the graph/document with WIFI_POWER_8_5dBm, the ~2500 ms WiFi connect duration, and C2/C4/C5 energy contribution: TPS613221A VOUT vs AA Battery Voltage.
Key change: the relevant low-power WiFi curves are now 75–100 mA; C2/C4 help only with short transients (~0.065 ms at 100 mA), so the 2.5 s connect window is dominated by AA cell loaded voltage, not capacitor storage.
— and there are more clips and build photos on the project's Photos & Videos page.
This project started with a weather forecast and a bad feeling.
I live near the High Tatras, and the wind here is not a polite, leaf-rustling affair. When a strong gust lines up with heavy rain — which happens more often than I'd like — an open window stops being a minor oversight and becomes water sheeting across the floor, a soaked sill, and a cleanup that eats a weekend. The worst part is the timing: it always seems to happen when nobody's home to notice the one window someone left cracked open that morning.
Image
Image
Image
So the brief was easy to state, if not to build: a small, battery-powered sensor that knows whether a window is open or closed and can tell me over WiFi — so that "window still open, storm rolling in, house empty" becomes a notification on my phone instead of a discovery when I get back.
The sensing idea is almost romantically low-tech. A reed switch is two thin metal blades sealed in a glass tube; bring a magnet close and they snap together, take it away and they spring apart. Mount the reed on the window frame and the magnet on the sash, and "is the window open?" reduces to "are these two blades touching?" No power, no chip, just physics. The brain is an ESP32-C3-MINI-1 — a thumbnail-sized module with a 2.4 GHz radio — whose entire job is to sleep almost all the time, wake the instant the reed changes, shout the news over the network, and drop straight back to sleep.
"Easy to state" and "easy to build" are different sentences, though, and the gap between them is where all the interesting engineering hides. Here's what it actually took — including the bug that had the thing cheerfully reporting "closed" while sleeping straight through every "open."
I designed the whole board in Flux, an AI-assisted electronics design tool, and the thing that changed most about how I worked wasn't drawing the schematic — it was that the hard trade-offs stopped being guesses. Every time I hit a "which is better?" fork, its copilot could generate an actual analysis to argue with, and a surprising number of the decisions below got settled on numbers instead of instinct. I've linked those analyses where they come up.
The smallest battery that still lasts months
The constraint I set myself was deliberately annoying: use the smallest battery I reasonably could, but get many months out of it. A sensor you have to recharge every few weeks is a sensor you stop trusting, and a fat battery pack defeats the point of something that should hide discreetly on a window frame.
My first instinct was a AAA cell — tiny, cheap, everywhere.
Image
But when Flux ran the current budget, AAA didn't survive scrutiny. For a realistically used window at around ten open/close cycles a day, the modeling landed somewhere in the two-to-four-month range, and worse, a AAA's ability to deliver the sharp current spikes a WiFi radio demands is thin. So I moved up one size to AA, and redoing the budget for the bigger cell told a far better story. That single step roughly doubles the lifetime — the same usage now models out to about four to eight months, and a rarely-touched window can stretch past a year — and, just as importantly, the bigger cell holds its voltage far better when the radio yanks current during a transmit.
The other half of "squeeze every drop out of a tiny battery" is the power chip. A fresh AA gives about 1.5 volts and sags toward 0.9 V as it tires, but the ESP32-C3 wants a steady 3.3 V. A boost converter — I used a TPS613221A — bridges that gap, stepping the voltage up and holding the rail rock-steady even as the cell fades. This particular part keeps working with its input all the way down to 0.9 V, and limps along even lower after startup, which means it drains the cell nearly empty before giving up rather than declaring a half-used battery "dead." Add it all up and the board idles at roughly eleven microamps — the current it takes to essentially not exist — which is what makes the months-long lifetime possible in the first place.
There's one more battery-saving choice worth flagging, because it comes back to bite me later: the resistor that holds the reed input at a known voltage is a deliberately enormous 1 MΩ. That value came straight out of a low-power reed analysis Flux generated, which weighed pull-up options from 100 kΩ all the way up to 4.7 MΩ — a weak resistor like this wastes almost no current even when the reed is closed, about three microamps instead of the thirty-plus a more conventional value would burn. That same analysis is also why the reed sits on one of the chip's wake-capable pins rather than an ordinary one. It was the right call for battery life. It was also, it turns out, the seed of the most frustrating bug in the build.
The chip that vanished a week before production
There's a particular heartbreak unique to hardware. You finish the layout — every track routed, every part placed, the board done — and then you go to actually order it, and the brain of the whole thing is out of stock with no restock date.
That's what happened with my first choice of radio module, an ESP8684-WROOM-02C. It's Espressif's budget Wi-Fi-and-Bluetooth part, and on paper it was the leaner pick for a minimal sensor: cheaper, and — the part I cared about — it sips a little less current on transmit than its bigger siblings. But "unobtainable" beats "theoretically optimal" every time, so I swapped it for an ESP32-C3.
The C3 is the safer, better-supported part — more memory, more pins, native USB, and a far broader ecosystem of examples to lean on — so in most respects it was an upgrade. But the swap wasn't free. The new module has a different footprint and pinout, which meant re-doing the layout I'd just finished. And the C3 pulls noticeably more current during a Wi-Fi transmit — enough to quietly tighten the very battery and brownout margins I was about to go to war with. It also, as I'd discover later, came with a wake-up quirk all its own, waiting patiently for me.
One AA cell, one big ask
Sleeping is the easy part. The problem is the half-second when the radio turns on.
A WiFi transmit burst is brutally hungry. At the antenna the radio can pull around 300 milliamps, and because a boost converter multiplies current as it steps voltage up, a tired AA can momentarily be asked for well over an amp — close to 1.1 A even on a fresh cell, and approaching 1.8 A as the battery nears empty. The converter's own current limit sits right in that neighborhood, somewhere between 0.75 and 1.6 A. In other words, high-power transmits on a weak battery live dangerously close to the edge, and the first few test reports proved it: the rail sagged mid-transmit, the chip detected a brownout, and it reset in the middle of its own sentence.
There's no single clever fix, just discipline — keep the radio on for as little time as possible, turn the transmit power down to the lowest level that still reaches the router, put generous capacitors on the output to act as a reservoir for the burst, and switch WiFi fully off before sleeping. Death by a thousand microamps is a real budget, and so is survival of each individual gulp.
The spec that wrote the firmware
Here's the part that still feels a little like cheating. Before I could debug firmware, I needed firmware — and I didn't start from a blank file. Flux generated a firmware technical requirements document straight from the design: the exact GPIO each function lives on, the reed's active-low polarity, the LED's common-anode wiring, the deep-sleep wake strategy, the boost converter's current limits — even the known gotchas of the specific chip and the exact library versions. It reads less like documentation and more like a brief written for whoever's about to write the code.
So that's what I did with it. I handed the whole document to an AI coding assistant and asked it to turn the spec into firmware. What came back compiled, flashed, and mostly ran on the first pass: the reed logic, the WiFi and BLE reporting paths, the sleep-and-wake state machine, all scaffolded from a specification the design tool had derived from my own schematic. The bugs in the rest of this article are the remaining twenty percent — the physical-world surprises no spec can fully predict. The first eighty percent, the part that used to be hours of boilerplate, came from the hardware describing itself.
That's a loop I didn't have available a year ago: the design tool understands the board well enough to explain it, precisely, to another machine — and between them, the two get me most of the way to working code. The result — the firmware and its companion server — is published in full on the project's Firmware & Server Code page.
Getting code onto it (the flashing dance)
Having working firmware is one thing; getting it onto the board is another — and here the board fought me too. There's deliberately no USB port; programming happens through a six-pin header and an external USB-to-serial adapter, which keeps the board small and cheap but removes all the convenience.
The first upload died with A fatal error occurred: ... No serial data received — frustrating, because the serial monitor was clearly showing the chip's startup messages. That contradiction was the clue: if I could read the chip but the uploader couldn't talk to it, the problem was one direction of the conversation, not the whole link. The cure was half unglamorous housekeeping — close every program holding the serial port, drop the upload speed to a more forgiving 115200 baud — and half the manual "download dance" a header-only board needs: hold BOOT, tap reset, start the upload, release BOOT once it connects. Flux's copilot helped me corner this one too — it pointed out that being able to read the chip only proved one direction of the link, and put the adapter's transmit line at the top of the suspect list.
The bug that only woke up in one direction
Then came the strange one — the bug worth the whole article.
With the sensor asleep, I'd slide a magnet up to the reed and the monitor would dutifully print a "closed" event. Perfect. Then I'd pull the magnet away, and... nothing. No "open." The chip slept right through it. Magnet back: instant "closed." Magnet away: silence. One direction worked flawlessly; the exact opposite may as well not have existed.
When a bug is that asymmetric, it's telling you something specific. The sensor wakes on a voltage level: when the window is closed it waits for the pin to go HIGH (open); when open, it waits for LOW (closed). LOW woke it; HIGH didn't.
The culprit was a helpful default fighting my hardware. To wake cleanly on a HIGH signal, the ESP32-C3 quietly switches on an internal pull-down resistor — roughly 10 kΩ to ground — so the pin has a tidy "low" to rest at until the real signal arrives. Sensible, unless your board already has its own pull-up on that pin. And mine did: that deliberately enormous 1 MΩ I'd chosen to save battery.
Now picture the tug-of-war. A 10 kΩ rope pulling the pin toward ground against a 1,000 kΩ rope pulling it toward 3.3 V. It isn't close. Even with the reed fully open, the pin sat at about 0.4 volts — nowhere near high enough to count as HIGH. The chip was patiently waiting for a signal that, electrically, could never arrive. The LOW direction worked because that wake mode adds an internal pull-up, which cooperates with the external one, and the reed shorting to ground sails past the threshold.
The fix, once the cause was clear, was small: tell the chip to keep its hands off that pin's resistors and "hold" the pad in that state through sleep, so the board's own 1 MΩ is the only thing setting the level. A few lines of code, and both directions woke instantly. But the lesson stuck — the very resistor I'd picked to stretch battery life was the thing that broke the wake-up. The datasheet and the schematic each made perfect sense alone. They simply disagreed about who owned that pin.
Where it landed
On the network side, the sensor stays humble. It fires a small, plain message to a tiny server running on an always-on machine at home — a few lines of code that log every event and can forward a push to my phone. Keeping the heavy encryption work off the battery and on the mains-powered server is the whole trick: the sensor does the cheap part and sleeps; the server does the expensive part and never runs out of power. It's also where the original purpose finally closes the loop — the server is the natural place to combine "this window is open" with "the forecast says wind and rain," so the alert only fires when it actually matters.
The hardware got its final form, too: a compact 3D-printed snap-fit enclosure — a base the board clicks into, a lid, and a separate matching holder for the magnet that mounts on the moving sash. No screws, no glue; the case snaps shut over the board and the AA slides in like it was always meant to live there. The magnet holder solves the unglamorous-but-critical mechanical problem of this whole product category: the magnet has to land in the same spot relative to the reed switch every single time the window closes, or none of the electronics matter.
Image
The payoff is a contact sensor that should run for a span measured in months on a single replaceable AA — the runtime report puts a normal window comfortably past half a year and a quiet one well over a year — from a board small enough to tuck onto a frame. There's headroom still on the table, too: a WiFi-versus-BLE comparison Flux worked up shows that reporting to a nearby Bluetooth hub instead of WiFi could stretch the same AA from months into years — roughly eight to eleven times longer — which is where this design goes next. None of which looked hard on paper. The reed switch is a century-old idea, the radio is a commodity, and the real lifetime limit probably isn't running out of stored energy at all — it's surviving each WiFi burst on an old, cold cell.
Almost every fork in this project got settled the same way — not by intuition, but by asking Flux to run the numbers. AAA or AA. Which radio module. WiFi or BLE. How weak the reed pull-up could safely go. The board is small and the parts are ordinary, but the reasoning behind them was made on evidence rather than hunches — and honestly, that's the part I'd most likely have gotten wrong on my own.
One project, open to anyone
Something worth pausing on: all of this — the schematic, the PCB layout, every analysis document I've linked, the firmware spec, the enclosure, the whole design — lives in one place. Flux keeps the electrical schematic, the board layout, and a Files tab full of documentation and mechanical files together in a single browser project. There's no scattering of design files across a schematic tool, a separate PCB package, a GitHub repo, and a Google Drive folder somewhere. It's all hosted together and it all points at the same source of truth — which is precisely why the firmware spec could be generated from the design in the first place, instead of drifting out of sync with it.
And I've made the entire project public — open to view, clone, and fork. That effectively makes it open-source hardware. Anyone can open it, generate the manufacturing outputs themselves — Gerbers, bill of materials, pick-and-place files — and order the identical board from a fab, with no permission and no file-wrangling. Or they can clone it, swap the AA holder for a coin cell, drop in a different sensor, re-run the current budget for their own use case, print their own enclosure, and make it theirs. If you want to build this exact sensor, I don't have to send you anything; the link to the project is the handoff.
That combination is what I keep coming back to — design, documentation, an AI-ready firmware spec, and a one-click path to an orderable, forkable board, with a copilot sitting across all of it that can run a current budget or chase a flashing bug on request. It's most of the reason a project this small ended up with this much rigor behind it. Powerful is the right word for it.
That's the quiet truth about "simple" hardware: the schematic is the easy 80%. The last 20% is a magnet, a stubborn pin, a boost converter at the edge of its limits — and, somewhere out past the Tatras, a window I'll now actually know about before the rain finds it.
A compact battery-powered door/window sensor built around the ESP32-C3-MINI-1-N4 module. The design uses a single non-rechargeable AA cell with a TPS613221A 3.3 V boost regulator, reed switch magnetic contact sensing, low-power wake/report/sleep firmware strategy, RGB status LED for setup feedback, BOOT/EN controls, programming header, and input polarity protection. It is intended for smart-home security and automation applications, supporting WiFi or Bluetooth LE hub reporting with emphasis on low idle current, reliable RF burst power delivery, and field-replaceable battery operation. #ESP32-C3 #BLE#WiFi#DoorSensor#WindowSensor#ReedSwitch#LowPower#BatteryPowered#SmartHome#IoT