Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add PWM with user selected output device PWM integrator #89

Merged
merged 2 commits into from
Jan 21, 2023

Conversation

vbousquet
Copy link
Contributor

@vbousquet vbousquet commented Jan 19, 2023

Warning, this is a very lengthy PR comment since this PR contains a fairly complicated new feature that took me quite some time to (i hope) understand.

Context

When I played with Twilight Zone, I stumbled upon 2 problems:

  • GI simulation was (partly) broken and needed hacks
  • Flashers were nice but dit not look true to the real table.

When I experimented with XMen, I had the same problem with (LED) flashers that I solved by pushing their power to unrealistic values but giving visually ok results. Lately, I played with CFTBL and the GI seemed broken needing hacks, and the flashers were not true to the real thing either. This added up with Guns'n Roses were flashers bulbs are directly visible to the player, and did not look about right.

After investigation, GI implementation in pinmame WPC only worked when a single light was dimmed. If more than one is dimmed at the same time, it woud break. So it was a controller emulation bug which is now (mostly) solved.

For the flashers, it is far more difficult and hence all the maths and tests made here. My understanding of the problem is the following:

Pulse Width Modulation used in Pinball hardware as I understand it

PWM is used with Triac/Thyristor/Darlington Transistor driven outputs for :

  • GI dimming (for example, WPC has 5 PWM outputs with modulation from 0 to 8 of a 8ms period)
  • Flasher modulation (for example, WPC performs output switching at IRQ frequency ~1ms)
  • Single coil solenoid to modulate between fire and hold strength or for progressive strength (Twilight zone shooter diverter for example)
  • Shaker motor speed

The effect on a device of PWM is entirely different depending on the connected device and its physical characteristic.

For example, an incandescent bulb is a varying resistor with resistance depending on filament temperature. It has a non linear heating/cooling curve. We measured a specific 44 bulb to ramp up from <10% visible emission to >90% in around 37ms. Its behavior (light flow & color) depends on the filament temperature.

On the other hand, LEDs have more or less instantaneous switching time (below 1µs). Online ressources state that most humans will not perceive flashing on/off LED above 50 cycles per second (100Hz) as flicker/flashing but only its strobscopic effect (lik wheel not moving in a movie), below this it depends on each human, finally, around and under 10 cycles per second (20Hz) most people will see the LED as flashing.

So the frequency limits between flashing and dimming for these 2 type of lights will be different as well as their visible emission outputs.

Another example are solenoids or shaker motors where the time constant are fairly larger than for LED & incandescent bulbs.

One point to note is that the connected devices can vary for a given table (for example, some tables have been shipped with 44 incandescent bulbs, but may be ran with 47 in a custom version).

Pinmame WPC PWM implementation

Pinmame WPC driver samples every 2 IRQ, then smooths lineary other the 28 samples. Therefore, the smoothing is performed over 56 IRQ, meaning every 56*8192/8000000 = 57,344ms (17 times per second).

This seems to work well for inductive outputs like solenoids but has a few drawbacks for others since it is not tied to the effective connected output device:

  • Smoothing time constant is fixed (57ms), causing some fast effects targeted at fast devices (lights) to be visibly smoothed out (for example, Twilight Zone flashers),
  • Smoothing is linear, causing an inaccurate response if the connected device does not have a linear behavior (incandescent bulbs for example),
  • Update frequency is fixed (17 times per second) not corresponding to the connected device nor the simulation output (screen FPS, or DOF light), therefore causing synchronization artefacts.
  • Update frequency can be too high for some fast effect to be correctly sampled (for example Creature From The Black Lagoon lights each ramp chase light in turn during 48 to 52 IRQ, causing miss or half lit lights to happen)

Each other driver implements a custom and different behavior.

Proposed fix

To account for these, the overall implementation needs to be aware of the connected device and simulates its dedicated response on the effective output device. Therefore it needs to take in acount :

  • The characteristics of the simulated device (incandescent bulb vs solenoid vs LED vs motor,… as well as intermediate electronics like voltage regulation,...)
  • The characteristics of the user output device (like FPS & brightness for a screen output, or for physical bulb, shaker motor, solenoid, fan, etc. the characteristic of this hardware and its associated electronic driver).

3 ways for implementing it were investigated:

  • Modify PinMame hardware driver to natively include the outputs and performs PWM integration.
  • Allow client application (VPE, VPX, DOF,…) to access high frequency sampling of outputs and let them manage PWM,
  • Allow client application to setup PWM integration inside PinMame

The first solution would need a large change of the code, with some challenge regarding backward compatibility, and would not solve the problem of taking in account the effective user output device, so it was not pursued. The second was initially attempted but was not satisfying for client application that access PinMame through low throughput communication (PPUC), it was not pursued either but the intent was (somewhat) kept for the proposed fix which is based on the third solution.

The proposed PR has the following features:

  • Add the possibility to configure each output independently through a dedicated function vp_setModOutputType (also available through VPinMame SetSolMask to account for B2S support), setting it to one of the predefined output type. The default behavior being backward compatible.
  • Add a (lightweight) method to store high frequency samples of outputs (limited to first 32 solenoids, 8 GI strings) that drivers must call from a suitable timer (like IRQ timer)
  • Add predefined PWM integrators for a set of common use cases (see below)
  • Trigger PSM integration when requested for changed outputs, and return the computed values as the state of the outputs

