For the individual assignment, I produced a microcontroller development board based on the XIAO ESP32-C6. I took the provided Gerber files, generated the G-code using the Carvera software, milled the board on our Carvera desktop CNC mill, soldered the components, and tested it.
Design to G-Code Workflow
The workflow for producing this board:
- Started with the provided Gerber files (F.Cu for copper traces, Edge_Cuts for the board outline)
- Imported the Gerber files into the Carvera desktop software (MakerCAM)
- Converted the Gerber files to G-code toolpaths for trace isolation and board outline
- Exported the final .nc G-code file and sent it to the Carvera for milling
Milling the Board
I milled the board on our Carvera desktop CNC mill by Makera. It's a compact 3-axis CNC designed for PCB milling, wood, and soft metals.
Carvera Specs
- Work area: 200 × 150 × 60 mm
- Spindle speed: 1,000–12,000 RPM
- Positioning accuracy: ±0.01 mm
- Tool changer: Automatic 4-tool carousel
- Probing: Automatic Z-probe for PCB leveling
- Software: MakerCAM (built-in CAM for Gerber → G-code)
- Vendor: Makera — Carvera Desktop CNC
The Carvera software (MakerCAM) handled the conversion from Gerber to G-code, generating the toolpaths for trace isolation and the board outline cut.
Milling the XIAO ESP32-C6 board on the Carvera
CNC milled XIAO ESP32-C6 development board on the Carvera
Design Files
Soldering
After milling, I hand-soldered the pin headers and components onto the board. I don't have video of this process since it's nearly impossible to hold a camera steady while soldering — you need both hands for the iron and the solder.
My soldering technique for these CNC-milled copper boards:
- Solder paste first: I apply a fair amount of solder paste to the pads before placing components, especially on milled copper boards. The copper traces on a milled PCB don't have the plated-through holes or solder mask that commercial boards have, so the paste helps the solder flow and bond properly to the raw copper surface.
- Fine wire solder: I use very thin gauge solder wire for the actual joints. Thin wire gives much better control over how much solder you're applying — on small pads and tight traces, too much solder can easily bridge between adjacent traces and create shorts. With fine wire, you can feed just a tiny amount at a time.
- Clean tip: Keeping the soldering iron tip clean and tinned is critical on milled boards. A dirty tip doesn't transfer heat efficiently, which means you end up holding the iron on the pad longer, risking damage to the copper trace (which can delaminate from the FR4 substrate if overheated).
- Flux: The solder paste contains flux, which cleans the copper surface and helps the solder wet properly. On milled boards, the copper oxidizes quickly after cutting, so flux is essential for getting good joints.
Testing — LED Blink
After soldering the components onto the milled board, I wrote a simple blink program to verify that the board was working correctly. The code toggles an LED connected to GPIO17 (pin D7) on and off every 500ms. I uploaded the code to the XIAO ESP32-C6 using the Arduino IDE — for details on how to set up the Arduino IDE for the ESP32-C6 and upload code, see Week 4 — Embedded Programming.
// LED Blink Test — XIAO ESP32-C6 Custom PCB
// Toggles LED on GPIO17 (D7) every 500ms to verify board functionality
#define LED_PIN 17 // D7 = GPIO17
void setup() {
pinMode(LED_PIN, OUTPUT);
}
void loop() {
digitalWrite(LED_PIN, HIGH); // LED ON
delay(500);
digitalWrite(LED_PIN, LOW); // LED OFF
delay(500);
}
How the Code Works
- GPIO17 (D7): This is the pin connected to the LED on the custom PCB. The
#definemaps it to a readable name. - setup(): Configures GPIO17 as an output pin so it can drive the LED.
- loop(): Continuously toggles the pin HIGH (3.3V, LED on) and LOW (0V, LED off) with a 500ms delay between each state — creating a 1Hz blink pattern.
Board Test — LED Blinking
LED blinking on the custom milled PCB — board test successful