Daniel sent us this one — he's building a parking spot presence sensor with an ESP32, planning to run it off a single 18650 cell because there's no mains power in the parking space. He wants to know if it's viable, and he's asking us to walk through the actual mathematics step by step, using credible numbers, so he can decide whether this thing runs for weeks or dies in two days. I love this question because it's exactly the moment every hobbyist hits — you've got the idea, you've got the parts, and then you stare at the battery and realize you have no idea how to even start the calculation.
The forums are no help. One guy says five years, another guy says his died overnight, and neither of them shows their work. So let's start where everyone starts — staring at a 18650 cell and a datasheet, wondering where to even begin.
The four-step framework Daniel outlined is exactly right. Find the sleep current, find the active and transmit currents, estimate the duty cycle, compute the average daily draw, then divide into the usable battery capacity. The framework is sound. It's the numbers people plug in that are usually wrong.
That's the whole episode right there — the framework versus the numbers. So let me lay out the three power states we're dealing with. First, deep sleep. The ESP32 is mostly asleep, waking only to check a timer. Second, active sensing — the ultrasonic sensor fires a ping, the ESP32 processes the return. Third, LoRaWAN transmission — the radio powers up, sends a packet, listens for a downlink. Those three states have wildly different current draws, and the whole game is weighting them by how much time the device spends in each one.
The trap is that the sleep current number is tiny, so people assume it doesn't matter, but the device spends almost all its time asleep. A small error there gets multiplied across twenty-four hours a day, three hundred sixty-five days a year. Meanwhile the transmit current is huge, but it happens for one and a half seconds at a time. So you have to get both right.
Let's start with the datasheet numbers, because you need a baseline before you can derate anything. ESP32 deep sleep, with the RTC memory retained so you can wake on a timer — Espressif's typical figure is ten microamps. That's the chip itself. The HC-SR04 ultrasonic sensor draws about fifteen milliamps when it's actively pinging, and the ping itself lasts about fifty milliseconds. If you leave the sensor powered between pings, it pulls roughly two milliamps in standby, but a smarter design cuts power to the sensor entirely between readings — use a MOSFET or a GPIO pin to switch it, and that standby current goes to zero.
The smart design is: sensor is off between pings, ESP32 wakes, powers the sensor, pings, reads, powers the sensor down, goes back to sleep. That way the sensor only costs you current during those fifty-millisecond windows.
Then the LoRaWAN module — an RFM95 or SX1276, which is what most of these projects use. Transmitting at plus twenty dBm, which is the maximum power setting and what you'd want for a parking garage, draws about a hundred twenty milliamps. The packet transmission takes roughly one and a half seconds. After transmitting, the module opens a receive window to listen for a downlink from the gateway — that's about ten milliamps for half a second. Two receive windows if you're using LoRaWAN class A, which is standard. So each transmission event is one point five seconds at a hundred twenty milliamps, plus one second total of receive windows at ten milliamps.
How often is it transmitting?
Daniel said maybe once every couple of days. Let's be conservative and say four times a day — once every six hours. That's enough to report status changes without being excessive. For the ultrasonic pings, the question is how often you need to check. A car doesn't appear or disappear in seconds. Checking once every five minutes is plenty — that's two hundred eighty-eight pings per day.
Now we do the math. And this is where I want you to walk through the unit conversions, because this is the part that trips people up. Milliamps times milliseconds doesn't give you milliamp-hours unless you convert the time units properly.
This is the single most useful thing we'll say today. When you're calculating battery life, you need everything in milliamp-hours. Current is in milliamps, time is in hours. If your event lasts milliseconds, you convert milliseconds to hours by dividing by three point six million — that's a thousand milliseconds per second times thirty-six hundred seconds per hour. Or you can think of it as dividing by thirty-six hundred to get to seconds, then by another thousand. Either way, the conversion factor from milliseconds to hours is one over three point six million.
Walk through one ping.
One ultrasonic ping. Fifteen milliamps for fifty milliseconds. Fifteen times fifty, divided by three point six million. That's seven hundred fifty divided by three point six million, which is zero point zero zero zero two zero eight milliamp-hours per ping. It's a comically small number. Multiply by two hundred eighty-eight pings per day, and you get zero point zero six milliamp-hours per day for the ultrasonic sensor. That's the active sensing budget.
The LoRaWAN transmit?
Four transmissions per day. Each one is a hundred twenty milliamps for one point five seconds, but we need seconds converted to hours. One point five seconds divided by thirty-six hundred is zero point zero zero zero four one seven hours. So each transmission is a hundred twenty times zero point zero zero zero four one seven — that's zero point zero five milliamp-hours per transmission. Four per day gives us zero point two milliamp-hours per day. The receive windows are four events times ten milliamps times one second total per event, converted to hours — that's four times ten times zero point zero zero zero two seven eight, which is zero point zero one one milliamp-hours per day. Tiny, but we'll include it for completeness.
Then the deep sleep, which is the big one because it runs constantly.
Ten microamps is zero point zero one milliamps. Running for twenty-four hours, that's zero point zero one times twenty-four, which is zero point two four milliamp-hours per day. So let's sum the spreadsheet-perfect numbers. Ultrasonic: zero point zero six. LoRa transmit: zero point two. LoRa receive: zero point zero one one. Deep sleep: zero point two four. Total daily draw: roughly zero point five one milliamp-hours per day. That's the number your spreadsheet gives you, and it's beautiful and wrong.
That's the moment where you lean back and think, my three thousand milliamp-hour battery will last five thousand eight hundred days, which is sixteen years, and I am a genius.
Then your device dies in three weeks and you're on the forum posting "what happened to my battery life." So let's add the first layer of reality. Your 18650 cell outputs a nominal three point seven volts, but it actually ranges from four point two volts fully charged down to about three volts empty. Your ESP32 and sensors want three point three volts. You need a voltage regulator. If you use a linear regulator — an LDO, low dropout regulator — the efficiency is basically the output voltage divided by the input voltage. At three point seven volts in and three point three out, that's about eighty-nine percent. The other eleven percent is burned as heat. So your zero point five one milliamp-hours drawn by the circuit actually requires zero point five one divided by zero point eight nine, which is zero point five seven milliamp-hours from the battery.
Not a huge hit, but it's real. And it gets worse as the battery voltage drops — at three point three volts in, the LDO can't even regulate properly, and below that the system browns out. So you can't use the full capacity of the cell anyway.
Right, which brings us to the battery capacity derating. A three thousand milliamp-hour 18650 cell — and that's a quality cell like a Samsung or Panasonic, not a no-name with an optimistic label — should never be discharged below three point zero volts. Going lower damages the cell permanently, and the voltage drops off a cliff below about three point two volts anyway. The usable capacity between four point two and three point zero volts is typically about eighty percent of the rated capacity. So your three thousand milliamp-hour cell is really a twenty-four hundred milliamp-hour cell in practice. At zero point five seven milliamp-hours per day, your runtime is twenty-four hundred divided by zero point five seven, which is about forty-two hundred days. That's still over eleven years. And that's still wrong.
Far we've got a spreadsheet that says this thing runs for over a decade. And every builder listening knows that's absurd. So where does the spreadsheet actually break?
The first break is the deep sleep current. I said ten microamps — that's the ESP32 chip itself, the bare silicon, under ideal lab conditions. But you're not using bare silicon. You're using a dev board, and dev boards have voltage regulators, USB-to-UART bridges, power LEDs, pull-up resistors. All of those draw current even when the ESP32 is in deep sleep. A typical ESP32 dev board — the kind you buy for five dollars on the internet — can draw anywhere from fifty to a hundred fifty microamps in deep sleep, not ten. I've measured boards that draw five milliamps in so-called sleep because the USB chip never powers down.
The sleep current isn't ten microamps. It might be a hundred. That's a factor of ten right there.
That alone takes your daily sleep budget from zero point two four milliamp-hours to two point four. Suddenly your total daily draw is closer to two point seven milliamp-hours, and your runtime drops from eleven years to about two and a half years. Still not bad, but we're not done.
This is where Daniel's skepticism about LoRaWAN actually working in a parking garage becomes directly relevant to the battery math.
It's the killer variable. LoRaWAN at eight hundred sixty-eight or nine hundred fifteen megahertz does not like reinforced concrete. The rebar mesh in concrete floors and walls acts as a Faraday cage — not a perfect one, but enough to attenuate the signal by twenty to thirty dB. If your parking sensor is in an underground garage, the gateway might be on a different floor, with multiple slabs of concrete and rebar between them. The link budget might be marginal. And when the link budget is marginal, packets get lost. LoRaWAN uses confirmed transmissions for important data — the device sends a packet, then listens for an acknowledgment. If it doesn't get one, it retransmits, usually at a lower data rate, which means a longer airtime, which means more current per attempt.
Retransmissions multiply your transmit budget. If half your packets need a retry, your daily transmit current goes from zero point two milliamp-hours to zero point three or zero point four. If the coverage is really bad and you're retrying two or three times per transmission, it could easily be zero point five to one milliamp-hour per day just for the radio.
There's another subtlety. When the signal is marginal, the LoRaWAN module might switch to a lower data rate — say from spreading factor seven to spreading factor twelve. At SF12, the same payload takes about twenty-five times longer to transmit. A packet that took fifty milliseconds at SF7 might take over a second at SF12. Your transmit current is the same — a hundred twenty milliamps — but it's flowing for much longer. So a single transmission in poor conditions could cost you zero point zero three milliamp-hours instead of zero point zero five. It doesn't sound like much, but multiply by retransmissions and it adds up.
Let's build the pessimistic scenario. Assume a dev board that draws eighty microamps in deep sleep — that's realistic for a board with a decent LDO and the USB chip disabled. Assume six transmissions per day instead of four, accounting for a fifty percent retransmission rate. And assume the battery capacity is further derated by temperature — if this parking spot gets cold in winter, and I'm guessing it does, battery capacity drops about twenty percent at freezing compared to room temperature.
Let's run those numbers. Deep sleep at eighty microamps: zero point zero eight milliamps times twenty-four hours is one point nine two milliamp-hours per day. Ultrasonic pings unchanged at zero point zero six. LoRa transmit at six events, zero point zero five each, is zero point three. Receive windows at six times zero point zero zero three is zero point zero one eight. Total daily draw: about two point three milliamp-hours per day. Battery capacity: three thousand milliamp-hours times seventy percent — that's eighty percent for usable voltage range, then another hit for temperature and aging, so let's call it twenty-one hundred usable milliamp-hours. Runtime: twenty-one hundred divided by two point three is about nine hundred thirteen days, or two and a half years.
Two and a half years is actually great. That's a viable project. But the margin is thinner than people think, and a few bad assumptions can collapse it.
The nightmare scenario is the underground concrete parking garage with the gateway three floors up. Deep sleep at a hundred fifty microamps because it's a cheap board. Retransmissions pushing you to ten or twelve transmission attempts per day, some at SF12. Now your daily draw might be five to eight milliamp-hours. With a cold battery at seventy percent capacity, your runtime is twenty-one hundred divided by six, which is three hundred fifty days. Still almost a year, but now you're in the territory where a particularly cold winter or a battery that's a few years old and has higher self-discharge pushes you below six months.
Self-discharge is the silent killer that nobody accounts for. A quality 18650 loses three to five percent of its charge per month just sitting there. Over a year, that's thirty-six to sixty percent of the capacity gone without doing any useful work. In a multi-year deployment, self-discharge can dominate the power budget.
If your device draws two milliamp-hours per day, that's about seven hundred thirty milliamp-hours per year for the circuit. But the battery is also losing maybe a hundred fifty milliamp-hours per year to self-discharge. It's not negligible, and in very low-power designs, it can be the largest single consumer.
What do you actually do about all this? Because the point isn't to scare people out of building things. The point is to build things that work.
The single most important thing you can do is measure. Before you commit to a final design, put a multimeter in series with your actual board and measure the deep sleep current. Not the ESP32 chip — your actual board, with whatever regulator and peripherals are on it. You might find it draws fifteen microamps, and you're golden. You might find it draws five milliamps, and you need to desolder the power LED and the USB-UART bridge, or switch to a bare ESP32 module without all the dev board cruft.
That's the thing — a bare ESP32-WROOM module on a custom board, with a good LDO and no USB chip, can genuinely hit that ten to fifteen microamp sleep current. The chip isn't lying to you. The dev board is.
The second thing is design for adaptive behavior. Daniel mentioned the sensor could just flash a local LED if the LoRaWAN doesn't work, and that's actually a great power-saving strategy. If the car presence state hasn't changed, don't transmit. If you've been checking every five minutes and the car has been there for six hours, you don't need to tell the gateway again. Only transmit on state change, or at most once a day as a heartbeat. That could cut your daily transmissions from four to less than one on average.
Unless you live somewhere where cars come and go constantly. But even then, a parking spot typically sees maybe two to four state changes per day. You're not transmitting every time you ping.
You can stretch the ping interval. Five minutes is conservative. Ten minutes is still more than fast enough for a parking sensor — you're not going to walk to your car, get in, and drive away in less than ten minutes. At one ping every ten minutes, you halve the ultrasonic power budget. It's already tiny, but every bit helps when you're chasing years of runtime.
There's also the hardware choices. An ESP32 module with an external antenna connector — a U.FL or IPEX connector — gives you a few dB better link budget than a PCB trace antenna. In a marginal coverage situation, those few dB might be the difference between a clean transmission at SF7 and a retry at SF12. The antenna gain directly translates to battery life.
If you're designing a board from scratch, use a buck converter instead of a linear regulator. A buck converter can be eighty-five to ninety-five percent efficient across the whole battery voltage range, versus an LDO that gets worse as the battery voltage drops. The quiescent current of a good buck converter might be a few tens of microamps, which is higher than a good LDO's quiescent current, but the improved efficiency under load often more than makes up for it. You have to run the numbers for your specific duty cycle.
Let's talk about the spreadsheet. The framework Daniel should build — and anyone listening should build — has three columns. Optimistic, realistic, pessimistic. The optimistic column uses datasheet numbers and ideal conditions. The realistic column uses measured sleep current, a reasonable retransmission rate, and eighty percent battery capacity. The pessimistic column uses worst-case sleep current, worst-case retransmissions, cold temperature derating, and aging.
The rule of thumb is: if the pessimistic column gives you a runtime that meets your minimum requirement, build it with confidence. If only the optimistic column works, you're going to be disappointed. If the realistic column works but the pessimistic column doesn't, you have a judgment call — and you should probably add a way to charge the battery or swap it easily.
For Daniel's parking sensor, the realistic numbers suggest two to three years of runtime, and even the pessimistic case with poor LoRaWAN coverage gives you close to a year. That's viable. That's worth building. The key is to build the local logic first — the ultrasonic sensor and the LED indicator — get that running on battery, measure the actual current draw, and then layer on the LoRaWAN as a bonus. That way, even if the network piece fails or costs more power than expected, you still have a useful device.
That's the fallback-first design philosophy. It's not just good engineering, it's good psychology. You get a win early — a working parking sensor with a local indicator — and then you can iterate on the connectivity without the pressure of the whole project depending on it.
The other thing I'd add is that if you're running the device for years, you need to think about battery replacement. An 18650 holder that lets you swap the cell without desoldering is worth the extra couple of dollars. And if the parking spot gets any ambient light, even a tiny solar panel — like a one-watt panel — changes the entire calculus. A one-watt panel in indirect light might give you fifty to a hundred milliwatts for a few hours a day. That's tens of milliamp-hours per day, which is an order of magnitude more than the device draws.
Solar takes you from "can it survive" to "can it run indefinitely," which is a much more interesting question. But that's a whole other episode — you've got maximum power point tracking, charge controllers, battery chemistry considerations for float charging. It's a deep rabbit hole.
The math we walked through today isn't hard. It's just tedious. Unit conversions, duty cycle estimates, derating factors. But running those numbers before you solder saves you from the particular heartbreak of building something clever, installing it, and watching it die in a week because you trusted the datasheet sleep current.
The numbers are all there in the datasheets. Ten microamps for the ESP32 chip. Fifteen milliamps for the HC-SR04 ping. A hundred twenty milliamps for the LoRaWAN transmit. The framework is: weight each current by how long it flows per day, sum them, divide into your derated battery capacity. The art is knowing which numbers to derate and by how much.
Measure your actual board. Design for the pessimistic case. Build the local logic first. And if you do all that, your parking sensor will probably outlast your car.
Now: Hilbert's daily fun fact.
Hilbert: In the 1780s, a French naturalist proposed that the rightful kings of Madagascar could be identified by their ability to balance a lemur on their head during the coronation ceremony — the theory being that the true sovereign emitted a unique animal-calming magnetism. The theory was published in a Parisian scientific journal and debated seriously for nearly a decade before anyone thought to actually test it.
I have so many questions, and I'm not sure I want answers to any of them.
The lemur vetoed the whole thing, presumably.
What happens when you add solar charging to the 18650 — does a small one-watt panel change the calculus from "can it survive" to "can it run indefinitely"? That's a question worth its own episode, and if listeners want that, let us know. For now, the takeaway is simple. The math isn't mysterious. Run it before you build, measure what you actually built, and design for the world as it is, not as the datasheet promises.
This has been My Weird Prompts. Thanks to our producer Hilbert Flumingtop. If you enjoyed this episode, tell someone who's ever stared at a battery and a datasheet and wondered where to start. Email the show at show at my weird prompts dot com.
Go build something that lasts.