8. Electronics Production

XIAO ESP32-C3 Development Board

This week I made and tested a microcontroller development board that I designed in Week 6. The workflow covers PCB layout export, G-code generation in Mods CE, CNC milling on the KEXU machine, component soldering, and functional verification. I also participated in the group assignment to characterize our lab's in-house PCB production process.

Assignment checklist

  • Linked to the group assignment page
  • Documented how I made the toolpath
  • Documented how I milled, stuffed, and soldered the board
  • Documented that my board is functional
  • Explained problems and how I fixed them
  • Uploaded source code and included a hero shot of my board

Assignment Tasks

Group Assignment

As a group we characterized how PCBs are made at Chaihuo — both in-house on the KEXU CNC and through a board house (JLCPCB). We tested machine parameters, documented the milling workflow, and compared milled vs. manufactured boards.

Week 8 Group Assignment — Chaihuo Fab Lab

What I learned from the group work

TopicKey takeaway
Design rules In-house milling needs ≥ 0.38 mm trace/space. Wider power buses are more reliable than thin signal traces after milling.
Z zero A board that is not flat or a Z zero that is slightly off produces shallow traces or cuts into the sacrificial layer. The paper-drag test is critical.
Mods workflow KiCad Gerber → PNG → Mods CE → G-code bridges design and the CNC controller. Always simulate before cutting copper.
Browser choice Use Chrome or Edge with Mods. Some browsers produce bad toolpaths with unwanted dots.
Post-milling Clean the board (scrape loose copper, wash off FR-4 dust) before soldering — oils and dust cause bad joints.

CNC Machine for Electronics Production

Last week I studied CNC machining on a larger machine. The same principles — fixturing, tool selection, origin setup, and G-code execution — apply to the smaller CNC mill we use for electronic production.

At Chaihuo Fab Lab I milled my board on the KEXU (刻序) benchtop CNC. PNG images are exported from KiCad Gerbers, toolpaths are generated in Mods CE, and the resulting .nc files are loaded directly into the machine controller.

Tools used for this board

OperationToolNotes
Trace isolation40° #502 V-bitOnly V-bits in our lab inventory are suitable for PCB tracing
Outline cut1.5 mm ball-end millUsed to cut the board free from the copper-clad sheet
Safety & machine care:
  • Place a sacrificial backing plate (wood) under the copper board.
  • Secure both the base and the board with double-sided tape.
  • Set the origin carefully at the start — confirm tool position before pressing start.
  • Wear a mask and goggles — FR-4 dust is fine and should not be inhaled.

Preparation — Components & Circuit

I designed this development board in Week 6, using the Fab Academy KiCad library. The carrier hosts a Seeed Studio XIAO ESP32-C3 with breakout headers, a push-button, and LEDs for I/O testing.

Bill of materials

ComponentQuantityRef on board
Seeed Studio XIAO ESP32-C31U1
CONN HDR 6POS 0.1" TIN SMD2J1, J2 — left & right pin breakouts
Tactile Switch SPST-NO Top Actuated SMD1SW1
LED 1206 SMD2D1, D2
RES 1 kΩ 1% 12062Current-limiting resistors for LEDs
RES 10 kΩ 1% 12061Button pull-up (revised design)

G-code Generation in Mods CE

I followed the Mods CE PCB milling workflow to go from KiCad design to CNC toolpaths. PNG images are required because they are lossless — JPEG compression can break fine trace geometry.

Step 1 — Export Gerber from KiCad

  1. In KiCad PCB Editor: File → Fabrication Outputs → Gerbers.
  2. Selected F.Cu (front copper) and Edge.Cuts (board outline).
  3. Exported the front copper and edge-cut Gerber files.
Export Gerber from KiCad

KiCad fabrication output — selecting layers for Gerber export.

Step 2 — Convert Gerber to PNG

  1. Uploaded the Gerber files to Gerber2Png.
  2. Set up the trace layer and edge layer, then exported PNG files.
  3. Verified that traces appeared as white lines on a black background (correct polarity for Mods).
Gerber2PNG upload interface

Gerber2PNG — upload Gerber files and configure layer export.

Exported trace and outline PNG files

Exported traces_toplayer_0.png and outline_toplayer_2.png ready for Mods.

Step 3 — Generate toolpaths in Mods CE

  1. Opened Mods CE in Chrome → right-click → programOpen Program.
  2. TRACES — This tool works with both SVG (top section) and PNG (bottom section). I used PNG. Click select png file and select traces_toplayer_0.png.
  3. The traces image appears in the preview window.
  4. Set the PCB milling preset to 40°#502 V-bit.
  5. Enable file output by turning the On/Off toggle ON.
  6. In Mill Raster 2D, click calculate to generate the G-code.
  7. Review the 3D preview simulation to verify the toolpath.
  8. Click save file to download traces_toplayer_0.png.nc.
  9. Outline pass: reloaded Mods, loaded outline_toplayer_2.png, set ball-end / end-mill parameters → Calculate → saved the outline file.
