Week 8: Electronics design

This week, the PCB designed in Week 6 was revisited and brought into the manufacturing stage using a MonoFab machine, followed by soldering and programming.

Before starting

A Printed Circuit Board (PCB) is a platform used to mechanically support and electrically connect electronic components through conductive copper traces etched onto a non-conductive substrate. PCBs are a fundamental element in modern electronics, as they allow circuits to be compact, robust, and reproducible.
Compared to a protoboard, PCBs offer several important advantages. While protoboard are ideal for rapid prototyping and testing due to their flexibility and reusability, they suffer from loose connections, susceptibility to noise, and limited current handling.
In contrast, PCBs provide stable electrical connections, reduced interference, improved signal integrity, and a much more compact and professional layout. This makes them suitable for final products and long-term use.
There are several types of PCBs depending on their complexity:
Single layer:

Which have one conductive layer and are used for simple circuits.

Double layer:

Which allow routing on both sides, improving space usage and design flexibility.

Multi layer:

Which consist of multiple stacked layers and are used in complex systems such as computers and embedded devices.

The manufacturing process of a PCB can vary depending on the available tools. In this case, a MonoFab (CNC milling machine) was used. This process involves:
  1. Importing the PCB design (usually in Gerber format).
  2. Milling the copper layer to isolate the traces (removing unwanted copper).
  3. Cutting the board outline (edge cuts).
  4. Soldering the components onto the board.
Other common manufacturing methods include chemical etching, where unwanted copper is removed using chemical solutions, and industrial fabrication, which uses advanced techniques such as photolithography for high precision.
Regarding components, modern PCB design heavily relies on Surface Mount Devices (SMD). These components are mounted directly onto the surface of the PCB, unlike traditional through-hole components, which require holes drilled through the board. SMD components offer several advantages:
  • Smaller size, enabling compact designs.
  • Better performance at high frequencies.
However, SMD components require more precision during soldering, especially when done manually, as they are smaller and more sensitive.
Additionally, designing a PCB involves considering factors such as power distribution, grounding (GND planes), trace width, and component placement, all of which impact the performance and reliability of the circuit. For example, adding a copper pour (like in the week6) to reduce noise, improves current return paths, and simplifies routing.
For further information about this topic and the machines at IBERO Puebla, please consult this week’s group page.

Export files

Using the PCB design from Week 6 as a base, a few adjustments need to be made before manufacturing.
The board outline must be placed on the Edge.Cuts layer, as this defines the physical shape of the PCB. Since the milling tool that will be used has a diameter of 2 mm, the outline must be designed with a line width equal to or greater than this value to ensure proper cutting and avoid inaccuracies during fabrication.
Fab termi
Fab termi
For the holes required to place or mount components on the board, these will be drawn on the User.1 layer for convenience. This can be done by creating circles with the required diameter, making sure they are adjusted according to the tool size that will be used. It is important to set these shapes as filled so they are properly interpreted during the manufacturing process.
Fab termi
Once this setup is complete, the next step is to generate the fabrication files by navigating to:
File -> Fabrication Outputs -> Gerbers (.gbr).
Fab termi
In the pop-up menu, some changes are required:
  • Change the output format to SVG, since this format is compatible with the MonoFab workflow.
  • Select each of the previously defined layers individually (such as traces, Edge.Cuts, and User layers).
  • Enable the option “Fit page to board” to ensure the design scales correctly.
  • Finally, click on “Plot” to generate the files.
Fab termi
Fab termi
With the SVG files generated, the design is now ready to move on to the next stage of the manufacturing process.
Fab termi
There are several ways to generate files suitable for Manufacturing Readiness Levels (MRL), which ensure that a design is properly prepared for fabrication. One practical approach is using a web-based tool developed by the Fab Lab community called MODS CE.
Within this platform, a wide variety of machines can be selected from the left-hand menu. In this case, the Roland SRM-20 milling machine was chosen under the “mill 2D PCB” option.
Fab termi
Fab termi
Fab termi
The interface provides a modular workflow, where each step corresponds to a stage in preparing the machining process. The first step is to import an .svg file, which contains the PCB design.
The modules “Read SVG” and “Convert SVG Image” are used to visualize and manipulate the working area of the PCB. These allow the user to define dimensions and identify cutting regions, which are typically shown in black (indicating where the tool will remove material). Another important module is “Set PCB Defaults”, which works in conjunction with “mill raster 2D”, as it defines the tool parameters such as cutting depth, speed, and offsets.
Fab termi

Drilling Process