The PR rely on the following set of integrators:

  • Default: just returns the same as before for backward compatibility
  • Linear PWM: returns the duty cycle ratio (since last integration request) to allow a client application to implement its own custom integrator
  • LED bulb:
    • Compute dimming by averageing the samples of the last 1/100s (so 10ms)
    • Returns the maximum of the (dimmed) intensities reached since last integration [not yet implemented]
  • Incandescent bulbs:
    • Add an electrical & thermodynamic simplified model of a bulb to be able to dynamically compute the filament temperature
    • Add a set of predefined bulb common characteristics
    • Add a set of predefined electronic drivers (voltage level, AC/DC, serial resistor, switching electronic,…)
    • Compute dynamic filament temperature, derived instantaneous light emission power, then compute dimmed emission by averageing it other the last 16 computed values (for simplicity, would be better to use a fixed length likely around 10ms to stick to the 100Hz retina response)
    • Returns the maximum of the (dimmed) intensities reached since last integration

Regarding light integrators :

  • Beside the bulb behavior (none for LEDs, filament & grey body for incandescent), a very simple empirical model of the eye is applied to account for the perceived dimming (averageing over 10ms) and retina persistance (maximum intensity over the integration period). This design supposes that the calls to get the changed values are aligned with the frequency at which they are presented to the user.
  • The returned value is the visible emission power at the expected color (2700K for incandescent bulbs and pure white for LED). Two points are to be noted on that choice:
    • LED dimming is supposed to be linear, that is to say that the visible emission power is linear with PWM. This is slightly inexact and should be improved in the future.
    • Incandescent bulb emission power takes in account the color temperature variation when heating/cooling (i.e. 1500K results in a lower visible emission power than 2700K and this is already taken in account). This requires that if the client application performs light tinting depending on emission power, it must account for the color intensity ratio between 2700K black body color and the applied tint to avoid incorrect light intensity.

How to use

The PR adds ModOutputType property to VPinMame Controller, but since it is usely accessed through B2S, it also extends SolMask property which is already used to setup modulated outputs:

  • Controller.SolMask(1000) = 301 will setup Solenoid 0 to use a 89 bulb wired like a flasher in a WPC system,
  • Controller.SolMask(1200) = 100 will setup GI 0 to use a 44 bulb wired to 6.3V AC.

Bulbs characteristics and wiring

Here are some findings on bulbs characteristics and wiring that were used to design this fix. These are just observation and will vary from boards to boards but give some hints on how the different values were chosen.

System/Table Category Bulb Voltage Comments
WPC/TZ, CFTBL, TOTAN GI 44/555 6.8V AC Through SC141 Triac with Vtm=1.83V max voltage drop (likely around 0.5V drop to reach 6.3V bulb rating)
WPC/TZ, CFTBL, TOTAN Lamps 44/555 18V DC switched through a TIP102 and a TIP107 (voltage drop supposed of 0.7V per semiconductor switch, datasheet states Vcesat=2V for I=3A)
WPC/TZ, CFTBL, TOTAN Flashers 89/906 20V DC switched through a TIP102 (voltage drop supposed of 0.7V per semiconductor switch, datasheet states Vcesat=2V for I=3A)
S11/GNR GI 44/555 6.3V AC
S11/GNR Lamps 44/555 18V DC 4.3 Ohms serial resistor
S11/GNR Flashers 89 32V DC Connected through TIP122 (max 2 to 4V Vcesat), an optional serial diode (when output is switched with a coil), a 3 Ohms resistor (and a relay to switch from coils)
GTS3/CueBW GI 6V AC Switched through relays
GTS3/CueBW Lamps 44/LEDs 20V DC Switched through MOSFETs (12P06 & 12N10L), serial 3,5 Ohms, then serie with 1N4004 voltage drop (1,1V) for bulbs / 120 Ohms with 1N4004 for LEDs
GTS3/CueBW Flasher 67 20V DC Serie with 0.33 Ohms resistor, switched by 12N10L (Mosfet, no voltage drop)
Whitestar/Austin-LOTR GI 44 5.7 AC Not investigated yet
Whitestar/Austin-LOTR Lamps 18V DC Not investigated yet. PWM needed for LOTR
Whitestar/Austin-LOTR Flasher 20V DC Not investigated yet. Connected through TIP122 (max 2 to 4V Vcesat)

Example outputs

The graphics below are a plot of the PWM integration at 1ms (so not the one that would be rendered at 60FPS, therefore 16ms period). White lines are the output digital state, blue line is the PWM integration (44 & 89 bulbs).

Twilight zone has one of the most complex PWM diming light show I found so far. For example (during Clock Millions) with full power flasher pulse but also short low power ones (Sol 28), sequences of flashes of different power (Sol 19) or GI dimming waves:

image

Tales of the Arabian Night also exhibits some complex dimming, like the genie flasher which is constantly slowly pulsed at mid power (Sol 25) or waves of GI fading when skillshot is succeeded like below:

image

@toxieainc
Copy link
Member

Fantastic research and execution, thanks!

@toxieainc toxieainc merged commit 3533858 into vpinball:master Jan 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants