After quickly realizing how much I hate writing tons of giant arrays by hand, I took some time out to write an animation editor.
The goal was simple, write a quick tool to write out lamp state buffers into a hard file. These are then loaded at runtime and can be played at any time.
Overall it was pretty straightforward. The perf of this tool is pretty damn awful and it’s very one-off, but it gets the job done. One thing I did notice is that transparent buttons load VERY slowly, which is kind of annoying since I use transparency to indicate the animation has no preference (Used for localization animations)
Importing and running the animations was dead simple with C#’s DataContractSerializer, it doesn’t even require the target class be the same code as long as the data structures match.
To say that I was hesitant to plug that toroid in would be a gross understatement. There are a lot of things that can go horribly wrong, and while I did have the foresight to fuse all the outputs, there’s still the chance of something going wrong upstream.
So after many confusing hours of confusing results with a multimeter due to the output caps, I finally worked up the guts to power it all on. I actually went as far as to set it to power on with a 10 second delay, then only be on for one second. Heh.
No disasters. There was a new solenoid lock bug, but that was easily sorted. Beyond that the GI relay popped during testing, everything else worked fine. Expect a video soon.
Soldered up the board with caution, but it appears that the whole thing works fine. Currently I’m testing at 12v and the only problem I’ve noticed is that the new ATX power supply I’m using does a poor job of handling large current spikes. Tests have gone very well, no signs of back EMF or noise bleeding into the IO board or causing oddities.
Next I’ll be wiring it up for 24/50v testing and, assuming nothing goes hilariously wrong, it’ll be time to start seriously looking at the graphics and software. The hardware is basically feature complete beyond replacing a few temporary off the shelf parts and building some wiring harnesses. I still might need to do another run of the IO board to solve the cabinet switch issues, but I’m still hoping I can get away with some creative wiring.
I spent some time last night doing a quick test by populating one row and firing against 12v. Initial tests look grim until I noticed the test area was at the end of the shift register chain and I only installed the relevant one, meaning the data pin was never getting fed.
Then I later found that I hard coded the number of registers to 2 instead of using the constant I wrote for this very reason, meaning I was constantly trying to populate a 32 bit data pool with 16 bits of data. Went well obviously.
Final tests happened around 2am and look good. At 12v pop bumpers fired (though were quite anemic which was a bit concerning). Next step is to introduce the high voltage 24/50v power supply, once I’m confident the board itself is stable. Luckily the board hasn’t yet exhibited any signs of noise issues, so the grounding might actually be adequate this time.
Now that you know where this giant mess of mad science and insanity is coming from, lets catch up to where we are now.
I quickly realized v1 was a mess. Ignoring the egregious ground issues which were causing ICs to pop at random, the number of interconnects and failure points was far too high. So step two was to build a main unified board which centralized everything and let me build nice clean ground planes. Due to the size of this megaboard, I moved to SMD parts. This sounded really scary at first but it turns out I can actually solder SOIC-16 parts faster than their through-hole counterparts! So much for SMD being hard; just stick with reasonable part sizes and quality tools and you’re golden.
After building this board I noticed a few major flaws.
The routing was done with an autorouter. Normally this would be fine but a lot of the solenoid logic traces ended up in really dirty paths and ended up noisy
I still hadn’t routed control lines for output enable and reclear on the shift registers, and now that the lamp ICs weren’t popping every 5 seconds, the issue became more obvious. The result was that during booting, a random selection or lamps would lock on at full 12v@100% duty cycle. This will cause them to burn out fairly quickly!
The switch matrix in this revision was wired wrong.
If I make a mistake I have to re-run the entire $100+ board!
The solenoid boards are now on their way to being fabbed. If all goes well there won’t be any hideous bugs and I’ll be hardware complete soon.
Not sure what’s up with the horizontal lines on the 5v ground plane, but it doesn’t look like it’s breaking any traces, so I’m just going to chalk it up to Eagle being Eagle and ignore it. I don’t remember setting any kind of hashing on either shape so maybe it’s some visual cue or something to separate the planes.
My last post was horribly boring, so picture time!
There is a LOT of back-catalog data here, so I’m going to break this post into parts. First, the prototype and v1 boards.
This whole mess started with boredom, beer, and a bit of urging from a co-worker. The original idea was very humble; Plug an arduino into the bally board set (replacing the MPU) and get a simple, low cost pinball board set that leverages a 16mhz processor. Piece of cake right?
Actually, it kind of was…
Using an Arduino, a quick breadboard circuit for the switch matrix (The circuitry for this exists as part of the MPU, so I couldn’t just plug into a “switch board”), and some jumper wires was all it took to get a fairly competent pinball controller up in the air for my Flash Gordon. I didn’t have display or sound control in this setup, so instead I uses a one way serial link to use my laptop as a sound/display device.
There were some switch matrix issues in this video, but I sorted it after I realized that the matrix needed to be pulled low instead of driven high. However, making Flash a less terrible game wasn’t really my goal.
For the last week I’ve been trying to sort out an issue with the serial bus. The basic problem turned out to be that the USB bus has a minimum packet size, which means sending lots of tiny 1 byte packets actually rapidly overflows the arduino’s hardware buffer.
The solution became fairly obvious, using locking I’d batch similar packet spans together, and instead of transmitting each byte individually, wrap it into a byte array. So if we need to update 5 lamps at once, we lock the serial buffer and write all 10 bytes out at once. While this does introduce a small amount of latency that could have been spared on some of the lamps, we want to synchronize these events anyway; so we’re actually just tightening up the timing a bit and ensuring the IO thread is waiting to send our data as soon as we’re finished populating the buffer.
This lead to a giant bug hunt caused by a bad for loop index. Lesson of the day: Arrays are 0 indexed, queue .count()s are not!
So as a more general progress update, I’m now able to spam the bloody hell out of the arduino and it seems to be quite content to keep up. There’s still some perf work to be done on the C++ side, but overall it’s looking quite good.
Working on finalizing the solenoid board design. Right now I’m fairly happy with it, just going through final checks to make sure everything’s routed correctly and there aren’t any silly mistakes, as well as general cleanup.
I really wanted to find a way to cut down on the mosfet count, but there doesn’t seem to be any obvious way to control a bunch of solenoids without a 1:1 mosfet count unless you use a matrix, which I’d rather avoid since it would mean putting a LOT of stress on the fets.
I broke the ground plane into two pieces, so the common return on the mosfets is shared across the entire row. Annoyingly I had to cut it in the middle so there’s a single trace that connects the two halves of the plane.. I might adjust this later, but it should be fine.
For those reading this and wondering what the actual fuck is going on, I’ll be doing some back-posting of older stuff later. For now you can read the original threadnaught here.