For drilling operations, a 0.79 mm drill bit is used. Before exporting the toolpath, it is necessary to adjust the feed rate in the Roland SRM-20 milling machine module to 0.2 mm/s, which helps prevent tool breakage due to excessive stress.
Fab termi
Fab termi
Additionally, the origin must be set to (0,0,0) in both the XY plane and Z axis to ensure proper alignment during machining. To export the file, the on/off button must be set to “true”, after which clicking “calculate” generates the toolpath. A preview of the PCB can be displayed by clicking “view”, or it may appear automatically after calculation.
Fab termi
Fab termi
An important detail

is that some holes, such as those for the transistor, may not appear. This occurs because the drill bit diameter is larger than the hole size defined in the design, making it impossible for the tool to reproduce those features accurately.

Traces Milling

The process for milling traces is similar, but with a key difference. When importing the SVG, the traces may appear in black, which indicates that they will be removed this is incorrect for PCB traces.
Fab termi
To fix this, the image must be inverted in the “Convert SVG Image” module, so that the tool removes only the surrounding copper and preserves the traces.
For this step, a 0.40 mm flat end mill is used with a feed rate of 4 mm/s, and the origin is again set to (0,0,0).
Fab termi
Fab termi
Fab termi
A limitation

observed in this stage is that small features, such as micro-USB pins, may appear merged in the preview. This happens because the tool diameter is too large to properly isolate such fine details, which is an important consideration when designing for CNC milling.

Board Outline

Finally, for cutting the board outline, a 1.59 mm cutout tool is used with a feed rate of 4 mm/s, maintaining the origin at (0,0,0).
Fab termi
Fab termi
In this case, the outline is correctly represented, and the toolpath accurately follows the intended board shape.
Fab termi
Fab termi

Board

SRM-20 by DGSHAPE

Moving on to the SRM-20 by DGSHAPE, the first step is to properly secure the PCB material onto the sacrificial bed. This is done using double-sided tape, ensuring the board is firmly attached. The sacrificial bed itself must be fixed to the MonoFab base using the provided screws or bolts to prevent any problem during machining.
Fab termi
Fab termi
Fab termi
To power on the machine, press the power button located at the back of the SRM-20.
Fab termi
Once the machine is on, open the control software VPanel, which allows manual and automated control of the milling process. The interface contains several important menus:
Fab termi
Set Origin Point:

This is used to define the reference position of the machine. The X/Y axes are set to establish the horizontal origin, and the Z axis is set separately to define the vertical starting point.

Move:

This option allows manual positioning of the toolhead to locate the origin or move to a specific point on the board.

Cursor Step:

Adjusts the step size or speed of manual movements, enabling fine or coarse positioning depending on the need.

Spindle:

Controls the rotation of the milling spindle. It is especially useful when setting the Z axis, as the tool can be carefully lowered without applying excessive force that could damage it.

Process Controls

These manage the execution of the machining jobs.

To load machining files, click on the “Cut” button. A new window will appear:
  1. Click “Delete All” to remove any previously loaded jobs.
  2. Click “Add” and select the .rml files generated earlier in MODS.
It is critical to follow the correct processing order:
Drilling -> Traces -> Outline
This order is essential because:
  • If drilling is done after milling traces, it may damage or lift the copper tracks.
  • If the outline is cut first, the board may move, ruining the remaining processes.
Fab termi
After loading the files in the correct order, press “Output” to start the machining process.

Tooling and Setup Considerations

The tool dimensions used in MODS correspond to real milling bits:
Process Tool Diameter
Drilling 0.8 mm
Traces rounded to 0.4 mm
Cutout 2 mm
Fab termi
Each tool must be manually installed by inserting the bit into the spindle and tightening it using an Allen key on the set screw.
Since each tool serves a different purpose, they must be changed between operations. This is why the files are executed separately and in a specific order.
Important:

Every time the tool is changed, the Z axis must be recalibrated, since the tool length may vary. Failing to do this can result in improper cutting depth or tool breakage.

The complete workflow consists of:
  1. Securing the PCB material to the bed.
  2. Setting the X, Y, and Z origin points.
  3. Loading the .rml files in the correct order.
  4. Running each process sequentially (drilling, traces, cutout).
  5. Changing tools and recalibrating Z between each step.
Fab termi

Solder

With the PCB already milled and cut, the next step is soldering. Since most of the components are SMD, it is necessary to pretin the pads before placing the components. This process consists of applying a small amount of solder to the pad by heating it with the soldering iron for a few seconds, and then feeding solder from the opposite side until it melts and forms a thin, even layer.
Once the pad is pretinned, the component can be positioned and soldered by reheating the pad and allowing the solder to secure it in place.
Fab termi
Fab termi
The soldering temperature used is 700°F (~370°C), which provides a good balance between efficient heat transfer and control. If the temperature is too low, the solder may not flow properly, resulting in weak or “cold” joints. On the other hand, excessively high temperatures can damage components, lift PCB pads, or degrade the board material.
Fab termi

