Íñigo Gutiérrez Febles
← Back to overview
Week 06

Electronics design

in-progress

weekly schedule.

Time blockWedThuFriSatSunMonTueWed
Global class3 h
Local class1,5 h1.5 h
Research2 h2 h1 h
Design3 h2 h
Fabrication
Documentation2 h1h1 h4 h
Review

background.

Electronics has been part of my training since university. During my engineering degree I worked extensively with circuit simulation — I ran my first electrical circuit simulations in PSpice, which gave me a solid foundation for understanding component behaviour before building anything physical. That said, the transition from schematic simulation to PCB design and physical fabrication is a different discipline, and this week was my first structured exposure to the full pipeline.

On the measurement side, the multimeter is a tool I use daily in my professional work as an automation and robotics engineer. Continuity checks, voltage verification, and basic component testing are routine tasks on industrial control systems, so that part of this week felt immediately familiar.


overview

This week is about electronics design — taking a circuit idea all the way from schematic to a fabrication-ready PCB using an EDA tool. Coming from an automation and robotics background, I deal with PLCs and pre-built boards every day, but I have never actually designed my own PCB from scratch. So this is genuinely new territory for me.

I used KiCad 9 (the CERN-backed open-source EDA tool) to design a simple development board around the Seeed XIAO RP2040 — the same microcontroller I have been working with since Week 04. The board has a socket for the XIAO, an LED with a current-limiting resistor, a tactile button with a pull-down resistor, and open header pins for future expansion. Simple on paper, but the real learning is in the process itself: understanding ERC errors, figuring out trace routing by hand, exporting SVGs correctly, and navigating the frankly unintuitive mods Project interface to generate toolpaths for the Roland MDX-20.

learning objectives.

  • Understand the full PCB design workflow: schematic → layout → fabrication files
  • Learn to use KiCad 9 (schematic editor, PCB editor, ERC, DRC)
  • Use the Fab Lab component libraries for KiCad
  • Understand what ERC and DRC check and why they matter
  • Generate fabrication-ready SVG files for PCB milling
  • Prepare toolpaths with mods Project for the Roland MDX-20
  • Use test equipment to observe microcontroller operation (group assignment)
  • Simulate a circuit

assignments.

  • Group assignment: Use the test equipment in the lab to observe the operation of an embedded microcontroller circuit (multimeter, oscilloscope, logic analyzer minimum)
  • Individual assignment — Simulate a circuit
  • Individual assignment — Design an embedded microcontroller system using parts from the Fab inventory, check design rules for fabrication
  • Extra credit: try another design workflow
  • Extra credit: design a case

group assignment — Test equipment.

For the group assignment, we need to demonstrate the use of test equipment on a microcontroller circuit board. I am documenting the instruments I will be working with. The actual testing will happen once the board is fabricated in Week 08 (Electronics Production).

Multimeter — Fluke 179 True RMS.

Fluke 179 True RMS multimeter with test probes and alligator clip accessories.
My Fluke 179 True RMS multimeter. I have been working with this one for over ten years.

This is my personal multimeter. I bought it years ago and it has been my daily instrument in the field — verifying motors, checking power distribution panels, debugging industrial control systems. It is the kind of tool you learn to trust.

FeatureSpecification
DC voltage0.1 mV – 1000 V
AC voltage0.1 mV – 1000 V (True RMS)
DC/AC current0.01 mA – 10 A
Resistance0.1 Ω – 50 MΩ
Capacitance1 nF – 9999 μF
Temperature-40 °C – 400 °C
Safety ratingCAT III 1000 V, CAT IV 600 V
Close-up of two pairs of Fluke test probes showing CAT III 1000V and CAT IV 600V safety rating markings.
Probe detail: CAT III 1000 V / CAT IV 600 V, 10 A rated. In my line of work I regularly measure 380–400 V AC lines, so the safety rating is non-negotiable.

I want to highlight the CAT III/IV rating specifically. In automation and robotics consulting, I frequently need to verify voltages on motors, power distribution lines, and control cabinets running at 380 V and 400 V AC. Having probes rated for those voltages is a safety requirement, not a luxury.

