Uncategorized

First off, here’s the end result:

The 3D model I used for this was this design from Etsy. It was well-designed, and looked like a closer match to the on-screen prop compared to the other models I saw.

Like the jetpack, I printed it in plain white PETG on my Bambu Lab P1S, then followed the same steps for sanding and painting from my previous post. (side note: the weld lines are part of the 3D model itself.) Unlike the Veepy jetpack model, this one came segmented in ways that would result in visible seams. Or at least it would with my printer — it did include a model of the whole helmet at once, if that’ll fit on your print bed.

Here’s a comparison picture between the old and new helmets, which also shows the (taped-together) sections of the new one:

To deal with the seams, I originally figured I’d use some classic Bondo auto-body-repair stuff, but at one point when I was picking up supplies, I happened upon the much more appealing plastic resin goo that cures immediately under ultraviolet light. I was an instant fan of that stuff — take your time applying it, it won’t harden until you want it to, at which point you can cure it immediately and not wait to continue working on it. It’s nice and sandable after curing, too. I used that stuff to cover up the seam lines, as well as to smooth out the top surface lines on the jetpack flaps, and even to extend part of of the central section of the jetpack that didn’t quite print perfectly.

This may have been a mistake, but I painted the top fin separately from the rest of the helmet, and then tried to glue it in place. Even after sanding the relevant spots, it was an incredibly tight fit. If I redid things, I’d try attaching it before painting.

The lenses were another tricky element. Those are tinted acrylic, thermoformed to the appropriate shape. The shape you’re using to press the hot acrylic sheet against is called the Buck. You wouldn’t want to 3D print the buck itself, because it would deform the printed plastic. The 3D model for the helmet included a model for an inverse mold of the buck, into which you can pour Plaster of Paris to make a solid buck that can survive oven temperatures.

Once the paster bucks were made for each eyepiece, I cut some pieces of 1/8″ thick tinted acrylic sheets to slightly larger than the shape I needed. I heated up an old toaster oven to 450-500F, and put in the buck with the acrylic piece on top of it, and waited a few minutes for the acrylic to visibly sag, indicating it was suitably bendy. It won’t droop enough to just flow over the buck like melted cheese — you need to force it into the shape. The best solution I found for that was to take a smooth silicone project mat and lay it over the piece, then press down hard on it with both hands. The silicone mat got warm, but not hot enough to burn me. Once the lenses were the right overall shape, I trimmed them down to the exact right shape with a dremel tool.

I wanted something to black out the mouth holes without restricting airflow, because otherwise I knew from my previous helmet that it would fog up the inside of the lenses pretty quickly. I had tried a few different solutions on the previous helmet, but eventually landed on the thing I used for this one as well: I took a black N95 mask from my COVID-days stash and cut out the outer black layer of it. It lets air through just fine, and doesn’t cause the lenses to fog up as much.

The inside of the helmet has a bunch of generic helmet padding stuck on it so it doesn’t rattle around on my head, and I made a quick fake leather chinstrap for it. I’ll be replacing the strap now that I’m starting on the leather work for the jetpack harness.

Oh, one last thing. For the first helmet, I was concerned about it being awkwardly sized, so I improvised a method of determining the proper amount to scale it in each direction such that it fit my head, but just barely. I took long LEGO plates and built a bit open rectangle and adjusted it in or out until I could just fit it over my head without issue. Then I measured that. Then I printed the single-piece version of the original helmet at about 30% scale, and measured the head opening with calipers, and scaled that up to 100%, and did the math to determine to appropriate scaling in each dimension. For the new helmet, I did the same thing, using the same LEGO frame as before. And once I printed the 30% version an scaled up its measurements, I found that its head opening was within a couple of centimeters of the target size. So no scaling needed. Fortuitous!

All of the pieces were printed using plain white PETG filament, so everything came out looking this this:

Painting anything like this was a new experience for me, so I learned a number of lessons along the way. I don’t have an airbrush, so I was going to be using regular spray paint cans, which can give a good metallic-looking finish if the surface is sufficiently prepared for them. Spraying chrome paint on the parts straight out of the printer would look awful, because the surface needs to be smooth. The shiny reflective paint will highlight every non-smooth detail on the surface, and every one of those will make it look less like metal. That means the visible layer lines from the 3D printing process have to be smoothed out, and so does any other disruption in the surface.

I went through some trial and error through the project, but in general I worked over the parts with a low-grit sandpaper (always wet sanding, to avoid making a cloud of plastic particulates), then put on a layer of sandable filler primer to help fill in the gaps, then (wet) sanded that with a medium-grit sandpaper, then repeated those two steps if it seemed necessary. Once I got things looking about as smooth as the primer would get, then I’d put down a layer of glossy black paint, and then go over that with a high-grit sandpaper. Then I’d bring out the chrome spray paint, doing lots of quick passes from slightly further away than the rest of the paint. Before any spray-painting pass, I’d wipe the surface down with a microfiber cloth, then with a tack cloth to make sure the paint wouldn’t hit some errant bit of dust or lint.

Once I got this process down, the pieces started looking incredibly metallic:

This was the first piece that I successfully got a good metallic finish on, and at this point I was stoked. I always intended to make something better than the first jetpack attempt, something that would make the first one look like a toy. But at this point it became clear that I could potentially make something indistinguishable from the on-screen props, and that inspired me to put in a lot of extra effort. I think this was also the point when I decided to add electronic effects to it.

The downside of that metallic finish was that it was _fragile_. Handling it rubbed paint off on my hands, and it dinged visibly and easily. I needed to protect things, so I grabbed a can of clear-coat spray protectant from the same brand of spray paint.

This was a mistake. Do not do this.

This was one of the first big lessons I learned here: I guess the clear-coat spray paint can be used successfully over regular colors, but using it on top of metallic paints just ruined the finish. I eventually found an explanation: the metallic spray paints are basically clear paints with tiny metallic-looking particles suspended in them, and when you spray it on something, the metallic particles stick to and coat the surface that you’re painting from inside that suspension, which is why it needs to be that smooth. But if you then spray the clear coat on it, it uses the same solvent as the metallic paint, so it just loosens up all of the metallic particles and lets them float around loose in the suspension, losing the smooth shiny surface. I saw some reports that you could successfully do this, but the steps were very fiddly and seemed to rely on a lot of luck.

Trying to find what people used as an alternative was tricky, because a) lots of people who are serious about this sort of thing are using airbrushes, which have different constraints, and b) the main product that people recommended no longer exists. The product in question was Future Polish, some brand of clear floor polish. It’s gone now, but I picked up a random brand of clear floor polish, squirted some onto a paper towel, and wiped the pieces down with it, and that seems to be working out well so far. It doesn’t look quite as good as it did with just the paint, but it’s a lot more durable.

So the main body of the jetpack was all done using chrome Rust-oleum spray paint. I tried their silver option, but that had a glittery finish that didn’t look right. The nose cones are a slightly different color in the movie, and based on a tip I saw online, I used Tamiya TAM85075 spray paint for those, and it seems like a perfect match. For the helmet and fan blades, I used Rust-oleum’s “metallic champagne bronze” and it seems fine.

If this was the kind of project I did with any regularity, I’m sure I’d pick up an airbrush and it would help. But I’m happy with the output of this process.

To start off, here’s what we’re talking about. You’ll want sound enabled for it.

This second attempt at a replica jetpack was also 3D printed (on a Bambu Lab P1S) using PETG filament, sanded and painted to achieve a metallic-looking finish. The 3D model was the “Veepy Jetpack” design, which is sadly no longer available. I am stunned at how well-designed this model is, not just in terms of being screen-accurate, but also how well things are engineered to support successful printing and assembly. There are even aspects that facilitate maintenance of it, something that I tried to continue in other areas of the build. The model was also designed to accommodate effects hardware, in order to provide lights and sound and a moving fan.