Mods CE PCB milling interface

Mods CE — PCB milling preset and Mill Raster 2D configuration.

Mods CE 3D toolpath preview

3D preview of the trace isolation toolpath before saving the G-code file.

Machine parameters used

ParameterV-bit (tracing)Ball-end mill (outline)
Feed speed4 mm/s4 mm/s
Spindle speed14,000 rpm14,000 rpm
Offset number44
Offset stepover0.2 mm0.2 mm
Cut depth0.23 mm0.45 mm
Tool40° #502 V-bit (0.3 mm effective)1.5 mm ball-end mill

CNC Setup & Milling

Fixturing the copper board

  1. Placed the single-sided copper-clad board (1.6 mm FR-4) on the sacrificial wooden backing plate.
  2. Secured it with double-sided tape and checked that the board was flat across the work area.

Tool change & zeroing

  1. Installed the V-bit for tracing and tightened it with the provided wrenches.
  2. Set X/Y at the front-left corner of the copper board.
  3. Set Z using the paper-drag test — lower until the bit just scratches the tape, then set Z = 0.
Changing tool on KEXU CNC

Installing and tightening the milling tool inside the KEXU CNC work chamber.

CNC setup with copper board

Copper-clad board secured on the sacrificial layer, ready for origin calibration.

Start milling

  1. Loaded traces_toplayer_0.png.nc from USB (FAT32, no hyphens in filename).
  2. Moved the tool above the origin point before pressing start.
  3. Ran the trace program first at 14,000 rpm spindle speed.
  4. Swapped to the ball-end mill, re-zeroed Z, loaded the outline G-code, and cut the board free.

PCB trace milling on the KEXU CNC — V-bit isolating copper traces on the development board.

CAUTION: After loading the toolpath and pressing start, milling begins immediately. Always confirm the tool is positioned above the origin before starting the job.

Post-processing

After milling there were burrs on the board surface. I removed them with sandpaper, then washed the board with soap and water to remove oils and FR-4 dust before soldering.

Problems and How I Fixed Them

Problem 1 — Shallow trace isolation (forgot to reset Z0)

On my first test I milled in different areas of the copper board but forgot to reset Z0 when moving to a new region. In some areas the V-bit did not cut deep enough, leaving thin copper bridges between traces.

Fix

Re-zeroed Z carefully using the paper-drag test at the chosen cutting region, then re-ran the trace G-code. After finding a flat area on the board, the second pass produced clean trace isolation.

Problem 2 — Bad toolpath from browser choice

My first attempt at generating G-code in Mods using an unsupported browser produced a toolpath with stray dots and irregular patterns around pad areas.

Fix

Switched to Chrome as recommended in the group documentation. Regenerated the toolpath — the simulation looked clean with no stray dots.

Problem 3 — First-time SMD soldering

This was my first time soldering 1206 SMD components. The tiny parts were difficult to hold in place without tweezers, and I accidentally bridged two adjacent XIAO castellated pads.

Fix

Used fine tweezers to position each component, tacked one corner first, then flowed solder on the remaining pads. Removed the bridge with solder wick and flux, then verified continuity with a multimeter.

Problem 4 — Pull-up resistor not correctly connected

After soldering the milled board, the button input did not work reliably. I checked the circuit again and found that the pull-up resistor was not correctly connected to the button net in the original layout.

Fix

I corrected the schematic and PCB in KiCad, adding a proper pull-up resistor to the button circuit, then ordered a revised board from JLCPCB. The manufactured board passed all functional tests.

Revised schematic with pull-up resistor on button

Revised circuit — pull-up resistor correctly connected to the button input.

Soldering

After milling and cleanup I soldered all components onto the board. I worked at the Fab Lab bench with a fume extractor, multimeter, and fine-tip soldering iron.

  1. SMD passives first: resistors, LEDs, and the tactile switch — tacked one corner, then soldered remaining pads.
  2. Headers: inserted both 1×6 pin headers, tacked one pin each for alignment, then soldered all pins.
  3. XIAO module last: placed the ESP32-C3 on its castellated pads, aligned the USB-C port flush with the board edge, and soldered each pad carefully.
  4. Inspection: checked all joints under magnification for bridges and cold joints.
Soldering setup at Fab Lab bench

Preparing SMD components and the milled board at the soldering station.

Soldering XIAO ESP32-C3 module

Soldering the XIAO ESP32-C3 module — tweezers are essential for positioning small SMD parts.