Soldering Temperatures

Temperature (°F) Application
600–650°F Delicate components, low thermal mass
650–700°F General SMD soldering (recommended range)
700–750°F Through-hole components or larger pads
750°F+ Heavy ground planes (use with caution)
Fab termi
For a more efficient assembly process, it is recommended to solder components in the following order:
  1. Capacitors and resistors (smallest components)
  2. LEDs (SMD)
  3. Buttons and connectors
  4. Microcontroller (XIAO RP2040)
This approach, going from smallest to largest, improves accessibility and reduces the risk of interfering with already soldered components.
Fab termi
Fab termi

Problems

Most of the issues encountered during fabrication were related to tool limitations during the milling process. In some cases, the milling bits were not fine enough to properly isolate the traces, causing them to remain partially connected.
  • When traces are unintentionally shorted, a practical solution is to carefully use a precision knife (cutter) to remove excess copper and separate the tracks.
Fab termi
Fab termi
Another issue appeared with the transistor holes, as no drill bit smaller than the lead thickness was available. This made it nearly impossible to create proper through-hole pads. As a workaround, the transistor leads were cut and the component was adapted into an SMD-like configuration.
However, this modification has several implications:
  • Reduced mechanical strength, making the component more fragile.
  • Higher risk of poor electrical contact due to smaller soldering area.
  • Potential long-term reliability issues, especially under vibration or stress.
Fab termi
Fab termi

Code

Installing the XIAO RP2350 in Arduino IDE

To allow the Arduino IDE to recognize the XIAO RP2350, it is necessary to install the appropriate board support libraries and configure the board correctly, including forcing it into programming mode when needed.
To understand the process, the following prompt was given to Gemini:
prompt

How can I program my XIAO RP2350 with Arduino?

Gemini

The Arduino IDE does not include native support for the RP2350 by default. Therefore, it is necessary to install the Earle Philhower core, which is widely considered the standard for RP2040/RP2350-based boards.
Steps:

1. Install Board Support (Core)

  • Open Arduino IDE and go to File → Preferences.
  • In the field “Additional Board Manager URLs”, paste the following link:
  • https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json
  • Then go to Tools → Board → Board Manager.
  • Search for “Raspberry Pi Pico/RP2040” and install it (making sure it includes RP2350 support).

2. Configure the XIAO in Arduino IDE

Once installed:
  • Board: Select Seeed XIAO RP2350
  • Optimization: Leave as Small (-Os)
  • Port: It may not appear the first time; this is normal.

3. Enter Bootloader Mode

If the board is not detected, it must be forced into bootloader mode:
  1. Connect the XIAO via USB-C
  2. Press and hold the BOOT button
  3. Press and release the RESET button
  4. Release the BOOT button
The device should now appear as an external drive named:
RPI-RP2

Code Adaptation and Libraries

Once the board was ready, an existing Arduino example was reused from the forum post by Arduino Forum (Keyboard/Mouse/Joystick Tutorial). Since this code dates back to 2015, it required updating to work with modern libraries and hardware.
After consulting Gemini, the required libraries were:
  • Adafruit_TinyUSB.h Enables USB HID functionality
  • Adafruit_NeoPixel.h Controls WS2812B RGB LEDs

The original Arduino Uno code was adapted to the XIAO RP2350 by:
  • Updating pin mapping to match XIAO pin labels (D0–D6)
  • Replacing simple serial output with USB HID keyboard functionality
  • Integrating NeoPixel control for RGB effects
  • Adding motor feedback control
This allows the device to function as a macro keyboard, sending real keystrokes to the computer.

Uploading the Code

Once the code is ready:
  1. Select the correct port where the XIAO is connected
  2. Select the correct board (Seeed XIAO RP2350)
  3. Click Verify to compile
  4. Click Upload to flash the program

CODE

The final code is:


#include <Adafruit_NeoPixel.h>
#include "Adafruit_TinyUSB.h"

// --- CONFIGURACIÓN PINES ---
const int pinRevPag = D0;
const int pinChrome = D1;
const int pinAt1    = D2; // Shift
const int pinAt2    = D3; // Tab
const int pinAt3    = D4; // Windows
const int pinRGB    = D5; // Pin para tus WS2812B
const int pinRetro  = D6; // Motor

// --- CONFIGURACIÓN NEOPIXEL ---
#define NUM_LEDS 10 
Adafruit_NeoPixel pixels(NUM_LEDS, pinRGB, NEO_GRB + NEO_KHZ800);
long pixelHue = 0;

