
Mermaid Diagram Generator
- 36 installs
- 19 repo stars
- Updated May 26, 2026
- wedsamuel1230/arduino-skills
Helps with ai & agent building tasks.
About
mermaid-diagram-generator is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted development.
- mermaid-diagram-generator
- AI & Agent Building
- AI-coding skill
Mermaid Diagram Generator by the numbers
- 36 all-time installs (skills.sh)
- +4 installs in the week ending Jul 27, 2026 (Skillselion tracking)
- Ranked #8,608 of 16,546 AI & Agent Building 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 mermaid-diagram-generatorAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 36 |
|---|---|
| repo stars | ★ 19 |
| Last updated | May 26, 2026 |
| Repository | wedsamuel1230/arduino-skills ↗ |
What it does
Helps with ai & agent building tasks.
Files
Mermaid Diagram Generator
Generate Mermaid diagrams from Arduino and embedded-system concepts without loading unnecessary detail up front.
Resources
scripts/generate_diagram.py- CLI generator for diagram outputreferences/diagram-templates.md- Mermaid templates by diagram typereferences/code-patterns.md- code-to-diagram extraction heuristicsreferences/validation-checklist.md- rendering and syntax checks
When to Use
Use this skill when the request asks to:
- visualize a state machine
- turn code into a flowchart
- document timing or protocol sequences
- show FreeRTOS task relationships
- add a diagram to project documentation
Do not use it for tiny code snippets where a diagram adds no clarity.
Workflow
1. Identify the diagram type:
- state flow -> open
references/code-patterns.md - timing or protocol sequence -> open
references/diagram-templates.md - task architecture -> open both
code-patterns.mdand
diagram-templates.md 2. Prefer the simplest diagram that explains the behavior. 3. Use scripts/generate_diagram.py when the input is structured enough for automation. 4. Run through references/validation-checklist.md before presenting the final Mermaid output.
Verification
- Mermaid syntax parses without errors.
- The diagram uses the correct abstraction level for the request.
- State names, transitions, or signals match the source material exactly.
- The output is readable without reverse-engineering the code.
Integration
- Pair with
freertos-patternsfor task and synchronization diagrams. - Pair with
arduino-code-generatorwhen a generated sketch also needs visual
documentation.
- Pair with
readme-generatorwhen the diagram should ship in repository docs.
{
"name": "mermaid-diagram-generator",
"metadata": {
"description": "Generate Mermaid diagrams from Arduino code to visualize state machines, timing, and architecture for documentation",
"version": "0.10.0",
"license": "MIT",
"author": "arduino-skills contributors",
"tags": [
"mermaid",
"diagram",
"visualization",
"state-machine",
"flowchart",
"documentation",
"arduino"
],
"category": "maker-tools"
},
"plugins": [
{
"name": "mermaid-diagram-generator",
"description": "Generate Mermaid diagrams from Arduino code for visual documentation",
"enabled": true
}
]
}
Code-to-Diagram Patterns
Use this reference when you need to map code structure to a Mermaid diagram type.
State Machines
Prefer a state diagram when the source contains:
enumor named state constantsswitchstatements over a current state- explicit transitions such as
currentState = NEXT_STATE
Extraction checklist:
1. List the stable state names first. 2. Map only real transitions, not temporary local flags. 3. Keep guard conditions short. 4. Collapse repeated self-transitions unless they matter to the user.
Flowcharts
Prefer a flowchart when the request is about control flow instead of named states.
Good inputs:
- initialization sequences
- validation gates
- error-handling branches
- one-shot workflows
Avoid flowcharts when the code is really an event-driven state machine.
Timing Diagrams
Use timing diagrams when the question depends on order and edges:
- I2C, SPI, UART, or custom signaling
- sensor sample cadence
- ISR to task signaling order
- debounce windows or timeout behavior
Capture:
- signal names
- ordering
- repeated cadence if it matters
- notable waits, setup, hold, or timeout windows
FreeRTOS or Multicore Architecture
Use a flowchart or graph when the request is about task relationships rather than temporal protocol edges.
Show:
- task or core ownership
- queues or notifications
- shared resources
- watchdog or timer interactions
Do not encode every line of code. Show the communication boundaries.
Mermaid Diagram Templates
State Machine Template
stateDiagram-v2
[*] --> Idle
Idle --> Active: event
Active --> Processing: start
Processing --> Done: complete
Done --> Idle: reset
Done --> [*]Flowchart Template
flowchart TD
A["Start"] --> B{"Check Input"}
B -->|Valid| C["Process Data"]
B -->|Invalid| D["Show Error"]
C --> E["Save Result"]
D --> F["End"]
E --> FTiming/Sequence Template
sequenceDiagram
participant Arduino
participant Sensor
Arduino->>Sensor: Request Data
Sensor->>Arduino: Send Reading
Arduino->>Arduino: Process
Arduino->>Serial: Log ResultFreeRTOS Architecture Template
flowchart LR
TaskA["Task A<br/>(Priority 2)"] -->|Queue| TaskB["Task B<br/>(Priority 1)"]
TaskB -->|Semaphore| TaskC["Task C<br/>(Priority 3)"]
TaskA -.->|Mutex| SharedResource[(Shared<br/>Resource)]
TaskC -.->|Mutex| SharedResourceClass Diagram Template
classDiagram
class Sensor {
+int pin
+float value
+begin()
+read()
}
class Display {
+show(value)
+clear()
}
Sensor --> Display: sends dataMermaid Validation Checklist
Use this reference before returning a Mermaid diagram.
Syntax Checks
- Validate node labels and edge syntax.
- Keep labels short enough to render cleanly.
- Avoid unsupported Mermaid features unless the target renderer is known.
Structural Checks
- The selected diagram type matches the problem.
- States, tasks, or signals map directly to the source material.
- Arrows express directionality correctly.
- The diagram does not hide important branching or synchronization points.
Readability Checks
- Remove decorative detail that does not help the reader.
- Group repeated or equivalent steps when it improves scanability.
- Keep the first read understandable without referring back to the code for
every edge.
Final Review
- Re-read the user's question and confirm the diagram answers it.
- If the diagram comes from generated output, spot-check the highest-risk edges
manually.
- If the diagram is intended for README or docs, prefer stable naming over local
shorthand.
#!/usr/bin/env python3
# /// script
# requires-python = ">=3.8"
# dependencies = ["argparse"]
# ///
"""Generate Mermaid diagrams from Arduino code.
Usage:
uv run --no-project scripts/generate_diagram.py --input main.ino --type state-machine
uv run --no-project scripts/generate_diagram.py --interactive
"""
import argparse
import re
import sys
def extract_states(code):
"""Extract state definitions from Arduino code."""
states = []
# Pattern 1: enum StateType { STATE_A, STATE_B, ... }
enum_pattern = r'enum\s+\w+\s*\{([^}]+)\}'
enum_match = re.search(enum_pattern, code)
if enum_match:
states_str = enum_match.group(1)
states = [s.strip().split('=')[0].strip()
for s in states_str.split(',') if s.strip()]
# Pattern 2: #define STATE_A 0
define_pattern = r'#define\s+(STATE_\w+)\s+\d+'
states += re.findall(define_pattern, code)
return list(set(states))
def extract_transitions(code, states):
"""Extract state transitions from code."""
transitions = []
for state in states:
# Pattern: currentState = NEXT_STATE or state = NEXT_STATE
pattern = rf'\w*[Ss]tate\s*=\s*({"|".join(states)})'
matches = re.findall(pattern, code)
for next_state in matches:
if next_state in states and next_state != state:
transitions.append((state, next_state))
return list(set(transitions))
def generate_state_diagram(states, transitions):
"""Generate Mermaid state diagram."""
lines = ["```mermaid", "stateDiagram-v2"]
if states:
lines.append(f" [*] --> {states[0]}")
for from_state, to_state in transitions:
lines.append(f" {from_state} --> {to_state}")
if states and ('DONE' in states[-1] or 'END' in states[-1]):
lines.append(f" {states[-1]} --> [*]")
lines.append("```")
return '\n'.join(lines)
def generate_flowchart(code):
"""Generate basic flowchart from code structure."""
lines = ["```mermaid", "flowchart TD"]
lines.append(' A["Start"] --> B{"Check Condition"}')
lines.append(' B -->|Yes| C["Action A"]')
lines.append(' B -->|No| D["Action B"]')
lines.append(' C --> E["End"]')
lines.append(' D --> E')
lines.append("```")
return '\n'.join(lines)
def generate_timing_diagram():
"""Generate I2C timing sequence diagram."""
lines = ["```mermaid", "sequenceDiagram"]
lines.append(" participant M as Master")
lines.append(" participant S as Slave")
lines.append(" M->>S: START")
lines.append(" M->>S: ADDRESS + W")
lines.append(" S->>M: ACK")
lines.append(" M->>S: DATA")
lines.append(" S->>M: ACK")
lines.append(" M->>S: STOP")
lines.append("```")
return '\n'.join(lines)
def interactive_mode():
"""Interactive diagram generation."""
print("\n=== Mermaid Diagram Generator ===")
print("1. State Machine (from Arduino code)")
print("2. Flowchart (template)")
print("3. Timing Diagram (I2C example)")
choice = input("\nSelect type (1-3): ").strip()
if choice == '1':
file_path = input("Arduino file path: ").strip()
try:
with open(file_path, 'r') as f:
code = f.read()
states = extract_states(code)
transitions = extract_transitions(code, states)
print(f"\nFound {len(states)} states")
print(f"Found {len(transitions)} transitions")
diagram = generate_state_diagram(states, transitions)
print("\n" + diagram)
output = input("\nSave to file? (path or Enter to skip): ").strip()
if output:
with open(output, 'w') as f:
f.write(diagram)
print(f"Saved to {output}")
except FileNotFoundError:
print(f"Error: File not found: {file_path}")
return 1
elif choice == '2':
diagram = generate_flowchart("")
print("\n" + diagram)
elif choice == '3':
diagram = generate_timing_diagram()
print("\n" + diagram)
else:
print("Invalid choice")
return 1
return 0
def main():
parser = argparse.ArgumentParser(
description="Generate Mermaid diagrams from Arduino code",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
Examples:
uv run --no-project scripts/generate_diagram.py --input main.ino --type state-machine --output docs/fsm.mmd
uv run --no-project scripts/generate_diagram.py --interactive
uv run --no-project scripts/generate_diagram.py --type timing --output docs/i2c.mmd
"""
)
parser.add_argument('--input', '-i', help='Arduino input file (.ino)')
parser.add_argument('--type', '-t',
choices=['state-machine', 'flowchart', 'timing'],
default='state-machine',
help='Diagram type (default: state-machine)')
parser.add_argument('--output', '-o', help='Output file (.mmd or .md)')
parser.add_argument('--interactive', action='store_true',
help='Interactive mode')
args = parser.parse_args()
if args.interactive:
return interactive_mode()
# Non-interactive mode
if args.type == 'state-machine':
if not args.input:
print("Error: --input required for state-machine type")
return 1
try:
with open(args.input, 'r') as f:
code = f.read()
states = extract_states(code)
transitions = extract_transitions(code, states)
print(f"Extracted {len(states)} states, {len(transitions)} transitions")
diagram = generate_state_diagram(states, transitions)
except FileNotFoundError:
print(f"Error: File not found: {args.input}")
return 1
elif args.type == 'flowchart':
diagram = generate_flowchart("")
elif args.type == 'timing':
diagram = generate_timing_diagram()
# Output
if args.output:
with open(args.output, 'w') as f:
f.write(diagram)
print(f"Diagram saved to {args.output}")
else:
print(diagram)
return 0
if __name__ == "__main__":
sys.exit(main())