Showing posts with label Tinkering. Show all posts
Showing posts with label Tinkering. Show all posts

09 September 2021

8-Bit Character LCD/Character LCD Clock Update

In the Character LCD Clock post I mentioned wanting to test out 8-bit communication and having to write my own library for it, and I recently remembered about it to stick it in my projects folder.

I ended up grabbing the datasheet for the 20×4 display that I have and Adafruit's character_lcd.py source code for references, but when I really started looking at both of them (and playing with some things in a Python shell), I found I didn't need to write my own library and could just modify Adafruit's code. As for what I modified, I changed _LCD_4BITMODE = const(0x00) to _LCD_4BITMODE = const(0x10) to set it to 8-bit mode from 4-bit. Yes the variable name didn't get changed, but it means that there is minimal change to the code. The other thing I changed was the __init__( arguments for the additional data pins, the class variables that are made from those arguments, the write function (specifics soon), and the __init__( arguments for Character_LCD_Mono and Character_LCD_RGB.

In the write function, it normally sets the "top" four bits to be written on the pins set to self.dl4 through self.dl7, sends a three-part pulse (self._pulse_enable() function), then sets the "bottom" four bits on the same four pins before another pulse. For 8-bit, all eight pins need to be set, and I just brought up the lines for the "bottom" four bits above the lines for the "top" four bits and then changed the class variables to match the ones I added before. The pulse only needs to be sent once after the eight pins are set.

Character_LCD_Mono and Character_LCD_RGB have the __init__( arguments change since they pass the pins over to the parent class (the 20×4 display I have does have a backlight).

I used mpy-cross to turn it into a smaller .mpy file and tried it out. I ended up making it the wrong version because I never recompiled mpy-cross after setting the CircuitPython version to compile when I was compiling CircuitPython. Anyway, after that, the 8-bit library worked just fine, and I thought it seems faster, but I think it's just a placebo. The reason is that the pulse function has three 1-microsecond pauses and the only other limiting factor is the 1-millisecond pause in the write function before it sets all the pins; therefore with 4-bit, 1006 microseconds is spent to write one character, and 1003 microseconds for 8-bit. It's very negligible, and I can understand why Adafruit never bothered with making an 8-bit library or why 4-bit is so much more common, it's because the benefit for eating up four more pins is not worthwhile in any meaningful way. However, 8-bit makes sense when it's a small project that doesn't use all that many pins, which means it's just to connect the pins to something rather than nothing.

And because of this, I decided to make the Character LCD Clock have an 8-bit connection just to use up some more pins and not let my library modding go to waste (well, it's not that hard of a mod, but still...).

09 July 2021

Parts Inventory, and Digi-Key and Mouser Data Matrix Barcodes

Hey, look at that, an actual blog post that doesn't require me to remember things from a week or more ago! Anyway, I think I might've mentioned in some recent post that I was going to inventory all the parts I have so it's easier to keep track of what I have, instead of having to dig through a couple boxes because "I think I have...".

The first step was to get a barcode scanner that also reads 2D barcodes and is reasonably-priced, and SparkFun's 2D Barcode Scanner Breakout was the answer. When I found it, I thought their stock of 42 would be okay, but when I looked at it the next day, they were all gone! I think I sat for a few days before I found that SparkFun does have a "wait for backorder items before shipping" option, so I went ahead and put in an order, since they said they had about 144 units being made. I technically would've been fine with the module itself, but I don't know if they'll ever be bringing them back in stock, since it's part of their "SparkX" line which is for experimental stuff. Looking through their blog yesterday, I guess the scanner breakout was released 28 May, so maybe because it's such a new product, they're focusing all the modules to the breakout boards until demand goes down. Hell, even as I write this, they're out of stock once again and planning on making 60 more; the "Top Sellers" tab on their front page contains the scanner breakout, and for a good reason.

I got the scanner a couple days ago and played around with it some... I mean I was seriously like this:


And it was great being able to scan something that would be automatically entered in a spreadsheet, text editor, whatever. While the barcode scanner app for Android by ZXing Team is a long-time favourite of mine, it's not a very streamlined approach when I need to get the scanned data to my computer (I have it set to auto-copy the scanned contents to the clipboard, and then I paste it into Discord).

Digi-Key's labels for each bag of parts contains a Data Matrix code (at least the newer ones do, I don't know when they switched over, but I have some Digi-Key bags at work that were from 2015 that has a 1D barcode), and scanning that with the barcode scanner (the one from SparkFun) yielded info similar to this:
[)>06P559-1099-ND1PPS2801A-4-AK1K7013275410K8165562911K14LJPQ1311ZPICK12Z956474013Z5583520Z00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Which I could kinda figure out stuff from, but I needed more info. I did a quick search and found some people trying to figure it out (this being one), but no one had a complete list, so I decided to just figure it out myself. At work, I scanned one with the app and found some non-printing characters as "tofu" and it made a lot more sense to me.

♫A little bit of tofu in the text.♫

Using Discord, I pasted it within a code box so that I don't lose the tofu, and though they don't show, they were still there when I transferred it into Mousepad.

Tofu, demystified.

I use CudaText as my main text editor, but well, the non-printing characters are less obvious. Anyway, Unicode 001d is "Information Separator Three" or "[GS]" (Group Separator), and 001e is "Information Separator Two" or "[RS]" (Record Separator). I didn't really care what they were besides that they were non-printing control characters, but well, the difference between 001d and 001e would kinda serve me later. Looking at the data in Mousepad with the boxed control characters, It was much easier to make things out, and I was able to figure out that the "category" markers precede whatever number they are. I think it'll just be easier to share the findings first before I talk about certain items individually.

Digi-Key barcode data (using data from Mousepad screenshot):
  1. [)>
    • Probably a scanning software thing.
  2. 06
    • Probably another scanning software thing, this number is the same between Digi-Key and Mouser.
  3. P559-1099-ND
    • Part number, either customer-specified or retailer-specified, prefixed with P.
  4. 1PPS2801A-4-A
    • Manufacturer part number, prefixed with 1P.
  5. K9438
    • Customer purchase order (PO) number, prefixed with K, may be blank.
  6. 1K70132754
    • Sales order (SO) number, prefixed with 1K.
  7. 10K81655629
    • Invoice number, prefixed with 10K.
  8. 11K1
    • No idea what this is, but seems to always be 1, prefixed with 11K.
  9. 4LJP
  10. Q13
    • Quantity of items, prefixed with Q.
  11. 11ZPICK
    • No idea what this is, but seems to always be PICK, prefixed with 11Z.
  12. 12Z9564740
    • Part ID, prefixed with 12Z.
  13. 13Z55835
    • Load ID, prefixed with 13Z.
  14. 20Z00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
    • Probably some sort of filler, prefixed with 20Z
I had thought 11K might've been MSL, but nope, the NeoPixels have the same value of 1. The invoice number (10K) stumped me for a little, until I went to check an email that I probably still had, and sure enough, the numbers matched. Since I don't need purchase order numbers for my personal orders, work was the best bet for figuring out K, though before scanning the two samples at work, I wasn't entirely sure how the data was structured.

While at work, I decided to scan Mouser's to see what it contained, and it was much less. Let's start with a screenshot of the data, and then jump right into the breakdown.

Miniscule compared to Digi-Key.

Mouser barcode data:
  1. >[)>06
    • Probably scanning software stuff. There's no 001e control character before 06, but at the least, the 06 is still the same in comparison to Digi-Key.
  2. K9439
    • Customer purchase order (PO) number, prefixed with K, web order number is used if customer does not provide a PO number.
  3. 14K022
    • Line item number (the line the item appears on an invoice, packing list, etc.), prefixed with 14K.
  4. PTP0194
    • Customer-specified part number, prefixed with P.
  5. 1P02-09-1117 (Cut Strip)
    • Manufacturer part number, prefixed with 1P, appears instead if there is no customer-specified part number. (This is from something else and isn't in/from the image.)
  6. Q10
    • Quantity of items, prefixed with Q.
  7. 11K062059574
    • Invoice number, prefixed with 11K.
  8. 4LLI
  9. 1VNeutrik
    • Manufacturer name, prefixed with 1V, may not be present.
I wasn't paying too much attention yesterday, so I thought Digi-Key and Mouser use the same structure, but I guess not. It's possible 11K for Digi-Key might be an another invoice number field, but I can't say for sure, and it's something I don't care about in all honesty. I was double-checking 11K for Mouser with some other part and found 1V, which might be something new, but again, not worthwhile for me. At the least, hopefully people looking for the structure find this blog post and is helpful to them.

Moving on. Because I found out about the control characters, I needed to figure out a way for the barcode scanner to send them. I tried the "serial over USB" (USB-COM) mode of the barcode scanner and ended up in an empty screen when loading up /dev/ttyACM1 (/dev/ttyACM0 is my Powermate), so I had to go the serial over UART route with a dev board. I used the Trinket M0 because it's small, and hooking up the barcode scanner to it was easy after I got a 6-position header soldered to the barcode scanner. I then pulled up a UART serial Adafruit guide as reference and had to try to fill in the blanks myself. It didn't seem to print anything out properly, and I tried baud rates of 9600 and 115200 in the code which both were claimed as the default in the settings manual (9600 is listed first as the default, but then 115200 is listed as the default three times after that, but eventually, I decided to scan the 115200 baud rate setting. And that was the problem all along, some mysterious default baud rate setting (I had a thought to go through them individually, but I didn't feel like it). I also tried USB-COM mode again and scanned the 115200 baud rate setting, but no dice, so I gave that mode up entirely.

A new problem arose, the printed text still contained no control characters, but the code I used has a line for printing the raw data, and after commenting that out, huzzah! I forgot when I swapped my janky wire set up for the 20-position GPIO set I bought along with the barcode scanner, but I did so because the ground wire kept popping off the barcode scanner header, and honestly, I should've done it sooner since it had a much better hold on the header pins. Anyway, the next issue was the fact that the raw data is a bytearray, and I needed to convert it to a string. Well, I thought I did, but I eventually realised that the conversion in the code was actually keeping the control characters, and that print() was the culprit of not printing them (I mean, they're called "non-printing" characters for a reason). While trying to see if print() had some sort of option to maybe print the characters, my eyes glanced over "sep" and I was reminded of replace(). Huge duh moment. I used a tab character to replace 001d and had replace() replace 001e with nothing, this would make things much more printable.

It was kinda in that mess where I was also thinking of trying to write the raw data to a file, and because I normally use open() in text, it took me a moment to remember about its ability to write bytes. While it did work with normal Python, CircuitPython refused to do it in the test because the flash appeared as read-only to it, and though I would've used an SD card over SPI, I didn't want to make things harder than it should be (plus I had just ordered the micro SD card breakout from Adafruit, so I would've had to wait anyway). Anyway, I think it was after I got replace() into the code (or it might've been a little before?) was when I decided to use the USB-HID library to emulate a keyboard, and because there's a library that allows a string as the input of what to send to the computer, I wanted to utilise that. The problem is that the examples changed with the documentation, so I had to try to figure it out, which wasn't too hard, but I was able to get it to work. It doesn't type nearly as fast as the barcode scanner directly, but at least I can get the control characters for processing before sending to the computer.

Because the .read() command for the UART serial only lasts for a bit, it was hard to test in the CircuitPython console, but it was fine in the code because of the looping. I also tried to send commands to the barcode scanner, but it was difficult at first because I forgot that there was a command prefix it looks for (^_^, caret underscore caret, I'm not kidding), and when I got it in there, it worked as intended. There was some other things I did/tried, but I won't talk about it because it's not really worthwhile.

The output (or at least simulated) from the MCU. I forgot the newline, but oh well.

Though I could do all the processing on the MCU of the stuff I care about (manufacturer's part number mainly), I wanted to keep the processing that needs to be done on the MCU as minimal as possible to make the job of scanning the inventory as quick as possible. I also added line in the code to send the save hotkey after it "types" the data, so that it's as automated as it can get. I still need to write the code for processing the file down to part numbers, but that won't be too hard and Pod will have it done before the snap of a finger.

Originally, I was thinking of buying a second barcode scanner (before I even bought the first) for a "scan and display" sort of thing, but this morning, I was considering on buying a third to keep in UART mode so that I don't have to change the settings. Along with this "third" barcode scanner, I also thought to make a custom breakout board with the ATSAMD21E18A-A because I thought I could maybe still get them, but it seems like Mouser's finally run out. Anyway, it would make it a single-board device instead of having two boards and some wires and be a little less awkward to use than the current setup with the Trinket M0. I'll still design it and such, but I won't be able finish the assembly for a while. Because I didn't really go over it that well, one would be in the fairly default mode for when I don't expect to run into control characters that would have the original board, another would be the self-contained "scan and display", and the last would be the UART version for when I need/expect control characters. Anyway, for anyone wanting the code for an Adafruit CircuitPython dev board to be able to get the above output with the barcode scanner, here's the not-entirely-pretty code based off of the code in the Adafruit guide I used:

import board
import busio
import digitalio
import usb_hid
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS

uart = busio.UART(board.TX, board.RX, baudrate=115200) #you can use any baud rate, just make sure your scanner is set to that rate!
kbd = Keyboard(usb_hid.devices) #make the keyboard object
klo = KeyboardLayoutUS(kbd) #make the keyboard layout object with the keyboard object

while True:
    data = uart.read() #because the barcode length is unknown, don't set an amount of bytes to read
    if data is not None:
        data_string = ''.join([chr(b) for b in data]) #this converts the data to a normal string
        data_string = data_string.replace("\x1d", "\t").replace("\x1e", "").replace("\r", "\n") #make the necessary replacements (the barcode scanner defaults to \r for newline, but can be changed to \n, so it's there in case of forgetfulness)
        klo.write(data_string) #use the keyboard layout object to "type" the data string
        kbd.send(224,22) #send ctrl+s to save the file, 224 is the keycode for control, 22 is the keycode for s

Important thing to note is to keep the focus in the target programme, otherwise you could lose the data from the scan and/or make things weird. Also, make sure RX of the scanner is connected to TX of the dev board, and TX of the scanner is connected to the RX of the dev board! But anyway, with this code, you just use the barcode scanner's scan button like normal and the MCU will spit out the data after it gets and processes it.

I need to double-check what appears in the Mouser barcode for my stuff, since I don't use/have PO numbers, and based on how the P/1P is for Mouser, I'm thinking I'll se a 1K and the corresponding number. I'll edit this when I confirm it and probably will say that I did below.

Found that Mouser uses the web order number for the PO number, so no 1K category in the place of K. Also found that Digi-Key's packing list has some small Data Matrix codes that include Unicode 0004, which is "End of Transmission". I won't modify the above code, but if the codes on the packing list are to be used, just tack on .replace("\x04","") to the replacement chain.

(Edit: 2021-07-17)
While doing some testing for projects that include a graphic screen of some sort (the aforementioned "scan and display" and maybe the PSU tester), I came across one of my old code tests when I was playing around with the Trinket M0 and various libraries. If you're using Linux of some sort, or at least something that allows you to type Unicode characters using Ctrl+Shift+U, then you can actually type any Unicode character using Adafruit's adafruit_hid.keyboard library. I completely forgot about this and I honestly should've remembered because it saves the chain of replacements. Anyway, the code for raw output:

import board
import busio
import digitalio
import usb_hid
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS

uart = busio.UART(board.TX, board.RX, baudrate=115200) #you can use any baud rate, just make sure your scanner is set to that rate!
kbd = Keyboard(usb_hid.devices) #make the keyboard object
klo = KeyboardLayoutUS(kbd) #make the keyboard layout object with the keyboard object

def send_unicode(char): #define a function to send the untypeable unicode character
    parts = hex(ord(char))[2:] #get the hexadecimal value of the untypable character without the "0x" prefix
    kbd.send(224,225,24) #send ctrl+shift+u so that the unicode value can be typed
    klo.write(parts) #send the unicode value
    kbd.send(44) #send space to finish the unicode entry

while True:
    data = uart.read() #because the barcode length is unknown, don't set an amount of bytes to read
    if data is not None:
        data_string = ''.join([chr(b) for b in data]) #this converts the data to a normal string
        for char in data_string: #iterate through each character in data_string
            try:
                klo.write(char) #try sending the character normally
            except:
                send_unicode(char) #or send it the other way if it can't be typed
        kbd.send(224,22) #send ctrl+s to save the file, 224 is the keycode for control, 22 is the keycode for s

01 July 2021

Adafruit's Debounce CircuitPython Library

I think it was after whatever previous post that I had mentioned it, I decided to tinker with it some within the Powermate (I also was partially annoyed with the button's input behaviour that I programmed). After making the necessary changes (importing, assigning, etc.), I changed the if statements to look for rise or fall instead of the button value, and didn't have much luck getting it to work while tweaking the code. I ended up just undoing all of the changes and leaving the tinkering for another day.

Last Friday, I decided to give it another whirl (I think I was thinking about it the night before and figured something out that would probably make it work) and made the necessary changes once again. I don't remember exactly what I did, but I did use .rose and .fell in conjunction with .value to get it working. I also already had a counter implemented in the old code that counted the amount of cycles the button was being held for, and I had also changed it to accomodate the new sleep time of 10ms (since the debouncer class defaults to 10ms cycles). I found from the library documentation that there's also .current_duration and .last_duration and kinda played with those a bit, but .last_duration didn't seem to be that useful (or at least for me). I tried using .current_duration for the profile switching, but it ended up being problematic, so I changed it back to read from the counter system. I left .current_duration where it turns the LEDs to the colour of the current profile because it works fine and it doesn't matter if I use that or my counter system there. I also had tried .current_duration with what the button does when pressed, but didn't work well.

With the script for mine fixed up, I fixed the one for my friend and gave him the library and the new code, even if his button just toggles the LEDs on or off. Button definitely works a lot better than the old code, and definitely planning on using the debouncer library where possible.

22 June 2021

3DS Input Redirect Controller

With some mention of a Discord server member having a modded 3DS firmware, I kinda decided to look into it, and after reading the instructions, it seemed pretty easy to do. I grabbed my secondary 3DS (because I pretty much had nothign to lose on it) and gave it a shot; it really was that easy and non-destructive.

One of the features is being able to control the 3DS with a controller connect to a computer over the network (obviously using a programme on the computer as well), which is pretty nice since the 3DS' directional pad is a little annoying for me to use (I guess I have larger than average hands?). For controllers I have the XBox 360 controller, the Horipad, the Joy Cons, or any of the Bluetooth SNES controllers (8Bitdo or Nintendo) to choose from. The Bluetooth SNES controllers are automatically out for not having a joystick (though probably not a huge deal), the Joy Cons I don't want to have to bother pairing/repairing, the Horipad is wired and connected to the switch dock that I don't want to have to bother with, and so that leaves me with the XBox 360 controller that gives me some disassociative issues because its buttons feel much different than the 3DS'.

With learning CircuitPython, I decided to make my own controller that has a few buttons to allow me to run a predefind macro that speeds up what I was doing a lot by hand; it would also have tactile buttons that'd probably feel a little closer to the 3DS than the XBox 360 controller does.

I think while using the Trinket M0 to do some tests, the programme to send the input to the 3DS didn't seem to register any of the buttons in the gamepad library for the directional pad, and while it sucked, I figured out to just emulate the directional pad by sending a couple joystick movements to make it seem like the joystick was flicked in that direction.

I think the code came first because it was easier to handle? On top of working on this project, I was also learning things about microcontrollers along with CircuitPython. It seems like I was originally planning on using the ATSAMD21E18A-A because it would fit all the inputs as well as having an analogue selector switch (using some resistors and a switch) and four function/macro buttons. Or at least so I thought, because at some point, I realised it took away PA24 and PA25, which were needed for the USB connection to the computer, so I decided to stick the axes of the two joysticks on an I²C ADC (ADS1015) to free up PA24 and PA25. I also had realised at some point that I could use an RTC for the year, month, and day for part of the macro instead of having to manually input it myself, and so I added added it to the I²C line.

I think I started writing the code at this point? (Seriously, there was so much going on that it's hard to remember everything in chronological order.) And with how long the code got, I was uneasy with how large the code was getting and I didn't know how much of the MCU's flash space would be left after all the libraries I needed, so I decided to add an SPI flash chip for expanded storage (it was at this point I hadn't had the Trinket M0 yet). Because of this, I needed four more pins from the MCU that I didn't have, so I opted to "upgrade" to the ATSAMD21G18A-A for more pins. It was likely around this time that I had to look for some other I²C pins because the SPI flash is normally connected to PA08, PA09, PA13, and PA14, and I had PA08 and PA09 planned for the I²C connections. I ended up using PA22 and PA23 for I²C, and then had a couple pins leftover with all the other inputs connected to their own pin. I think I was also just going to use a CircuitPython build for a board that was similar, but after a bit of digging, I became less sure that was a good idea.

I forgot how I ended up with needing a second selection switch, but it seems like I ditched the joystick axes to be able to fit them in? Anyway, I designed the first version of the board after getting some data (button spacing from the Joy Cons), and I think the board sat without traces and airwires for a while before I bucked down and started to do it. I had a bit of problems with placement of the flash and RTC, as well as running the traces for them, but did eventually figure it out. The I²C lines for the RTC was the most annoying because not only did I need to connect the two pins to the MCU, I needed to connect them to separate pull-up resistors as well, but the other problem was getting the trace for the backup battery to the corresponding RTC pin while keeping the trace short and reasonable, and a friend suggested to run the trace in the space between the pull-up resistor pads, which I failed to see (I was getting tired).

Section of the board with the flash, RTC, MCU, part of the backup battery holder (CR2032), and some of the buttons.
If you see the problem with the I²C lines, I'll get to that later.

I think it was sometime after this when I had the Trinket M0, and loading the necessary libraries onto the MCU's flash (the Trinket M0 doesn't have an external flash chip) showed me how much space I had left, which is more than I originally thought. I think I had to strip all the comments and extra whitespace out to really be sure it'd fit? Anyway, since I confirmed that I'd have plenty of space, I could remove the flash chip and shift the pins around a little to have enough analogue pins free for the joystick axes again (even if there's no board space for them).

Sometime I found a guide on building CircuitPython, which includes a link to a guide on adding a new board to CircuitPython, and the latter guide lead me to the configuration files that I'd need to change. Or maybe I came upon it some other way? Regardless, there was the pins.c file with the pin names that board uses to make it easier for the programmer to reference in code, and while I really didn't want to have to make names for it, I did anyway. Later on, I discovered microcontroller.pin that invalidated the need for this.

I forgot to mention, but I think it was around the second board revision (I at least had the Trinket M0) that I found a different version of the input redirect programme for the computer that allowed button assignment, so I was able to give the programme specific buttons for directional pad and allowed me to get rid of the virtual joystick flicking thingy I was doing. I suppose I'll talk about the programme more here. Anyway, the programme (either version) has a window that the user can click on to send the coordinate touched to the 3DS (emulating the 3DS' touchscreen being pressed at that point), but the problem with it was that it wasn't very accurate. The programme allows a specific point to be sent (using L3 or R3 as the trigger) and the point that I sent didn't correspond with what the 3DS says it received (if I sent 205,198, it'd say 208,201). What I tried to do at first for compensation (because I needed the macro to move the mouse and click on the touchscreen emulator) was to get screenshots and scale them down and figure out the translation of points, which kinda worked... Eventually, I found points that corresponded and found that the weird scaling issue is from the horizontal center and below vertical center of the screen. I think at this point I tried poking with the source code (I had to compile the programme anyway) to try to get it to work correctly, but no luck.

I had decided to gather a bunch of points and try to figure out an equation to fix the problem, but I couldn't get anything to work. I think I tried to get an equation from a scatter plot, but I think it kinda worked, but I think I figured it'd be more accurate if I got more points. I then collected literally all the points on the x and y axes to plug into the scatter plot (just one axis though, considering that the scaling is different for both axes), and while it took a bit to get them in, I had something much more accurate (I think I had played around with the dead zones a bit, but don't remember if the final equations included them or not) to work with. After modifying and compiling the code (for the umpteenth time), the coordinates were spot on, except every so often where a pixel would be skipped (it would go from 25 to 27, for example, but be fine after that until the next one), which was good enough because it was much more accurate than it was with the original equation. Because the programme (the one with the button assignment) also allowed the touch emulation window to be resized, it also included some maths to compensate for that, so I had to tinker around with it. I couldn't really get it to work with the window resize, so I ended up just locking the window at a fixed size instead to avoid the hassle.

While the untouched equation for the touchscreen emulation is fine by logic/mathematics, for some reason it just didn't work correctly in Linux, and I kinda did want to try the Windows version (which I think there was a pre-compiled package for), I didn't want to have to reboot to Windows or use Bazett. I might've done a quick test in windows, but I don't remember. I also had tried tinkering with the sent bits before tinkering with the equation and stuff, but that just made the emulation not work most of the time.

It was towards the start of the project that I was planning to have one set of buttons and joysticks and have two microcontrollers so that I could connect to two computers to control two 3DS units with one controller (yeah, it'll do the same thign on both units, but it makes stuff like pokémon trades easier), but after trying to just run the input redirection programme again and just changing the IP address in the second instance (I had applied the mod to my main 3DS at this point), I didn't need to do that. This idea is why I had gotten an ADS1015 breakout from Adafruit, because the Raspberry Pi doesn't have analogue inputs and was also supposed to be the testbed for it. I still did the test, but with connecting the ADS1015 to the Trinket M0 instead, but what I was trying to figure out was if I would be able to connect one joystick axis to two different analogue inputs and get the same values, and it turned out as I expected. (I also had gotten a joystick breakout from Adafruit along with the ADS1015.)

Anyway, another thing I was worried about was how much memory I'd end up needing to run the code and such, but because the Trinket M0 doesn't have enough pins and only has a few pins broken out, I wasn't able to do any testing until I finished my ATSAMD21G18A-A and ATSAMD51J19A-A dev boards. Turns out that there is enough memory to run it if I don't import analogio and add the analogue pins to the programme, but because I had been planning on making another controller that had joysticks, I wanted to keep the MCU the same to make it easier. Obviously the code with the joysticks and stuff ran just fine on the ATSAMD51J19A-A since that MCU has about 6 times the memory than the other, and I went to make another revision to the board using that MCU instead.

Somewhere during this deep dive on these MCUs and CircuitPython (likely between the second and third revisions of the board for this project), I ended up reading about pin muxing (I think for a different concurent project), which I think lead me to save a copy of the IO table from the two MCUs' datasheets before making a spreadsheet with them so that I could sort it by pin or whatever. Before this, I had been relying on the schematics that Adafruit has for their dev boards, but in some cases, it wasn't specific enough. Anyway, I found that for I²C, it was specific pads on the ports that determined which one was SDA and SCL, so while PA22 and PA23 are both I²C pins (on SERCOM 3 or 5), they have to be used specifically. Further in the datasheet gives the specifications that pad 0 is SDA and pad 1 is SCL (there's designations for pad 2 and pad 3, but we're ignoring them for simplicity), and because PA22 is pad 0 and PA23 is pad 1 (again either on SERCOM 3 or 5), PA22 has to be SDA and PA23 has to be SCL. Because I was using the schematic for some Adafruit dev board, it just had PA22 and PA23 labelled as "I²C" without saying which were SDA and SCL, so I had just guessed that it didn't matter or whatever. Turns out that I had the signals swapped in the first and second revisions of the board, but I only ripped the SDA and SCL traces up (and did a pin swap) in the second revsion because that was the more concerning one, even if it wasn't going to be made. I'll be talking more about the pin muxing stuff in a different post for the project that it belongs to.

In my notes, I had the ATSAMD51G and ATSAMD51J as the replacements for the ATSAMD21G if there wasnt' enough memory, but I later found that I wouldn't be able to use the 51G because it's not available in the same package as the 21G along with the fact that it loses one IO pin for a pin that connects to an inductor and such to vary the power input it needs for power savings (if running off of a battery, for example). My only option became the 51J, which was a little larger in size than the 21G, but not much larger (I think the moulded plastic is about 14×14mm compared to 10×10mm?). I wanted to try to keep the routed traces as much as I could, so that I would have a little easier time re-routing, and it made it a bit of a mess while I had to avoid running the design rule check (which would bring up obvious errors). Some inputs did have to shift pins a bit, but otherwise the traces are fairly similar to the second reviison. I also added the connectors for the (Joy Con) joysticks as a placeholder, so that I would be sure I had a path for all the traces (mainly for the left joystick), including the joystick button.

The reasoning for using the Joy Con joysticks for the controller is because of its ease to replace compared to the usual soldered-on variant, and its compact Z-height. While waiting to be able to test the memory consumption of the code, I dug up what I could on the connectors and the joystick measurements, and ended up buying a set of 3rd-party replacement joysticks to be able to measure and confirm the measurements that I found. I had also used it to somewhat mock up an ideal location for the joystick in relation to the directional pad buttons.

One of the design changes between the third revision of the board and the first revision of the board with joysticks was adding a couple more switches to be able to switch the L3 and R3 inputs between the joystick buttons and the discreet buttons (L3 and R3 would be reassigned as the power and home buttons within the input redirection programme) so that I wouldn't have buttons that didn't do anything or were annoying to actuate. The first thing I did was place the left joystick in accordance to my notes (meaning its centre had a negative x coordinate) and then shifting everything over that would need to shift over. I think i calculated the shift for the ABXY buttons to make space for the right joystick, but because some or all of the pads of three of the buttons would extend past the 100mm limiatation of the free version of EAGLE, I had to move them manually by editing the board file (which is literally just a fancy XML file). The next thing I did was move the top of the board and some of the components up to match where the top of the board was in relation to the ABXY buttons. Because of the limits to where I can place the joystick connector and the reachability of the L button, I ended up having to have the L button on the bottom of the board instead of the top. The right joystick was easier to place since there was a bunch of space on top of the board near the MCU (which is under the board).

I think a little later I decided to add an RGB LED for indication, so that I would have an idea of the backup battery state and to know whether or not one of the macros are still running, and I agonised over the placement a bit because of needing to run a trace between it and the MCU and another trace for 5-volt power, but settled near the centre as the best option. Though I already had shifted the pin assignments for the added switches and buttons, I eventually decided to shift the assignments again to make it easier to route the signal trace for the LED so that it wouldn't take such a long path across half the board with having to switch between the top and bottom layers. Luckily, this ended up cleaning the rest of the traces up more.

While doing the inital layout on the first revision of the original board, I was kinda joking around with a friend saying that I could fit a CR2032 and a CR1225 on the board, but I eventually went with the CR2032 because it's more common (I think the CR1225 was actually from the Raspberry Pi clock project where I was considering on making an RTC "backpack" in adition to the display board, which didn't). Anyway, with how much extra board space I gained from the expansion, I mocked up being able to have multiple CR2032 batteries and came up with about 3 or 4 batteries, but with some maths I did back with the first revision of the original board, one CR2032 would last about 9 years, so having it last three or four times that would be a little inane. I also accidentally blocked the path for the backup battery to connect to the RTC because I worried about all the other traces first, but this was fixed with a couple of vias to run part of the trace over the blockage. The trace for the battery check had to take a weird path, since I have the RTC in roughly the same location and the analogue pins being on the opposite side of the MCU.

Battery trace highlighted.

Oh right, after changing MCUs, I forgot I had to change the reset circuit because I was copying the design from some of Adafruit's dev boards (:x), so I had to fiddle with that when I realised it, but I made it work.

While the board is complete and ready to be fabricated, the fact that I only bought enough MCUs for the Griffin Powermate hack and the dev boards and the fact that the silicon shortage had affected suppliers (Mouser, Digi-Key, etc) a little after I bought those MCUs mean that the project is at a standstill until I either wait until there's a stable supply of MCUs or order a small supply of MCUs that will arrive whenever it does. I think this'll be it for now, I don't think there's really much to say about the code and I can't think of anything else about the project to talk about that I haven't already.

18 June 2021

Cherry MX Spring Modification

A few years ago, I did a spring mod of some Cherry MX switches that made it a little harder to press certain keys, but it was an imperfect solution. I don't remember how I got to looking for a single-spring solution, but I found a bunch that had higher forces than the stock 80cN springs I was using, and it was hard to decide what sort of force to go with without testing them. I went with 210 gram force springs and ordered about 3 dozen of them because I didn't need too many and they weren't all that cheap.

The springs in a bag.

While they look quite long, that was a length I wasn't concerned about since it was really more about the compressed length that was one of the limiting factors. It's slightly larger in diameter than the standard springs, but it still fits fine. This spring makes it a bit harder to reassemble the switch, but not difficult or impossible. Once I had the switch on a board, it was a lot harder to press than I thought (or tried before soldering), but it's blatantly obvious when accidentally hitting it. I think the spring moves a bit weird in the switch because the click doesn't always happen when the switch actuates, so I could've used a red or silent red or whatever instead of the blue stem, oh well.

Hackintosh

With some of the programmes I was writing (the world clocks one being the one I remember best), a friend wanted to be able to use it, but he daily drives Mac OS, so there wasn't an easy way to allow him to use it without compiling the programme. And because i3rd was superceded by Pod, I decided to put i3rd to use by making a hackintosh. I used the 120GB 2.5 inch SSD from the double drive pi (I think that was the Raspberry Pi 3?) as the boot drive since I wasn't going to need a huge amount of space and I didn't want to buy anything if I didn't have to.

I found some reddit where someone did a hackintosh with the same DeskMini that I have but with a generation older CPU and went the same route as them since there was the links to the instructions and stuff. It wasn't too bad from what I remember, but I think there were times that I wasn't sure if the installation was being slow or if it froze.

The one thing I couldn't figure out how to fix was getting more VRAM than 5MB, I tried a lot of things and eventually decided to just live with it. I did get whichever stuff tested/compiled and such, though with one of them, the GUI glitches out when running, which is likely due to the lack of VRAM (this was during testing and it didn't get compiled or shared).

I have plans to try a Mac OS VM with VirtualBox (since it might allow me to have 128MB of VRAM), but I keep forgetting about it. It's uncertain when my friend will shift to Apple Silicon, but it'll be when I'll grab a Mac Mini with the same SoC to not have to worry about using a VM or having VRAM issues.

16 June 2021

Bluetooth SNES Controller to SNES Converter via Raspberry Pi

A long time ago my (half) brother let me use his SNES for numerous years, but some years ago he took it back, and I was left with the games. I eventually saw a review video that Linus Tech Tips did on the Super NT, and after some months, I bought one to be able to play my SNES games again whenever I wanted to. I also bought an 8Bitdo Bluetooth SNES controller with receiver for the SNES, since I kinda wanted the buttons to have the Super Famicom colour scheme, and also because the wired controller I have is a Mad Catz High Performance controller (see below the break) that had a broken directional pad (think of it as a very cheap version of the directional pad on the XBox 360 controller). (Pretty much I was left with a short stick that still allowed use of the directional pad, but it wasn't something to use for anything serious... Also it didn't have any sort of "centre nub" that prevented all four directions being pressed at the same time.)

Anyway, Nintendo released their SNES emulator for Switch Online subscribers (I'm calling it a SNES emulator because that's pretty much what it is and it'll be easier to make the distinction), and I was able to use the 8Bitdo controller fine except for the screenshot or home buttons (which were needed for the emulator menus), but I ended up just using the Joy Cons instead. I forgot when Nintendo launched their Bluetooth SNES controller (again, making distinctions), but I bought a set of four (the max per account) so that I'd have two for the emulator and two for the Super NT. I also bought another 8Bitdo Bluetooth controller receiver for the SNES, which kinda sat after I made sure it worked with the 8Bitdo controller.

When I finally got Nintendo's Bluetooth SNES controllers, they wouldn't pair with the receivers (pretty sure that's what it was), and after checking if there were firmware updates for the receivers, there were none. I decided to take matters into my own hands since I was able to pair the controllers just fine with Pod or my phone, and it shouldn't be that hard to translate the inputs to GPIO outputs. I looked up what ways I had to level shift the 3.3-volt outputs to 5 volts, and besides transistors, I found the SN7407. I also found the CD4021 used in some example SNES/NES controller circuits.

While attempting to design a board, I ran into the issue of where to source the voltage for the SN7407, the pull-up resistors, and the CD4021. I designed an experimentation board that allowed me to switch which 5-volt source to use (either the Raspberry Pi or the SNES Super NT), and which ground to use (only for the ICs). It also had some small tactile buttons so I'd be able to test with a game running and a 5-position tiny XLR connector for connection to the Super NT (more on this later). What I found was to power the CD4021s from the Super NT, and everything else from the Raspberry Pi. I think I modded the board for some reason, but it's escaping me (I think it might've been that the buttons were supposed to connect the SN7407 input pins to ground and not 3.3 volts). With the needed information, I was able to continue on with the final board.

Originally I was going to make one Raspberry Pi handle one player, but I can't remember what lead me to making a board for both players and having one Raspberry Pi handle both players. I also had done some testing with Pod and one of the controllers to poke around with the button values and such.

With all the work I had done (thankfully no other boards besides the experimentation was made), 8Bitdo had finally released the firmware update that included Nintendo's Bluetooth SNES controllers, and I dropped the project since it was no longer needed. Unfortunately I already had bought two Raspberry Pi 0 W boards (from different vendors), but they would end up reserved for another project.

I think it might've waited a while between when Nintendo launched the Bluetooth SNES to starting this project, since the experiment board was designed in June of last year.

Resources I used before I dropped the project:


The reasoning for the 5-position tiny XLR connectors was that the Mad Catz controller had a wire break near the plug, so I had to hack something together to get it working once more (besides taping the wire to the connector in a position that it would work). I used some SNES controller extension cables to make an adapter to connect the Mad Catz controller to the SNES, an XLR to XLR extension (or to be able to plug in the experiment board), and another adapter so that the SNES to SNES extension can still happen if needed.

To fix the directional pad, I grabbed the old directional pad top and bottom from my XBox 360 controller (I reshelled it from white to black), and used the bottom to model the receiver and bottom plate for the Mad Catz controller. I got a stepper drill to increase the hole size in the controller for the new directional pad assembly and drilled it out to the approximate size of the one in the Xbox 360 controller.

I had the receiver 3D printed via FDM process and while it looked okay, it really wasn't. Besides it having a little more flex than I wanted, some of the holes were undersized, so when I did some sort of test fit (can't remember if it was with or without the Mad Catz controller), I had to use a drill to be able to separate the top piece from the receiver, destroying the only spare XBox 360 directional pad top I had. It was a little tough to decide whether to buy a button set that included the piece I needed or to order a couple dozen of the piece I needed, but I eventually went with the latter.

I think I just had the receiver reprinted with MJF (multi-jet fusion), but with it showed that I had a portion too thick because I screwed up the maths — the button press pads and the connecting plate were supposed to be 3mm thick total, not the plate itself. After the fix (and some tweaks to the keying in the plate), I sent it off to be printed (still MJF), and when I got it, it worked as intended. I also did have to find my own screws to join the top to the receiver (no screws was included with the reshelling kit), but with a small box of salvaged screws, I found something that worked (this was confirmed before I had the FDM receiver).

It looks a bit weird because the XBox 360 directional pad top leaves a larger gap in the recess than the original (though the original was long gone before this, so I don't have a proper size comparison), but it's functionally fine otherwise. I didn't realise that I adjusted the angle of the directional pad until now, but from the testing after finishing the project, I didn't notice any issues? Or maybe I'm just seeing things, I dunno.

Normal (probably about 2mm around the directional pad) and mine (about 5mm around the directional pad).


I dunno how they assembled the directional pad, but I do remember it had a 5-6mm diameter plastic shaft connecting the inside piece to the top piece, and because there was a lot of space below the top piece when pressing down, it slowly strained the plastic where the top piece and shaft meet until the top piece broke off. I think I tried to super glue it back on, but it didn't work (also, this was numerous years ago).
Since I found pictures that I had...

Boards, finished board top, finished board bottom, and modded board.

11 June 2021

Balanced Headphone Hack/Sennheiser HD 598 CS

With the X5 III, I wanted to have a pair of balanced headphones, so I chopped the connector off of one of my Sony MDR-XB500s and found that it has 4 wires and not three, and after a bit of probing, I confirmed that the two pairs were for each speaker.

It was a little tough to find 2.5mm right angle TRRS cables, but I did find them, and after getting some 4-pole mini/tiny XLR connectors (both male and female), I worked out a pinout scheme and soldered accordingly. The reason for using the tiny XLR connectors was to make it modular, so I'd also be able to use the headphones with normal, single-ended 3.5mm devices (and it looks a lot cleaner than a bunch of heatshrink.

Eventually I decided to get new headphones because the MDR-XB500 didn't really match what I was hearing from the sound system in my car (which has the Harmon Kardon speaker system), and after some reasearch, my options were Sennheiser's HD 598 CS and some Audio-Technica headphones that I don't remember the model number. Luckily, I found both demo models in the nearby computer parts store, so I was able to swing by after work with my X5 III to check out the sound and fitment, and decided on the HD 598 CS. I bought one elsewhere because it was cheaper, and having found a good enough reference sound from this video (spefically the soda can opening) while waiting on the HD 598 CS, and when I had it, I tested it and the MDR-XB500s with it in single-ended mode. The HD 598 CS reproduced the sound correctly to my ears while the MDR-XB500 had a very dampened sound ("muddy" I guess?).

What I was looking for in a headphone was a single cable to one of the earcups (the Y cable on the MDR-XB500 was annoying over time, especially after the mod) and that it had a more neutral sound (the MDR-XB500 is tuned for more bass). I can't remember if I was specifically looking for detachable cables, but the HD 598 CS has it and because the connector to the earphones is a 2.5mm (I think) TRRS, it got me curious. After the audio test (and probably some more audio testing) when I had decided to keep them, I chopped off the 6.35mm plug on the long cable and found four wires, and after some probing, each of the wires correspond to each of the TRRS points on the headphone connector side. The cables provided with the HD 598 CS is a 1m cable that has an inline microphone and a 1.8m cable that has a 6.35mm plug, so I only had one cable to modify. I cut the cable down to a reasonable length before putting the tiny XLR connector on it and then turned the long remainder into an extension cable.

I think I continued to use the 2.5mm right angle TRRS adapter I made for the MDR-XB500s until I found a 2.5mm right angle TRRS cable on Mouser, which I bought with some more connectors. The problem with the original ones were that they were cheap and the rings and sleeve (probably the tip too) of the plug were having a ring worn into them from the plug incidentally turning around within the jack; the ones from Mouser are holding up just fine to this day.

I also made an adapter using the 6.35mm plug, but that was from the second HD 598 CS that I bought. (Yes, I have two pairs of them and two pairs of the MDR-XB500s.)

Anyway, I don't think I can really tell the difference between single-ended and balanced, but well, if I can easily DIY some single-ended headphones to balanced, why not do it?

10 June 2021

Repasting Triela

A while ago my parents' laptop started to thermal shutdown after a bit of use, and I had disassembled the laptop and cleaned the heatsink fins, but while trying to clean the paste from the CPU, I got some stuck between the legs of a capacitor array. I'll keep it short to say that I was unsuccessful in some way to remove it and ordered a replacement CPU. (Eventually some part of the mobo died which prevented the laptop from passing post.)

Anyway, besides learning from that to start using cotton swabs to clean laptop cpus, I decided to apply new paste to Triela since she had her original paste. I found that the motherboard has two open spots for video RAM, and that there were thermal pads in those spots on the heatsink.

I replaced the old thermal pads with some scrap thermal pads that my best friend gave me on the GPU and video RAM before applying the paste to the cpu and putting her back together. The GPU actually did have a thermal pad on top of it which had a slight crack in it, but it's hard to say if it existed before I removed the heatsink.

Triela's running cooler now, and as always, I didn't take temperatures before doing any of this, so I only really have fan noise for comparison.

Shizuma

I can't remember all I previously typed (see "updates" for exactly what I mean), but essentially some things happened and my best friend was able to get Shizuma back. While it was a bit unreal, I did check the battery/hard drive panel and sure enough the misalignment on the panel at the hard drive was there (from when I put a 11.5mm tall hard drive in without knowing/realising 9.5mm was the limit), so I knew it was Shizuma.

I was going to install Snow Leopard, but ended up poking around trying some live Linux distros while I was at my best friend's place since the DVD drive didn't seem to want to read the snow leopard disk for some reason.

Sometime later (at home), I got the DVD drive out of Shizuma and disassembled it to find nothing obviously wrong and once I put it back in, it read the disk just fine. I installed Snow Leopard after doing a "half and half" partition scheme on the hard drive and then installed Manjaro afterwards. Booting was kinda weird since it goes straight to GRUB2 and trying to boot OSX from GRUB2 results in a kernel panic, but this was solved by disabling GRUB2's OS probe and holding option when turning Shizuma on to properly boot OSX.

I found that I could put 8GB of ram in Shizuma as long as the firmware was at least a certain version, and Shizuma had the latest version (well, the last for that model) already installed when I checked.

I applied new thermal paste since I don't doubt that Shizuma had anything but the original paste, and found that a couple of the dies still had a miniscule amount of liquid non-solidified paste. I also found that the heatsink copper for one of the dies had oxidised unevenly in the pattern of the etched markings on the die. Surprisingly, the heatsink fins were fairly clean with some dust on the outer fins, but even though the airflow design's not really great for cooling, it's at least decent for keeping the heatsink fins clean.

I got the ram about a week after that and installed it before trying to run MemTest86 (after figuring out how why the option was missing in GRUB), finding that 4-5 passes is the usual amount that most people test for. I saw the first pass finish after about an hour, so I was thinking another three hours and it should be done, but I was wrong and I stopped the test after getting too tired from staying up.

I started again the next morning and after about an hour, the screen turned off, which I found the cause to be that Shizuma wasn't plugged in. after I plugged her in, I started it once more and occasionally glanced at the screen. First pass took an hour (as I had seen previously), second test took about two hours (which I was also aware of), third test took three hours, and the fourth took about four hours for a total of about eight hours.

I don't remember exactly when I went and reinstalled Snow Leopard and Manjaro, but I did it to repartition the drive since I really didn't need to give OSX half the drive.

The reason why MemTest86 didn't show up in GRUB2 was because of Shizuma's EFI, so I needed to use the UEFI version of MemTest86 which was luckily in AUR, and after installing and rebooting, it showed up in GRUB2.

Recently I got a laptop stand with fans, but with the minute space between the top of the stand and the bottom of Shizuma, the airflow isn't great. As of this draft writing, I'm currently designing a riser that uses the mesh to stabilise it's location and lift the hinge end about 20mm.

I'm not entirely sure what I'll be using Shizuma for, but I'll find a use at some point.
With the laptop stand, I just used rubber feet to raise the hinge end up about 10mm (unless the stand I was originally talking about is a different one, I dunno). I also changed the 5 volt fans out for 12 volt ones and designed a replacement control board that uses a Firewire 400 jack to get power from Shizuma's Firewire 800 jack (via a Firewire 800 to Firewire 400 cable). I might write more about the replacment control board in a separate post, but don't hold your breath.

19 March 2017

Soundcard Switchboard 2

Before I start, I'll post the pictures of the test boards that I was testing the plated slots that I took a couple minutes before starting this post.

Just the 3-up in my hand for a quick picture.You might be able to tell that the slots are parallel to each other, but not to the edge of the board.

Anyway, I had received the boards first with the boards for the solder station, and had set them aside since the order from Mouser was back-ordered. Once I received the parts, I began with taking a bit of time at work to do the switches.

I took pictures as I soldered the wires to the switch. Deformity/dents on the heatshrink tubing on the last couple pictures is from trying to recover the unshrunk diameter of the tube since it shrunk while I was soldering.

Some closer shots. The LED polarity is marked on the plastic of the switch though the LED legs follow the usual "anode leg is longer than the cathode leg".

Obviously I shrunk the heatshrink around the soldered ends.

Both switches after shrinking.

I then covered the wires with larger heatshrink tubing to make it look a bit nicer (though it wouldn't be visible anyway).

Before and after.

I then utilised some larger heatshrink that had some adhesive on the inside to try to keep the stress away from the solder joints. I was lucky that the outside diameter of the tubing was less than the bushing. The adhesive heatshrink tubing took a lot longer to shrink since the wall was thicker and the adhesive also need to absorb the heat to activate.

Before and after. It didn't turn out entirely like I wanted it to, but it at least was adhered to the switch body.

With that done, I needed to drill out the holes in the 3.5" to 5.25" external bay adapter for the switches. The week before I had observed how to utilise the vertical mill at work for basic usage, so I was relatively prepared the day after making the switches to drill the holes into the panel.

I had decided beforehand that I would utilise the vertical mill, since I would be able to keep the holes aligned horizontally even if I was off a bit vertically - I wanted this to look nice. I was also thinking to get a drawing out to have the machinist drill them out for me, but I didn't really want to deal with the awkwardness of asking him directly and/or asking the manager to have him do it.. Anyway, picture time.

Different views of the newly modified bracket.

I also drilled some small holes for securing the cable to the bracket to further remove stress from the solder joints as I had forgotten to mention before posting the pictures (which were done the day after). I next installed the switches and found why I was supposed to drill the holes larger, which is because of a boss of a different diameter that the O-ring fits around. Had I drilled it out to the proper size, the switches would be able to sit flat while compressing the rings, but that didn't happen and I didn't have access to anything larger than a 1/2" drill (I think the datasheet for the switch calls for a 13.6mm hole).

I decided to ignore it and keep working, since it wasn't entirely noticeable, and with the second switch, I tweaked the adhesive heatshrink too much and heard a snap. I think my heart stopped for a moment since I was hoping to hell that the snap wasn't from the LED legs. I took a moment with the semi-broken multimeter (the one seen in one of the pictures from the solder station project thing) to checked the forward voltage, which gave me a reading and drove the LED to light up enough to ease my fears; I also checked the switch, though I doubted the lugs would be able to snap like that - switch function passed. The snap was probably caused by the adhesive detaching from the switch body. I then secured the cables to the bracket once the nuts were tightened.

Front-ish and top view. Semi-broken multimeter in the background of the front view image.

I then reattached the multi-card reader to the bracket before reinstalling it into Melty.

Same views as before with the card reader, and the assembly installed in Melty.

After spending a couple hours cable managing, I found that the Hirose connectors were not going to work with the Iwiss crimpers I currently had, and went with utilising a pair of needlenose pliers to do what I could to crimp them to the wire. After loading the plugs correctly, I shrank the heatshrink tubing before making the power harness. I decided to use red for the cable to the switch on the right side of the case, so that I would be able to differentiate between the cables if I ever wanted to change the button order.

The best-attempt crimp job, finished left switch harness, process of the right switch harness, and the power cable harness.

I then connected the power harness and then tucked the three cables awkwardly "in" the PSU shroud so that they would kinda stay put and not cause too much trouble.

New cable management, 5 volt power for switchbox added, inside shots, front shot (though probably not needed).

I tucked Melty back under the "desk" and hooked her back up before relaxing for the night and the next morning I began assembly on the board.

The usual pictures.

When it came time to the jacks, I soldered one of the three legs to the board and was going to utilise the PCI panel to line them up better when I found out that I screwed up the spacing between the jacks.

This actually isn't the correct panel (this one has 8 holes and not 9), but you can still tell that the spacing is wrong.

I was upset that had made that sort of mistake and decided to set it all aside and change gears to the solder station boards.

I forgot to mention that when I was drilling the holes for the bracket, I drilled out the holes in the correct PCI panel out larger so that the shoulder washers that I purchased would work with it and isolate the sleeve signals from one another. I also bead blasted it and painted it with some matte spray paint, but I never took pictures of it.

Anyway, I took the "wrong" panel to work to use the pin gauges to measure the diameter of the holes and it varied within a couple thousandths. I also measured between the diameters of the holes and also measured between the out-most two holes and divided by 8. I think it was when I was using the pin gauges when I realised the panel had 8 holes and not 9. The difference between measuring one and measuring the total and then dividing by 8 was one or two thousandths difference, so I think I took the result from dividing by 8 since that would be a bit more nominal than just taking the one measurement between two of the holes.

I decided to redraw the PCB instead of trying to fix the current one as I didn't want to have to deal with the existing polygons and traces. Surprisingly, it actually didn't take as long to redraw it, since some of the values would be staying the same between the new and old boards, and I sent the design to OSH Park once I was satisfied.

Before and after ratsnest tool.


I decided to bead blast the "wrong" panel during lunch to get the weird crud off the back (which was also present on the "correct" panel) and to make it a bit nicer. There's still some discolouration from where the crud was, and I'm guessing there was some sort of corrosion going on with its previous utility.

I just don't think my camera likes taking a good shot of the bead blasting.

I had found out that there were cheaper crimp tools to be able to crimp the tiny Hirose connectors, and after finding what it was and verifying in the list, I found it on Amazon and promptly ordered them.

I had booted Melty into Windows to check if I was having the same errors that a friend was having with a game and noticed that my files drive was offline, and after verifying it in Manjaro, I powered her down and investigated. Eventually I found a SATA cable unplugged from the motherboard and then I removed the one above it to plug the one that become unplugged back in (since I couldn't manipulate it back into the port with the one above it still plugged in) before plugging the one above it back in.

I then did a test tug and it became unplugged. I found that the release latch was designed just right so in a stacked configuration like that, the plug above it would depress it enough to where it wouldn't latch. I really didn't want to rerun the SATA cables (or even mess with any of the cables), and decided on trying to flatten the release latch so that it hopefully wouldn't do it again. After some careful squeezing with a pair of pliers, I got it flattened enough to where it stayed latched with the other SATA cable plugged in above it. The only thing is that it seemed like the release latch was dangerously close to the edge of the moulding that keeps it down.

Before and after.

While it wasn't directly related to the project, it was caused by this project. Anyway, the day after I crimped new connectors to the switch harnesses with the new crimp tool (Engineer Inc. PA-20), noticing that some of the previous contacts came off a bit too easily.

Just an after image because I was kinda in a hurry.

I had also really awkwardly used my new heatgun to shrink the new tubing, but it turned out well enough. The boards were supposed to arrive that day as well and I spent time desoldering all the components from the PCB, and once I was done with that, I just killed time in my room as I checked the tracking number.

Unfortunately, the boards never showed up, and for whatever reason, it took the package seven hours to get to the local post office from the main one which probably isn't more than an hour away. I was irate that the rest of my Saturday went to waste, but after getting home on Monday from work, I got the boards and quickly started on finishing the project.

The usual views. Yay 3.1! (Maybe "Yay!"...)

I first set the jacks into the PCB and checked the hole spacing to ensure myself that this wasn't going to all go horribly wrong at the last moment again, and i was definitely reassured.

Blast that bloody window!

I quickly began soldering the components back to the board, starting with the resistor, and I almost soldered the Molex header before the relays but I caught myself before I let too much solder flow.

Progress.

Being paranoid doesn't hurt sometimes, right?

With just one leg of the jack soldered, I tried a few things to try to keep the jacks aligned before deciding on just utilising "brute force". Once it was soldered, it looked fairly nice in the panel.

Still have a bit more to go.

Since there was the leftover PCB from when they were connected to the other PCBs in the panel at the board house, I decided to see if I could file it away enough so that it wouldn't interfere with the panel later on, and I was surprised with how easy it was - I just wished I thought about it before soldering the jacks on.

I think you can tell?

With how wide the outermost diameter of the shoulder washer is, I knew I had to cut them down so that they wouldn't overlap, and while I should've done it Saturday, I was a bit too frustrated with the post to do so. As I began cutting the first, I decided on a pattern, where the middle would be uncut, and the others would "D" outward from it.

The pattern as I was cutting the shoulder washers. The cuts shoulder washer, with the shoulder up.

Luckily it didn't take too long, and I awkwardly tightened the nuts with a pair of needlenose pliers (after failing to use a slotted screwdriver on one side of the nut). I tried to get the slots to line up, but eventually gave up.

Finger-tightened and plier-tightened.

Now that the board is assembled, it was time to install it. I first chose the slot directly above the Sound Blaster card, but found that I'd have no space at all for the plugs, so I moved it to the one above that. I also had a tight spacing issue with the 1394 front header plug, and so after I moved it up, that was no longer an issue.

Harnesses connected to the board, switchboard in the originally-intended location, switchboard in the revised location.

Next was to connect all the right-angle stereo plugs into their proper spots and to test out the sound. I ended up switching the spots for orange and black because of the Logitech's X540 cable harness. It obviously doesn't matter as long as the flanking cables are of the same "colour".

Views of the semi-organised "mess".

Manjaro passed the surround sound test, while I had a weird issue with Windows - the surround speakers were putting sound out through the center and sub while the centre and sub was coming through front speakers (or something like that). I checked that everything was correctly plugged in and such, and eventually looked up the manual to see that I had shifted plugs to the right by one jack when I had put Melty back under the "desk". After fixing the cables, Windows passed the surround sound test.

The semi-organised "mess", revised.

I think I explained that the LEDs in the switches would light for the soundcard not in use. So when the motherboard's soundcard is "active", the switch to change to the Sound Blaster card would be the lit LED, and vice versa. Probably a bit easier to see...

Sound Blaster card "active", motherboard soundcard "active".

I was done, I was satisfied, and I cleaned up whatever I needed to clean up and take care of other things before heading to bed.

Recently I found an Iwiss ratcheting crimper that works with JST connectors, which I think are very similar to the tiny Hirose connectors I use, and I had saved it in my wishlist while my compatibility question went unanswered on Amazon. Eventually I went ahead and ordered it to test it out for myself, since it seemed like I wasn't ever going to get an answer. I received it last week and first utilised it on the breadboard power cable, confirming my theory.

Today, I decided to redo the connectors (third time's a charm, eh?) since I was pulling out the bracket out to remount the card reader with washers, and ended up redoing 6 of the 8 connectors (two of them were crimped too well with the Engineer Inc. crimper and didn't want to come off at all). It was obviously a lot less awkward to redo the heatshrink now that the cable ends aren't inside Melty.

Four connectors after crimping new connectors, two connectors after crimping the new connectors (red and white), and completed ends. Also, dry skin is dry.

I also poked around and had a suspicion that some sheet metal screws from work (it comes with one of the parts that is purchased, but doesn't get used) was similar in diameter and thread to the ones that held the bracket to the case, and after confirming my suspicions, I decided to utilise them to secure the bracket to the case even further, although the screws are much longer than the ones that came with the bracket.

Longscrew is long (but doesn't encounter anything).

After getting the bracket back in Melty, I re-ran the cables and did a bit of cable management, closing her up once I was done (though I forgot to reconnect the USB 3.0 front panel to the header).

Inside views. I tied the cables from the card reader and a SATA power cable to the edge of the 3.5" drive bay (a bit hard to see minus the red cable ties).

I also meant to take a picture earlier of the cable management of the top fan cable, where I removed the pins from the housing and threaded it through the hole of the cable tie-down loop of the motherboard tray to get a much neater look.

Black (or red) heatshrink would make it look even better, but I realised too late. C'est la vie.

The relays are actually audible this time, since the board is attached to the panel via the audio jack threads. It's not a huge deal, since it's just one simple "click", though I doubt there's an easy way to silence the relays anyway.

The only way to improve this project is to have it auto-switch, but I think that requires parts I'm not familiar to using.

I think the main thing I learned with this project is to not assume. I only really took a ruler and thought that the hole spacing (centre to centre) is about 1mm without taking my calipers and measuring the actual spacing between the holes (by edge) and the diameter of the hole itself. Had I known I was going to screw up ahead of time, I probably would've made a proper 4-layer board with the sound traces in the inner layers, so that the ground planes would properly shield them from EMI. I suppose I could improve it that way, but I've already spent enough money on this project.

Eventually I'll work on the Raspberry Pi clock project, but it's just a side project and not a main project like this or the solder station. For now, I'll be able to focus on story-writing since I have about 3-4 stories I want to work on (one of them just needs another pass of proofreading), and sometimes I don't want to pull myself away from it to do other things.

Anyway, ciao for now!