# Electronics Production - Week 8 ---- ## Assignments > **Electronics Production** > > **group assignment** > > - characterize the design rules for your in-house PCB production process > > **individual assignment** > > - make and test a microcontroller development board that you designed > - extra credit: make it with another process ## Group Assignment [Group Page](https://fabacademy.org/2025/labs/ilmenau/assignments/week08/) ### General PCB-milling We used the [Marcera Carvera](https://www.makera.com/products/carvera) for milling the PCB, which is very convenient because of the automatic tool changer. #### Preparation For preparation, we did the following steps: **(-1. HOME THE CARVERA)** 0. We milled our bed flat so that the PCB is exactly flat on the surface 1. We first check, if the board is straight (with a straight object, here a caliper): - if not, we just bend it, until its straight ![IMAGE_STRAIGHT](../media/Week8/out/group_straight.jpg) 2. Next, we stuck double-sided tape onto our PCB and the PCB on our milling bed. Important here is: - The tape should have: **thin adhesive**, **not to strong**, **no strings/structure strengthener in it and on the side** - let edges of tape over PCB - look for dirt etc. - don't need to tape everywhere - press down! - should not move ::::{grid} :::{grid-item} ![IMAGE_TAPE](../media/Week8/out/group_tape.jpg) ::: :::{grid-item} ![IMAGE_STUCK](../media/Week8/out/group_flat_bed.jpg) ::: :::: 3. Another very important step is the exact Z-Zero point, which should be on top of the PCB with a high accuracy. - to deep -> mill might break (especially normal, thin mills, v-bit is fine) - to shallow -> path with not wide enough **Approaches:** 1. Use the auto-z-probe of the carvera, but this is not very precise und thus unsuitable ![IMAGE_Z_PROBE](../media/Week8/out/group_auto_probe.jpg) 2. Drop the tool, drive down and grab it again, but this approach also does not work that nice with de Carvera, because of the rubber stopper 3. Use a multi-meter, spin the mill and touch mill and board with the multi-meter and drive down, until it beeps ![IMAGE_Z_MULTI](../media/Week8/out/group_multimeter.jpg) We have chosen the 3. Method, which resulted in a good z-zeroing. 4. Now just setting the x and y work origin and milling could start. #### GCODE-Generation For generating the GCODE, we use the [Fabmodules](https://modsproject.org/) ([Source-Code](https://gitlab.fabcloud.org/pub/project/mods)) with the already prepared Carvera-Program. **How It Works** The Fabmodules use a black and white PNG file and look for edges from white to black, meaning that the **path to carve out should be white**. It just goes through the PNG line by line and calculates the distance to those black and white differences and saves the shortest one in a matrix. And this is done from every direction and reverse. This results in a big matrix where 0 means there is a trace and a bigger number means there is no trace.\ Then to generate the path, it uses on one hand the tool diameter and the offset-number to generate the path. Pretty cool and easy principle :D **Generation** So the workflow breaks down to those steps, when the pcb is designed in : 1. Generate the black and white PNG of the traces and exterior - more notes on those step is [below](#from-kicad-to-png), because its not trivial/easy (as I hoped) 2. Go to the [Fabmodules](https://modsproject.org/) and open the Carvera-Program (right-click->open program->carvera->mill 2D PCB) Also in the prepared program, an **exterior can be chosen simultaneously** to do the **path-carving and cutout in one go**. The 'mill 2D PCB all' program is used for removing all of the copper from the PCB. ::::{grid} :::{grid-item} ![IMAGE_FAB_MODULES_1](../media/Week8/out/fabmodules_program.png) ::: :::{grid-item} ![IMAGE_FAB_MODULES_2](../media/Week8/out/fabmodules_carvera.png) ::: :::: 3. On the left modules, 'Select PNG file' and upload on the top the pathes and on the bottom the exterior cutout. ![IMAGE](../media/Week8/out/fabmodules.png) 4. Next set your mill and PCB parameters on the middle 'mill dual tool'-module (especially the tool diameter and cut-depth and max-depth) and machine-speeds on the 'multi_toolpath to gcode'-module (maybe cut- and plunge-speed and spindel RPM). - we just changed: - first tool diameter: 0.2mm - cut depth: 0.3mm - cut max: 1.6mm - and reduced cut speed to 6mm/s and plunge-speed to 3mm/s - also in later setting we used for 'offset-number' 4, which resulted in better separated paths (from the rest-copper) 5. Then click 'Calculate' on the middle module to generate the gcode, you can then save the .nc file and look at the GCODE on a little preview (if it does not pop up, use 'view multitool_path ' module) ![IMAGE_GCODE](../media/Week8/out/design_rule_gcode.png) #### Milling In [Preparation](#preparation) we already setup the Carvera. So we just need to upload the GCODE tho the machine (bottom-left 'page'-icon -> upload), select the file (in the view, click select), last time check the g-code in the preview and then start the milling (bottom left play-button). ![IMAGE_MILLING](../media/Week8/out/design_rule_milled.jpg) Then use a scraper or knife to cut the taps and carefully break out the board from the rest. To clean up the traces, use the knife/scraper or steel wool to remove the ridge. ### Design-Rule To determine the design-rules, we used [Neil's Traces-Test](https://academy.cba.mit.edu/classes/electronics_production/linetest.traces.png). ![IMAGE_DESIGN_PARAM](../media/Week8/out/design_rule_finished.jpg) #### Outcomes **0.2mm vbit** - track width ~ 0.254mm - clearance ~ 0.178mm ## Individual Assignments ### From KiCAD to PNG For exporting the paths routed in KiCAD, there are many options (GERBER, SVG, PDF,...) but did it following steps 1. 'Plot' (the plot icon next to the printer) the traces and in the popup select 'SVG' in the top left dropdown and then select the layers to generate the paths (in my case only 'Edge.Cuts' and 'F.CU') and then 'Plot' in the bottom right. ![IMAGE_KiCAD_PLOT](../media/Week8/out/kicad_plot.png) 2. Open the SVGs in Inkscape, open 'Document Properties' and click 'Resize to content' - **IMPORTANT**, add a little margin (e.g. 1.5mm, also change from pixel to mm format, if not already) so that lines on the edges are properly recognizes in fab-modules 3. Select all and center it again (you need to group everything and 'CTRL+SHIFT+A', the 'Align and Distribute'-Tab). 4. Maybe invert the colors for lines and filled pads (can be annoying, because traces are stroked paths and pads are not stroked but filled shapes -.-), but can also be done in the fab-modules - **IMPORTANT** for the exterior, the howl board and exterior need to be distinct shapes, NOT PATHs, so it should look like my examples below 5. Then, if the image and the paths should look right, open the 'Export'-Tab (CTRL+SHIFT+E), and Export it as a PNG - **IMPORTANT** set the **DPI to ~1000**, so the PNG has a high enough resolution for the Fabmodules!! Then for the milling process, see [above](#milling) ### Test Programmer Boards #### FTDI USB Bridge For testing out above PNG generating method, I first used the [USB-to-Serial Bridge](https://gitlab.fabcloud.org/pub/programmers/programmer-serial-d11c) from the lecture and adjusted the design-rules in KiCAD (in 'Board Settings' under 'Design-Rules'). Also tried out tracing a bitmap to paths which flowered good. ##### PNG ![IMAGE_PNG_TRACES](../media/Week8/out/at_tiny_programmer_traces.png) ![IMAGE_PNG_EXTERIOR](../media/Week8/out/at_tiny_programmer_outline.png) ##### GCODE ![IMAGE_FAB_MODULES](../media/Week8/out/bridge_gcode.png) ##### Milling ::::{grid} :::{grid-item} ![IMAGE_MILLING_1](../media/Week8/out/bridge_mill.jpg) ::: :::{grid-item} ![IMAGE_MILLING_2](../media/Week8/out/bridge_milling.jpg) ::: :::: ![IMAGE_milled](../media/Week8/out/bridge_finished.jpg) ::::{grid} :::{grid-item} ![IMAGE_POST](../media/Week8/ftdi_clean_traces.jpg) ::: :::{grid-item} ![IMAGE_POST](../media/Week8/ftdi_clean_traces2.jpg) ::: :::: Here I also scratched away the milled traces in the USB connector. **Cutting** I also cut some vinyl for the back because the PCB is not thick enough for the USB slot. ::::{grid} :::{grid-item} ![IMAGE_CUTTING](../media/Week8/out/bridge_cutting.jpg) ::: :::{grid-item} ![IMAGE_CUTTING](../media/Week8/ftdi_back.jpg) ::: :::: **Result** ![IMAGE_FINISHED](../media/Week8/out/bridge_milled.jpg) ##### Soldered On soldering I finally tried out the FLUX technique for soldering an MCU, which works as follows: - first, carefully fix the IC on one pin so that every leg is on the pads - next cover the legs in FLUX (I used a brush) - now use a bug enough soldering iron head and put a bit of solder on it - then slowly and with a reasonable temperature (I used 300°C) scrape with the wide side over the in FLUX covered legs (cover multiple pins at once) until every leg has enough solder With a bit of practice works very nicely. ![IMAGE_SOLDERED](../media/Week8/out/bridge_soldered.jpg) #### SWD Programmer But the above board can't be programmed, without an SWD programmer, which could also be handy for other boards, so I milled this [USB SWD Programmer](https://gitlab.fabcloud.org/pub/programmers/programmer-swd-d11c): ::::{grid} :::{grid-item} ![IMAGE](../media/Week8/Programmer-SWD-D11C-F_Cu.png) ::: :::{grid-item} ![IMAGE](../media/Week8/Programmer-SWD-D11C-Edge_Cuts.png) ::: :::: There I also tried out to mill away everything between the parts. ::::{grid} :::{grid-item} ![IMAGE](../media/Week8/swd_solder.jpg) ::: :::{grid-item} ![IMAGE_PROGRAMMER](../media/Week8/swd_milled.jpg) ::: :::: #### Programmer Recursion Here I thought, I could flash this one directly via USB but I then found out, I also need a Programmer for this one... NOOOOOOO -.- But in Neil's lecture about Embedded Programming, I found [a litte article](https://learn.adafruit.com/programming-microcontrollers-using-openocd-on-raspberry-pi/overview) about using the Raspberry Pi for programming via [OpenOSC](http://openocd.org/) ([Github](https://github.com/openocd-org/openocd/)). So I tried that out as described in the article. For accessing the pi, I used my own network setup, which made some parts a bit more complicated but I didn't need an extra display, mouse and keyboard :D. ![IMAGE](../media/Week8/pi_pc_setup.jpg) :::::{hint} :class: dropdown I used [Archlinux](archlinuxarm.org) for my PI, but I needed following packages: ```bash $ pacman -S base-devel autoconf pkgconf gcc automake ``` And unfortunately for the configure-step, you need [jimtcl](https://aur.archlinux.org/packages/jimtcl), which we need to build from scratch... And also to work with OpenOSC's GPIO access, the device `/dev/gpiomem` needs to be accessible which is not present in the standard archlinux-aarch64 kernel because if the missing kernel-module/build parameter. But fortunately there is the `linux-rpi` kernel directly from RaspberryPi available: ```bash $ pacman -S linux-rpi ``` For this to install, you need to uninstall the current kernel and also the uboot-firmware but it will still works! ::::{note} OpenOSC actually is already build and available via pacman but unfortunately it does not ork with the RaspberryPi config, because the build of the package was not configured with support for gpio pins.. So you need to build it yourself. :::: ::::: I only adjusted following steps of the provided config to work with my device: ```bash # download the formware for the SWD flasher soldered above wget https://academy.cba.mit.edu/classes/embedded_programming/SWD/free_dap_d11c_mini.bin ``` Then I followed the instructions from the article and it worked :D. ![IMAGE](../media/Week8/pi_flash_setup.jpg) Then I could use the SWD programmer to flash the FTDI programmer with: ```bash edbg -ebpv -t samd11 -f sam_ba_SAMD11C14A.bin ``` ![IMAGE_FLASH_SETUP](../media/Week8/flasher_flash_setup.jpg) And to test it, I took a small ATTiny board with an LED and... ::::{grid} :::{grid-item} :columns: 7 ![IMAGE_PROGRAMMER](../media/Week8/flash_attiny.jpg) ::: :::{grid-item} ![IMAGE](../media/Week8/attiny_works.jpg) ::: :::: Blinks!! ### Own PCB I improved my PCB from the Electronics Design Week, so I fixed the DRC and shortened the board a bit. The tricky part here was milling the hols... #### PNG First Images where not inverted, which resulted in way to big holes. ::::{grid} :::{grid-item} ![IMAGE_PNG_TRACES](../media/Week8/out/Assignment-traces.png) ::: :::{grid-item} ![IMAGE_PNG_EXTERIOR](../media/Week8/out/Assignment-Holes.png) ::: :::: Then I inverted it but there was a weird line in the gcode preview, which was because the inverted version on the right side was not completely black: ![IMAGE_GIMP](../media/Week8/out/gimp.png) So I fixed it in GIMP and then the path was better. #### GCODE Here the weird line from the wrong png. ![IMAGE_FAB_MODULES](../media/Week8/out/PCB_weird_gcode.png) And here with the fixed version: ![IMAGE_FAB_FIXED](../media/Week8/PCB_good_gcode.png) #### Milling ![IMAGE_MILLING_1](../media/Week8/out/PCB_milling.jpg) ```{video} ../media/Week8/pcb_milling.mp4 :width: 100% ``` ::::{grid} :::{grid-item} ![IMAGE_MILLING_2](../media/Week8/out/PCB_milling_finished.jpg) ::: :::{grid-item} ![IMAGE](../media/Week8/PCB_milled.jpg) ::: :::: ::::{grid} :::{grid-item} Here the version where I forgot the Inversion: ![IMAGE_FINISHED](../media/Week8/out/PCB_finished.jpg) Here the holes are way to big... ::: :::{grid-item} And here the version with inversion: ![IMAGE_FINISHED](../media/Week8/out/PCB_better_finished.jpg) Better (I know, I didn't clean it right) ::: :::: #### Design Fail After it to me was pointed out, that: - traces are most of the time way to big, I used 0.3mm but 0.4-0.6mm would be better - I used way to small 0-ohm resistors (and also I didn't needed them at all -.-) - I should place SMD and through hole components on different sides #### Redesign So after above things where pointed out to me, I adjusted the design accordingly (changed the midi direction so I can mount it on the bottom, adjusted the resistor footprint and rerouted): ![IMAGE_PATHS](../media/Week8/PCB_redesign.jpg) #### Construction ![IMAGE](../media/Week8/PCB_solder.jpg) For easier soldering the legs onto the XIAO, I used this little technique ferdi recommended me: ::::{grid} :::{grid-item} :columns: 7 ![IMAGE](../media/Week8/xiao_solder1.jpg) First stick the pins into a breadboard and solder on the MCU. Then stick the header onto the foots and solder it on for a good alignment. ::: :::{grid-item} ![IMAGE](../media/Week8/xiao_solder2.jpg) ::: :::: :::{note} Here I just used tongs to bend the THT header to be an SMD one xD. I forgot to change the footprint -.- ::: ![IMAGE](../media/Week8/PCB_finished_solder.jpg) #### Testing I first test with a laboratory PSU and a multi-meter: ![IMAGE_TEST](../media/Week8/PCB_test_LED.jpg) There unfortunately I killed one LED because I set allowed current to high and had the voltage a bit to high -.- ![IMAGE](../media/Week8/dead_led_better.jpg) I changed it and everything worked fine without XIAO. For testing with the XIAO I used just a [basic LED Blink example](https://github.com/espressif/esp-idf/tree/master/examples/get-started/blink) and adjusted it for my matrix: ```c #include "driver/gpio.h" #include "esp_log.h" #include "freertos/task.h" static const char *TAG = "example"; #define BLINK_GPIO 7 #define CONFIG_BLINK_PERIOD 1000 // in ms static uint8_t s_led_state = 0; static void blink_led(void) { /* Set the GPIO level according to the state (LOW or HIGH)*/ for (int i = 1; i < 4; i++) { gpio_set_level(i, s_led_state); } } static void configure_led(void) { ESP_LOGI(TAG, "Example configured to blink GPIO LED!"); for (int i = 1; i < BLINK_GPIO; i++) { gpio_reset_pin(i); /* Set the GPIO as a push/pull output */ gpio_set_direction(i, GPIO_MODE_OUTPUT); if (i >= 4) { // for the matrix, set all negative pins to low gpio_set_level(i, 0); } } } void app_main(void) { /* Configure the peripheral according to the LED type */ configure_led(); while (1) { ESP_LOGI(TAG, "Turning the LED %s!", s_led_state == true ? "ON" : "OFF"); blink_led(); /* Toggle the LED state */ s_led_state = !s_led_state; vTaskDelay(CONFIG_BLINK_PERIOD / portTICK_PERIOD_MS); } } ``` And it also worked :D ```{video} ../media/Week8/led_blink.mp4 :width: 100% ``` I then did more about it in [Input](TODO) and [Output devices](./output_devices.md#final-project-poc). ## Notes - [Adrianino](https://fabacademy.org/2020/labs/leon/students/adrian-torres/adrianino.html) ### KiCAD - U .. select entire tracks (may need to be pressed multiple times) - under/near chip small track width - good base track width: - 0.4mm - 0.6mm - thicker for power lanes ### Fab modules - [Fab Modules](https://modsproject.org) - use chrome - offset-number -> rounds around traces - 0 == fill/mill all away - think about tool thickness when milling - DRC Check in KiCAD!! (Design-Rule Check) - png dpi >= 500 ### Carvera -> make folder for yourself on it (for gcode) - nc .. Numerical Control - PCB-milling z == 0 on top of the PCB - for centering/finding exect x,y zero - 'Edge-Finder' - PCB mill-shank is smaller then wood milling shank - don't forget ring, if not on it already - check, if tool changer tool is deep in the holes (the plastic ring should be almost in) - adapter for probe if used another shank - always home!! ### PCB Milling - RC1 vs RC4 important for design-rules - before milling the PCB, use a hair-ruler to check, it it is straight - most error is the PCB is not fixed enough or it it is not straight enough - PCB glewing very important (double-sided tapes) - **thin adhesive**, **not to strong**, **no strings/structure strengthener in it** - let edges of tape over PCB - look for dirt etc. - don't need to tape everywhere - press down! - should not move - important -> make sure, baseboard is flat! (just mill it flat) - z-zero-ing needs to be perfect (easily brake mill)