Finished soldered board

Milled board after soldering all components.

Board Testing

Pin mapping (revised board)

On the corrected HelloworldNew board, the button and LEDs connect to these XIAO ESP32-C3 pins:

PinConnected toDirectionNotes
D7Tactile switch (SW1)InputUses INPUT_PULLUP — reads LOW when pressed
D8LED 1 (D1)OutputActive HIGH through 1 kΩ resistor
D9LED 2 (D2)OutputActive HIGH through 1 kΩ resistor

What the test program does

  1. Setup: starts USB serial at 115200 baud, configures D7 as input with internal pull-up, and sets D8/D9 as outputs (both off).
  2. Loop: reads the button state every 10 ms.
  3. On press: when the button goes from not-pressed (HIGH) to pressed (LOW), waits 50 ms for debounce, then toggles both LEDs together.
  4. Serial output: prints LED ON or LED OFF to the serial monitor so I can confirm the button is detected.

How to upload

  1. Open HelloWorldWeek8.ino in Arduino IDE.
  2. Board: XIAO_ESP32C3 · Port: the USB-C serial port · Enable USB CDC On Boot.
  3. Upload, then open Serial Monitor at 115200 baud.
  4. Press the button — both LEDs should toggle; serial monitor should print the new state.

Test firmware

Full source: HelloWorldWeek8.ino

/*
 * HelloWorldWeek8.ino
 * Button on D7 (INPUT_PULLUP) — press reads LOW
 * LEDs on D8 and D9 — toggle together on each press
 */

#define SWITCH_PIN  D7
#define LED1_PIN    D8
#define LED2_PIN    D9

bool ledState = false;
bool lastButtonState = HIGH;

void setup() {
  Serial.begin(115200);
  pinMode(SWITCH_PIN, INPUT_PULLUP);
  pinMode(LED1_PIN, OUTPUT);
  pinMode(LED2_PIN, OUTPUT);
  digitalWrite(LED1_PIN, LOW);
  digitalWrite(LED2_PIN, LOW);
}

void loop() {
  bool currentButtonState = digitalRead(SWITCH_PIN);

  // Detect falling edge: button just pressed (HIGH → LOW)
  if (lastButtonState == HIGH && currentButtonState == LOW) {
    delay(50);  // debounce
    ledState = !ledState;
    digitalWrite(LED1_PIN, ledState ? HIGH : LOW);
    digitalWrite(LED2_PIN, ledState ? HIGH : LOW);
    Serial.println(ledState ? "LED ON" : "LED OFF");
  }

  lastButtonState = currentButtonState;
  delay(10);
}

Test results

Result: The revised JLCPCB board passed all tests.

Hero Shot

The finished XIAO ESP32-C3 carrier board — designed in KiCad, first milled on the KEXU CNC, then revised and manufactured by JLCPCB after fixing the pull-up resistor connection.

Hero shot — finished XIAO ESP32-C3 PCB

Button press toggles the LEDs; serial monitor prints the button state over USB.

Reflection & Key Takeaways

  1. Design for your machine. Trace width and clearance must match the milling process, not just KiCad DRC defaults.
  2. Z zero is everything. Forgetting to reset Z0 when moving to a new board region was my biggest milling mistake.
  3. Simulate before cutting. Mods 3D preview and Wokwi simulation both caught issues before wasting copper or ordering a bad board.
  4. Check the schematic, not just the layout. The pull-up resistor bug only became obvious after soldering — a continuity check against the schematic would have caught it earlier.
  5. Two fabrication methods teach different lessons. Milling taught me fixturing and Z-height; JLCPCB gave me a reliable board to verify the corrected circuit.

Source Files

All design, manufacturing, and firmware files for this assignment:

KiCad design

FileDescription
HelloworldNew.kicad_sch Schematic — revised design with pull-up resistor fix
HelloworldNew.kicad_pro KiCad project file
HelloWorldWeek6-F_Cu.gbr Front copper Gerber (original Week 6 design, used for milling)
HelloWorldWeek6-Edge_Cuts.gbr Board outline Gerber (original Week 6 design)
Week 6 documentation Original KiCad design workflow

Milling files (PNG → G-code)

FileDescription
traces_toplayer_0.png Trace layer image — input to Mods CE for isolation milling
outline_toplayer_2.png Board outline image — input to Mods CE for cutout
drills_toplayer_1.png Drill layer image
traces_toplayer_0.png.nc Generated trace G-code — loaded on KEXU CNC to mill copper traces

Firmware (source code)

FileDescription
HelloWorldWeek8.ino Arduino test program — button on D7 toggles LEDs on D8/D9, prints state over serial
← Week 7 Back to Assignments Week 9 →