Quoted from zacaj:<why I do design my own boards, part 1>
With one node board hooked up and solid, I can test my flippers! They are very strong, which should be expected since I threw FL-11629s, the strongest option williams had, in a game with no ramps. That was on purpose though, like with the slings, I want to turn them down and tweak them to where I like.
Unlike on Poker, this time I'm using solid state flippers. Each coil has a power and a hold winding, and they have individual transistors powering them, just like WPC did in the 90s, so that's new territory I need to figure out. And judging by the struggles even most commercial manufacturers are having these days, it's not a simple thing. There are lots of concerns to balance:
- flipper strength
- flipper 'snappiness'
- flipper responsiveness
- control: can you do tiny taps, tip passes, and other finesse moves?
- they shouldn't drop when a fast moving ball hits them
- no 'JPP feel' where the outer-most shots on the playfield are weak
- no 'flipper fade' from the coils overheating
A lot of this has to do with the EOS switch. Some games don't have one. Most games don't seem to need one. I'd rather not have one on this game either, since I'm running low on switch inputs. But a lot of these problems would also just go away if I simply added a high voltage EOS and controlled the entire flipper via a single transistor, letting the EOS take care of managing the power winding. And I can always fall back to that if needed. But I think that an EOS limits your power somewhat. Since the switch has to open before the flipper has reached the end of its stroke, there'll necessarily be at least some portion of the stroke that's at low power when it could be at high power. Optimally the flipper would always be at high power until the moment *after* the ball leaves the flipper.
The way that most systems seem (I can't see their source code so this is all guesses and measurements) to use a fully solid state flipper is pretty simple. When the flipper button closes, fire the power winding for 40ms. (sometimes less, I think JJP is closer to 30ms, sometimes this is configurable, but both WPC and DE seem to use 40). If the EOS switch opens (eg, the bat got pushed down a bit)... fire the power winding for 40ms. That's it. Simple, easy to implement. Data East games don't even use a CPU for this, it's just some logic chips and timers. This same logic is also laid out in the tutorials+docs for many homebrew systems.
So I started with that on my game too. The game played good, the flippers felt fine. But then I checked the logs on my node board and noticed some issues. Often, the act of pressing in the flipper button would result in 2-3 'triggers' of the switch... which would result in 2-3 overlapping 40ms pulses. In other words, the flipper was actually firing for more than 40ms, sometimes as much as 65. Flipper feels fine to the player, seems to be working properly, and might even be more powerful than before, if the 40ms wasn't actually enough. But the flipper is spending a lot of time energized when it doesn't need to be, which means more heat!
Next issue: while just holding the flipper button in, the coils are triggering again! Turns out just moving your fingers around on the button while holding it in is enough to get signal drops from the contacts, which surprises me. These are new contacts too. So randomly, even at a stand still, the coils are being pulsed for 40ms again and heating up.
Issue three: when you release the button, sometimes you get another quick on/off pulse from the switch contacts. Sometimes you'll actually see this, the flipper will drop a bit then fire again, then drop for real. Other times it's not easily perceptible, but the flipper drop is effectively lagging 40ms behind when it should.
All three of these could be addressed with some aggressive debouncing (and in fact, the game code itself does, so the lane change isn't going crazy all the time), but adding some debounce logic from scratch on the node board's tiny processor will be a challenge. And besides, any debouncing of the flipper buttons will lead to lag, and probably prevent some of the finess+control I'm aiming for, so I want to avoid it if possible.
I tried adding some more rules to cut out specific cases like this, and things seemed good at first, but sooner or later I'd manage to create some weird edge case that'd result in a flipper being down while the button was pressed, and the code was becoming increasingly complicated, so it was clear I was approaching this from the wrong angle.
I decided to take a more literal approach, and connect the transistor output directly to the input signal, without any filtering. That way as soon as the user pressed or released the button, there'd be an immediate reaction, which should feel the most similar to hardware flippers on older games. But I still didn't have an EOS switch, so I needed to control the power winding somehow, but I didn't want it to be a set pulse or anything. I figured that, when the flipper button is released, the flipper necessarily drops at a slower speed than when it raises, so I could conservatively simulate the timing of an EOS by counting how long the button is pressed and released for. Instead of a set 40ms pulse, I'll count up to 40ms when the button is closed, and if the button is released, I'll start counting down again. So a 1ms release+press of the button would result in only a 1ms pulse, which won't cause overheating issues. And since there's no logic of ensuring certain pulses or debouncing, there's a lower chance of bugs.
So I coded that up, and it seemed to work. Flippers flipped reliably, no dropping when pushed or non-flips. But the flippers were really weak! Looking at my logs, whenever I press my flipper button, I actually get 6-8 press-release cycles, just from dirty signal from the button contacts. So basically my flipper is dropping out 6 times during the flip. I knew that could happen, but I didn't expect it to be noticeable since each drop should be under half a millisecond. Turns out they're not! Suspiciously, every single drop is 4ms, and there's no way that's right. After some debugging, I found out that, any time the node board attempts to send a second message while the first message is still sending, it freezes the entire thing for 4ms. This had apparently been happening the entire time, but I never paid enough attention to my logs to notice the pattern until now. This turned out to be a bug in my message queuing logic, which was also causing some other corruption issues I hadn't had time to track down yet, so I rewrote that and added some checks.
One of the checks I added was one to make sure the queue wasn't full. I had figured the messages should get sent pretty much instantly, as I was running at a fairly high data rate, but maybe one or two could get backed up, so I'd made a 5 deep queue. Once I added a safety check to make sure the queue wasn't full, I found out it was actually filling up fairly often. This wasn't very noticeable since I also had the 4ms lag time when sending a message, so the board would be frozen, and thus couldn't check the switches to generate more messages! But without the 4ms lag time I found that I needed to increase the queue to 50 items to be safe.
50 messages at once? That sounds weird. How are 50 switch events being generated in a quarter second? I'm not even in multiball yet! Turns out that even just pressing the flipper button is sometimes managing to generate 40-50 close+open events as the contacts get dragged across each other, which seems crazy to me. I wanted the switch detection to be fast and give me all the data so I could do smart things with it but... I don't think I have any use for *this* much data. Even when I added some 1ms debouncing, it was still sometimes 20-30 events. The game definitely doesn't care about anything under 5-10ms, but the flipper logic could. If the flippers can be made to still work good with this level of noise, maybe it's fine to just spam the game code with all this data and let it filter it out? I've never worked with a data bus like this before so I'm not sure if I'm creating a headache for myself down the line if the amount of data here grows even further....
The amount of noise here still seems out of hand though, so I'm going to have to dig out my scope again and start doing some more verification of the signals