Flippers: activation_switch: not working?

54 views
Skip to first unread message

Ryan McQuaid

unread,
Jul 26, 2025, 1:53:24 AMJul 26
to MPF Users
I'm spinning up a new project and after some doing I have been able to get 0.80 and GMC talking to VPX. The documentation and example code could do with an update so I will try to make a guide when I'm 100% done. I was just about to call it "ready for proper development" when I came across an issue I cannot explain. The ONLY thing I cant seem to get working in MPF<>VPX are flippers. After some troubleshooting I have narrowed the problem down to "activation_switch:" seemingly being ignored. 

- logs indicate flippers are successfully enabled, as does the "flippers enabled" lamp I have on VPX. 
- I can see the proper flipper switches reacting in the MPF window and in the logs
- I see no coil firing entries in the logs leading me to believe the commands are not being generated at all as oppose to being lost between MPF and VPX
- If I swap Sol labels in VPX with the trough solenoid the flipper will fire the expected short pulse otherwise meant for the ball serve
- Changing the activation switch to a playfield switch instead of a mapped button switch had no effect (as expected, I'm just trying everything)
- If I use  "sw_flip_events:" instead of "activation_switch:" the flipper will fire (though it did not reset,  I assume I need a separate event to release it)
- I have quadruple checked all switch names, Sol numbers, and mappings and used VSCode's AI to look for mismatches. Everything lines up as it should. 

It seems like everything is fine in the chain leading up to and then following the "activation_switch:" setting on the flippers. MPF just appears to be ignoring it. 


2025-07-26-00-50-53-mpf-MCSQUID-PC.log

Ryan McQuaid

unread,
Jul 26, 2025, 2:05:32 AMJul 26
to MPF Users
config flipper.png

Alex L

unread,
Jul 26, 2025, 3:54:53 AMJul 26
to MPF Users
Hm I wrote a long response digging into this and Google Groups seems to have completely eaten it. Maybe I shouldnt have used backticks to surround code blocks.

Er, tldr is sw_release_events is your counterpart for sw_flip_events

If you open a github PR or issue on the MPF repo I'm happy to jump over there and discuss.

I dug around a little and ended up suggesting that per flipper.py line 110 you would see _enable_main_coil_pulse_rule and _enable_hold_coil_rule (thus, platform_controller.set_pulse_on_hit_and_release_rule and set_pulse_on_hit_and_enable_and_release_rule) for the flipper config you presented,
while an autofire (oh, that was important - do you have autofires working? I assumed yes) would call platform_controller.set_pulse_on_hit_rule instead.
Maybe the implementations of these different rule registration types have some gap that still needs to be closed.

Okay google dont eat this one too!

Ryan McQuaid

unread,
Jul 26, 2025, 3:51:47 PMJul 26
to MPF Users
Hey Alex,
I recieved your initial message via PM. I'll paste it here.

Hi Ryan, interesting problem, thanks for being so specific about your debugging steps and config. Have flippers previously worked or is this a last piece of integration that is still to-do?

Before getting into the weeds - the counterpart of sw_flip_events is sw_release_events :)

You mention that only flippers do not work, and do mention that event-based flipper activation works as well as misc coil firing, and it sounds like the trough (so, ball_devices) works as well (though I don't know anything about VPX or Sol objects) -- does this mean that MPF autofires also work? I'm going to assume in the rest of this answer that they do, and dig into the differences between configurations between autofire and flipper - maybe the solution will be in the gaps there.

When a flipper is configured, it registers different rules based on the configuration options. Per your configs and MPF 0.80.0.dev9 , mpf/devices/flipper.py:110 in `enable` it seems like you would end up running the private functions `_enable_main_coil_pulse_rule` and `_enable_hold_coil_rule`. This would result in the following rules:

```
        rule = self.machine.platform_controller.set_pulse_on_hit_and_release_rule(
            SwitchRuleSettings(switch=self.config['activation_switch'], debounce=False, invert=False),
            DriverRuleSettings(driver=self.config['main_coil'], recycle=False),
            PulseRuleSettings(duration=self._get_pulse_ms(), power=self._get_pulse_power())
        )
```

```
        rule = self.machine.platform_controller.set_pulse_on_hit_and_enable_and_release_rule(
            SwitchRuleSettings(switch=self.config['activation_switch'], debounce=False, invert=False),
            DriverRuleSettings(driver=self.config['hold_coil'], recycle=False),
            PulseRuleSettings(duration=self._get_hold_pulse_ms(), power=self._get_hold_pulse_power()),
            HoldRuleSettings(power=self._get_hold_power())
        )
```

For comparison, autofire.py:84#enable might have for a miscellaneous device (say, a pop bumper):

            self._rule = self.machine.platform_controller.set_pulse_on_hit_rule(
                SwitchRuleSettings(switch=self.config['switch'], debounce=debounce, invert=self.config['reverse_switch']),
                DriverRuleSettings(driver=self.config['coil'], recycle=recycle),
                PulseRuleSettings(duration=self.config['coil_overwrite'].get('pulse_ms', None), power=self.config['coil_overwrite'].get('pulse_power', None))
            )


The rules themselves look pretty similar, and none of them seem to be doing anything particularly complex to resolve or delay calculation of their arguments. Maybe something in the details will jump out for you? I haven't started any spelunking into the platform controller, but the three rules we see here have three different registration functions (eg  `set_pulse_on_hit_and_release_rule`), maybe something is inconsistent in their implementations?

I'm happy to keep discussing on here, but groups is a little awkward for code - if you open an issue or PR on github I'll happily jump there as well

Ryan McQuaid

unread,
Jul 26, 2025, 4:22:46 PMJul 26
to MPF Users
I had a few minutes to mess with this today,

Just to see if i had a complete workaround I added the release event and mapped them to  sw_(tag)_active and  sw_(tag)_inactive making sure to set debug to true for the switches so they would post the events. 
My flippers work perfectly with this workaround. I'm sure I will see some significant latency start to creep in as development takes it from a shell of a game to complete software but this is good enough for now. 

Starting to go under the hood in python is something I can only occasionally make sense of. I was able to resolve a few errors setting up the VPX bridge by peaking at the underlying .py file and seeing that it was mostly a straight passthrough without any black box style crap going on, but looking at the rules you posted above I don't get any additional information. 

For anyone diving into this further than I am able. This is what the bridge is feeding to MPF from main.py:

    def ChangedSolenoids(self):
        """Return a list of changed coils."""
        return self._dispatch_to_mpf("changed_solenoids")
 
I'm pretty sure its a list of numbers generated from the coil number in config. I have no idea where "changed_solenoids" comes from but if coils activated by flipper: "activation switch" somehow did not make their way into this table it would explain my issue.  I learned this because the example in the bridge download labels the coils as "coil1" "coil2" etc which causes a type mismatch error when VPX tries to swallow it. changing my config coil number to integers "1" "2" fixed this. 

Once I get this all running well enough I'll put together an updated bridge guide with a working example and some code comments to help others have less trouble in the future. 

Ryan McQuaid

unread,
Jul 26, 2025, 4:25:46 PMJul 26
to MPF Users
Correction to my last post. Cant find an edit button.

"This is what the bridge is feeding to MPF from main.py:" should be  "This is what the bridge is feeding from MPF to VPX from main.py in mpf_vpcom_bridge:"
Reply all
Reply to author
Forward
0 new messages