Testing and measurements with multimeter.

I recorded a demonstration of the different measurements and tests I performed on my XIAO RP2040 board using a digital multimeter. The video shows:

  • Voltage measurements across the integrated LED (parallel mode).
  • Continuity tests on PCB traces and solder joints.
  • Diode check mode to verify LED polarity and functionality.
  • Attempts to measure current consumption and the limitations encountered with integrated components.

Multimeter testing: voltage measurements, continuity checks, and diode verification on XIAO RP2040 board

This hands-on testing helped me understand the practical challenges of characterizing integrated modules versus discrete components.

Oscilloscope — DSO Shell (DIY kit).

DSO Shell DIY kit user manual showing soldering instructions and component list next to the assembled PCB.
The DSO Shell comes as a soldering kit (models 15001K/15002K). Good SMD practice, and you end up with a working oscilloscope.
Assembled DSO Shell pocket oscilloscope powered by a 9V Varta battery, showing a signal trace on screen.
DSO Shell in action, powered by a 9 V battery. Limited bandwidth and sample rate, but perfectly adequate for basic microcontroller signal inspection.

An oscilloscope displays electrical signals as waveforms: voltage on the vertical axis, time on the horizontal. Unlike a multimeter, which gives you a single static reading, an oscilloscope shows how a signal behaves over time — its shape, frequency, amplitude, and duty cycle. That makes it the right tool for anything involving PWM, communication protocols, or any signal that changes faster than a display can follow.

The DSO Shell at Fab Lab León is a pocket unit assembled from a DIY soldering kit. It runs on a 9 V battery and has limited bandwidth compared to a bench instrument, but it is fully adequate for inspecting microcontroller-level signals.

What do we expect to see?

PWM (Pulse Width Modulation) does not actually vary the voltage on a pin — it varies the proportion of time the pin spends at its high logic level within each cycle. At 1 kHz, the pin switches on and off 1000 times per second. The RP2040 operates at 3.3 V logic, so the pin alternates between 0 V and 3.3 V at that rate. The LED cannot respond fast enough to each individual pulse, so it perceives the average — which is why it appears to fade smoothly even though the pin is always either fully on or fully off.

On the oscilloscope screen we therefore expect to see a rectangular wave — clean vertical edges, a flat top at ~3.3 V, a flat bottom at 0 V — and the width of the high pulse changing continuously as the duty cycle ramps up and down. The carrier frequency should read close to 1000 Hz, and the Vpp should be close to 3.3 V.

Verifying the setup in Thonny.

Before connecting the oscilloscope, I went through a few steps to confirm the signal was actually present on the target pin.

Step 1 — Confirm the interpreter. In Thonny, Tools → Options → Interpreter must be set to MicroPython (RP2040) on the correct COM port. The status bar at the bottom of the window confirms this.

Step 2 — Check available pins. With no datasheet for the Qpad immediately at hand, I queried the board directly from the Thonny shell:

from machine import Pin
print(dir(Pin.board))  # lists all GPIO names exposed by the firmware

This returned all GPIO names available on the firmware, confirming GP26 (D0) was present and unassigned.

Step 3 — Verify PWM on the target pin. Before running the full fading loop, I sent a static 50 % duty cycle to GP26 to confirm the pin was functional:

from machine import Pin, PWM

p = PWM(Pin(26))      # assign PWM peripheral to GP26 (physical pad D0)
p.freq(1000)          # set carrier frequency to 1 kHz
p.duty_u16(32768)     # 32768 out of 65535 = 50 % duty cycle
print("OK")           # confirm execution reached this line

The shell returned OK and the LED lit at half brightness — confirming the pin was outputting PWM correctly.

Step 4 — Run the fading script. Once the static test passed, I loaded the full script:

from machine import Pin, PWM
from time import sleep

led = PWM(Pin(26))    # assign PWM to GP26 — D0 header pin, accessible with a probe

led.freq(1000)        # 1 kHz carrier: 1000 on/off cycles per second