The Veepy design also incorporates off-the-shelf hardware components when possible, for things like the flap actuator parts, the braided hoses and copper pipes on the engines, the fan, and hundreds of tiny rivets. Having the rivets be a separate component not only made them look more realistic, but it made the sanding process easier without having to work around hundreds of little bumps.

To make maintenance easier, the nose cone sections are held in place with magnets, and can be carefully pried off. That gives access to the inside of the tanks (if your hands are small enough). The engines rest in a bracket inside the tanks, and are secured with a single screw each to keep them from popping out of place. Removing that screw makes it possible to remove the entire engine, at which point the tank is empty. The tanks are attached to the central section at the bottom by some 1/4″ screws, and at the top there’s a long threaded rod running from one tank to the other, through the radiator section. Those parts are designed so that once the nose cones are removed, you can unscrew the nut from one end of the threaded rod, slide it over to the other tank, and pull out the radiator. At that point you have access to the central section from the top, which is useful since that’s designed to contain the effects electronics.

I took things a step further and worked to keep the tanks separable from the central section if necessary. The little rivets are all super-glued into place, but the ones that would connect the central piece to the tanks are only glued to the central section. That made the tanks separable, but it would leave a small gap visible between the tanks and central section when things flexed at all. To counter that, I removed a handful of strategically-located rivets and replaced them with threaded fake rivets that can be secured from both sides. These are normally called Chicago Rivets, and I found some that worked for it, but installing and removing them was really fiddly. So instead I took some long-ish M3 stainless steel screws, filed the heads down until they looked like the rest of the rivets, and secured them with wingnuts on the back side. Now the tanks are securely attached to the central section, but I can undo that part and remove them if needed.

I think the only other tweak I made to the Veepy design was to replace a couple of threaded wood inserts with head-set inserts, because I was afraid the wood inserts would end up breaking the 3D printed plastic. Regardless, the Veepy design was incredibly impressive, and it inspired me to put in the extra effort necessary for other aspects of the project.

I have long been a fan of the 1991 film The Rocketeer, and especially the iconic design of the hero’s jetpack and helmet. A few years ago, I thought “why do I even have a 3D printer if I’m not going to make a replica jetpack?” So, I found some decent free STL files and printed them out using metallic-looking “silk” PLA filament. The proper approach to something like this would involve a ton of sanding and painting to get a realistic metallic look, but I wasn’t going to commit to that kind of effort. The end result was pretty satisfying and well-received:

That’s them hanging on my office wall. I filled in various seams on them with metallic-looking hot glue that did a reasonable job imitating welding lines. The harness was pretty rudimentary, just consisting of some woven nylon straps and metal buckles.

Towards the end of that project, I found a much better-designed 3D printable model of the jetpack, but it would have required actual sanding and painting — the silk filament looks reasonably metallic at a distance, but not if you put it next to actual metal, and the better design used a number of metal components. So I purchased the improved design and filed it away for the next time I felt the need for a really obsessive project. A couple of months ago I decided it was time, and I’ve been very pleased with the results. So now it’s time to start documenting the project.

Just a quick update here. No hardware changes since last time, but I finally got around to putting in rudimentary ghost key rejection. What I tried was laughably simple: if there are more than two new keys being detected in a single scanning pass, ignore them both and send no updates, until the next change occurs. It doesn’t even check to see if they are in positions to cause ghosting — it just relies on the fact that ghost keypresses will always appear instantaneously with the last key, and for normal keypresses that’s very unlikely. Since making that change, it’s just perfect. No ghost keypresses, and no lost keys from what I’ve noticed.