// --- CONFIGURACIÓN USB HID ---
uint8_t const desc_hid_report[] = { TUD_HID_REPORT_DESC_KEYBOARD() };
Adafruit_USBD_HID usb_hid(desc_hid_report, sizeof(desc_hid_report), HID_ITF_PROTOCOL_KEYBOARD, 2, false);

void setup() {
  usb_hid.begin();
  pixels.begin();
  pixels.setBrightness(50); 

  pinMode(pinRevPag, INPUT_PULLUP);
  pinMode(pinChrome, INPUT_PULLUP);
  pinMode(pinAt1,    INPUT_PULLUP);
  pinMode(pinAt2,    INPUT_PULLUP);
  pinMode(pinAt3,    INPUT_PULLUP);
  pinMode(pinRetro,  OUTPUT);

  Serial.begin(115200);
}

void loop() {
  efectoGamer();

  if ( !TinyUSBDevice.mounted() ) return;

  // --- REVPAG ---
  if (digitalRead(pinRevPag) == LOW) {
    digitalWrite(pinRetro, HIGH);
    uint8_t keycode[6] = { HID_KEY_PAGE_UP }; 
    usb_hid.keyboardReport(0, 0, keycode);
    while(digitalRead(pinRevPag) == LOW) efectoGamer(); 
    usb_hid.keyboardRelease(0);
    digitalWrite(pinRetro, LOW);
  }

  // --- CHROME (Secuencia) ---
  if (digitalRead(pinChrome) == LOW) {
    digitalWrite(pinRetro, HIGH);
    // Alt + F4
    uint8_t f4[6] = { HID_KEY_F4 };
    usb_hid.keyboardReport(0, KEYBOARD_MODIFIER_LEFTALT, f4);
    delay(100); usb_hid.keyboardRelease(0);
    delay(500);
    // Win + R
    uint8_t r_key[6] = { HID_KEY_R };
    usb_hid.keyboardReport(0, KEYBOARD_MODIFIER_LEFTGUI, r_key);
    delay(100); usb_hid.keyboardRelease(0);
    delay(400);
    // Escribir "chrome"
    const char* cmd = "chrome";
    for(int i=0; cmd[i]; i++) {
      uint8_t k[6] = { (uint8_t)(HID_KEY_A + (cmd[i] - 'a')) };
      usb_hid.keyboardReport(0, 0, k);
      delay(30); usb_hid.keyboardRelease(0); delay(30);
      efectoGamer();
    }
    // Enter
    uint8_t enter[6] = { HID_KEY_ENTER };
    usb_hid.keyboardReport(0, 0, enter);
    delay(100); usb_hid.keyboardRelease(0);
    while(digitalRead(pinChrome) == LOW) efectoGamer();
    digitalWrite(pinRetro, LOW); 
  }

  // --- Shift ---
  if (digitalRead(pinAt1) == LOW) {
    digitalWrite(pinRetro, HIGH);
    uint8_t keycode[6] = { 0 }; 
    usb_hid.keyboardReport(0, KEYBOARD_MODIFIER_LEFTSHIFT, keycode);
    while(digitalRead(pinAt1) == LOW) efectoGamer(); 
    usb_hid.keyboardRelease(0);
    digitalWrite(pinRetro, LOW);
  }

  // --- Tab ---
  if (digitalRead(pinAt2) == LOW) {
    digitalWrite(pinRetro, HIGH);
    uint8_t keycode[6] = { HID_KEY_TAB };
    usb_hid.keyboardReport(0, 0, keycode);
    while(digitalRead(pinAt2) == LOW) efectoGamer(); 
    usb_hid.keyboardRelease(0);
    digitalWrite(pinRetro, LOW);
  }

  // --- Windows ---
  if (digitalRead(pinAt3) == LOW) {
    digitalWrite(pinRetro, HIGH);
    uint8_t keycode[6] = { 0 }; 
    usb_hid.keyboardReport(0, KEYBOARD_MODIFIER_LEFTGUI, keycode);
    while(digitalRead(pinAt3) == LOW) efectoGamer(); 
    usb_hid.keyboardRelease(0);
    digitalWrite(pinRetro, LOW);
  }
}

void efectoGamer() {
  for (int i = 0; i < pixels.numPixels(); i++) {
    int hueOffset = i * (65536 / pixels.numPixels());
    pixels.setPixelColor(i, pixels.gamma32(pixels.ColorHSV(pixelHue + hueOffset)));
  }
  pixels.show();
  pixelHue += 256; 
  if (pixelHue >= 5 * 65536) pixelHue = 0;
  delay(5); 
}


Results

In my computer and gameplay

Fab termi

Download files

For download 3D and others files, just click on the dancing shrimp.