It's 1:47 AM. Your ESP32 refuses to appear on the I2C bus, the Serial Monitor prints a wall of rst:0x3 (SW_RESET) lines, and Home Assistant still shows the sensor as unavailable. If you've ever spent three evenings chasing a floating SDA line or a missing Wire.begin() call, you already know the real bottleneck in embedded work isn't the idea — it's the debugging loop. Swapping a logic analyzer for a well-structured prompt doesn't replace your multimeter, but it collapses the time between "it doesn't work" and "here's the line that's wrong."
This collection is written for people who solder more than they type — makers, IoT tinkerers, and firmware engineers running Arduino, ESP32, Raspberry Pi and Home Assistant stacks. Each prompt targets one concrete stage: component selection, sketch generation, interrupt logic, I2C/SPI troubleshooting, MQTT wiring, power profiling, and log triage. The examples are real-shaped problems, not toy demos.
A word on discipline before we start. Treat the model as a fast, slightly overconfident junior engineer: it will hallucinate register names if you let it. Always verify against primary sources — the official Espressif ESP-IDF docs, the Arduino Language Reference, the MQTT 3.1.1 OASIS spec, and the Home Assistant developer documentation. The prompts below are designed to force citations and incremental diffs, which is exactly what keeps a hallucination from burning your afternoon.
1. Component triage before you order anything
Task: Pick a microcontroller + sensor combo against hard constraints (voltage, current, sleep budget).
Prompt:
"I'm building a battery-powered soil-moisture node. Constraints: 3.7V LiPo, must run 6 months on 2000mAh, Wi-Fi reporting every 30 min, one analog sensor, max $12 BOM. Compare ESP32-C3, ESP32-S3, and an ATmega328P + ESP-01 combo. For each: deep-sleep current (cite Espressif/Atmel datasheets), ADC limitations, and whether the ADC is usable with Wi-Fi active. Output a table."
Example result: The model returns a comparison table and correctly flags the classic ESP32 trap — ADC2 is shared with the Wi-Fi radio, so analogRead() on ADC2 pins returns garbage while Wi-Fi is on; use ADC1. That single caveat (documented in Espressif's ADC docs) saves the most common beginner mistake on this exact project.
2. From datasheet to first blink — a scaffolded sketch
Task: Generate a compilable sketch from a plain-language behavior spec.
Prompt:
"Write an Arduino sketch for an ESP32 that reads a DHT22 on GPIO 4 and a pushbutton on GPIO 0 (active-low, internal pull-up), blinks the onboard LED at 1Hz when Wi-Fi is disconnected, and goes solid when connected. Use non-blocking millis() timing — no delay() in loop(). Add a comment block citing the DHT library's required read interval."
Example result: You get a clean loop() with a timing struct, plus the reminder that DHT22 needs ≥2s between reads (per the Aosong AM2302 datasheet). The non-blocking requirement is the key: blocking delay() in loop() is the #1 reason beginners' MQTT heartbeats time out.
3. Interrupts without the classic volatile bug
Task: Get ISR logic right the first time.
Prompt:
"I have a rotary encoder on ESP32 GPIO 34/35 (both input-only). Show me an ISR-based decoder. Explain why the shared counter must be volatile, why I must use IRAM_ATTR, and why Serial.print() inside an ISR is dangerous. Give me the correct attachInterrupt call and a debounce strategy that doesn't block."
Example result: The answer explains that ISRs run in IRAM and any flash-resident function called from one must be marked IRAM_ATTR; that Serial uses interrupts internally and will deadlock or drop data; and it replaces naive delay-debouncing with a timestamp comparison. This is the single most useful prompt for anyone fighting phantom encoder ticks.
4. I2C bus forensics
Task: Diagnose a device that won't enumerate.
Prompt:
"My BME280 doesn't show up on an I2C scan on ESP32 (SDA=21, SCL=22). Walk me through a diagnostic tree: pull-up resistors (what value and why), address conflicts (BME280 is 0x76 or 0x77), voltage levels, and clock stretching. Then give me an Arduino I2C scanner sketch that prints found addresses in hex and flags the reserved ranges."
Example result: You get a checklist and a working scanner. The prompt's value is the why: it explains that I2C needs pull-ups (typically 4.7kΩ) because the lines are open-drain, and that missing pull-ups are the most frequent cause of a silently dead bus. Cross-check addresses against the Bosch BME280 datasheet.
5. SPI vs I2C decision with real numbers
Task: Choose a bus for a display + SD card + sensor combo.
Prompt:
"Compare I2C and SPI for driving a 1.3-inch OLED, an SD card, and an IMU on one ESP32. For each bus give typical max clock (I2C standard/fast mode, SPI on ESP32), number of pins required, and multi-device support via chip-select. Recommend a layout and list the exact GPIOs, avoiding strapping pins and input-only pins."
Example result: A table showing I2C at 100/400kHz (and up to 1MHz in fast-mode-plus) versus ESP32 SPI at tens of MHz, with the pin cost. The model recommends SPI for the display and SD (bandwidth-bound), I2C for the IMU, and warns against using GPIO 6–11 (flash) and 34–39 (input-only).
6. MQTT that survives a flaky router
Task: Write a resilient MQTT publishing loop.
Prompt:
"Write an ESP32 sketch using PubSubClient to publish JSON telemetry to home/sensor1/state every 60s. Requirements: reconnect with exponential backoff, set a Last Will and Testament on home/sensor1/status = offline, use QoS 1, and never block longer than 100ms. Explain the LWT mechanism per the MQTT 3.1.1 spec."
Example result: You get a reconnect routine with backoff and a correctly registered LWT. The LWT detail matters: it's how Home Assistant knows a node died instead of assuming stale data is live. Verify topic semantics against the OASIS MQTT 3.1.1 specification.
7. Home Assistant discovery without hand-editing YAML
Task: Get an ESP node auto-discovered.
Prompt:
"Show me the MQTT discovery payload my ESP32 must publish so Home Assistant auto-creates a temperature sensor entity. Include the homeassistant/sensor/<node>/config topic, the JSON fields (name, state_topic, unit_of_measurement, device_class, unique_id), and a minimal device block. Cite the HA MQTT discovery docs."
Example result: A ready-to-publish config topic. The payoff: no more editing configuration.yaml and restarting HA for every new node. Always confirm field names against the current Home Assistant MQTT discovery documentation, since schema details evolve.
8. Power profiling and sleep budgeting
Task: Hit a 6-month battery target.
Prompt:
"My ESP32 node averages 18mA in deep sleep — way too high. List the usual culprits: onboard USB-serial chip, LDO quiescent current, floating GPIOs, an always-on LED, and Wi-Fi not fully shut down. Give me a measurement plan using a multimeter or INA219 and a checklist to get deep-sleep current under 100µA."
Example result: A prioritized checklist. The honest caveat — many dev boards can't reach true microamp sleep because of the USB-UART bridge and regulator, so real low-power builds often use a bare module. This is where a prompt saves you from buying three boards to learn one lesson.
9. Serial Monitor log triage
Task: Turn a panic dump into a fix.
Prompt:
"Here's my ESP32 crash log: [paste Guru Meditation Error: Core 0 panic'ed (LoadProhibited) with the backtrace]. Decode the exception type, explain what LoadProhibited means, and give me three likely causes in order of probability. Tell me how to symbolize the backtrace with addr2line."
Example result: The model explains that LoadProhibited is a bad memory read (often a null or dangling pointer), ranks causes, and provides the xtensa-esp32-elf-addr2line command to map addresses to source lines — exactly the workflow in Espressif's panic-handling guide.
10. Raspberry Pi as the always-on hub
Task: Wire a Pi into the stack without reinventing MQTT.
Prompt:
"I want a Raspberry Pi 5 to run Mosquitto and Node-RED as the local hub for my ESP32 nodes, bridged to Home Assistant. Give me the install commands, a minimal mosquitto.conf with listener 1883 and allow_anonymous false, and a password-file setup. Explain the bridge config to a cloud broker."
Example result: Concrete shell commands and a config file. The security note — disabling anonymous access and using mosquitto_passwd — is the part most tutorials skip, and it's the difference between a hobby hub and an open relay on your LAN.
11. The rubber-duck review of your whole repo
Task: Catch design smells before they bite.
Prompt:
"Review this project structure [paste tree]. I have one .ino doing Wi-Fi, MQTT, sensor reads and OTA in loop(). Suggest a modular split (separate files/classes), point out blocking calls, and propose an OTA update flow that won't brick the device on a failed flash. Prefer ArduinoOTA with a rollback note."
Example result: A refactor plan splitting transport, sensing, and update concerns, plus an OTA flow with a watchdog. This is the prompt that turns a working prototype into something you can leave running for months.
Where these prompts actually pay off
| Stage | Prompt | Routine it removes |
|---|---|---|
| Selection | #1 | Datasheet cross-checking |
| Coding | #2, #3 | Boilerplate + ISR pitfalls |
| Wiring | #4, #5 | Bus forensics |
| Connectivity | #6, #7 | MQTT/YAML fiddling |
| Power | #8 | Trial-and-error boards |
| Debug | #9, #11 | Log decoding |
The through-line is simple: these prompts don't think for you, they structure the boring parts — the syntax checks, the interrupt flags, the discovery payloads, the power checklists — so your attention stays on the hardware in front of you. Keep your datasheets open, verify every register and topic name, and treat the model as a fast first-pass reviewer rather than an oracle.
If you want to go deeper into prompt-driven embedded and IoT work, the practical guides on asibiont.com/blog extend this into automation, agent workflows, and hands-on build logs. Grab your board, open a Serial Monitor, and start with prompt #9 the next time something panics — your future self at 1:47 AM will thank you.
Comments