while True:
    # ramp duty cycle up from 0 % to 100 %
    for duty in range(0, 65536, 512):      # 65535 = full on in MicroPython's u16 scale
        led.duty_u16(duty)                 # update duty cycle
        sleep(0.01)                        # wait 10 ms before next step

    # ramp duty cycle back down from 100 % to 0 %
    for duty in range(65536, 0, -512):
        led.duty_u16(duty)
        sleep(0.01)

The LED faded smoothly and continuously. With the signal confirmed active on D0, the oscilloscope probes could be connected with confidence.

Measurement.

The board used is the Qpad — a didactic game pad built around the XIAO RP2040, developed at CBA MIT. The black probe goes to a GND pad on the board; the red probe to the D0 header pin on the XIAO.

Qpad board with XIAO RP2040 mounted, showing the header pins and OLED display connector.
The Qpad with XIAO RP2040. The red probe connects to D0 (first header pin, left side of the XIAO counting from the USB-C connector); the black probe to any GND pad.

The DSO Shell was configured at 1 V/div vertically and 0.2 ms/div horizontally.

DSO Shell screen showing a rectangular PWM waveform at 1.112 kHz with Vpp 3.40 V and duty cycle 83.6%.
DSO Shell screen: 1.112 kHz rectangular wave, Vpp 3.40 V, duty cycle 83.6 %, period 0.898 ms. Scale: 1 V/div · 0.2 ms/div.
ParameterMeasuredExpected
Frequency1.112 kHz1.000 kHz
Period0.898 ms1.000 ms
Vpp3.40 V3.30 V
Duty cycle83.6 %0–100 % (sweeping)
Vrms1.21 V

Is this coherent with what we expected?

Yes, completely. The waveform is a clean rectangular wave — confirming the pin switches fully between its two logic states with no intermediate levels, exactly as PWM requires.

The frequency reads 1.112 kHz against the 1000 Hz set in code. The discrepancy comes from the overhead of the MicroPython interpreter executing the sleep() calls and the loop itself, which adds a few microseconds per cycle. This is normal and expected when generating PWM this way in MicroPython.

The Vpp of 3.40 V against the nominal 3.3 V of the RP2040 is within the DSO Shell’s calibration tolerance — a 3 % deviation is entirely acceptable for this instrument.

The duty cycle of 83.6 % simply reflects the exact moment in the fading sweep at which the oscilloscope triggered. Had the screenshot been taken a moment earlier or later it would show a different value — which is precisely the point: the duty cycle is what the code is changing continuously, and the oscilloscope captures it at one instant.

All observations are consistent with the code, with the expected behaviour of PWM, and with the visual result seen on the LED.

DSO Shell measuring the PWM output on pin D0 of the Qpad (XIAO RP2040). The waveform shifts as the duty cycle changes during the fading cycle.

Logic analyzer — 24 MHz 8-channel.

USB logic analyzer with 8 channels, cables, and Dupont jumper wires.
8-channel USB logic analyzer (24 MHz) from the Fab Lab. Useful for debugging I2C, SPI, UART, and other digital protocols.

A logic analyzer captures digital signals over time and displays them as timing diagrams. Unlike an oscilloscope, which measures voltage as a continuous analogue value, a logic analyzer only resolves high and low states — but it does so with high timing precision and can decode communication protocols (I2C, SPI, UART) automatically. For a PWM signal, the key advantage over the oscilloscope is the ability to capture several seconds of data and see how the duty cycle evolves across the entire recording.

The unit at Fab Lab León is a generic 8-channel USB device compatible with the Saleae Logic 2 software (version 2.4.42). It connects to the computer via USB and requires no external power.

Setup in Logic 2

Logic 2 device settings panel showing 12 MS/s sample rate, Timer mode set to 3 seconds, and Glitch filter enabled.
Device settings: 12 MS/s sample rate, Timer capture mode set to 3 seconds. No protocol analyzer added — the PWM signal is read as raw digital.

