Electronics Design

06-electronics-design.org-screenshot-2026-03-04_14-02-05.png.jpg

1. Week assignments

Group assignment:

  • Use the test equipment in your lab to observe the operation of a microcontroller circuit board (as a minimum, you should demonstrate the use of a logic analyzer)
  • Document your work on the group work page and reflect what you learned on your individual page

Individual assignment:

  • Use an EDA tool to design a development board that uses parts from the inventory to interact and communicate with an embedded microcontroller

2. Prior Knowledge

I have never used any of the tools discussed before so I am very excited to get started.

3. Work!

This week we will be playing around with KiCad. I already installed version 9 during the student bootcamp.

3.1. Group assignment

Here are some photos of the excellent local lecture Erwin gave.

06-electronics-design.org-IMG_20260226_104912.jpg
Figure 1: Erwin explaining "full bridge rectifier"
06-electronics-design.org-IMG_20260226_123200.jpg
Figure 2: Erwin explaining how to use an oscilloscope

Heleen did an excellent job describing our group efforts this week.

Erwin brought a mystery Arduino Uno which did "stuff" on pins and we were tasked to find out what it does, using the oscilloscope and a logic analyser. It was a fun quest but at some point some of the pins stopped going from high to low. Reconnecting the USB of the board helped so we crashed the firmware! The pins which did not stop flip-flopping were pins with PWN activated so that was an interesting find we could not have made without crashing the software.

We used the following measurement tools:

  • Multimeter
  • Oscilloscope (for the manual see this link)
  • Logic Analyser (shop for it here)
06-electronics-design.org-IMG_20260226-163000.jpg
Figure 3: Me assisting Henk with the Logic Analyser (photo by Heleen)

3.2. Simple LED in KiCad

To install the "KiCad FabLib" library in KiCad, I went to Tools -> Plugin and Content Manager -> Libraries, selected the library, used Install and Apply pending changes. It contains the component inventory of the fablabs for use with KiCad.

Then I created a new project in KiCad called "simple-led", opened Preferences and Manage Symbol Libraries. From the Global Libraries list I (only) selected PCM_fab. Next, I opened the Schematic Editor and was presented with a blank canvas.

3.2.1. Schematic

For the first experiment, I want to make a simple circuit to light an LED using an LED and resistor from the "FabLib". I selected the Place Symbols tool, placed a "LED_1206" and a "R_1206" component on the canvas. Then I used Place Power Symbols to add "PWR_GND" and "PWR_5V". With the Draw Wires tool, I connected the LED cathode to ground, the LED anode to the resistor and the other side of the resistor to 5V.

06-electronics-design.org-screenshot-2026-03-01_16-14-14.png.jpg
Figure 4: Basic LED circuit

Running the Electric Rules Checker (ERC) gave me two errors about "Input Power pin not driven by any Output Power pins". For "PWR_GND" and "PWR_5V".

06-electronics-design.org-screenshot-2026-03-01_16-17-22.png.jpg
Figure 5: ERC errors about power pins

I searched the web and found a KiCad forum post about exactly this issue. Adding "PWR_FLAG" to both wires directly connected to the power symbols fixed the ERC errors. If I understand it correctly, KiCad expects a power source such as a battery or voltage regulator to provide power but no such component is available in the "FabLib".

06-electronics-design.org-screenshot-2026-03-01_16-31-35.png.jpg
Figure 6: Basic LED circuit with power flags

3.2.2. PCB

Next, I wanted to see what a Printed Circuit Board (PCB) would look like for this circuit. I switched to the PCB editor and ran Update PCB from Schematic.

06-electronics-design.org-screenshot-2026-03-01_16-51-03.png.jpg
Figure 7: Update PCB from Schematic