One unfortunate effect from the current decoder/diode arrangement is that I can’t really set things up for this to go to sleep and be awaked by an interrupt when any key gets pressed. So I don’t have a great way for this to go into a very low-power mode, but I can at least try to optimize the regular power usage a little. Throughout all of the previous iterations, I had a 1ms delay following each scanning pass, but the passes were now happening much faster without the IO expanders. I tried doubling the loop delay to 2ms, and noticed no change in responsiveness, but greatly increased battery life. At some point I’ll probably put something in to increase that a lot (like 25ms or so) if there haven’t been any keys pressed in an hour or so, and that’ll presumably make another huge difference. But for right now everything’s great.

Oh, I should also put in some kind of support for volume/media control. That would be useful.

So a couple of days ago I noticed that a cryptocurrency/NFT startup was using Blocks from Hell on their site (along with other unlicensed games) as part of a thing they push as “Get Paid to Play Games!”. In reality you have to front some amount of currency to play games, and while you play they pool it together and use it to mine new currency via Proof-of-Stake, and kick back some scaled percentage to you. So it’s less “get paid to play games” and more “a weird savings account that only accrues interest when you are actively playing Minesweeper, from a non-bank that is not regulated or insured”. I can see why they went with their description. The games, of course, serve no real purpose beyond marketing gimmick and psychological hook.

I am amused by the hypocrisy involved in people who are selling NFTs from a website built by copying a bunch of games without any permission or licensing. Not surprised, but amused.

Anyway, for any future cases like this, I am not interested. For the current site, I asked them to remove the game and they have promised to take it down in the next couple of weeks.

Now that I’m partly back in my office, I had to have two functioning keyboards again. I dusted off the two latest-version modified NMB keyboards, and tweaked the debounce timing on them slightly, and they’re working fine as my daily drivers. The current debounce logic is very rudimentary; between each loop through scanning the keyboard matrix, the firmware delays by 1ms. If there was a change in key state, this is sent over bluetooth, and the firmware delays by DEBOUNCE_DELAY (currently 20ms) before scanning again. If I were super picky, I’d just ignore bounces in the most recently-changed key, but for real-world typing this seems fine. Any time I get spurious key repeats, I can either clean the switch contacts or increase the delay value.

I do need to implement some kind of anti-ghosting mechanism, since the old keyboards have no NKRO diodes or anything; if I’m sloppy while typing, I’ll easily start getting ghost keypresses. My plan for a rudimentary solution for that is that if there’s ever a key-scanning update that results in two keypresses being added in the same millisecond, then ignore that update until the state changes again. Most of the cases where I’m getting ghost keypresses are when I’m pressing three keys in sequence but I’m late in releasing the earlier keys, so I get events for key1, key2, and then key3+ghost_key. (This happens when two of the keys being pressed share a row, and two of the keys being pressed share a column, and the end result basically shorts out another intersection on the key matrix. So if the keys being pressed are at A1, B1, and A2, when the third key is pressed it will also appear that B2 is pressed, because row 2 and column B are connected through the other three keyswitches.) Anyway, since I don’t know which of the two simultaneous keys being detected is real, I can just ignore both of them, and once one of the first two keys is released the situation should be resolved and the next update can go through.

One of the keyboards is the large Windows-key-equipped version, with everything mounted internally. The other one is one of the smaller 101-key models, and the bluetooth board is mounted on top, in a socket, too tall to fit inside the case. I finally got tired of using it with the top part of the case removed, so I just cut a hole out of the top to accommodate it. Much nicer.

As of the last update, I had a nice setup with a couple of Supermicro cases; one used as a SAS JBOD box, and one containing a consumer Intel motherboard. I happened upon a good deal on another Supermicro server, this time in a 2U case with 24 hotswap 2.5″ SAS bays (connected to an expander) dual 1200W PSUs, and an X8DTH motherboard with two Xeon E5645 CPUs, 64GB of ECC RAM, a built-in LSI SAS HBA, and IPMI with remote KVM. I was just shopping around for a motherboard, and for the price the case was just a bonus.

I started out by moving the new motherboard into one of the 3U cases; I wasn’t sure I was going to use the 2U case at all, and the 3U case would let me use full-height cards in the 7(!) PCIe x8 slots in the new board. That setup was really unstable, though, and eventually I came to the conclusion that the PSUs in the 3U cases just weren’t up to the task.

