
Circuit Debugger
- 165 installs
- 19 repo stars
- Updated May 26, 2026
- wedsamuel1230/arduino-skills
Helps with debugging tasks.
About
circuit-debugger is a Claude Code skill for debugging. It helps solo builders move faster with AI-assisted development.
- circuit-debugger
- Debugging
- AI-coding skill
Circuit Debugger by the numbers
- 165 all-time installs (skills.sh)
- +10 installs in the week ending Jul 27, 2026 (Skillselion tracking)
- Ranked #208 of 596 Debugging skills by installs in the Skillselion catalog
- Data as of Aug 1, 2026 (Skillselion catalog sync)
npx skills add https://github.com/wedsamuel1230/arduino-skills --skill circuit-debuggerAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 165 |
|---|---|
| repo stars | ★ 19 |
| Last updated | May 26, 2026 |
| Repository | wedsamuel1230/arduino-skills ↗ |
What it does
Helps with debugging tasks.
Files
Circuit Debugger
Systematic approach to diagnosing hardware issues in maker projects.
Resources
This skill includes bundled tools and references:
- scripts/generate_debug_sketch.py - Arduino sketch generator for I2C scanner, GPIO tester, ADC checker, PWM tester
- references/measurement-procedures.md - Comprehensive multimeter and oscilloscope guide
Quick Start
Generate I2C scanner:
uv run --no-project scripts/generate_debug_sketch.py --i2c --output i2c_scanner.inoGenerate GPIO tester:
uv run --no-project scripts/generate_debug_sketch.py --gpio --pins 2,3,4,5 --output gpio_test.inoGenerate all debug sketches:
uv run --no-project scripts/generate_debug_sketch.py --allInteractive mode:
uv run --no-project scripts/generate_debug_sketch.py --interactiveTrigger Phrases
- "My circuit doesn't work"
- "Component is getting hot"
- "No power to the board"
- "Sensor not responding"
- "Intermittent/random failures"
- "Works sometimes, not others"
Debugging Protocol
Phase 1: Power System Check (Do First!)
Visual Inspection (30 seconds)
□ Check for smoke, burn marks, or melted plastic
□ Verify power LED on microcontroller is lit
□ Look for loose wires or cold solder joints
□ Confirm correct polarity on polarized components (LEDs, caps, diodes)Multimeter Tests (Set to DC Voltage)
Test Point | Expected Value | If Wrong
------------------------|-----------------|------------------
VCC to GND on MCU | 3.3V or 5V | Check regulator, power source
Sensor VCC pin | Match datasheet | Check wiring, broken trace
Motor driver VCC | Logic + Motor V | Separate supplies needed?
Battery terminals | Rated voltage | Dead/discharged batteryCommon Power Issues:
| Symptom | Likely Cause | Fix |
|---|---|---|
| No voltage anywhere | Disconnected power, blown fuse | Check continuity from source |
| Low voltage (< 4V when expecting 5V) | Overloaded supply, bad regulator | Reduce load, check current draw |
| Voltage drops under load | Undersized power supply | Calculate total current, upgrade PSU |
| Reverse polarity | Swapped wires | Check all connections, may have damaged components |
Phase 2: Ground Continuity
Critical Rule: All grounds must be connected together.
Multimeter: Set to CONTINUITY (beep mode)
Test these pairs - ALL should beep:
□ Arduino GND ↔ Sensor GND
□ Arduino GND ↔ Motor driver GND
□ Arduino GND ↔ Display GND
□ Arduino GND ↔ Power supply negative
□ All breadboard GND rails connectedGround Problems Cause:
- Erratic sensor readings
- I2C/SPI communication failures
- Motors behaving randomly
- Displays showing garbage
Phase 3: Signal Verification
Digital Signals (Set multimeter to DC Voltage)
// Add this debug code to verify pin states
void debugPins() {
Serial.println("=== Pin States ===");
Serial.print("D2: "); Serial.println(digitalRead(2) ? "HIGH" : "LOW");
Serial.print("D3: "); Serial.println(digitalRead(3) ? "HIGH" : "LOW");
// Add more pins as needed
}Expected Readings:
| Signal Type | HIGH | LOW | Floating (Bad!) |
|---|---|---|---|
| 5V Logic | 4.5-5.5V | 0-0.5V | 1-3V unstable |
| 3.3V Logic | 2.8-3.6V | 0-0.3V | 0.8-2V unstable |
I2C Troubleshooting:
// Run this I2C scanner first
#include <Wire.h>
void setup() {
Serial.begin(115200);
Wire.begin();
Serial.println("I2C Scanner");
for (uint8_t addr = 1; addr < 127; addr++) {
Wire.beginTransmission(addr);
if (Wire.endTransmission() == 0) {
Serial.print("Found device at 0x");
Serial.println(addr, HEX);
}
}
}
void loop() {}| I2C Problem | Check |
|---|---|
| No devices found | SDA/SCL swapped? Pull-ups present? Correct address? |
| Address conflict | Two devices same address? Check AD0/AD1 pins |
| Intermittent | Weak pull-ups (try 4.7kΩ), long wires, noise |
Phase 4: Component Isolation
The Divide-and-Conquer Method:
1. Disconnect ALL external components
2. Verify MCU works alone (blink LED)
3. Add ONE component at a time
4. Test after EACH addition
5. When failure occurs, problem is last added componentComponent-Specific Tests:
LEDs:
□ Correct polarity? (long leg = anode = positive)
□ Current limiting resistor present? (330Ω-1kΩ typical)
□ Test LED alone with battery + resistor
□ PWM pin? Try digitalWrite firstMotors/Servos:
□ Never connect directly to MCU pin (use driver!)
□ Separate power supply for motors
□ Flyback diode on DC motors
□ Check stall current vs driver ratingSensors:
□ Correct operating voltage (3.3V vs 5V!)
□ Level shifter needed for mixed voltage?
□ Decoupling capacitor (100nF) near VCC pin
□ Pull-up resistors for I2C (4.7kΩ typical)Phase 5: Software vs Hardware
Quick Software Test:
// Minimal test - does the MCU even run?
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(115200);
Serial.println("MCU is alive!");
}
void loop() {
digitalWrite(LED_BUILTIN, HIGH);
delay(500);
digitalWrite(LED_BUILTIN, LOW);
delay(500);
Serial.println("heartbeat");
}| If This Works | If This Fails |
|---|---|
| Hardware likely OK, check your code | Check USB cable, bootloader, board selection |
Quick Reference: Common Failures
| Symptom | First Check | Second Check | Third Check |
|---|---|---|---|
| Nothing works | Power supply | USB cable | Board selection in IDE |
| Gets hot | Short circuit | Reversed polarity | Overcurrent |
| Works then stops | Power brownout | Overheating | Memory leak |
| Erratic behavior | Floating inputs | Missing grounds | Noise/interference |
| I2C fails | Pull-ups | Address | Wire length |
| Motor jerky | Power supply | PWM frequency | Driver current |
Multimeter Quick Guide
Measurement | Setting | Probes
---------------|--------------|------------------
DC Voltage | V⎓ (20V) | Red=signal, Black=GND
Continuity | ))) or Ω | Either direction
Resistance | Ω | Component out of circuit!
Current | A or mA | IN SERIES (break circuit)When to Ask for Help
If after this protocol you still can't find the issue: 1. Take clear photos of your wiring 2. Draw a schematic (even hand-drawn) 3. List exact components with part numbers 4. Share your complete code 5. Describe what you expected vs what happened
References
- See references/multimeter-guide.md for detailed measurement techniques
- See references/common-mistakes.md for beginner pitfall gallery
{
"name": "circuit-debugger",
"metadata": {
"description": "Systematic hardware debugging guide for Arduino/ESP32/RP2040 circuits. Use when user reports: circuit not working, components getting hot, no power, intermittent failures, unexpected behavior, sensor not responding, LED not lighting, motor not spinning. Guides through power checks, continuity testing, signal tracing, and component isolation using multimeter techniques.",
"version": "0.8.0",
"license": "MIT",
"author": "arduino-skills contributors",
"tags": ["debugging", "hardware-troubleshooting", "electronics", "maker", "testing"],
"category": "maker-tools"
},
"plugins": [
{
"name": "circuit-debugger",
"description": "Systematic approach to diagnosing hardware issues in maker projects using multimeter techniques",
"enabled": true
}
]
}
Common Hardware Mistakes Gallery
Beginner Hall of Fame (We've All Done These!)
1. Reversed LED Polarity
WRONG: CORRECT:
[Short leg]─R─VCC [Long leg]─R─VCC
[Long leg]──GND [Short leg]──GND
Remember: Long leg = Anode = Positive = +
Flat side of LED body = Cathode = Negative = -Symptom: LED doesn't light up Fix: Flip the LED around
2. Missing Current-Limiting Resistor
WRONG (will burn out LED):
GPIO ──────[LED]────── GND
CORRECT:
GPIO ──[330Ω]──[LED]── GNDSymptom: LED very bright then dies, or GPIO pin damaged Fix: Always use 220Ω-1kΩ resistor with LEDs
3. Breadboard Power Rails Not Connected
Many breadboards have SPLIT power rails!
[+]───────── [+]─────────
[-]───────── [-]─────────
↑
GAP HERE - not connected!
Add jumper wire to connect both halvesSymptom: Components on one side work, other side dead Fix: Bridge the gap with jumper wires
4. Wrong Breadboard Row
Component leads must be in DIFFERENT rows:
WRONG (shorted): CORRECT:
A B C D E A B C D E
1 [===LED===] 1 [LED]
2 [LED]
Both legs in row 1 Legs in rows 1 and 2
= short circuit = proper connectionSymptom: Component doesn't work or gets hot Fix: Ensure leads span multiple rows
5. Forgetting Pull-Up Resistors on I2C
I2C REQUIRES pull-ups!
VCC
│
[4.7kΩ]
│
MCU SDA ───┴─── Sensor SDA
(Same for SCL line)Symptom: I2C scanner finds nothing, or intermittent communication Fix: Add 4.7kΩ pull-ups from SDA and SCL to VCC
6. 5V Sensor on 3.3V MCU (or vice versa)
ESP32 is 3.3V logic!
WRONG:
5V sensor ──────────→ ESP32 GPIO
(can damage ESP32!)
CORRECT:
5V sensor ──[Level Shifter]──→ ESP32 GPIOSymptom: Erratic behavior, sensor works briefly then MCU dies Fix: Use level shifter or voltage divider
7. Motor Connected Directly to GPIO
WRONG (will damage MCU):
GPIO ───────[MOTOR]─── GND
↑
Motors need more current
than GPIO can provide!
CORRECT:
GPIO ──[Driver]──[MOTOR]─── Motor Power
│
Separate power supplySymptom: Motor doesn't move, MCU resets, or GPIO burns out Fix: Use motor driver (L298N, TB6612, L293D)
8. Missing Flyback Diode on Inductive Loads
Motors/relays generate voltage spikes when turned off!
CORRECT (with flyback diode):
┌────[DIODE]────┐
│ ← stripe │
└──[MOTOR/RELAY]┘
│ │
Driver GNDSymptom: Random resets, erratic behavior, damaged components Fix: Add flyback diode (1N4001-1N4007) across motor/relay
9. Servo Power from Arduino 5V Pin
WRONG:
Arduino 5V ──→ Servo VCC
(can cause brownouts!)
CORRECT:
External 5V ──→ Servo VCC
└─→ Arduino GND (connect grounds!)Symptom: Servo jitters, Arduino resets, erratic behavior Fix: Use external 5V power supply for servos
10. Floating Input Pins
WRONG:
Button ──────→ GPIO (set as INPUT)
↑
Pin floats when button open
Reads random HIGH/LOW
CORRECT:
VCC
│
[10kΩ] Pull-up
│
Button ───┴──→ GPIO (INPUT)
│
GND
Or use INPUT_PULLUP mode:
pinMode(BUTTON_PIN, INPUT_PULLUP);Symptom: Random triggering, noise-sensitive inputs Fix: Use INPUT_PULLUP or external pull-up/down resistor
Intermediate Mistakes
11. Ground Loops
Multiple ground paths can create noise:
WRONG: CORRECT:
MCU ─┬─ Sensor MCU ────┬─ Sensor
└─ Motor Driver │
└─ Power GND Star ground
all to one pointSymptom: Noisy sensor readings, especially when motors run Fix: Use star grounding, separate analog/digital grounds
12. Inadequate Decoupling Capacitors
Every IC needs decoupling!
VCC
│
[100nF] ← Close to IC!
│
[IC]
│
GNDSymptom: Occasional glitches, communication errors, resets Fix: Add 100nF ceramic capacitor close to every IC's VCC pin
13. Long I2C Wires
I2C is designed for short distances (<30cm)
Long wires = increased capacitance = signal degradation
Solutions:
1. Shorter wires
2. Lower I2C speed (Wire.setClock(100000))
3. Stronger pull-ups (2.2kΩ instead of 4.7kΩ)
4. Use I2C extender chip for long runsSymptom: I2C works close, fails when wires extended Fix: Keep I2C wires short, or use I2C bus extender
14. PWM Frequency Mismatch
Some components need specific PWM frequencies:
- LEDs: Any frequency >100Hz (no flicker)
- Motors: 1-20kHz typical
- Servos: 50Hz (20ms period) required!
- ESCs: Varies, check datasheetSymptom: Component behaves strangely, servo jitters Fix: Match PWM frequency to component requirements
15. Shared SPI Without Proper CS Handling
Multiple SPI devices need separate Chip Select:
CS1 CS2
│ │
[A] [B]
↑ ↑
MOSI/MISO/SCK shared
IMPORTANT: Only ONE CS low at a time!Symptom: SPI devices interfere with each other Fix: Ensure all CS pins HIGH before selecting device
Debug Checklist Template
□ Power LED on MCU lit?
□ Correct voltage at VCC?
□ All grounds connected?
□ Correct pin assignments in code?
□ Component polarity correct?
□ Resistors where needed?
□ Pull-ups on I2C?
□ Level shifters for mixed voltage?
□ Decoupling caps near ICs?
□ Flyback diodes on motors/relays?
□ External power for high-current loads?
□ No floating input pins?Circuit Debugging Measurement Procedures
Multimeter Basics
Safety First
- Never measure resistance in a powered circuit
- Start with highest range when unknown
- Check meter leads for damage before use
- Use proper probes (not worn/broken tips)
Common Measurements
1. Continuity Testing
Purpose: Check if two points are electrically connected
Procedure: 1. Turn off/disconnect power 2. Set multimeter to continuity mode (🔊 symbol) 3. Touch probes to two points 4. Beep = connected, No beep = open
When to Use:
- Verify solder joints
- Check for broken traces
- Test switches/buttons
- Find shorts
Expected Results:
| Component | Should Beep? |
|---|---|
| Wire | Yes |
| Closed switch | Yes |
| Open switch | No |
| Diode (forward) | Yes (with resistance) |
| Diode (reverse) | No |
| Capacitor | Brief beep, then no |
---
2. DC Voltage Measurement
Purpose: Measure voltage between two points
Procedure: 1. Set meter to DC voltage (V⎓) 2. Select appropriate range (or auto-range) 3. Black probe to ground/reference 4. Red probe to measurement point 5. Read display
Common Voltages:
| Source | Expected |
|---|---|
| USB | 4.75-5.25V |
| LiPo battery | 3.0-4.2V |
| 3.3V regulator | 3.2-3.4V |
| 5V regulator | 4.9-5.1V |
| Arduino 5V pin | 4.5-5.5V |
| Arduino 3.3V pin | 3.1-3.5V |
Troubleshooting:
- 0V = No power, broken connection
- Lower than expected = Overloaded, bad regulator
- Higher than expected = Check regulator, source
---
3. Current Measurement
Purpose: Measure current flowing through circuit
Procedure: 1. BREAK the circuit where you want to measure 2. Set meter to DC current (A⎓) 3. Connect meter IN SERIES (current flows through meter) 4. Red to upstream, black to downstream 5. Read display
⚠️ WARNING:
- Never connect ammeter in parallel!
- Use correct port (mA vs 10A)
- Start with highest range
Typical Currents:
| State | Current |
|---|---|
| Arduino Uno idle | 40-50mA |
| ESP32 WiFi active | 80-250mA |
| ESP32 deep sleep | 10-150µA |
| LED (typical) | 10-20mA |
| Servo idle | 10-20mA |
| Servo moving | 100-500mA |
---
4. Resistance Measurement
Purpose: Measure resistance of component or connection
Procedure: 1. POWER OFF - Never measure resistance in live circuit! 2. Set meter to Ω (ohms) 3. Touch probes to component leads 4. Read display
Component Values:
| Component | Typical Resistance |
|---|---|
| Wire/trace | <1Ω |
| LED (forward) | 20-200Ω |
| Pull-up resistor | 1kΩ-10kΩ |
| Potentiometer | Varies with position |
| Thermistor | Varies with temp |
| Open circuit | OL (overload) |
| Short circuit | 0Ω |
---
5. Diode/LED Testing
Purpose: Test diode functionality and forward voltage
Procedure: 1. Set meter to diode test mode (▷|) 2. Red probe to anode (+), black to cathode (-) 3. Read forward voltage drop 4. Reverse probes - should show OL
Expected Forward Voltages:
| Diode Type | Forward Voltage |
|---|---|
| Silicon (1N4148) | 0.6-0.7V |
| Schottky | 0.2-0.4V |
| Red LED | 1.8-2.2V |
| Green LED | 2.0-2.4V |
| Blue/White LED | 3.0-3.4V |
| Zener (reverse) | Zener voltage |
---
Common Debug Scenarios
Scenario 1: Device Not Powering On
Checklist:
□ Check power source voltage
□ Check regulator input voltage
□ Check regulator output voltage
□ Check for shorts (0Ω between VCC and GND)
□ Feel for hot components
□ Check fuse/polyfuse if presentScenario 2: Intermittent Operation
Checklist:
□ Check all solder joints (cold joints?)
□ Wiggle wires while measuring voltage
□ Check connector seating
□ Look for loose screws/standoffs touching traces
□ Check power under load vs idleScenario 3: Sensor Not Working
Checklist:
□ Verify power at sensor VCC pin
□ Check I2C/SPI connections with scope/logic analyzer
□ Run I2C scanner to find address
□ Verify pull-up resistors present for I2C
□ Check signal levels match MCU voltageScenario 4: Motor/Actuator Issues
Checklist:
□ Measure motor supply voltage
□ Check driver IC is getting logic power
□ Verify PWM signal present
□ Check for proper ground connection
□ Test motor directly with power supply
□ Check current - motor might be stalled---
Logic Level Reference
| Logic Family | LOW | HIGH | Note |
|---|---|---|---|
| 5V TTL | 0-0.8V | 2.0-5V | Arduino Uno |
| 5V CMOS | 0-1.5V | 3.5-5V | ATmega328 |
| 3.3V CMOS | 0-1.0V | 2.3-3.3V | ESP32, RP2040 |
| 1.8V CMOS | 0-0.6V | 1.2-1.8V | Some sensors |
Level Shifting Required When:
- 5V Arduino ↔ 3.3V sensor
- 3.3V MCU ↔ 5V display
- Any mixed-voltage I2C bus
---
Oscilloscope Quick Reference
When Multimeter Isn't Enough:
Use oscilloscope for:
- PWM signal verification
- Serial communication debugging
- Timing-critical signals
- Noise analysis
- I2C/SPI bus issues
Common Signals:
PWM:
- Square wave
- Check frequency and duty cycle
- Look for clean edges
I2C:
- SDA: Data, bidirectional
- SCL: Clock, master-driven
- Both idle HIGH (pull-ups)
- Look for ACK bits
UART/Serial:
- Idle HIGH
- Start bit (LOW)
- 8 data bits
- Stop bit (HIGH)
---
Quick Debug Commands (Arduino Serial)
// Print all pin states
void debugPins() {
for (int i = 0; i < 14; i++) {
Serial.print("D"); Serial.print(i);
Serial.print(": "); Serial.println(digitalRead(i));
}
for (int i = 0; i < 6; i++) {
Serial.print("A"); Serial.print(i);
Serial.print(": "); Serial.println(analogRead(i));
}
}
// Measure execution time
unsigned long start = micros();
// ... code to measure ...
unsigned long duration = micros() - start;
Serial.print("Duration: "); Serial.print(duration); Serial.println(" µs");
// Memory check
extern int __heap_start, *__brkval;
int freeMemory() {
int v;
return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}Multimeter Usage Guide for Beginners
Safety First
- NEVER measure current directly across a power source (creates short circuit!)
- Start with highest range, work down
- Discharge capacitors before measuring resistance
- Don't measure live mains voltage as a beginner
Essential Measurements
DC Voltage (Most Common)
Setting: V⎓ or VDC, 20V range for Arduino projects
How to measure:
1. Set dial to DC Voltage (V with straight line)
2. Select 20V range (covers 0-20V)
3. Black probe → Ground/Negative
4. Red probe → Point to measure
5. Read display
Red probe here
↓
VCC ───[component]─── GND
↑
Black probe hereInterpreting Results:
| Reading | Meaning |
|---|---|
| 4.8-5.2V | Good 5V rail |
| 3.2-3.4V | Good 3.3V rail |
| 0V | No power or open circuit |
| Negative value | Probes reversed |
| Unstable/jumping | Floating or noisy |
Continuity Test
Setting: Diode/Continuity symbol (sounds like ))) )
How to use:
1. Set dial to continuity (beep symbol)
2. Touch probes together → should beep
3. Test connections → beep = connected
Testing a wire:
[====WIRE====]
↑ ↑
Probe Probe
Beep = Good wire
No beep = Broken wireUse For:
- Checking if wires are connected
- Finding broken traces on PCB
- Verifying solder joints
- Finding shorts (unexpected beeps!)
Resistance
Setting: Ω (Ohms)
IMPORTANT: Remove component from circuit first!
Otherwise you measure parallel paths, wrong value.
How to measure:
1. Set to Ω range (start with 20kΩ)
2. Touch probes to component leads
3. If shows "1" or "OL", increase range
4. Read value
Common resistor values:
- 330Ω = LED current limiter
- 4.7kΩ = I2C pull-up
- 10kΩ = Common pull-up/downCurrent (Advanced - Use Carefully!)
Setting: A or mA
⚠️ WARNING: Must break circuit and insert meter IN SERIES!
WRONG (will blow fuse or damage meter):
VCC ──[A]── GND ← SHORT CIRCUIT!
CORRECT:
VCC ──[A]──[Load]── GND
↑
Meter measures current
flowing through loadCurrent Measurement Setup:
Before:
VCC ─────[LED+R]───── GND
After (insert meter):
VCC ──[mA]──[LED+R]── GND
↑
Break wire here,
insert meter in gapTroubleshooting with Multimeter
"Nothing Powers On"
1. Check battery/power supply voltage
- Fresh 9V battery: 9.0-9.6V
- Drained 9V battery: <7V
- USB power: 4.75-5.25V
2. Check voltage at MCU VCC pin
- If 0V: trace back to power source
- If correct: MCU may be damaged
3. Check for shorts
- Continuity between VCC and GND
- Should NOT beep! If it does = short circuit"Component Gets Hot"
1. Immediately disconnect power!
2. Check for reversed polarity
3. Check for short circuits
4. Verify component voltage rating
5. Calculate if current is excessive"Sensor Gives Wrong Values"
1. Verify VCC voltage at sensor
2. Check signal voltage levels
3. Test with known-good values
4. Check for noise (unstable readings)Quick Reference Card
| What to Measure | Setting | Probes | Expected |
|---|---|---|---|
| Arduino 5V rail | VDC 20V | Red=5V pin, Black=GND | 4.8-5.2V |
| Arduino 3.3V | VDC 20V | Red=3.3V, Black=GND | 3.2-3.4V |
| Battery | VDC 20V | Red=+, Black=- | Rated voltage |
| Wire intact? | Continuity | Both ends | Beep |
| Resistor value | Ω | Both leads | Marked value |
| LED polarity | Diode | Either way | Shows ~0.6-2V one way |
| I2C pull-up | Ω | SDA/SCL to VCC | ~4.7kΩ |
Budget Multimeter Recommendations
- Beginner: Any $15-25 auto-ranging meter
- Recommended: AstroAI DM6000AR, Kaiweets HT118A
- Pro: Fluke 117 (expensive but lifetime tool)
Key features needed:
- Auto-ranging (easier to use)
- Continuity beeper
- DC voltage to 20V+
- Current measurement (mA range)
#!/usr/bin/env python3
"""
Debug Sketch Generator - Creates diagnostic Arduino sketches
Generates diagnostic code for common debugging tasks:
- I2C bus scanner
- SPI device tester
- GPIO pin tester
- Serial loopback test
- Voltage/ADC checker
- PWM output tester
- Interrupt tester
Usage:
uv run --no-project scripts/generate_debug_sketch.py --i2c
uv run --no-project scripts/generate_debug_sketch.py --gpio --pins 2,3,4,5
uv run --no-project scripts/generate_debug_sketch.py --adc --pins A0,A1,A2
uv run --no-project scripts/generate_debug_sketch.py --all --output debug_suite.ino
"""
import argparse
from typing import List, Optional
# =============================================================================
# Sketch Templates
# =============================================================================
I2C_SCANNER = '''/*
* I2C Bus Scanner
* Scans for all connected I2C devices and reports addresses
*
* Wiring:
* SDA -> A4 (Uno) or 21 (Mega) or GPIO21 (ESP32) or GP4 (Pico)
* SCL -> A5 (Uno) or 20 (Mega) or GPIO22 (ESP32) or GP5 (Pico)
*
* Common I2C addresses:
* 0x27, 0x3F - LCD displays
* 0x3C, 0x3D - OLED displays (SSD1306)
* 0x68 - DS3231 RTC, MPU6050
* 0x76, 0x77 - BME280/BMP280
* 0x48-0x4F - PCF8591, ADS1115
* 0x20-0x27 - PCF8574 I/O expander
* 0x50-0x57 - EEPROM (24LC256)
*/
#include <Wire.h>
void setup() {
Serial.begin(115200);
while (!Serial) delay(10); // Wait for serial (Leonardo/ESP32)
Wire.begin();
Serial.println();
Serial.println("========================================");
Serial.println(" I2C Bus Scanner v1.0 ");
Serial.println("========================================");
Serial.println();
scanI2C();
}
void loop() {
Serial.println("\\nPress any key to scan again...");
while (!Serial.available()) delay(100);
while (Serial.available()) Serial.read();
scanI2C();
}
void scanI2C() {
byte deviceCount = 0;
byte error;
Serial.println("Scanning I2C bus (0x03 to 0x77)...");
Serial.println();
// Print header
Serial.print(" ");
for (byte i = 0; i < 16; i++) {
Serial.print(" ");
if (i < 16) Serial.print(i, HEX);
}
Serial.println();
for (byte row = 0; row < 8; row++) {
Serial.print(row, HEX);
Serial.print("0: ");
for (byte col = 0; col < 16; col++) {
byte addr = (row << 4) | col;
if (addr < 0x03 || addr > 0x77) {
Serial.print(" --");
} else {
Wire.beginTransmission(addr);
error = Wire.endTransmission();
if (error == 0) {
Serial.print(" ");
if (addr < 16) Serial.print("0");
Serial.print(addr, HEX);
deviceCount++;
} else {
Serial.print(" --");
}
}
}
Serial.println();
}
Serial.println();
Serial.print("Found ");
Serial.print(deviceCount);
Serial.println(" device(s)");
if (deviceCount > 0) {
Serial.println("\\nDevice details:");
for (byte addr = 0x03; addr <= 0x77; addr++) {
Wire.beginTransmission(addr);
if (Wire.endTransmission() == 0) {
Serial.print(" 0x");
if (addr < 16) Serial.print("0");
Serial.print(addr, HEX);
Serial.print(" - ");
Serial.println(identifyDevice(addr));
}
}
}
}
String identifyDevice(byte addr) {
// Common device identification
switch(addr) {
case 0x27: case 0x3F: return "LCD I2C (PCF8574)";
case 0x3C: case 0x3D: return "OLED SSD1306";
case 0x68: return "DS3231 RTC or MPU6050";
case 0x69: return "MPU6050 (ALT)";
case 0x76: case 0x77: return "BME280/BMP280";
case 0x48: return "ADS1115/PCF8591";
case 0x50: return "EEPROM 24LC256";
case 0x57: return "MAX30102 Pulse Sensor";
case 0x1E: return "HMC5883L Compass";
case 0x53: return "ADXL345 Accelerometer";
case 0x40: return "INA219 Current Sensor or HTU21D";
case 0x44: return "SHT31 Humidity";
case 0x29: return "VL53L0X ToF Sensor";
default:
if (addr >= 0x20 && addr <= 0x27) return "PCF8574 I/O Expander";
if (addr >= 0x50 && addr <= 0x57) return "EEPROM";
return "Unknown device";
}
}
'''
GPIO_TESTER = '''/*
* GPIO Pin Tester
* Tests digital I/O functionality
*
* Features:
* - Output test (LED blink pattern)
* - Input test with pullup
* - Measures pin capacitance indication
*
* Test pins: {pins}
*/
const int TEST_PINS[] = {{{pins_array}}};
const int NUM_PINS = {num_pins};
void setup() {{
Serial.begin(115200);
while (!Serial) delay(10);
Serial.println();
Serial.println("========================================");
Serial.println(" GPIO Pin Tester v1.0 ");
Serial.println("========================================");
Serial.println();
Serial.println("Testing pins: {pins}");
Serial.println();
// Test each pin
for (int i = 0; i < NUM_PINS; i++) {{
testPin(TEST_PINS[i]);
}}
Serial.println("\\nOutput test - watch for LED blink pattern...");
outputTest();
}}
void loop() {{
// Continuous input monitoring
Serial.println("\\nMonitoring inputs (press any key to restart)...");
while (!Serial.available()) {{
for (int i = 0; i < NUM_PINS; i++) {{
pinMode(TEST_PINS[i], INPUT_PULLUP);
}}
Serial.print("Inputs: ");
for (int i = 0; i < NUM_PINS; i++) {{
Serial.print("D");
Serial.print(TEST_PINS[i]);
Serial.print("=");
Serial.print(digitalRead(TEST_PINS[i]));
Serial.print(" ");
}}
Serial.println();
delay(500);
}}
while (Serial.available()) Serial.read();
Serial.println("\\n--- Restarting test ---\\n");
for (int i = 0; i < NUM_PINS; i++) {{
testPin(TEST_PINS[i]);
}}
outputTest();
}}
void testPin(int pin) {{
Serial.print("Pin D");
Serial.print(pin);
Serial.print(": ");
// Test as output
pinMode(pin, OUTPUT);
digitalWrite(pin, HIGH);
delay(1);
digitalWrite(pin, LOW);
// Test as input with pullup
pinMode(pin, INPUT_PULLUP);
delay(1);
int pullupVal = digitalRead(pin);
// Test as input without pullup
pinMode(pin, INPUT);
delay(1);
int floatVal = digitalRead(pin);
Serial.print("pullup=");
Serial.print(pullupVal);
Serial.print(" float=");
Serial.print(floatVal);
// Diagnosis
if (pullupVal == HIGH && floatVal == LOW) {{
Serial.println(" [OK - normal]");
}} else if (pullupVal == HIGH && floatVal == HIGH) {{
Serial.println(" [OK - pulled high externally]");
}} else if (pullupVal == LOW) {{
Serial.println(" [WARNING - pulled low or shorted to GND]");
}} else {{
Serial.println(" [OK]");
}}
}}
void outputTest() {{
// Set all as outputs
for (int i = 0; i < NUM_PINS; i++) {{
pinMode(TEST_PINS[i], OUTPUT);
}}
// Blink pattern
for (int cycle = 0; cycle < 5; cycle++) {{
// All on
for (int i = 0; i < NUM_PINS; i++) {{
digitalWrite(TEST_PINS[i], HIGH);
}}
delay(200);
// All off
for (int i = 0; i < NUM_PINS; i++) {{
digitalWrite(TEST_PINS[i], LOW);
}}
delay(200);
}}
// Sequential chase
for (int cycle = 0; cycle < 3; cycle++) {{
for (int i = 0; i < NUM_PINS; i++) {{
digitalWrite(TEST_PINS[i], HIGH);
delay(100);
digitalWrite(TEST_PINS[i], LOW);
}}
}}
Serial.println("Output test complete");
}}
'''
ADC_CHECKER = '''/*
* ADC / Analog Input Checker
* Reads and displays analog values with voltage calculation
*
* Test pins: {pins}
* Reference: {vref}V (10-bit = 0-1023)
*/
const int ADC_PINS[] = {{{pins_array}}};
const int NUM_PINS = {num_pins};
const float VREF = {vref}; // Reference voltage
const int ADC_MAX = 1023; // 10-bit ADC
void setup() {{
Serial.begin(115200);
while (!Serial) delay(10);
Serial.println();
Serial.println("========================================");
Serial.println(" ADC Analog Checker v1.0 ");
Serial.println("========================================");
Serial.println();
Serial.print("Reference voltage: ");
Serial.print(VREF);
Serial.println("V");
Serial.print("Testing pins: {pins}");
Serial.println();
Serial.println();
// Print header
printHeader();
}}
void loop() {{
// Read and display all channels
for (int i = 0; i < NUM_PINS; i++) {{
int raw = analogRead(ADC_PINS[i]);
float voltage = (raw * VREF) / ADC_MAX;
float percent = (raw * 100.0) / ADC_MAX;
// Pin label
Serial.print("A");
Serial.print(ADC_PINS[i] - A0);
Serial.print(": ");
// Raw value (padded)
if (raw < 1000) Serial.print(" ");
if (raw < 100) Serial.print(" ");
if (raw < 10) Serial.print(" ");
Serial.print(raw);
Serial.print(" | ");
// Voltage
Serial.print(voltage, 3);
Serial.print("V | ");
// Percentage bar
int bars = percent / 5; // 20 chars max
Serial.print("[");
for (int b = 0; b < 20; b++) {{
if (b < bars) Serial.print("#");
else Serial.print(" ");
}}
Serial.print("] ");
Serial.print(percent, 1);
Serial.println("%");
}}
Serial.println("----------------------------------------");
delay(500);
}}
void printHeader() {{
Serial.println("Pin | Raw | Voltage | Level");
Serial.println("----------------------------------------");
}}
'''
PWM_TESTER = '''/*
* PWM Output Tester
* Tests PWM output on specified pins with varying duty cycles
*
* PWM Pins by board:
* Uno/Nano: 3, 5, 6, 9, 10, 11
* Mega: 2-13, 44-46
* ESP32: Any GPIO (LEDC)
* Pico: Any GPIO
*
* Test pins: {pins}
*/
const int PWM_PINS[] = {{{pins_array}}};
const int NUM_PINS = {num_pins};
int currentDuty = 0;
int direction = 1;
bool fadeMode = true;
void setup() {{
Serial.begin(115200);
while (!Serial) delay(10);
Serial.println();
Serial.println("========================================");
Serial.println(" PWM Output Tester v1.0 ");
Serial.println("========================================");
Serial.println();
Serial.println("Testing pins: {pins}");
Serial.println();
Serial.println("Commands:");
Serial.println(" 0-255: Set specific duty cycle");
Serial.println(" f: Toggle fade mode");
Serial.println(" s: Stop all outputs");
Serial.println();
// Initialize pins
for (int i = 0; i < NUM_PINS; i++) {{
pinMode(PWM_PINS[i], OUTPUT);
}}
}}
void loop() {{
// Check for serial commands
if (Serial.available()) {{
String cmd = Serial.readStringUntil('\\n');
cmd.trim();
if (cmd == "f") {{
fadeMode = !fadeMode;
Serial.print("Fade mode: ");
Serial.println(fadeMode ? "ON" : "OFF");
}} else if (cmd == "s") {{
for (int i = 0; i < NUM_PINS; i++) {{
analogWrite(PWM_PINS[i], 0);
}}
Serial.println("All PWM stopped");
fadeMode = false;
}} else {{
int duty = cmd.toInt();
if (duty >= 0 && duty <= 255) {{
currentDuty = duty;
fadeMode = false;
for (int i = 0; i < NUM_PINS; i++) {{
analogWrite(PWM_PINS[i], currentDuty);
}}
Serial.print("Set duty cycle: ");
Serial.print(currentDuty);
Serial.print(" (");
Serial.print((currentDuty * 100) / 255);
Serial.println("%)");
}}
}}
}}
// Fade mode - smooth ramp up/down
if (fadeMode) {{
currentDuty += direction * 5;
if (currentDuty >= 255) {{
currentDuty = 255;
direction = -1;
}} else if (currentDuty <= 0) {{
currentDuty = 0;
direction = 1;
}}
for (int i = 0; i < NUM_PINS; i++) {{
analogWrite(PWM_PINS[i], currentDuty);
}}
// Display
Serial.print("PWM: ");
Serial.print(currentDuty);
Serial.print(" [");
int bars = currentDuty / 12; // ~21 chars
for (int b = 0; b < 21; b++) {{
if (b < bars) Serial.print("=");
else Serial.print(" ");
}}
Serial.println("]");
delay(30);
}}
}}
'''
SERIAL_LOOPBACK = '''/*
* Serial Loopback Tester
* Tests serial communication by sending and receiving
*
* For loopback test: Connect TX to RX directly
* For device test: Connect to external serial device
*
* Tests:
* 1. Self loopback (wire TX to RX)
* 2. Baud rate validation
* 3. Data integrity
*/
// Test configuration
const long BAUD_RATES[] = {9600, 19200, 38400, 57600, 115200};
const int NUM_BAUDS = 5;
void setup() {
Serial.begin(115200);
while (!Serial) delay(10);
Serial.println();
Serial.println("========================================");
Serial.println(" Serial Loopback Tester v1.0 ");
Serial.println("========================================");
Serial.println();
Serial.println("Connect TX -> RX for loopback test");
Serial.println("Or connect to target device");
Serial.println();
Serial.println("Commands:");
Serial.println(" t - Run loopback test");
Serial.println(" s - Send test string");
Serial.println(" m - Monitor incoming data");
Serial.println();
}
void loop() {
if (Serial.available()) {
char cmd = Serial.read();
while (Serial.available()) Serial.read(); // Clear buffer
switch (cmd) {
case 't':
case 'T':
loopbackTest();
break;
case 's':
case 'S':
sendTestString();
break;
case 'm':
case 'M':
monitorMode();
break;
}
}
}
void loopbackTest() {
Serial.println("\\n--- Loopback Test ---");
Serial.println("Ensure TX is connected to RX");
Serial.println();
// Wait for any existing data
delay(100);
while (Serial.available()) Serial.read();
// Test string
const char* testStr = "LOOPBACK_TEST_12345";
int testLen = strlen(testStr);
Serial.print("Sending: ");
Serial.println(testStr);
// Send test string (will echo back through loopback)
Serial.print(testStr);
Serial.flush();
// Wait for response
delay(100);
char response[50];
int received = 0;
unsigned long start = millis();
while (received < testLen && (millis() - start) < 1000) {
if (Serial.available()) {
response[received++] = Serial.read();
}
}
response[received] = '\\0';
Serial.print("Received: ");
Serial.println(response);
// Compare
if (received == testLen && strcmp(response, testStr) == 0) {
Serial.println("Result: PASS - Loopback OK");
} else if (received == 0) {
Serial.println("Result: FAIL - No response (check TX-RX connection)");
} else {
Serial.print("Result: FAIL - Received ");
Serial.print(received);
Serial.print(" of ");
Serial.print(testLen);
Serial.println(" bytes");
}
}
void sendTestString() {
Serial.println("\\n--- Sending Test Pattern ---");
// ASCII printable range
Serial.println("ASCII printable characters:");
for (char c = 32; c < 127; c++) {
Serial.print(c);
}
Serial.println();
// Numbers
Serial.println("\\nNumber sequence:");
for (int i = 0; i < 10; i++) {
Serial.print(i);
}
Serial.println();
Serial.println("\\nTest complete");
}
void monitorMode() {
Serial.println("\\n--- Monitor Mode ---");
Serial.println("Displaying incoming bytes (press any key to exit)...");
Serial.println();
int byteCount = 0;
unsigned long lastPrint = 0;
while (true) {
// Check for exit (data from USB serial)
// This is tricky in loopback mode...
// Display any received data
while (Serial.available()) {
char c = Serial.read();
// Print as hex and ASCII
if (c >= 32 && c < 127) {
Serial.print(c);
} else {
Serial.print("[");
Serial.print((int)c, HEX);
Serial.print("]");
}
byteCount++;
}
// Stats every 2 seconds
if (millis() - lastPrint > 2000) {
Serial.print("\\n[");
Serial.print(byteCount);
Serial.println(" bytes received]");
lastPrint = millis();
// Exit after timeout with no data
if (byteCount == 0) {
Serial.println("No data - exiting monitor");
break;
}
byteCount = 0;
}
delay(10);
}
}
'''
VOLTAGE_DIVIDER = '''/*
* Voltage Divider Calculator & Tester
* Calculates and tests voltage divider circuits
*
* Schematic:
* Vin ----[R1]----+----[R2]---- GND
* |
* Vout (to ADC)
*
* Formula: Vout = Vin * (R2 / (R1 + R2))
*
* Connect Vout to: {adc_pin}
*/
const int ADC_PIN = {adc_pin};
const float VREF = {vref}; // ADC reference voltage
const int ADC_MAX = 1023; // 10-bit ADC
// Resistor values (ohms) - adjust to match your circuit
float R1 = {r1}; // Top resistor (Vin side)
float R2 = {r2}; // Bottom resistor (GND side)
// Calculated divider ratio
float dividerRatio;
void setup() {{
Serial.begin(115200);
while (!Serial) delay(10);
Serial.println();
Serial.println("========================================");
Serial.println(" Voltage Divider Calculator v1.0 ");
Serial.println("========================================");
Serial.println();
// Calculate ratio
dividerRatio = R2 / (R1 + R2);
float maxVin = VREF / dividerRatio;
Serial.println("Configuration:");
Serial.print(" R1 (top): ");
Serial.print(R1 / 1000, 1);
Serial.println(" kΩ");
Serial.print(" R2 (bottom): ");
Serial.print(R2 / 1000, 1);
Serial.println(" kΩ");
Serial.print(" Divider ratio: ");
Serial.println(dividerRatio, 4);
Serial.print(" ADC reference: ");
Serial.print(VREF);
Serial.println("V");
Serial.print(" Max input voltage: ");
Serial.print(maxVin, 2);
Serial.println("V");
Serial.println();
Serial.println("Commands:");
Serial.println(" r - Read voltage");
Serial.println(" c - Continuous reading");
Serial.println(" 1/2 - Adjust R1/R2 values");
Serial.println();
}}
void loop() {{
if (Serial.available()) {{
char cmd = Serial.read();
while (Serial.available()) Serial.read();
switch (cmd) {{
case 'r':
case 'R':
readVoltage();
break;
case 'c':
case 'C':
continuousRead();
break;
case '1':
adjustR1();
break;
case '2':
adjustR2();
break;
}}
}}
}}
void readVoltage() {{
// Take multiple readings for stability
long sum = 0;
for (int i = 0; i < 10; i++) {{
sum += analogRead(ADC_PIN);
delay(10);
}}
float avgRaw = sum / 10.0;
float vout = (avgRaw * VREF) / ADC_MAX;
float vin = vout / dividerRatio;
Serial.println("\\n--- Voltage Reading ---");
Serial.print("ADC raw: ");
Serial.println(avgRaw, 1);
Serial.print("Vout (ADC): ");
Serial.print(vout, 3);
Serial.println("V");
Serial.print("Vin (calculated): ");
Serial.print(vin, 2);
Serial.println("V");
}}
void continuousRead() {{
Serial.println("\\nContinuous mode (any key to stop)...");
while (!Serial.available()) {{
int raw = analogRead(ADC_PIN);
float vout = (raw * VREF) / ADC_MAX;
float vin = vout / dividerRatio;
Serial.print("ADC:");
Serial.print(raw);
Serial.print(" Vout:");
Serial.print(vout, 3);
Serial.print("V Vin:");
Serial.print(vin, 2);
Serial.println("V");
delay(500);
}}
while (Serial.available()) Serial.read();
}}
void adjustR1() {{
Serial.println("\\nEnter R1 value in ohms:");
while (!Serial.available()) delay(10);
R1 = Serial.parseFloat();
updateRatio();
}}
void adjustR2() {{
Serial.println("\\nEnter R2 value in ohms:");
while (!Serial.available()) delay(10);
R2 = Serial.parseFloat();
updateRatio();
}}
void updateRatio() {{
dividerRatio = R2 / (R1 + R2);
Serial.print("New ratio: ");
Serial.println(dividerRatio, 4);
Serial.print("Max Vin: ");
Serial.print(VREF / dividerRatio, 2);
Serial.println("V");
}}
'''
def generate_i2c_scanner() -> str:
"""Generate I2C scanner sketch"""
return I2C_SCANNER
def generate_gpio_tester(pins: List[int]) -> str:
"""Generate GPIO tester sketch"""
pins_str = ", ".join(map(str, pins))
return GPIO_TESTER.format(
pins=pins_str,
pins_array=pins_str,
num_pins=len(pins)
)
def generate_adc_checker(pins: List[str], vref: float = 5.0) -> str:
"""Generate ADC checker sketch"""
# Convert pin names to Arduino pin numbers
pin_nums = []
for p in pins:
if p.startswith('A'):
pin_nums.append(f"A{p[1:]}")
else:
pin_nums.append(f"A{p}")
pins_str = ", ".join(pins)
pins_array = ", ".join(pin_nums)
return ADC_CHECKER.format(
pins=pins_str,
pins_array=pins_array,
num_pins=len(pins),
vref=vref
)
def generate_pwm_tester(pins: List[int]) -> str:
"""Generate PWM tester sketch"""
pins_str = ", ".join(map(str, pins))
return PWM_TESTER.format(
pins=pins_str,
pins_array=pins_str,
num_pins=len(pins)
)
def generate_serial_loopback() -> str:
"""Generate serial loopback tester"""
return SERIAL_LOOPBACK
def generate_voltage_divider(adc_pin: str = "A0", vref: float = 5.0,
r1: float = 30000, r2: float = 7500) -> str:
"""Generate voltage divider calculator sketch"""
return VOLTAGE_DIVIDER.format(
adc_pin=adc_pin,
vref=vref,
r1=r1,
r2=r2
)
def interactive_mode():
"""Interactive sketch generator"""
print("=" * 60)
print("Debug Sketch Generator - Interactive Mode")
print("=" * 60)
print()
print("Available sketches:")
print(" 1. I2C Bus Scanner")
print(" 2. GPIO Pin Tester")
print(" 3. ADC/Analog Checker")
print(" 4. PWM Output Tester")
print(" 5. Serial Loopback Test")
print(" 6. Voltage Divider Tester")
print(" 7. Generate All")
print()
choice = input("Select sketch (1-7): ").strip()
sketch = ""
filename = "debug_sketch.ino"
if choice == "1":
sketch = generate_i2c_scanner()
filename = "i2c_scanner.ino"
elif choice == "2":
pins_input = input("Enter GPIO pins (comma-separated) [2,3,4,5]: ").strip()
pins = [int(p.strip()) for p in (pins_input or "2,3,4,5").split(",")]
sketch = generate_gpio_tester(pins)
filename = "gpio_tester.ino"
elif choice == "3":
pins_input = input("Enter ADC pins (comma-separated) [A0,A1,A2]: ").strip()
pins = [p.strip() for p in (pins_input or "A0,A1,A2").split(",")]
vref = float(input("Reference voltage [5.0]: ").strip() or "5.0")
sketch = generate_adc_checker(pins, vref)
filename = "adc_checker.ino"
elif choice == "4":
pins_input = input("Enter PWM pins (comma-separated) [3,5,6,9]: ").strip()
pins = [int(p.strip()) for p in (pins_input or "3,5,6,9").split(",")]
sketch = generate_pwm_tester(pins)
filename = "pwm_tester.ino"
elif choice == "5":
sketch = generate_serial_loopback()
filename = "serial_loopback.ino"
elif choice == "6":
adc = input("ADC pin [A0]: ").strip() or "A0"
vref = float(input("Reference voltage [5.0]: ").strip() or "5.0")
r1 = float(input("R1 (ohms) [30000]: ").strip() or "30000")
r2 = float(input("R2 (ohms) [7500]: ").strip() or "7500")
sketch = generate_voltage_divider(adc, vref, r1, r2)
filename = "voltage_divider.ino"
elif choice == "7":
# Generate all into one file
sketches = [
"// ===== I2C SCANNER =====",
generate_i2c_scanner(),
"\n// ===== GPIO TESTER =====",
generate_gpio_tester([2, 3, 4, 5]),
"\n// ===== ADC CHECKER =====",
generate_adc_checker(["A0", "A1", "A2"]),
]
sketch = "\n\n".join(sketches)
filename = "debug_suite.ino"
print("\nNote: Multiple sketches generated. Copy desired section to use.")
else:
print("Invalid choice")
return
# Save
custom_name = input(f"\nOutput filename [{filename}]: ").strip()
if custom_name:
filename = custom_name if custom_name.endswith(".ino") else custom_name + ".ino"
with open(filename, 'w') as f:
f.write(sketch)
print(f"\n✓ Generated: {filename}")
print(f" Upload to Arduino and open Serial Monitor at 115200 baud")
def main():
parser = argparse.ArgumentParser(description="Debug Sketch Generator")
parser.add_argument("--interactive", "-i", action="store_true", help="Interactive mode")
parser.add_argument("--i2c", action="store_true", help="Generate I2C scanner")
parser.add_argument("--gpio", action="store_true", help="Generate GPIO tester")
parser.add_argument("--adc", action="store_true", help="Generate ADC checker")
parser.add_argument("--pwm", action="store_true", help="Generate PWM tester")
parser.add_argument("--serial", action="store_true", help="Generate serial loopback")
parser.add_argument("--voltage", action="store_true", help="Generate voltage divider")
parser.add_argument("--pins", type=str, help="Comma-separated pin list")
parser.add_argument("--vref", type=float, default=5.0, help="Reference voltage")
parser.add_argument("--output", "-o", type=str, help="Output filename")
parser.add_argument("--all", action="store_true", help="Generate all sketches")
args = parser.parse_args()
if args.interactive:
interactive_mode()
return
sketch = ""
filename = args.output or "debug_sketch.ino"
if args.i2c:
sketch = generate_i2c_scanner()
filename = args.output or "i2c_scanner.ino"
elif args.gpio:
pins = [int(p) for p in (args.pins or "2,3,4,5").split(",")]
sketch = generate_gpio_tester(pins)
filename = args.output or "gpio_tester.ino"
elif args.adc:
pins = (args.pins or "A0,A1,A2").split(",")
sketch = generate_adc_checker(pins, args.vref)
filename = args.output or "adc_checker.ino"
elif args.pwm:
pins = [int(p) for p in (args.pins or "3,5,6,9").split(",")]
sketch = generate_pwm_tester(pins)
filename = args.output or "pwm_tester.ino"
elif args.serial:
sketch = generate_serial_loopback()
filename = args.output or "serial_loopback.ino"
elif args.voltage:
sketch = generate_voltage_divider("A0", args.vref)
filename = args.output or "voltage_divider.ino"
elif args.all:
sketches = [
generate_i2c_scanner(),
generate_gpio_tester([2, 3, 4, 5]),
generate_adc_checker(["A0", "A1", "A2"]),
generate_pwm_tester([3, 5, 6, 9]),
generate_serial_loopback()
]
# Save each separately
names = ["i2c_scanner.ino", "gpio_tester.ino", "adc_checker.ino",
"pwm_tester.ino", "serial_loopback.ino"]
for s, n in zip(sketches, names):
with open(n, 'w') as f:
f.write(s)
print(f"Generated: {n}")
return
else:
parser.print_help()
return
with open(filename, 'w') as f:
f.write(sketch)
print(f"Generated: {filename}")
if __name__ == "__main__":
main()