Configuration used:

  • Sample rate: 12 MS/s (closest available to the recommended 10 MS/s)
  • Capture mode: Timer — 3 seconds
  • Analyzers: none — PWM is not a serial protocol, so no decoder is needed
  • Channel: D0 only (CH0 on the logic analyzer)
  • Glitch filter: enabled

Connections are identical to the oscilloscope: CH0 cable to D0, GND cable to a GND pad on the Qpad.

Capture results

Logic 2 overview of the full 3-second capture on channel D0, showing hundreds of PWM pulses with visibly varying width across the timeline.
Full 3-second capture. The pulse width varies continuously across the recording — the duty cycle sweeping from 0 % to 100 % and back is clearly visible even at this zoom level.
Logic 2 zoomed view of several PWM cycles on channel D0, showing a measured period of 999.91 µs, pulse width of 749.917 µs, duty cycle 75 %, and frequency 1 kHz.
Zoomed view: period 999.91 µs, pulse width 749.917 µs, duty cycle 75 %, frequency 1 kHz. Logic 2 calculates these values automatically from the selected cycle.

Logic 2 capturing the PWM output on pin D0 of the Qpad (XIAO RP2040). The full 3-second timeline shows the duty cycle sweeping continuously as the fading script runs.

Oscilloscope vs logic analyzer — same signal, two perspectives

Both instruments measured the same PWM signal on pin D0. The results are consistent and complementary:

ParameterDSO Shell (oscilloscope)Logic 2 (logic analyzer)
Frequency1.112 kHz1.000 kHz
Period0.898 ms0.999 ms
Duty cycle83.6 %75 %
Vpp3.40 V— (digital only)
Timeline viewSingle frameFull 3 s sweep

The duty cycle and frequency differ between the two readings because each instrument captured a different moment in the fading sweep — the duty cycle is continuously changing, so any two snapshots will show different values. Both are correct for their respective instants.

The oscilloscope provides the voltage dimension — confirming the signal swings between 0 V and 3.3 V as expected. The logic analyzer provides the time dimension — the overview capture makes it immediately visible that the pulse width is sweeping across the full recording, something the oscilloscope cannot show in a single frame.

Neither instrument alone tells the complete story. Together they give a full characterisation of the signal.


Individual assignment — PCB design with KiCad

Setting up KiCad 9 and the Fab libraries

First step: install KiCad 9 and import the Fab Lab component libraries. These libraries contain symbols and footprints for the components available in the Fab inventory, which ensures whatever I design can actually be built with what we have in stock. The installation process follows the Fab Academy KiCad tutorial.

One important detail: when searching for components in the schematic editor, I had to make sure I was looking inside the Fab library folders specifically, not the default KiCad libraries. The Fab footprints match the actual parts we have.

Schematic design — first iteration

My board follows the minimum requirements for this week: a XIAO RP2040 on a socket, one LED, one tactile button, and open pins for future use. The circuit is straightforward:

  • M1: Module_XIAO_Generic_SocketSMD — the XIAO socket from the Fab library
  • D1: LED_1206 — a 1206-package LED connected to pin D0
  • R1: 1 kΩ resistor — current limiting for the LED (calculated for ~2 mA at 3.3 V with a ~1.8 V forward drop)
  • SW1: Switch_Tactile_Omron — a tactile push button connected to pin D1
  • R2: 470 Ω resistor — pull-down for the button
Initial KiCad schematic showing XIAO RP2040 socket with LED, resistor, button, and pull-down resistor. Pins D2 through D10 have no connections and no no-connect flags.
First version of the schematic. Notice pins D2–D10 are left floating with no no-connect flags — KiCad will complain about this.

A couple of things I got wrong on this first pass that Claude pointed out during our design session:

Resistor naming. I initially named the 1 kΩ resistor R1K, which is not standard EDA practice. The convention is to use a sequential reference designator (R1, R2, R3…) and put the value separately. KiCad’s annotation tool later caught this and renamed it to R1K1, which is still ugly. I ended up fixing it to just R1 with a value of 1K.

Unused pins need no-connect flags. Pins D2 through D10 are intentionally unused in this design, but KiCad does not know that. Without explicit no-connect flags (the X symbol), the ERC will flag every single one as an unconnected pin warning. In KiCad 9, you place them via Place → No Connect Flag or the shortcut Q.