So, I moved the board back to the 2U case and used both 3U cases as SAS JBOD boxes. I had to pick up a replacement GPU to fit the half-height slots of the 2U case, but the new setup is rock-solid. The end result has 54 drive bays, 24 threads, and 96GB of RAM. The 2U case has passive heatsinks on the Xeons, and uses midplane fans with ducting to cool everything. The stock fans were super loud, but replacing them with Noctua fans didn’t provide sufficient cooling. I ended up putting the stock fans back in and fiddling with a script to slow down the stock fans via SMBus. It’s not as quiet as I’d like, but it’s quiet enough. I replaced the home-built rack with a metal-frame one, albeit without sides or a top. Cable management is definitely a lot easier.

Success! I got the latest PCBs over the holidays, and finally had a chance to assemble a couple of them. Using the new decoder chip instead of the i2c GPIO expander is way faster. Faster enough that for the first time in this project, I had to worry about putting in a debouncing delay. (Keyswitches like these “stutter” a bit when closing or opening, so if you’re fast enough at scanning them, you’ll get repeated presses.) The loop that scans through the rows/columns has a 1ms delay at the end, so I just added an additional delay any time the key state changed, and adjusted that until things seemed stable (around 10ms). At that point most of the keys were fine, but a few of them sporadically stuttered. I popped the keycaps off and cleaned the switch contacts with sandpaper, and now they’re fine. (One nice feature of the NMB/Hi-Tek “space invaders” keyswitches is that you can do this without disassembling everything.)

The PCB I made stacks onto the Adafruit Feather microcontroller board, and then attaches to the keyboard PCB. For testing purposes, I have all of these things socketed, but at that point the whole mess sticks up enough that the top of the keyboard frame won’t fit. I haven’t found detachable connectors that were low-profile enough to fit, so for actual deployment I’m soldering everything down pretty much flat. Here’s the Feather and adapter board soldered together, and stuck into a testing socket:

In fact, there are two general models of keyboard that I’m working with; that one is the more compact layout (the RT8756C+ and similar). It predates the existence of the Windows modifier keys. The other models are the RT8255C+ and RT8255CW+, the latter of which is the only one of these keyboards I’m aware of that includes the Windows key. These models have a larger, flatter case, and they have no space on top for the adapter. They do have a bit of space underneath, though. On the wrong side of the PCB. So, for those it’s a bit of a hack. Here’s the top side:

In place of the original 40-pin microcontroller, there’s just some header pins, pushed all the way down so they stick on the other side enough that I can solder them in place and then still stick a connector onto them, like so:

That’s the same Feather/adapter combo as before, but assembled upside-down, with a 40-pin socket soldered to the adapter so it can connect with the pins hanging down from the keyboard PCB:

I had to trim the socket to fit around the decoder chip, but it all fits, and works. Here’s what it looks like installed:

It’s a pretty minimal installation; just the adapter/Feather combo, a Li-Poly battery, and a microUSB extension leading to the outside, so it can be plugged in for charging and reprogramming.

Now that the keyboard is functional, I’ve been able to start going through the rest of the to-do list for features. First up was making the capslock light work. I could make the NumLock and Scroll Lock lights work, but nothing really uses them. One of the to-do items is to repurpose the Scroll Lock light as a battery indicator (flash slowly at 50%, quickly at 10%). I need to put in some ability to have a hotkey for “Consumer Control” keys like volume up/down and playback control. I don’t know how long this battery lasts with the current arrangement, but I may want to put in some sort of sleep mode. Unfortunately, one drawback of the current arrangement with the decoder chip is that there’s no way to select all columns at once so I can have the microcontroller go into sleep mode until any key at all gets hit and generates an interrupt. I may be able to rework the design to add in transistor logic to accomplish that, but it would undoubtedly be more complex. Worst-case, I can designate a special “wake key” that is the only one that would wake up the keyboard and just monitor that one.

