Wow, two weeks have passed since Christmas. Wow, we’re one week into 2024. Happy New Year!
I have an 8-year-old niece and I thought I’d give her an electronics kit for Christmas. Well, it seems that in modern electronics kits, electronic components are covered in a bunch of plastic, making everything look kind of childish. They are a little safer I suppose because they are too big to be swallowed. But at least I (as a child) didn’t really like stuff with a “Fisher-Price” look, I tended to want the real deal. So I decided to make my own electronics kit with my own manual! I just put in a few components I mostly had on hand (I also washed them before, just in case I’d used them somewhere dirty before):
5 red LEDs with a low forward voltage (around 1.7V), this way you can show that they light up (barely) with very fresh alkaline batteries. (Note: most red LEDs have a higher forward voltage of 1.85V or so, and wouldn’t light up at all)
5 blue LEDs
5 white LEDs
5 100 uF (or so) electrolytic capacitors
5 470 uF (or so) electrolytic capacitors
5 470 ohm (or so) resistors
5 2n2222 transistors
2 CR2032 batteries
2 CR2032 battery holders (the ones I bought can just barely fit into a breadboard)
Optional: 4x AA/AAA battery holder and AA/AAA batteries (referenced in text, so make sure to remove reference if you don’t want to include them)
Some wires
1 breadboard
I didn’t include a multimeter, but if the child’s/person’s household doesn’t have one, it might make sense to include one. (The manual doesn’t really fully explain how to use multimeters, however.)
In the manual, the first experiment makes use of the fact that blue and white LEDs have a forward voltage that is quite compatible with CR2032 coin cells. The experiment just sandwiches a coin cell between an LED’s legs.
Then the manual explains that this doesn’t work with red LEDs and a resistor is used to limit the current. (Actually it will probably be okay for a while because coin cells don’t give a lot of current.) Some effort is made to explain voltage, current, and resistance, but (hopefully) on a level that is (possibly, barely) understandable by an 8-year-old.
A little later, capacitors are explained a bit. And transistors. The final experiment is a circuit that has some twinkling LEDs. The following is a similar circuit, just to give you an idea:
Old video shot on a potato.
And here’s the completed set, just before wrapping it:
DIY electronics kit, complete with “Instuction Manual” (d’oh!)
The manual is in .odt format (can be opened in LibreOffice and similar) and you can download it below. It includes some copyrighted pictures from other sites (the battery pic, the diode symbol(s), the transistor pic, the capacitor pic, and the empty breadboard pics). The front page image is AI-generated but heavily edited. Note: LibreOffice may have a bug that prevents emoji from being included in exported PDF files. My printed booklet ended up not containing emoji and I noticed only much later. :(
I made a booklet using the following LibreOffice print settings and a stapler:
Make sure to select “A4” and “Landscape” before selecting “Brochure”, otherwise LibreOffice might get the layout wrong.
If you want to customize the manual for somebody else, you should read through the entire thing. Edit it to your heart’s content. There is at least one reference to “8-year-olds”, maybe do a search. There are references to “dad or uncle” and “parents”. The “license” is “public domain”. Feel free to give credit, but you don’t have to.
Or alternatively: how to get svg2shenzhen to recognize your drill paths as drill holes
(My) rationale: there is an Inkscape extension called svg2shenzhen. This extension creates Gerber and KiCad files that can be used to create printed circuit boards, from standard SVG files. Also, this extension has a funny name. Older, DIY printed circuit boards are just a high-DPI bitmap. Using Inkscape and this extension, you can trace the bitmap and then convert it to Gerber. However, most PCBs (especially old PCBs) need to have holes drilled. The drill locates are just circles in the bitmap, and after tracing, they’re just paths. The svg2shenzhen extension (at the time of this writing) detects circles in a certain layer as locations that need to be drilled, but not paths.
I’m not an Inkscape expert, but AFAIK Inkscape (at the time of this writing) doesn’t have a built-in tool to convert (mostly) circular paths to circles. So I wrote a simple extension that does this! It works fine on Linux. Not so sure about Windows.
Extensions are made of only two files, a file that describes the extension, and the extension code (which is in Python in many cases). These two files just have to be placed into the location shown in Edit -> Preferences -> System -> User extensions, which in my case is ~/.config/inkscape/extensions/.
Here are the two files, you can copy them into a text editor like Kate or gedit or Notepad, what have you, and save them into the above directory. I recommend keeping my file names, path2circle.inx and path2circle.py. Note, some skeleton code in path2circle.py was generated by ChatGPT, though it was quite wrong. That’s where some of the verbose comments and extraneous code came from.
import inkex
from inkex import Circle
class Path2Circle(inkex.EffectExtension):
def effect(self):
# Iterate through all the selected objects in the SVG
for node in self.svg.selection:
# Check if the object is a path (or any other object type)
if node.tag.endswith("path"):
# Get the bounding box of the object
x, y, width, height = self.get_object_dimensions(node)
x = x.minimum
y = y.minimum
# with open('/path/to/debug/directory/debug_output.txt', 'a') as f:
# print(f"Object Dimensions: x={x}, y={y}, width={width}, height={height}", file=f)
layer = self.svg.get_current_layer()
diameter = min(width, height)
layer.add(self.add_circle(x, y, diameter/2))
def add_circle(self, x, y, radius):
"""Add a circle at the given location"""
elem = Circle()
elem.center = (x+radius, y+radius)
elem.radius = radius
return elem
def get_object_dimensions(self, object_node):
# Get the bounding box of the object
bbox = object_node.bounding_box()
# Extract the bounding box coordinates
x = bbox.x
y = bbox.y
width = bbox.width
height = bbox.height
return x, y, width, height
if __name__ == '__main__':
Path2Circle().run()
To use the extension, you probably first need to restart Inkscape. (You do not need to restart Inkscape after changing the extension, however.) Select all the paths you’d like to convert, and then hit Extensions -> Custom -> Path2Circle. Note: the extension doesn’t actually care if the paths even remotely look like circles, so make sure to select the correct paths. You can easily modify the extension to calculate the radius differently, or e.g. replace paths with other objects, such as squares, rectangle, or ellipses. Let me know if you need help doing that.
In a previous post, we did some warmups — playing MSX games using a fake PS3 controller. In this post, we’ll be using GP2040-CE to control a Nintendo Switch. (No analog stick support implemented at the moment, but it wouldn’t be hard.) At the time of writing, most of the code to do this is already there! And I’m sure there will be support for USB-HID controllers in no time, so this post will probably be outdated soon. Update: Analog is implemented too, and the diff below has been updated.
Anyway, you just need to put GP2040-CE on your Pico and get into the web configuration. In add-ons, you enable keyboard support, and then set up the “Keyboard Host Configuration”, which looks like this:
GP2040-CE keyboard mapping and other configuration
Then you can connect a generic USB keyboard to the Raspberry Pi Pico, and connect the Pico to the Nintendo Switch. (For electrical reasons, I do not recommend setting a pin for 5V power here, and just putting the host USB +5 on the VBUS pin of the Pico.)
Things that could come in handy: Breadboard, Raspberry Pi Pico, USB port that can be connected to one of the Pico’s GPIO pins
If everything works and you can control Sonic using your keyboard, great, you can move on to the next step! If it didn’t work, it probably won’t magically get better from here on out, so make sure to check those connections. The green/white wires can be D+/D- or D-/D+!
Now we’ll perform a small modification to the existing code. I’m basing my work on commit 961c49d5b969ee749ae17bd4cbb2f0bad2380e71. Beware, this may or may not work with your controller. I’d recommend taking a look at the above-mentioned previous post where we modify a Pico-PIO-USB example and to check if your controller behaves the same way. I have only two controllers to test with, and I only tested with one! Anyway, here’s the diff:
Good luck. Miraculously, everything worked perfectly for me. The keyboard worked immediately, the above code modification worked immediately without having to do any debugging, and I’ve gotta say, my fake PS3 controller feels quite okay! (Note that you will have to press the PlayStation button after connecting your PS3 controller.)
Symptoms on real PS3: probably “crazy behavior”, I didn’t actually test on a real PS3. Symptoms when connected to a computer with a program open that displays the gamepad status: random button presses, button “flickering”, buttons going on and off randomly, possibly depending on how the controller is held.
Cause in my case: rubber cushion is worn out, and/or physical damage to the controller’s case and/or loss of one of the screws. The rubber cushion sits on a piece of plastic, and a flex cable is sandwiched between the rubber cushion and the PCB. If the rubber cushion loses some of its original height, for example due to wear, or if one of the controller’s screws are lost and the PCB isn’t pressed as hard against the rubber cushion as it used to, buttons will randomly appear pressed or unpressed. (When there is absolutely no connection between the flex cable and the PCB, all buttons will appear pressed. When the connection is flaky, buttons may appear pressed all the time, or go on and off.)
Fix: adding a little height to the cushion fixed the problem for me.
In this pic, I’m holding the flex cable with one of my fingers. The tube (it’s a piece of heat shrink, actually) is what I added to improve contact between the flex cable and PCB. The original rubber is still there.