Running the ERC — and learning from the errors

The Electrical Rules Check is where things got interesting. I ran it and got a wall of violations.

KiCad ERC showing 7 violations: 3 errors for undriven power input pins on 3V3, 5V, and GND, plus 4 warnings for unconnected global labels.
First ERC run: 3 errors and 4 warnings. The errors on the power pins are the ones that confused me the most.

The 4 warnings were about global labels (D0, D1, A0, A1) not being connected elsewhere in the schematic — single-sheet design, used once. Not a real problem.

The 3 errors were more puzzling: “Input Power pin not driven by any Output Power pins” on the XIAO’s 3V3 (pin 12), 5V (pin 14), and GND (pin 13). What does this even mean?

Claude’s explanation: The XIAO symbol in the Fab library defines 3V3, 5V, and GND as Power Input pins. KiCad expects every Power Input pin to be driven by a corresponding Power Output pin somewhere in the schematic. But since the XIAO generates these voltages internally from USB, there is no explicit Power Output pin in my schematic feeding those nets. The ERC sees undriven power rails and flags them as errors.

The fix: add a PWR_FLAG symbol to each of these nets. PWR_FLAG tells the ERC that the net is indeed powered. It is annotation-only — it does not add any physical component to the board.

This was a genuine “aha” moment. The circuit works perfectly fine without the flags, but understanding why the ERC complains — and resolving it properly instead of just ignoring the errors — felt like the right approach.

KiCad schematic editor showing the Properties panel for a global label A0, with the corrected schematic using global labels A0 and A1 for D0 and D1 connections.
Close-up of the corrected schematic using global labels (A0, A1) instead of the initial naming, with the Properties panel confirming the label type as Input.
KiCad showing both the Annotate Schematic dialog with the message Updated 1K from R1K to R1K1 and the ERC window showing zero violations.
After running annotations (which renamed R1K to R1K1 — a naming issue I later fixed properly) and adding PWR_FLAG symbols, the ERC came back clean.

Final schematic

Final corrected KiCad schematic with PWR_FLAG on 3V3, 5V, and GND nets, no-connect flags on unused pins D2 through D10, and clean component annotations.
The corrected schematic: PWR_FLAG symbols on 3V3, 5V, and GND; no-connect flags on D2–D10; properly named components R1 and R2.

The final schematic includes all the fixes: PWR_FLAG on the three power nets, no-connect flags on all unused XIAO pins, and properly named components. The ERC passes clean.

PCB layout — manual routing.

Moving from schematic to PCB layout, the first thing I did was set up the track widths in Board Setup → Design Rules → Pre-defined Sizes: 0.4 mm (standard for Fab Academy boards milled with a 1/64” endmill) and 0.8 mm as a wider option. In practice, I routed everything at 0.4 mm.

KiCad Board Setup dialog showing Pre-defined Sizes with track widths 0.4 mm and 0.8 mm configured.
Board Setup: pre-defined track widths. 0.4 mm is the standard for PCB milling with a 1/64 inch endmill.

I routed every trace manually — no autorouter. The principle is straightforward: keep traces as short and direct as possible. Less resistance, cleaner signal paths, and easier to mill. With only a handful of components, the routing was manageable, though I had to think carefully about physical placement to avoid crossings on a single-layer board.

Design Rules Check (DRC).

Once the layout was complete, I ran the DRC with “Test for parity between PCB and schematic” enabled. This checks not only physical design rules (minimum clearances, track widths) but also verifies that the PCB matches the schematic — no missing connections, no extra traces.

KiCad DRC result showing 0 violations, 0 unconnected items, 0 schematic parity errors. The routed PCB layout is visible behind the dialog.
DRC result: 0 violations, 0 unconnected items, 0 schematic parity errors. Ready for export.

Clean. Zero violations, zero unconnected items, zero schematic parity errors.

Exporting SVGs for fabrication.