I also need to come up with a good solution for filtering out ghosted keys; since keyboards like this work by connecting rows and columns of connections, if you press some arrangements of keys, they’ll short out and make it look like an additional key is pressed. If you press the keys in position A1 and A4, and then press the key in the C1 position, it will also appear that you pressed the C4 key; column C and row 4 are connected because C and 1 are connected, and 1 and 4 are both connected together through A. Newer keyboards that support effectively unlimited simultaneous keypresses (NKRO, or N-key rollover) work by having a diode inline with each keyswitch, preventing it from shorting out backwards like that. These keyboards don’t have any of that. My plan for this so far is to take advantage of the fact that when a ghosted key appears, it should always be two new keys being detected in the same scanning pass, which is unlikely to happen otherwise. So if it sees two new keys being pressed, it should just ignore them until the next key state change occurs.

Anyway, unless I think of a clever arrangement for supporting interrupt-driven wakeup, the hardware side might be done.

I realized that the last time I mentioned my home server, it was when I switched away from unRAID. I did so because I really wanted dual-drive redundancy, and more powerful options for running services other than basic file-sharing on it. That was some years ago, and I’ve since switched back to unRAID, because starting with version 6, it basically checks all the boxes. It now supports dual-drive parity, mirrored cache drive pools, and a very impressive collection of software add-ons made possible by docker. I’m very happy with it.

Case-wise, I think I started out using an old Antec P180 tower case, then moved things into the Norco 4U rackmount case mentioned in the older posts. It was dirt-cheap for rackmount gear, and it was just impossibly loud. You could easily hear it from another floor of my house. But it was cheap, and fit a lot of drives, and like a lot of hobbyists, all I really want is enterprise-grade hardware for cheapo prices.

After the Norco case, I moved things into the NZXT H2 tower case; I could fit 13 3.5″ hard drives into it along with a few SSDs, and it was nearly silent. I ended up making my own SATA power cables for my modular power supply to clean up the airflow inside. A nice case, but once I moved into a place where I could stash the server in the basement, I was ready for something bigger. I briefly expanded by picking up a dual external-port SAS controller card, and connecting it to a couple of 4x drive pods in an old multi-drive SCSI enclosure — you can get replacement plates for the back that swap out the old SCSI connectors with SAS, eSATA, USB, or whatever.

After doing some research online, I concluded that the cheap enterprise-grade solution I was looking for was used Supermicro gear. I really liked the look of the 933T chassis, a 3U server with 15 vertical hard drives lined up in a row. They’re all hot-swappable with a SATA backplane. (There are SCSI and SAS backplane options, but I believe the SAS version requires interposers for SATA drives, so whatever.) The 933T occasionally showed up on eBay for ~$150, often with an old Opteron-based motherboard. One nice feature of Supermicro’s hardware like this is that it’s all ATX standard, so you can swap it out for whatever else. The included power supply supported 3 redundant hotswap PSU modules, so that’s a plus.

It was pretty noisy, so I swapped out various fans (including some 40mm fans in the PSU modules, probably the noisiest of them). Now it’s nice and quiet.

Another nice feature of Supermicro stuff is that they sell a ~$20 board designed to convert an ATX server case into a JBOD drive enclosure; it hooks up to the ATX power connector and various case connectors (power & reset button, power LED, etc.) and lets you power on/off the device without a full motherboard in it. So I bought two 933T’s! One of them contains the motherboard (an Intel DZ77GA-70k) and SAS controller, the other contains the JBOD “motherboard” and a SAS expander hooked up to the backplanes. So now I have a quiet 6U server with room for 30 hotswappable drives.

I built a simple wooden rack using some 12U brackets to put everything in, and eventually added in a couple of 2U UPS’s and an old 1U console. At some point I’d like to replace the rack with something solid (with removable panels), but otherwise I’m thrilled with the current arrangement.