This dropped both components (note, there's no power components here because they are "special" symbols) on the canvas. After placing them next to each other a narrow blue line appeared between them.

06-electronics-design.org-screenshot-2026-03-01_16-54-39.png.jpg
Figure 8: Blue line between LED and Resistor

Surely the Design Rules Checker (DRC) should fail on this so I ran it. It failed on two errors:

  • Violation: "Board has malformed outline (no edges found on Edge.Cuts layer)"
  • Unconnected Items: "Missing connection between items"
06-electronics-design.org-screenshot-2026-03-01_16-59-34.png.jpg
Figure 9: Missing connection between items

To fix the first issue, I selected the Edge.Cuts layer and used the Draw Rectangle tool to draw a box around the two components. For the second issue I used the Route Single Track tool to draw a trace between the LED and the resistor. Running the DRC yielded no more errors.

06-electronics-design.org-screenshot-2026-03-01_17-07-14.png.jpg
Figure 10: Complete PCB
06-electronics-design.org-screenshot-2026-03-01_17-08-35.png.jpg
Figure 11: 3D view of the PCB

Now, it became very apparent that the power symbols are just some markers. The PCB does not have a way to connect a power source and ground to it. The "FabLib" only contains a coin cell battery holder component, which is an obvious connector for hooking up a battery. I could not find any other connector that is an obvious connector for other power sources. Header pins, perhaps?

3.2.3. Simulation

I noticed KiCad comes with a Simulator tool in the schematic editor, so I just started it to see what happens. It opened a new window with some output on it:

Note: Compatibility modes selected: ps lt a
Line no. 3, d1 __d1, missing tokens
warning, can't find model 'r_1206' from line
r1 net-_d1-a_ pwr_5v r_1206
Circuit: KiCad schematic
Error on line 2 or its substitute:
r1 net-_d1-a_ pwr_5v r_1206
unknown parameter (r_1206)
Command: esave none

It seemed to find my schematic confusing, so I added a value of "100" to "R1" in the schematic editor to make it understand it is a 100Ω resistor. I closed the simulator and reopened it.

Note: Compatibility modes selected: ps lt a
Line no. 3, d1 __d1, missing tokens
Circuit: KiCad schematic
Error on line 3 or its substitute:
d1 __d1
could not find a valid modelname
Command: esave none

That helped for the resistor but it was still confused about "D1", the LED. I opened the properties of the LED in the schematic and found a Simulation Model button which allows me to select a "SPICE model".

06-electronics-design.org-screenshot-2026-03-01_17-32-48.png.jpg
Figure 12: Simulation model

Unfortunately, there's no LED model to select, so I selected Diode because an LED is a diode. I reopened the simulator and the errors were gone.

Note: Compatibility modes selected: ps lt a
Circuit: KiCad schematic
Command: esave none

So I hit "Run Simulation", giving me the following output:

Circuit: KiCad schematic
Doing analysis at TEMP = 27.000000 and TNOM = 27.000000
Using SPARSE 1.3 as Direct Linear Solver
Warning: singular matrix:  check node probe_int_net-_d1-a__r1_1
Note: Starting dynamic gmin stepping
Warning: singular matrix:  check node probe_int_net-_d1-a__r1_1
Warning: Dynamic gmin stepping failed
Note: Starting true gmin stepping
Warning: singular matrix:  check node probe_int_net-_d1-a__r1_1
Warning: singular matrix:  check node probe_int_net-_d1-a__r1_1
Warning: singular matrix:  check node probe_int_net-_d1-a__r1_1
Warning: singular matrix:  check node probe_int_net-_d1-a__r1_1
Warning: True gmin stepping failed
Note: Starting source stepping
Warning: source stepping failed
Note: Transient op started
Note: Transient op finished successfully
 Reference value :  0.00000e+00
No. of Data Rows : 1


Simulation results:

I(r1):                    0A
I(d1):                    -7.8616e-122fA
V(pwr_gnd):               7.8616e-11fV
P(d1):                    -9.58985e-247fW
V(pwr_5v):                -3.9308e-11fV
V(net-_d1-a_):            -3.9308e-11fV
P(r1):                    3.26063e-257fW

Hmm, fA, fV, fW, all femto values; \(10^{-15}\). These values are basically zero…

Searching for a solution, I found this KiCad 9 simulation video which adds a special power source for simulations. At that point, I did not have any simulation components available in the component picker. So I went back to the KiCad start window and opened Preferences to open the Manage Symbol Libraries window, found the "Simulation_SPICE" library and activated it. Back in the schematic editor, I could add a "VDC" component from the simulation library and hook it up to the "PWR_GND" and "PWR_5V" parts of the net.

06-electronics-design.org-screenshot-2026-03-01_17-48-19.png.jpg
Figure 13: Schematic including simulator power

I reran the simulator but the results are not much better:

Simulation results:
I(r1):                    -5.01pA
I(d1):                    -5.01pA
I(v5):                    -5.01pA
P(v5):                    -25.05pW
V(pwr_gnd):               -5V
P(d1):                    25.05pW
V(pwr_5v):                258.016pV
V(net-_d1-a_):            -242.984pV
P(r1):                    2.51001e-06fW

Pico values; \(10^{-12}\)…

I think, the diode needs more simulation model parameters set. I started with Limiting Values.

06-electronics-design.org-screenshot-2026-03-01_18-04-35.png.jpg
Figure 14: Limiting values of diode

But the values remained the same. Confused, I tried swapping the direction of the LED and the values seemed closer to what I expected.

Simulation results:

I(r1):                    -42.4791mA
I(d1):                    42.4791mA
I(v5):                    -42.4791mA
P(v5):                    -212.396mW
V(pwr_gnd):               -2.85415V
P(d1):                    31.948mW
V(pwr_5v):                2.14585V
V(net-_d1-k_):            -2.10206V
P(r1):                    180.448mW

And they were nicely drawn into the schematic.

06-electronics-design.org-screenshot-2026-03-01_18-08-03.png.jpg
Figure 15: Schematic with simulation values

I do not know if these values make any sense at all.

The direction of the LED was really bugging me. I opened the Simulation Model for the LED and the anode and the cathode are swapped in the Pin Assignments?!

06-electronics-design.org-screenshot-2026-03-01_22-32-46.png.jpg
Figure 16: Anode and Cathode are swapped?

So I swapped them and fixed the schematic. The result became worse.

Circuit: KiCad schematic
Doing analysis at TEMP = 27.000000 and TNOM = 27.000000
Using SPARSE 1.3 as Direct Linear Solver
Warning: singular matrix:  check node probe_int_net-_d1-a__d1_1
Note: Starting dynamic gmin stepping
Warning: singular matrix:  check node probe_int_net-_d1-a__d1_1
Warning: Dynamic gmin stepping failed
Note: Starting true gmin stepping
Warning: singular matrix:  check node probe_int_net-_d1-a__d1_1
Warning: singular matrix:  check node probe_int_net-_d1-a__d1_1
Warning: singular matrix:  check node probe_int_net-_d1-a__d1_1
Warning: singular matrix:  check node probe_int_net-_d1-a__d1_1
Warning: True gmin stepping failed
Note: Starting source stepping
Warning: source stepping failed
Note: Transient op started
Error: Transient op failed, timestep too small
Error: The operating point could not be simulated successfully.
Any of the following steps may fail.!
DC solution failed -
Last Node Voltages
------------------
Node                                   Last Voltage        Previous Iter
----                                   ------------        -------------
probe_int_net-_d1-a__d1_1                      -nan                 -nan
probe_int_probe_int_pwr_gnd_d1_d1_2                 -nan                 -nan
probe_int_pwr_gnd_d1                           -nan                 -nan
d1probe_int_vref                               -nan                 -nan
d1:power                                       -nan                 -nan
net-_d1-a_                                     -nan                 -nan
pwr_gnd                                        -nan                 -nan
probe_int_pwr_5v_v5_1                          -nan                 -nan
probe_int_pwr_gnd_v5_2                         -nan                 -nan
v5probe_int_vref                               -nan                 -nan
v5:power                                       -nan                 -nan
pwr_5v                                         -nan                 -nan
probe_int_net-_d1-a__r1_1                      -nan                 -nan
probe_int_probe_int_pwr_5v_r1_r1_2                 -nan                 -nan
probe_int_pwr_5v_r1                            -nan                 -nan
r1probe_int_vref                               -nan                 -nan
r1:power                                       -nan                 -nan
bprobe_int_r1power#branch                         0                    0
r1:probe_int_n1#branch                         -nan                 -nan
r1:probe_int_n2#branch                         -nan                 -nan
bprobe_int_r1vref#branch                          0                    0
bprobe_int_v5power#branch                         0                    0
v5:probe_int_n1#branch                         -nan                 -nan
v5:probe_int_n2#branch                         -nan                 -nan
bprobe_int_v5vref#branch                          0                    0
bprobe_int_d1power#branch                         0                    0
d1:probe_int_a#branch                          -nan                 -nan
d1:probe_int_c#branch                          -nan                 -nan
bprobe_int_d1vref#branch                          0                    0
r1#branch                                      -nan                 -nan
v5#branch                                      -nan                 -nan
d1#branch                                      -nan                 -nan
doAnalyses: OP:  Timestep too small; trouble with node "d1probe_int_vref"
run simulation(s) aborted

Simulation results:

I'm giving up..

3.3. Simple LED in EveryCircuit

To find out if the values I found in the KiCad simulation (when I swapped the LED) made any sense I, tried EveryCircuit. I recreated the circuit there and ran it.

everycircuit-1.png
Figure 17: Simple LED in EveryCircuit

Well, that did not help. I was even more confused now.

A nice thing about EveryCircuit is that it will show a burning component when you over power it.

everycircuit-2.png
Figure 18: Burning LED in EveryCircuit

3.4. Clock Board with a Microcontroller

In week 4, I played with the XIAO RP2040, and this week I wanted to make a clock (my final project is an alarm clock) using that microcontroller. The RP2040 contains a Real-Time Clock (RTC), so it should be able to keep time and does not need some extra component to do so. I don't know how I will display time in my final project yet but this week I'll try and see if I can build a 7-segment display digits out of LEDs.

The problem with 7 segment displays is that I need to have \(4 \times 7 = 21\) output pins to drive all LEDs and the XIAO only has 10 I/O pins. I can get rid of one when the left digit only shows 1 or 2 and no 0, but that will not help me much.

Doing a web search, I found out this is, of course, a solved problem. There are specialized chips which can translate a 4-bit (0 till 9 can be encoded in 4 bits) value to a 7-segment output. For instance, the 7447 chip is a "BCD to 7-Segment Decoder". Unfortunately, that still leaves me at \(4 \times 4 = 16\) pins which is still 6 pins over budget.

More web searches reveal that this can be solved by Charlieplexing, which basically only lights up a specific group of LEDs at a specific time but alternates these groups very fast, so the human eye perceives them as all glowing simultaneously. This reminds me of PIO programming on the RP2040, so that should be doable!

As a general rule, using Charlieplexing, one can drive \(n \times (n-1)\) LEDs with \(n\) pins. So, 10 pins can drive \(10 \times 9 = 90\) LEDs! With 6 pins I should be able to drive \(6 \times 5 = 30\) LEDs.

This article about Charlieplexing describes pretty well how to wire these up. So I opened KiCad to write a schematic for this.

06-electronics-design.org-screenshot-2026-03-02_11-14-50.png.jpg
Figure 19: Schematic for 28 LEDs connected to RP2040 XIAO

The ERC reported unused pins on the XIAO; I do not know what to do with that.

Next, the PCB! It took me a couple of minutes to realize I had stepped into a horror story. Something I should have realized when making the schematic: plenty of crossing wires!

06-electronics-design.org-screenshot-2026-03-02_11-50-28.png.jpg
Figure 20: Crossing wires…
06-electronics-design.org-screenshot-2026-03-02_11-52-31.png.jpg
Figure 21: Close up of crossing wires..

Avoiding crossing wires is going to be hard, and finding an optimal solution (least number of crossing wires) isn't much easier. This goes beyond what I can do this week, so I needed to rethink my design.

3.5. Single digit board

I still liked the idea of Charlieplexing, so I wanted to try and see if a single digit was doable. Having only 7 LEDs means scaling down from 6 pins to 4 pins; which drive \(4 \times 3 = 12\) LEDs.

06-electronics-design.org-screenshot-2026-03-02_12-55-48.png.jpg
Figure 22: Schematic for 7 LEDs using 4 pins

Running the ERC, I am getting plenty of unconnected pin errors because I am not using these pins. I still do not know if and how I need to fix these.

Next, the PCB Editor. This was a lot easier than with 28 LEDs. First, I just spread them out, rotated a few of them to untangle them some more, and moved them around until the routing seemed doable.

06-electronics-design.org-screenshot-2026-03-02_13-28-19.png.jpg
Figure 23: Layouted on a PCB

Running the DRC only yielded some warnings about text height being out of range. I think this is because the footprint in the FabLib is incorrect somehow.

06-electronics-design.org-screenshot-2026-03-02_13-37-18.png.jpg
Figure 24: PCB in 3D viewer

3.5.1. Simulation in Wokwi

To see if it actually works, I recreated it in Wokwi. For this, I selected a Raspberry Pi Pico because that's pretty close to a XIAO RP2040; both use an RP2040.

The canvas drawing was a bit hard because the UI does not allow routing traces but wants to do it for you. This results in wires drawn on top of each other, making it hard to see which goes where. I ended up editing the diagram.json JSON-file to hook up the LEDs to the right resistors. Another advantage of doing this manually was that I did not see the third pin on the top left of the Pico is a GND pin and not pin 3. In the JSON file, it is very obvious what is what.

Having all the components in place and hooked up, I translated code from the Charlieplexing website to Python to see if the LEDs could be lit up individually.

import time
from machine import Pin

while True:
    for i in range(4):
        for j in range(4):
            if i != j:
                print(i, "/", j)
                Pin(i, Pin.OUT).value(0)
                Pin(j, Pin.OUT).value(1)
                time.sleep(.5)
                Pin(i, Pin.IN)
                Pin(j, Pin.IN)

And it worked!

Note that sometimes no LEDs are lit at all, that's because only 7 LEDs are present, but 4 pins encode for 12 LEDs, and the code tries all possibilities.

Next, I wanted to make it show digits. First I mapped the LED pin combinations to segments.

7_Segment_Display_with_Labeled_Segments.svg.png
segment high low
A 1 0
B 2 1
C 2 3
D 2 0
E 3 2
F 0 1
G 1 2

I tested this with the code below.

import time
from machine import Pin

A=[1, 0]
B=[2, 1]
C=[2, 3]
D=[2, 0]
E=[3, 2]
F=[0, 1]
G=[1, 2]

while True:
    for p in [A, B, C, D, E, F, G]:
        i = p[0]
        j = p[1]
        Pin(i, Pin.OUT).value(0)
        Pin(j, Pin.OUT).value(1)
        time.sleep(.5)
        Pin(i, Pin.IN)
        Pin(j, Pin.IN)

With the above, I tried to make digits.

import time
from machine import Pin

A=[1, 0]
B=[2, 1]
C=[2, 3]
D=[2, 0]
E=[3, 2]
F=[0, 1]
G=[1, 2]

D0=[A, B, C, D, E, F]
D1=[B, C]
D2=[A, B, G, E, D]
D3=[A, B, G, C, D]
D4=[F, B, G, C]
D5=[A, F, G, C, D]
D6=[A, F, G, E, C, D]
D7=[A, B, C]
D8=[A, B, C, D, E, F, G]
D9=[A, F, B, G, C, D]

def show(segs):
    start_time = time.time()
    while time.time() == start_time:
        for seg in segs:
            i = seg[0]
            j = seg[1]
            Pin(i, Pin.OUT).value(0)
            Pin(j, Pin.OUT).value(1)
            Pin(i, Pin.IN)
            Pin(j, Pin.IN)

while True:
    for d in [D0, D1, D2, D3, D4, D5, D6, D7, D8, D9]:
        show(d)

The result is very slow but it works! To get this to run properly, I'll need to play around with PIO. The following video run at 10 times speed.

3.5.2. Some push buttons

Because Charlieplexing saved me some pins, I decided to add some push buttons to the board to allow adding some functionality using software. Directly driving 7 LEDs and 4 push buttons would have been impossible without Charlieplexing on the XIAO because it only exposes 11 I/O pins!

06-electronics-design.org-screenshot-2026-03-03_21-12-48.png.jpg
Figure 25: Schematic with buttons added

The ERC errors are really annoying, especially the one about pin 13, which I am using for ground for the push buttons. Do I need a "PWR_FLAG" here?

[power_pin_not_driven]: Input Power pin not driven by any Output Power pins
    ; error
    @(8400 mils, 3450 mils): Symbol M1 Pin 13 [GND, Power input, Line]

For all the errors, see: ERC.rpt.

Back at the Waag I asked Henk about these ERC error and my dear peer Christian told me the solution: use the Place No Connection Flags tool to mark the unconnect pins and add a "PWR_FLAG" to get around the error on the ground pin.

06-electronics-design.org-screenshot-2026-03-04_10-18-03.png.jpg
Figure 26: Final and happy schematic
06-electronics-design.org-screenshot-2026-03-04_14-03-54.png.jpg
Figure 27: Final PCB design
06-electronics-design.org-screenshot-2026-03-04_14-02-05.png.jpg
Figure 28: Pretty render of final PCB design

4. Reflection

What a ride! I was really looking forward to this week and it totally delivered.

4.1. Good

I learned a lot this week and am very happy with what I accomplished. KiCad is really nice, and Wokwi is quite impressive.

4.2. Bad

I really dislike using GUIs, and this week was a lot of GUIs. Fortunately, KiCad is pretty good.

4.3. Ugly

The final board is ugly. I created the edge cut very fast to satisfy the DRC but wanted to try make something prettier in Inkscape an import that. Next time, I'll add a edge cut before doing the routing because moving components breaks the routing.

Also, I don't understand simulation in KiCad, and that's probably why it was not covered in the lectures because it is an advanced feature.

5. Source files

Copyright © 2026 Remco van 't Veer

Licensed under a
CC BY-NC-SA 4.0

Build using
GNU Emacs, Org Mode and GNU Guix

Source code hosted at
gitlab.fabcloud.org