This is the dev documentation for an unreleased version of MPF!
This is the documentation for MPF 0.54+, which is the “dev” (next) release of MPF that is a work-in-progress. Unless you’re specifically looking for this version, you probably want to use the version of documentation called “latest” which is for the latest released version of MPF. That documentation is at docs.missionpinball.org/en/latest.
Debouncing in Pinball Machines¶
A pinball machine is a mechanical machine with a lot mechanical, electronic and electromagnetical interferences. This has to be mitigated on multiple levels to prevent unwanted effects:
- Prevent too much communication between hardware platform and CPU. A lot of switch changes could easily overflow the communication bus or starve the CPU/controller.
- Prevent too many switch events in the game. It is not uncommon to show slides or play sounds on a switch event. If this event occurs very often this may easily slow down your game.
- Prevent coils from pulsing too often. If a coil pulses on a switch hit and the switch activates constantly it might essentially be stuck on for the whole time which in the best case would only blow a fuse and in the worst case might burn down the machine.
As you can see there are multiple types of debouncing. We will explain how to use those in the following:
Switch Debouncing at the Hardware Level¶
To prevent too much communication between you hardware platform and your CPU there is typically some switch debouncing at the hardware level. This is what most electronic engineers will first think about when taking about debouncing.
On the surface, switch debounce is pretty straightforward. Switches are mechanical things, computers are fast, and your pinball software wants to make sure a switch is actually in a new state before acting on a switch.
Pinball controllers set debounce in different ways. For example, some platforms (for instance, P-ROC, P3-ROC) say “a switch must be in a new state for 2 consecutive reads” to be considered debounced, while other platforms (e.g. FAST) focus on time-based durations rather than number of reads, saying, “a switch must be in a new state for X milliseconds before it’s considered debounced.” In practise, there is not much difference between those two.
When considering switch debounce, the switch usually is supposed to be active for the whole debounce time. So this could also be called “minimum active time”. Usually this time is in the range of two to four milliseconds. The reason for that is that waiting for a minimum active time induces some lag to the switch event.
Still, switch debounce is often disabled for hardware rules (e.g. for pop bumpers or sling shots) to render them more responsive. However, this also them more susceptible to interferences or phantom hits. For that reason, in some platforms, even in that case a minimal debounce time is enforced (around one millisecond).
There is very little reason to increase switch debounce time to more than about four ms (see next section on what to do instead). Because if you set your debounce times too long, then you risk switch events being missed. (It would be annoying if a ball brushed a pop bumper and the bumper not didn’t fire.)
Preventing too many Switch Events in MPF¶
Depending on the type of switch you will see hits between five and fifty milliseconds. So any switch debounce time above that will miss switch hits. However, if you set your debounces too short, you risk getting multiple switch events for what should have been a single switch event. (Again it would be annoying if a ball hit a pop bumper and that bumper fired once, but you actually got back multiple switch events which led to multiple scores, multiple sound effects, etc.)
The solution to this is to combine switch debounce with a window to ignore multiple hits. There are two ways to implement this.
The first and most used way is to define a period after registered hit which
ignores all further hits.
This setting is called
ignore_window_ms in your
For example, if you set
ignore_window_ms: 100, then a switch is activated once,
then again 50ms later, the second activation will be ignored. The timer is set based on
the last switch hit that activated the switch, so if another switch hit came in 105ms
after the first (which would be 55ms after the second), it will also count.
In most cases you can easily set
ignore_window_ms to a few hundred milliseconds.
This will not affect hardware rules. Use
recycle on your
working with computationally expensive callbacks which is called throttling.
The goal here is similar but the implementation is differerent.
Instead of having a window after each activation this defines a maximum number
of calls per time unit. For instance a maximum of 10 calls per second.
This would certainly also be possible in MPF but is currently not supported.
We think this would be inferior to
ignore_window_ms since it is more
susceptible to bursts it might still cause temporary lags.
However, we might add this later to prevent permanent problems with bad
or bouncy switches.
Preventing Coil Overheating¶
When enabling coils you usually use PWM to control the maximum power.
However, when pulsing coils they are often enabled without any PWM for a while.
This works fine for a single activation but might cause problems when a switch
is activated repeatedly (i.e. because of interferences). In that case, the coil
would be permanently pulsed and, thereby, enabled all the time. That will
hopefully only blow a fuse on that coil but might as well burn down the
machine. To prevent this there is
recycle on your
coil. When set to true it will prevent any further pulse
for a certain time after a pulse (similar to
ignore_window_ms on the
switch above). The duration depends on your platform and might also be
Understanding switch scanning loop speed¶
The other major factor which affects debounce involves the timing of how the switches are read.
In all modern pinball platforms, a switch changing state doesn’t interrupt the controller. Instead, the controller reads the state of all switches at a certain interval.
But even this varies from platform-to-platform, and even based on whether you have matrix or direct switches. (More on this in a bit.)
The important thing, though, is that different controllers and different types of switches are checked at different intervals. That could be every millisecond, or every 1ms, or every 2ms… really it’s up to the controller and switch type as they’re all different. Scanning speed induces some delay and jitter to your debounce times. Refer to your platform documentation for details.
In most cases switch matrixes are scanned slighly slower than direct switches on a hardware platform. However, they are usually still fast enough not to cause any problems with missed switches.