For milling on the Roland MDX-20, we need SVG files — one for copper traces (F.Cu layer) and one for the board outline (Edge.Cuts layer). I went to File → Plot and configured the export:

KiCad Plot dialog configured for SVG export with F.Cu and Edge.Cuts layers selected.
Plot dialog configured for SVG export. F.Cu for traces, Edge.Cuts for the board outline.

I opened the exported SVGs in Illustrator to verify they looked correct before feeding them into mods:

F.Cu SVG opened in Adobe Illustrator showing the copper trace pattern in black on white background.
F.Cu SVG in Illustrator — verifying the trace pattern before sending to mods.
Edge.Cuts SVG opened in Adobe Illustrator showing an empty artboard with the board outline — the rectangle is not visible at this zoom level, showing the file is nearly blank.
Edge.Cuts SVG in Illustrator. The file opened correctly but the outline rectangle sits outside the default view area — zooming to fit reveals it.

Verifying toolpaths with mods.

mods Project is a web-based tool for generating machine toolpaths. It is… not the most intuitive interface I have ever used. The entire thing is a visual node-based pipeline where you connect processing modules with cables. Powerful in concept, overwhelming in practice when you first open it.

Full mods project pipeline for Roland Monofab PCB milling showing the complete node graph.
The full mods pipeline for the Roland MDX-20. It reads an SVG, converts it, applies thresholds, calculates distance transforms and offsets, generates toolpaths, and outputs to the machine or saves as a file.

Before going further, I wanted to verify the toolpath visually — roughly like a slicer preview in 3D printing. I loaded the PNG exported from the Gerber file (converted using gerber2png.fablelab.kerala.in) into mods and the result was completely wrong.

mods toolpath preview showing hundreds of spurious red movements scattered across the canvas, with the actual PCB traces highlighted in blue at the centre.
Toolpath preview loaded from Brave. The blue paths are the actual board traces; the red vectors are hundreds of spurious tool movements that would waste machining time without affecting the copper.

My instructors and I spent time troubleshooting — different export settings, different mods configurations. Nothing resolved it. The breakthrough came during a session with Nuria (one of the local instructors): she shared a PNG that had previewed correctly on her laptop, I loaded it on mine, and it was still broken. At that point I noticed the mods interface had changed slightly — it looked like the tool had been updated. On a hunch, I tried Firefox instead of Brave.

mods mill raster 2D toolpath preview in Firefox, showing clean concentric offset paths around all PCB features with no spurious movements.
The same board loaded in mods via Firefox. The mill raster 2D preview shows clean, ordered offset passes around each pad and trace — exactly what a correct toolpath should look like.
mods 3D preview in Firefox showing the copper-coloured PCB substrate with milled isolation channels around the board traces.
The updated mods 3D viewer (Firefox) renders a copper-toned simulation with isolation channels visible around the traces. This view confirmed the toolpath was interpreting the design correctly.

Brave is built on Chromium — the same open-source engine that powers Chrome — yet Chrome rendered mods correctly while Brave did not. The most likely explanation involves Brave’s aggressive privacy features, which by default can intercept or modify WebAssembly execution and canvas-based rendering. mods relies heavily on both for its toolpath computation. Maybe disabling Brave Shields for the mods domain could likely resolve it, but I have not confirmed this. For now, Firefox or Chrome are the verified browsers for running mods at Fab Lab León.

The milling parameters are configured in the “set PCB defaults” module:

mods Project PCB defaults module showing three tool profiles for trace and outline milling.
PCB defaults: three tool profiles. The 1/64 inch endmill is standard for trace isolation; 1/32 inch for cutting the board outline.
ProfileTool diameterCut depthMax depthOffsetsSpeed
Mill traces (1/64”)0.40 mm0.10 mm0.10 mm44 mm/s
Mill outline (1/32”)0.79 mm0.61 mm1.83 mm14 mm/s
Mill traces (10 mil)0.25 mm0.10 mm0.10 mm42 mm/s

The mill raster 2D module is where you hit Calculate to generate the toolpath:

