Hello,
I do have a problem that sometimes mpf doesn't recognize that my ball is in the plunger lane.
My configuration looks like this
ball_devices:
bd_trough:
ball_switches: s_ball_trough_1, s_ball_trough_2, s_ball_trough_3, s_ball_trough_4, s_ball_trough_jam
eject_coil: c_ball_trough
tags: trough, home, drain
jam_switch: s_ball_trough_jam
eject_coil_jam_pulse: 20ms
eject_targets: bd_plunger
debug: true
confirm_eject_type: switch
confirm_eject_switch: s_plunger
bd_plunger:
ball_switches: s_plunger
mechanical_eject: true
Before we look into the log files, note that there a timer called plunger_inactive, that is a timer which checks if the switch s_plunger is inactive (after being activated) for more than a second to start the ball save time. I believe that can be ignored here in the logs.
In normal situations the log information look like this:
```
1
026-04-29 20:30:42,062 : DEBUG : ball_device.bd_trough : Firing eject coil. Current balls: 3.
2
2026-04-29 20:30:42,087 : INFO : SwitchController : <<<<<<< 's_ball_trough_1' inactive >>>>>>>
3
2026-04-29 20:30:42,088 : INFO : SwitchController : <<<<<<< 's_ball_trough_jam' active >>>>>>>
4
2026-04-29 20:30:42,088 : INFO : EventManager : Event: ======'machine_var_audits_switches_s_ball_trough_jam'====== Args={'value': 3331, 'prev_value': 3330, 'change': 1}
5
2026-04-29 20:30:42,089 : DEBUG : ball_device.bd_trough : SC: Ball left. Old count: 3
6
2026-04-29 20:30:42,089 : DEBUG : ball_device.bd_trough : Got ball left during eject
7
2026-04-29 20:30:42,090 : DEBUG : ball_device.bd_trough : SC: Switch 's_ball_trough_1' changed too recently. Aborting count!
8
2026-04-29 20:30:42,090 : INFO : ball_device.bd_trough : State: ball_left
9
2026-04-29 20:30:42,090 : INFO : ball_device.bd_trough : Ball left
10
2026-04-29 20:30:42,090 : INFO : ball_device.bd_trough : Wait for confirm with timeout 10.0
11
2026-04-29 20:30:42,099 : INFO : SwitchController : <<<<<<< 's_ball_trough_jam' inactive >>>>>>>
12
2026-04-29 20:30:42,249 : INFO : SwitchController : <<<<<<< 's_ball_trough_3' inactive >>>>>>>
13
2026-04-29 20:30:42,249 : INFO : SwitchController : <<<<<<< 's_ball_trough_2' inactive >>>>>>>
14
2026-04-29 20:30:42,319 : INFO : SwitchController : <<<<<<< 's_ball_trough_1' active >>>>>>>
15
2026-04-29 20:30:42,319 : INFO : EventManager : Event: ======'machine_var_audits_switches_s_ball_trough_1'====== Args={'value': 3654, 'prev_value': 3653, 'change': 1}
16
2026-04-29 20:30:42,341 : INFO : SwitchController : <<<<<<< 's_ball_trough_2' active >>>>>>>
17
2026-04-29 20:30:42,341 : INFO : EventManager : Event: ======'machine_var_audits_switches_s_ball_trough_2'====== Args={'value': 5856, 'prev_value': 5855, 'change': 1}
18
2026-04-29 20:30:42,600 : DEBUG : ball_device.bd_trough : SC: Switch 's_ball_trough_3' changed too recently. Aborting count!
19
2026-04-29 20:30:42,749 : DEBUG : ball_device.bd_trough : SC: Switch 's_ball_trough_2' changed too recently. Aborting count!
20
2026-04-29 20:30:42,819 : DEBUG : ball_device.bd_trough : SC: Switch 's_ball_trough_2' changed too recently. Aborting count!
21
2026-04-29 20:30:42,841 : DEBUG : ball_device.bd_trough : SC: Counted 2 balls. Active switches: [<switch.s_ball_trough_2>, <switch.s_ball_trough_1>]. Old: 2
22
2026-04-29 20:30:42,842 : DEBUG : ball_device.bd_trough : SC: New count 2 last: 2
23
2026-04-29 20:30:43,331 : INFO : SwitchController : <<<<<<< 's_plunger' active >>>>>>>
24
2026-04-29 20:30:43,331 : INFO : EventManager : Event: ======'s_plunger_active'====== Args={}
25
2026-04-29 20:30:43,331 : INFO : EventManager : Event: ======'machine_var_audits_switches_s_plunger'====== Args={'value': 5700, 'prev_value': 5699, 'change': 1}
26
2026-04-29 20:30:43,331 : INFO : Timer.plunger_inactive : Stopping Timer
27
2026-04-29 20:30:43,331 : INFO : EventManager : Event: ======'timer_plunger_inactive_stopped'====== Args={'ticks': 1, 'ticks_remaining': 1}
28
2026-04-29 20:30:43,332 : INFO : ball_device.bd_trough : Got eject confirm
29
2026-04-29 20:30:43,332 : INFO : ball_device.bd_trough : Eject successful
30
2026-04-29 20:30:43,332 : INFO : EventManager : Event: ======'balldevice_bd_trough_ball_eject_success'====== Args={'balls': 1, 'target': <ball_device.bd_plunger>}
31
2026-04-29 20:30:43,332 : DEBUG : ball_device.bd_trough : Exited eject mode. Eject success: True
32
2026-04-29 20:30:43,333 : INFO : EventManager : Event: ======'balldevice_bd_trough_ball_count_changed'====== Args={'balls': 2}
33
2026-04-29 20:30:43,333 : INFO : ball_device.bd_trough : State: idle
34
2026-04-29 20:30:43,333 : DEBUG : ball_device.bd_trough : Waiting for eject request.
35
2026-04-29 20:30:43,333 : DEBUG : ball_device.bd_trough : BCH: Counting. New count: 2 Old count: 2
36
2026-04-29 20:30:43,334 : DEBUG : ball_device.bd_trough : BCH: Counting. New count: 2 Old count: 2
37
2026-04-29 20:30:43,378 : INFO : SwitchController : <<<<<<< 's_plunger' inactive >>>>>>>
38
2026-04-29 20:30:43,379 : INFO : EventManager : Event: ======'s_plunger_inactive'====== Args={}
39
2026-04-29 20:30:43,379 : INFO : Timer.plunger_inactive : Starting Timer.
40
2026-04-29 20:30:43,379 : INFO : EventManager : Event: ======'timer_plunger_inactive_started'====== Args={'ticks': 1, 'ticks_remaining': 1}
41
2026-04-29 20:30:43,379 : INFO : EventManager : Event: ======'timer_plunger_inactive_tick'====== Args={'ticks': 1, 'ticks_remaining': 1}
42
2026-04-29 20:30:43,676 : INFO : SwitchController : <<<<<<< 's_plunger' active >>>>>>>
43
2026-04-29 20:30:43,676 : INFO : EventManager : Event: ======'s_plunger_active'====== Args={}
44
2026-04-29 20:30:43,677 : INFO : EventManager : Event: ======'machine_var_audits_switches_s_plunger'====== Args={'value': 5701, 'prev_value': 5700, 'change': 1}
45
2026-04-29 20:30:43,677 : INFO : Timer.plunger_inactive : Stopping Timer
46
2026-04-29 20:30:43,677 : INFO : EventManager : Event: ======'timer_plunger_inactive_stopped'====== Args={'ticks': 1, 'ticks_remaining': 1}
47
2026-04-29 20:30:44,177 : INFO : ball_device.bd_plunger : Received ball from <ball_device.bd_trough>
48
2026-04-29 20:30:44,178 : INFO : EventManager : Event: ======'balldevice_bd_plunger_ball_enter'====== Args={'new_balls': 1, 'unclaimed_balls': 0, 'new_available_balls': 0, 'device': <ball_device.bd_plunger>}
49
2026-04-29 20:30:44,178 : INFO : EventManager : Event: ======'balldevice_bd_plunger_ball_entered'====== Args={'new_balls': 0, 'device': <ball_device.bd_plunger>}
50
2026-04-29 20:30:44,178 : INFO : EventManager : Event: ======'balldevice_bd_plunger_ball_count_changed'====== Args={'balls': 1}
51
2026-04-29 20:30:44,179 : INFO : ball_device.bd_plunger : State: waiting_for_target_ready
52
2026-04-29 20:30:44,179 : INFO : EventManager : Event: ======'balldevice_bd_plunger_ball_eject_attempt'====== Args={'balls': 1, 'target': <playfield.playfield>, 'source': <ball_device.bd_plunger>, 'mechanical_eject': False, 'num_attempts': 0}
53
2026-04-29 20:30:44,179 : INFO : ball_device.bd_plunger : State: ejecting
54
2026-04-29 20:30:44,179 : INFO : ball_device.bd_plunger : Ejecting ball to <playfield.playfield>
55
2026-04-29 20:30:44,179 : INFO : EventManager : Event: ======'balldevice_bd_plunger_ejecting_ball'====== Args={'balls': 1, 'target': <playfield.playfield>, 'source': <ball_device.bd_plunger>, 'mechanical_eject': False, 'num_attempts': 0}
56
2026-04-29 20:30:44,180 : INFO : ball_device.bd_plunger : Wait for ball to leave device
57
2026-04-29 20:30:44,365 : INFO : SwitchController : <<<<<<< 's_plunger' inactive >>>>>>>
58
2026-04-29 20:30:44,365 : INFO : EventManager : Event: ======'s_plunger_inactive'====== Args={}
59
2026-04-29 20:30:44,365 : INFO : Timer.plunger_inactive : Starting Timer.
60
2026-04-29 20:30:44,365 : INFO : EventManager : Event: ======'timer_plunger_inactive_started'====== Args={'ticks': 1, 'ticks_remaining': 1}
61
2026-04-29 20:30:44,366 : INFO : EventManager : Event: ======'timer_plunger_inactive_tick'====== Args={'ticks': 1, 'ticks_remaining': 1}
62
2026-04-29 20:30:44,366 : INFO : ball_device.bd_plunger : State: ball_left
63
2026-04-29 20:30:44,366 : INFO : ball_device.bd_plunger : Ball left
64
2026-04-29 20:30:44,366 : INFO : ball_device.bd_plunger : Wait for confirm with timeout 10.0
65
2026-04-29 20:30:45,366 : DEBUG : Player : Setting 'base_plunger_inactive_tick' to: 0, (prior: 1, change: -1)
66
2026-04-29 20:30:45,366 : INFO : EventManager : Event: ======'player_base_plunger_inactive_tick'====== Args={'value': 0, 'prev_value': 1, 'change': -1, 'player_num': 2}
67
2026-04-29 20:30:45,366 : INFO : Timer.plunger_inactive : Timer Complete
68
2026-04-29 20:30:45,366 : INFO : Timer.plunger_inactive : Stopping Timer
69
2026-04-29 20:30:45,366 : INFO : EventManager : Event: ======'timer_plunger_inactive_stopped'====== Args={'ticks': 0, 'ticks_remaining': 1}
70
2026-04-29 20:30:45,366 : INFO : EventManager : Event: ======'timer_plunger_inactive_complete'====== Args={'ticks': 0, 'ticks_remaining': 1}
71
2026-04-29 20:30:45,367 : INFO : EventManager : Event: ======'ball_save_default_timer_start'====== Args={}
72
2026-04-29 20:30:48,038 : INFO : SwitchController : <<<<<<< 's_right_flipper' active >>>>>>>
73
2026-04-29 20:30:48,039 : INFO : EventManager : Event: ======'machine_var_audits_switches_s_right_flipper'====== Args={'value': 16947, 'prev_value': 16946, 'change': 1}
74
2026-04-29 20:30:49,199 : INFO : SwitchController : <<<<<<< 's_right_flipper' inactive >>>>>>>
75
2026-04-29 20:30:49,289 : INFO : SwitchController : <<<<<<< 's_ramp' active >>>>>>>
76
2026-04-29 20:30:49,290 : INFO : EventManager : Event: ======'playfield_active'====== Args={'source': 'ramp_sequence_shot'}
```
In above log file look at lines 47 - 52, here we see that the plunger has received a ball. I assumed that this is being decided based on my configured switch s_plunger, but I am not sure anymore. Now let us take a look at an example where it fails:
```
1
026-04-29 20:33:19,417 : DEBUG : ball_device.bd_trough : Firing eject coil. Current balls: 3.
2
2026-04-29 20:33:19,445 : INFO : SwitchController : <<<<<<< 's_ball_trough_1' inactive >>>>>>>
3
2026-04-29 20:33:19,445 : INFO : SwitchController : <<<<<<< 's_ball_trough_jam' active >>>>>>>
4
2026-04-29 20:33:19,446 : INFO : EventManager : Event: ======'machine_var_audits_switches_s_ball_trough_jam'====== Args={'value': 3336, 'prev_value': 3335, 'change': 1}
5
2026-04-29 20:33:19,446 : DEBUG : ball_device.bd_trough : SC: Ball left. Old count: 3
6
2026-04-29 20:33:19,447 : DEBUG : ball_device.bd_trough : Got ball left during eject
7
2026-04-29 20:33:19,447 : DEBUG : ball_device.bd_trough : SC: Switch 's_ball_trough_1' changed too recently. Aborting count!
8
2026-04-29 20:33:19,447 : INFO : ball_device.bd_trough : State: ball_left
9
2026-04-29 20:33:19,447 : INFO : ball_device.bd_trough : Ball left
10
2026-04-29 20:33:19,448 : INFO : ball_device.bd_trough : Wait for confirm with timeout 10.0
11
2026-04-29 20:33:19,458 : INFO : SwitchController : <<<<<<< 's_ball_trough_jam' inactive >>>>>>>
12
2026-04-29 20:33:19,601 : INFO : SwitchController : <<<<<<< 's_ball_trough_3' inactive >>>>>>>
13
2026-04-29 20:33:19,602 : INFO : SwitchController : <<<<<<< 's_ball_trough_2' inactive >>>>>>>
14
2026-04-29 20:33:19,670 : INFO : SwitchController : <<<<<<< 's_ball_trough_1' active >>>>>>>
15
2026-04-29 20:33:19,670 : INFO : EventManager : Event: ======'machine_var_audits_switches_s_ball_trough_1'====== Args={'value': 3660, 'prev_value': 3659, 'change': 1}
16
2026-04-29 20:33:19,703 : INFO : SwitchController : <<<<<<< 's_ball_trough_2' active >>>>>>>
17
2026-04-29 20:33:19,704 : INFO : EventManager : Event: ======'machine_var_audits_switches_s_ball_trough_2'====== Args={'value': 5862, 'prev_value': 5861, 'change': 1}
18
2026-04-29 20:33:19,959 : DEBUG : ball_device.bd_trough : SC: Switch 's_ball_trough_3' changed too recently. Aborting count!
19
2026-04-29 20:33:20,103 : DEBUG : ball_device.bd_trough : SC: Switch 's_ball_trough_2' changed too recently. Aborting count!
20
2026-04-29 20:33:20,170 : DEBUG : ball_device.bd_trough : SC: Switch 's_ball_trough_2' changed too recently. Aborting count!
21
2026-04-29 20:33:20,204 : DEBUG : ball_device.bd_trough : SC: Counted 2 balls. Active switches: [<switch.s_ball_trough_2>, <switch.s_ball_trough_1>]. Old: 2
22
2026-04-29 20:33:20,204 : DEBUG : ball_device.bd_trough : SC: New count 2 last: 2
23
2026-04-29 20:33:20,507 : INFO : SwitchController : <<<<<<< 's_plunger' active >>>>>>>
24
2026-04-29 20:33:20,507 : INFO : EventManager : Event: ======'s_plunger_active'====== Args={}
25
2026-04-29 20:33:20,507 : INFO : EventManager : Event: ======'machine_var_audits_switches_s_plunger'====== Args={'value': 5709, 'prev_value': 5708, 'change': 1}
26
2026-04-29 20:33:20,508 : INFO : Timer.plunger_inactive : Stopping Timer
27
2026-04-29 20:33:20,508 : INFO : EventManager : Event: ======'timer_plunger_inactive_stopped'====== Args={'ticks': 1, 'ticks_remaining': 1}
28
2026-04-29 20:33:20,508 : INFO : ball_device.bd_trough : Got eject confirm
29
2026-04-29 20:33:20,509 : INFO : ball_device.bd_trough : Eject successful
30
2026-04-29 20:33:20,509 : INFO : EventManager : Event: ======'balldevice_bd_trough_ball_eject_success'====== Args={'balls': 1, 'target': <ball_device.bd_plunger>}
31
2026-04-29 20:33:20,509 : DEBUG : ball_device.bd_trough : Exited eject mode. Eject success: True
32
2026-04-29 20:33:20,509 : INFO : EventManager : Event: ======'balldevice_bd_trough_ball_count_changed'====== Args={'balls': 2}
33
2026-04-29 20:33:20,509 : INFO : ball_device.bd_trough : State: idle
34
2026-04-29 20:33:20,509 : DEBUG : ball_device.bd_trough : Waiting for eject request.
35
2026-04-29 20:33:20,510 : DEBUG : ball_device.bd_trough : BCH: Counting. New count: 2 Old count: 2
36
2026-04-29 20:33:20,510 : DEBUG : ball_device.bd_trough : BCH: Counting. New count: 2 Old count: 2
37
2026-04-29 20:33:20,825 : INFO : SwitchController : <<<<<<< 's_plunger' inactive >>>>>>>
38
2026-04-29 20:33:20,826 : INFO : EventManager : Event: ======'s_plunger_inactive'====== Args={}
39
2026-04-29 20:33:20,826 : INFO : Timer.plunger_inactive : Starting Timer.
40
2026-04-29 20:33:20,826 : INFO : EventManager : Event: ======'timer_plunger_inactive_started'====== Args={'ticks': 1, 'ticks_remaining': 1}
41
2026-04-29 20:33:20,826 : INFO : EventManager : Event: ======'timer_plunger_inactive_tick'====== Args={'ticks': 1, 'ticks_remaining': 1}
42
2026-04-29 20:33:21,827 : DEBUG : Player : Setting 'base_plunger_inactive_tick' to: 0, (prior: 1, change: -1)
43
2026-04-29 20:33:21,827 : INFO : EventManager : Event: ======'player_base_plunger_inactive_tick'====== Args={'value': 0, 'prev_value': 1, 'change': -1, 'player_num': 1}
44
2026-04-29 20:33:21,827 : INFO : Timer.plunger_inactive : Timer Complete
45
2026-04-29 20:33:21,827 : INFO : Timer.plunger_inactive : Stopping Timer
46
2026-04-29 20:33:21,828 : INFO : EventManager : Event: ======'timer_plunger_inactive_stopped'====== Args={'ticks': 0, 'ticks_remaining': 1}
47
2026-04-29 20:33:21,828 : INFO : EventManager : Event: ======'timer_plunger_inactive_complete'====== Args={'ticks': 0, 'ticks_remaining': 1}
48
2026-04-29 20:33:21,828 : INFO : EventManager : Event: ======'ball_save_default_timer_start'====== Args={}
49
2026-04-29 20:33:23,010 : INFO : SwitchController : <<<<<<< 's_slingshot_right' active >>>>>>>
50
2026-04-29 20:33:23,010 : INFO : EventManager : Event: ======'s_slingshot_right_active'====== Args={}
51
2026-04-29 20:33:23,010 : INFO : EventManager : Event: ======'playfield_active'====== Args={'source': 'ac_slingshot_right'}
52
2026-04-29 20:33:23,011 : INFO : EventManager : Event: ======'unexpected_ball_on_playfield'====== Args={}
53
2026-04-29 20:33:23,011 : INFO : EventManager : Event: ======'machine_var_audits_switches_s_slingshot_right'====== Args={'value': 3816, 'prev_value': 3815, 'change': 1}
54
2026-04-29 20:33:23,012 : DEBUG : Player : Setting 'score' to: 2730, (prior: 2680, change: 50)
55
2026-04-29 20:33:23,012 : INFO : EventManager : Event: ======'player_score'====== Args={'value': 2730, 'prev_value': 2680, 'change': 50, 'player_num': 1, 'source': 'base'}
56
2026-04-29 20:33:23,020 : INFO : EventManager : Event: ======'machine_var_machine_score_player1'====== Args={'value': 2730, 'prev_value': 2680, 'change': 50}
57
2026-04-29 20:33:23,038 : INFO : SwitchController : <<<<<<< 's_slingshot_right' inactive >>>>>>>
```
Now there is no entry in this log file that the plunger has received a ball. We do see though, e.g. line 23, that my switch s_plunger is active. So a faulty switch I would rule out. I have no idea why it comes to that situation once in a while, my though was that s_plunger would confirm that the ball has left the trough and is on the plunger lane. Now I assume there is more behind it.
The question behind it is not of academic nature, the real problem is now the following:
- if the ball stays in play until a certain timeout is reached, mpf assumes that the ball is on the playfield --> all good (see lots of unexpected_ball_on_playfield messages until that timeout)
- if the ball drains before that timeout is reached, mpf would _not_ kick out the next ball for the next player and I have to kill mpf and restart
```
2026-04-29 20:40:23,336 : INFO : EventManager : Event: ======'machine_var_audits_switches_s_ball_trough_4'====== Args={'value': 5472, 'prev_value': 5471, 'change': 1}
2026-04-29 20:40:23,385 : INFO : SwitchController : <<<<<<< 's_ball_trough_4' inactive >>>>>>>
2026-04-29 20:40:23,419 : INFO : SwitchController : <<<<<<< 's_ball_trough_3' active >>>>>>>
2026-04-29 20:40:23,419 : INFO : EventManager : Event: ======'machine_var_audits_switches_s_ball_trough_3'====== Args={'value': 5541, 'prev_value': 5540, 'change': 1}
2026-04-29 20:40:23,886 : DEBUG : ball_device.bd_trough : SC: Switch 's_ball_trough_3' changed too recently. Aborting count!
2026-04-29 20:40:23,919 : DEBUG : ball_device.bd_trough : SC: Counted 3 balls. Active switches: [<switch.s_ball_trough_3>, <switch.s_ball_trough_2>, <switch.s_ball_trough_1>]. Old: 2
2026-04-29 20:40:23,920 : DEBUG : ball_device.bd_trough : SC: New count 3 last: 2
2026-04-29 20:40:23,920 : DEBUG : ball_device.bd_trough : SC: Updating count to 3
2026-04-29 20:40:23,920 : DEBUG : ball_device.bd_trough : BCH: Counting. New count: 3 Old count: 2
2026-04-29 20:40:23,920 : DEBUG : ball_device.bd_trough : BCH: Found 1 new balls
2026-04-29 20:40:23,920 : INFO : EventManager : Event: ======'balldevice_bd_trough_ball_count_changed'====== Args={'balls': 3}
2026-04-29 20:40:23,920 : INFO : ball_device.bd_trough : Received unexpected ball
2026-04-29 20:40:23,921 : INFO : EventManager : Event: ======'balldevice_captured_from_playfield'====== Args={'balls': 1}
2026-04-29 20:40:23,921 : INFO : EventManager : Event: ======'sw_playfield_active'====== Args={'balls': 1}
2026-04-29 20:40:23,921 : INFO : EventManager : Event: ======'playfield_active'====== Args={'source': None}
2026-04-29 20:40:23,921 : INFO : EventManager : Event: ======'unexpected_ball_on_playfield'====== Args={}
2026-04-29 20:40:23,921 : INFO : EventManager : Event: ======'playfield_ball_count_change'====== Args={'balls': -1, 'change': -1}
```
In above log at the top you see that the trough switches get activated, so the ball drained. In the last line you see that we have -1 balls on the playfield.
Anyone any idea how it can come to such a situation, what I can do about it or even someone who know what I made wrong?
Any help is highly appreciated ! Killing a game just before a new highscore is really frustrating :-(
Thanks!