Embedded Systems Debugging with AI: 14 Prompts for STM32, ESP32, and Arduino That Save Hours (and Boards)
Embedded development is unforgiving: a wrong register bit, a floating pin, or a missing pull-up can cost you a day and a burned MCU. Datasheets run 1000+ pages, errata sheets hide critical bugs, and oscilloscope traces don't explain themselves. Meanwhile, AI models like GPT-4, Claude 3.5, and Gemini 1.5 have read more reference manuals than any human ever will — but they hallucinate register addresses and confuse SPI modes. The trick is knowing which prompts work and where to double-check.
This guide is a battle-tested collection of 14 prompts for STM32, ESP32, and Arduino workflows. Each prompt includes the exact text to copy, a usage example, and a reality check. I've used these on real projects — from a BLE sensor node to a Modbus gateway — and they cut debugging time from hours to minutes. But I've also seen AI invent a non-existent HAL_I2C_Master_Transmit_DMA() variant. So treat every output as a draft, not gospel.
Before we dive in: always verify against official sources. STM32 reference manuals (RM0008, RM0433), ESP-IDF docs, and Arduino core sources are the ground truth. AI accelerates, but you sign off on the schematic.
1. Datasheet-to-Register Decoder
Task: Extracting register configurations from a 900-page reference manual without losing your mind.
Prompt:
You are an embedded systems engineer. I'm working with STM32F411 (RM0383). I need to configure TIM2 in PWM mode on channel 1, 1 kHz, 50% duty, clocked from APB1 at 50 MHz. Provide: (1) exact register sequence with addresses, (2) C code using CMSIS, (3) timer calculation formula, (4) common pitfalls. Cite section numbers from RM0383.
Example output snippet:
// PSC = 0, ARR = 49999 for 1 kHz at 50 MHz
TIM2->PSC = 0;
TIM2->ARR = 49999;
TIM2->CCR1 = 25000; // 50% duty
TIM2->CCMR1 |= (6 << 4); // PWM mode 1
TIM2->CCER |= 1; // Enable CH1
TIM2->CR1 |= 1; // Enable timer
Reality check: AI often gets the PWM mode bits right but forgets BDTR for advanced timers (TIM1/TIM8). Always cross-check with the reference manual.
2. I2C Bus Hang Debugger
Task: Diagnosing a stuck I2C bus (SDA held low) on STM32 or ESP32.
Prompt:
My STM32F4 I2C1 hangs after a sensor read. SDA is stuck low, SCL is high. The sensor is a BME280 at 0x76. I'm using HAL_I2C_Mem_Read. List: (1) root causes ranked by probability, (2) recovery sequence in C (bit-banging 9 clocks), (3) how to add timeout and bus reset, (4) preventive measures.
Example recovery code:
void i2c_bus_recover(void) {
GPIO_InitTypeDef gpio = {0};
// Configure SCL as open-drain output
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6 | GPIO_PIN_7);
gpio.Pin = GPIO_PIN_6;
gpio.Mode = GPIO_MODE_OUTPUT_OD;
gpio.Pull = GPIO_NOPULL;
gpio.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOB, &gpio);
for (int i = 0; i < 9; i++) {
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET);
delay_us(5);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);
delay_us(5);
}
// Re-init I2C peripheral
}
Reality check: The 9-clock recovery is standard (see NXP UM10204 I2C-bus specification). AI sometimes suggests toggling SDA instead of SCL — wrong.
3. SPI Mode Confusion Resolver
Task: Matching SPI mode (CPOL/CPHA) between MCU and peripheral.
Prompt:
I have an STM32L4 talking to an ADXL345 accelerometer via SPI. The ADXL345 datasheet says "SPI mode 3" but my scope shows data shifted by one bit. Explain CPOL/CPHA combinations, show how to set SPI mode 3 in STM32 HAL, and list 3 symptoms of wrong mode with fixes.
Example:
hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH;
hspi1.Init.CLKPhase = SPI_PHASE_2EDGE;
Reality check: ADXL345 actually supports SPI mode 3 and mode 0 depending on CS timing. AI may oversimplify — check the sensor's timing diagram.
4. UART Framing Error Analyzer
Task: Debugging UART garbage output (baud rate mismatch, framing errors).
Prompt:
My ESP32 UART2 receives garbage from a Modbus RTU device at 9600 8N1. I see framing errors in the log. List: (1) top 5 causes, (2) how to measure actual baud with a scope, (3) ESP-IDF code to set 9600 8N1 with proper GPIO matrix routing, (4) how to add CRC validation for Modbus.
Example code:
uart_config_t cfg = {
.baud_rate = 9600,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
};
uart_param_config(UART_NUM_2, &cfg);
uart_set_pin(UART_NUM_2, 17, 16, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
Reality check: Modbus RTU requires 3.5-character silence between frames. AI often forgets this — add it manually.
5. Power Consumption Optimizer
Task: Reducing average current on battery-powered STM32/ESP32 nodes.
Prompt:
My STM32L051 sensor node draws 2 mA average, target is 50 µA. It wakes every 10s, reads BME280 over I2C, transmits via LoRa. List: (1) power reduction steps ranked by impact, (2) code for STOP mode with RTC wakeup, (3) which peripherals to disable, (4) how to measure with a µCurrent.
Example low-power snippet:
HAL_SuspendTick();
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
SystemClock_Config(); // Reconfigure after wake
HAL_ResumeTick();
Reality check: ESP32 deep sleep is ~10 µA, but Wi-Fi wake costs ~100 mA for seconds. AI may suggest unrealistic numbers — verify with datasheet.
6. RTOS Task Priority Advisor
Task: Designing FreeRTOS task priorities and stack sizes.
Prompt:
I'm building a FreeRTOS app on ESP32-S3 with tasks: sensor_read (100 Hz), ble_tx (event-driven), display_update (10 Hz), logger (low priority). Suggest priorities, stack sizes, and IPC (queues vs semaphores). Show code for task creation and a queue between sensor and BLE.
Example:
xTaskCreatePinnedToCore(sensor_task, "sensor", 4096, NULL, 5, NULL, 0);
xTaskCreatePinnedToCore(ble_task, "ble", 8192, NULL, 4, NULL, 1);
Reality check: Stack sizes depend on library usage. AI estimates are rough — use uxTaskGetStackHighWaterMark() to verify.
7. Errata Sheet Interpreter
Task: Finding relevant silicon bugs before they bite.
Prompt:
For STM32F103 (popular "Blue Pill"), list the top 5 errata that affect I2C, ADC, and USB. For each: describe symptom, workaround, and code snippet. Cite the errata sheet ES096.
Example: Errata "I2C analog filter may provide wrong value" — workaround: disable analog filter or use digital filter.
Reality check: Always download the latest errata from st.com. AI may reference older revisions.
8. Oscilloscope Trace Explainer
Task: Interpreting a waveform screenshot described in text.
Prompt:
I see on my scope: SPI CLK at 1 MHz, MOSI data changes on rising edge, but MISO is flat. CS is low. The slave is an MCP3008 ADC. List probable causes and how to verify each with a scope.
Reality check: AI can't see your screen. Describe precisely: voltage levels, timing, noise.
9. Arduino Library Compatibility Checker
Task: Resolving library conflicts on ESP32/Arduino.
Prompt:
I'm using Arduino IDE with ESP32 core 3.0.0. Libraries: Adafruit_BME280, WiFi, PubSubClient. Compilation fails with "multiple definition of Wire". Explain cause and fix (include library versions).
Reality check: ESP32 core 3.x migrated to ESP-IDF 5, breaking many libs. Check GitHub issues.
10. Bootloader and Flash Layout Planner
Task: Designing partition tables for OTA updates.
Prompt:
For ESP32 with 4 MB flash, I need OTA updates, SPIFFS for config, and a factory partition. Provide a partition table CSV and explain each offset and size. Include code to trigger OTA via HTTP.
Example CSV:
# Name, Type, SubType, Offset, Size
nvs, data, nvs, 0x9000, 0x4000
otadata, data, ota, 0xd000, 0x2000
app0, app, ota_0, 0x10000, 0x140000
app1, app, ota_1, 0x150000,0x140000
spiffs, data, spiffs, 0x290000,0x160000
Reality check: Offsets must be 4 KB aligned. AI sometimes misaligns.
11. Sensor Fusion Math Tutor
Task: Implementing Madgwick or Kalman filter on MCU.
Prompt:
Explain how to implement a Madgwick filter on STM32F4 for MPU6050 at 100 Hz. Provide C code (float), explain quaternion update, and how to tune beta. Include I2C read function for raw data.
Reality check: Floating-point on M4 is fast, but on M0 use fixed-point. AI may ignore this.
12. Modbus/CAN Protocol Generator
Task: Building protocol frames quickly.
Prompt:
Generate C structs and functions for Modbus RTU master reading holding registers from slave 0x01, function 0x03. Include CRC16 calculation and a test vector (slave 1, start 0, qty 2 → response bytes).
Example CRC:
uint16_t crc16(uint8_t *buf, int len) {
uint16_t crc = 0xFFFF;
for (int i = 0; i < len; i++) {
crc ^= buf[i];
for (int j = 0; j < 8; j++)
crc = (crc & 1) ? (crc >> 1) ^ 0xA001 : crc >> 1;
}
return crc;
}
Reality check: Modbus CRC is little-endian on wire. AI often swaps bytes.
13. Hardware Schematic Reviewer
Task: Catching design errors before PCB fabrication.
Prompt:
Review this schematic description for an STM32F4 + W5500 Ethernet + USB: [list connections]. Check: pull-ups on I2C, decoupling caps, crystal load caps, BOOT0, USB series resistors. Flag issues.
Reality check: AI can't see the actual schematic. Provide netlist text or detailed description.
14. Unit Test Generator for Embedded C
Task: Adding tests without hardware.
Prompt:
Generate Unity tests for a ring buffer implementation in C (init, push, pop, full, empty). Mock hardware dependencies. Provide CMake setup for host build.
Example test:
void test_ring_buffer_push_pop(void) {
ring_t rb; ring_init(&rb);
ring_push(&rb, 42);
TEST_ASSERT_EQUAL(42, ring_pop(&rb));
}
Reality check: Unity is real (ThrowTheSwitch). AI knows it well.
Where AI Fails (and You Must Verify)
- Register addresses: Always check the reference manual. AI hallucinates offsets.
- Timing diagrams: AI can't read them. You must.
- Errata: Only official sheets matter. AI may cite obsolete revisions.
- Power numbers: Datasheet conditions vary. AI gives typical, not worst-case.
- Library versions: APIs change. Pin versions in your prompt.
Conclusion
AI won't replace your oscilloscope or your brain, but it will save you hours on datasheet archaeology, boilerplate code, and protocol math. Use these 14 prompts as a starting toolkit, always verify against official docs (RM0008, ESP-IDF, Arduino core), and keep a scope handy. The best embedded engineers in 2026 aren't the ones who memorize every register — they're the ones who ask the right questions and validate the answers. Start with prompt #2 on your next I2C hang, and you'll never debug alone again.
Comments