mods mill raster 2D module showing calculated toolpath preview with red dots representing the cutting path.
Mill raster 2D after calculating the toolpath. The red dots show where the endmill will cut. 4 offset passes, 0.5 stepover, climb milling direction.

The save file problem.

After hitting Calculate, nothing happened when I tried to save the .rml file. Looking at the output section more carefully, I realized the save file module was disconnected — the on/off switch routing the toolpath output to “save file” was off (grey), while the switch going to WebUSB (direct machine connection) was active.

mods Project output section showing the Roland MDX-20 module, two on/off switches, WebUSB module, and save file module.
The output section. The upper switch routes to WebUSB (direct to machine), the lower switch to save file. I needed to activate the lower one to download the .rml.

The fix: click the lower on/off toggle to activate the save file route, then re-run Calculate. The .rml downloaded immediately. But it took me a while to figure this out — the visual feedback in mods is subtle and the documentation is sparse. Estimated machining time shown by mods: approximately 1 hour 25 minutes.

The actual milling will happen in Week 08 — Electronics Production.


Workflow diagram.

After going through this entire process, I want to leave a clear reference for my future self. This is the complete flow from idea to fabrication-ready files:

flowchart TD
    A["Install KiCad 9 + Fab Libraries"] --> B["Schematic Editor"]
    B --> B1["Place components from Fab library"]
    B1 --> B2["Wire connections"]
    B2 --> B3["Add PWR_FLAG to power nets"]
    B3 --> B4["Add no-connect flags to unused pins"]
    B4 --> B5["Run Annotate"]
    B5 --> C["Run ERC"]
    C -->|Errors| B
    C -->|Clean| D["PCB Editor"]
    D --> D1["Set track widths — Board Setup\n0.4 mm for 1/64 inch endmill"]
    D1 --> D2["Place and arrange components"]
    D2 --> D3["Route traces manually"]
    D3 --> D4["Draw board outline — Edge.Cuts"]
    D4 --> E["Run DRC with schematic parity"]
    E -->|Errors| D
    E -->|Clean| F["Export SVG — File → Plot"]
    F --> F1["F.Cu layer → traces"]
    F --> F2["Edge.Cuts → outline"]
    F1 --> G["mods Project"]
    F2 --> G
    G --> G1["Load SVG into\nRoland Monofab PCB pipeline"]
    G1 --> G2["Select tool profile\n1/64 in traces · 1/32 in outline"]
    G2 --> G3["Calculate toolpath"]
    G3 --> G4["Activate save file switch"]
    G4 --> H["Download .rml file"]
    H --> I["Mill on Roland MDX-20\nWeek 08"]

    style A fill:#0FD9B0,stroke:#0a8a6e,color:#000
    style I fill:#0FD9B0,stroke:#0a8a6e,color:#000

Simulation

Pending — I plan to simulate the LED + button circuit in Wokwi before fabrication.


Reflection

This was my first time designing a PCB from scratch, and honestly, the hardest part was not the circuit itself — it was navigating the tools. KiCad is powerful but has a steep learning curve, especially around library management and understanding what the ERC is actually telling you. The PWR_FLAG issue is a perfect example: the error message is technically correct but completely opaque if you do not already know how KiCad models power pins internally.

mods Project was the other surprise. The node-based pipeline is flexible, but the UI gives very little feedback about what is connected and what is not. The save file switch being off by default cost me a good chunk of time just staring at the screen wondering why nothing was downloading. And then the browser compatibility issue added another layer of frustration — spending time debugging a toolpath rendering problem that turned out to be a Brave vs. Firefox issue is not where you expect to lose an afternoon.

On the positive side, routing traces by hand on a simple board was satisfying. There is something appealing about finding the cleanest path for each connection, keeping things short and direct. I can see how this becomes a real puzzle on more complex boards.

The connection to my final project is clear: eventually I will need to design the control PCB for my standing desk — managing four synchronized motors with PID control, reading encoder feedback, driving a TFT display, and handling user input. This week’s board is trivial compared to that, but the workflow is the same. Just more components, more nets, and tighter constraints.

Design files

{/* TODO: add .rml files once milling is confirmed */}