Appendix 3. Plunger Sensor Technical Notes
Tracking a plunger for pinball simulation is a surprisingly difficult
technical challenge. At first glance, it looks like a pretty easy
problem with some simple solutions: it's just a linear position
sensor, and there are some standard approaches for that. But there
are two details to pinball simulation that make the problem harder:
you need fine spatial resolution, and you need to be able to
take readings quickly.
Spatial resolution and sampling speed
How well a plunger performs in a pinball simulator depends upon its
spatial resolution and sampling speed. I consider a sensor suitable
if it can determine the true plunger position to within 1/100", and
produce at least 200 such position readings per second.
Spatial resolution refers to how precisely you can locate the current
position of the physical plunger. The pinball simulator uses the
position reading from the sensor to draw the on-screen plunger on the
video display in real time, so that the player can see the on-screen
plunger animated in sync with the physical plunger. For that
animation to be realistic and smooth, the on-screen position has to
track the physical position as finely as the video display can draw
it. On an HD screen at playfield size, the spacing between pixels is
about 1/50 of an inch, and on a 4K monitor it's about 1/100 of an
inch. On a full-sized pin cab, the on-screen plunger should be
roughly the same size as the real plunger, so if you want smooth,
pixel-accurate animation, the sensor has to be able to pick up
movement of the physical plunger on the same scale as the size of the
on-screen pixels. That requires 1/100" precision from the sensor.
Spatial resolution also affects the quality of the physics simulation.
All of the pinball simulators read the plunger position via the
Windows USB joystick interface, which is capable of representing high
precisions. Visual Pinball can handle 16-bit resolution, which
translates to one part in 65,536, or about 50 microns (millionths of
an inch) over the 3" travel of a physical plunger. That's a lot finer
than the 1/100" resolution required for smooth animation, and much
finer than any virtual pinball plunger sensors currently available
(for Pinscape or any other system). The point is that there are
practical benefits to working on better sensor designs than we have
today, since VP's physics model can take advantage of a lot finer
spatial resolution than today's sensors provide.
Sensor speed is also critically important. The plunger moves really
fast when you pull it back and release it, so in order to track that
motion in real-time, the sensor has to be able to take readings
quickly. My measurements with the AEDR-8300 sensor indicate that the
plunger in my test rig, which is a standard Williams/Bally plunger
with a medium-tension spring, moves at a peak speed of about 4.5
meters per second. That means that the plunger covers its full 80mm
travel range in about 25ms. To keep up with that fast motion, the
sensor has to be able to take readings at least about every 5ms, or
200 times per second. Sensors with slower sampling rates than that
will suffer from "aliasing", where they mistake retrograde motion for
forward motion (or vice versa) when the plunger bounces back after
hitting the barrel spring. When aliasing occurs, VP can't calculate
the speed of the plunger correctly, which screws up the physics
simulation. Aliasing can lead to wildly erroneous speed calculations.
The Pinscape firmware has special handling to detect and correct for
aliasing in slower sensors, but that necessarily loses information
about the true instantaneous speed and position, so it's better if the
sensor can produce readings frequently enough that the aliasing filter
is never triggered.
This is one of the simplest ways to measure a linear position, and it
actually compares pretty well to more complicated approaches. It's
used in a lot of industrial applications where you need fast readings
without extremely high resolution.
Physically, a potentiometer consists of a fine electrode that moves
across a resistive conductor such as graphite - something that
conducts electricity, but with relatively high resistance. Resistance
in a material like graphite is a function of the distance between
measuring points, so as you move the electrode across the graphite,
the resistance between the electrode and any fixed point on the
graphite varies with the distance between the two points. If you
measure the resistance at point A as higher than the resistance at
point B, you know that point A is further away from the fixed end than
For our purposes, we use "linear taper" potentiometers, which are
built so that the electrical resistance varies linearly with the
electrode position. Voltage and resistance are also linearly related
(through Ohm's Law), so if we supply a fixed voltage across the fixed
ends of the pot, the voltage we read at the electrode will vary
linearly with the resistance, which varies linearly with the position
of the electrode. The KL25Z has an on-board analog-to-digital
converter (ADC) that can sample an analog voltage level and report it
to the software as a digital reading.
How accurate is a potentiometer? The one that we recommend in the
parts list is readable to about 1% accuracy with the KL25Z ADC. That
translates to about 3/100". So it's not quite as good as we need for
perfectly smooth animation, and it means that the "jitter filter" in
the Pinscape firmware is usually needed to get steady readings when
the plunger is standing still.
This could be improved by using a different potentiometers with higher
accuracy, but I haven't found anything available that looks like it
would do better.
The potentiometer's spatial resolution might not be perfect, but its
sampling speed is extremely fast. The potentiometer itself can be
sampled in arbitrarily short intervals, as it provides an analog
voltage level that adjusts to changes in position effectively
instantaneously. Everything at the analog level moves at the speed of
electric field propagation in the conductors, which is close to the
speed of light. So the limiting factor isn't the analog signal, but
rather the ADC sampling time. The ADC works by charging a small
capacitor internally, and this takes a more macroscopic amount of
time. The fastest possible ADC sampling time on the KL25Z is about
10µs, although there's a significant trade-off between speed and
accuracy, so we use a slower mode that takes more like 30µs for
each reading. That's still about 100 times faster than we need it to
be (as discussed earlier, we only need readings about every 5ms), so
we can take many readings over the sampling period and average them
together, to further reduce noise and improve accuracy. Since the
January 2020 version, the firmware takes readings continuously, and
computes a rolling average each time a result needs to be sent to the
PC. Each reading sent to the PC represents the average of 128 ADC
samples. This smooths out the noise and makes for highly stable
Quadrature is an electrical engineering term describing two signals
that are 90° out of phase with each other. This has numerous
applications in signal processing, but the one we're concerned with
here is its use for motion sensing. A quadrature motion encoder works
by observing transitions between "on" and "off" zones marked along a
"measuring stick", using two sensors that are offset slightly from one
another. The measuring stick is more formally called a "scale".
The 90° phase difference in this case refers to the size of the
offset between the two sensors: it's arranged so that it's half the
size of the marked on/off zones on the scale. If you observe the
on/off signal from each sensor as they move across the scale, you'll
see the leading sensor make its on/off transitions 90° of phase
ahead of the trailing sensor. Which sensor is the "leading" sensor
and which is the "trailing" one depends on which direction they're
moving across the scale, so you can tell which direction you're moving
by observing the phase between the two signals and seeing which sensor
is making its transitions first at each step. Or, equivalently, you
can look to see if the signals are 90° or 270° out of phase
with each other.
The scale can be implemented in many ways, but the common element is
that it has to have a series of on/off zones of about equal size
across the range of travel. These can be electrically conductive and
non-conductive regions, for example, or magnetic north/south poles, or
optical black/white or transparent/opaque bars. The specific
quadrature sensors that we use in the Pinscape projects are optical
sensors, so our scales use the transparent/opaque approach. In other
words, our scale is simply a series of black bars printed on
A quadrature sensor isn't actually a position sensor - it's a
motion sensor. This type of sensor can only detect when it's
moving from one bar to the next on the scale, and the direction of
that motion (using the signal phase). If we combine these two
capabilities - detecting a change from one bar to the next, and
knowing which direction we went during that change - we can keep count
of how many bars we are away from our starting point. So if we have a
known starting point, and we know the length of each bar, we can infer
our current position: our position at any given time is the starting
position plus or minus the net distance we've moved since then.
For the plunger application in particular, we have an excellent "known
starting point", namely the plunger rest position. It's usually safe to
assume that the plunger starts at the rest position, so we take that
to be the initial position at startup. All subsequent inferred
positions are relative to this starting point.
There's an inherent drawback to using a quadrature sensor as a
position sensor by way of the net travel distance, which is the
possibility for missed transitions. If the sensor ever misses a
transition, the count will no longer be in sync with reality, so the
inferred position that we figure based on the count will differ from
the actual position by the number of missed counts. Sensors in
practice do tend to miss some fraction of transitions, so the error
between inferred and actual position tends to increase over time. To
mitigate this in our application, the Pinscape software can be set,
optionally, to reset the inferred position to the starting (plunger
rest) position after any extended period without any motion. Just as
it's usually safe to assume that the initial position at system
startup is the rest position, it's a good bet that a motionless
plunger is in equilibrium at its rest position, since it's
difficult to hold it perfectly still anywhere else for any length of
time, and there's no reason to do so even if you could.
Interfacing a quadrature sensor to the KL25Z is straightforward. We
treat the two sensor output channels as digital inputs (high/low
signal levels, corresponding to the on/off zones in the scale), and
set them up to trigger interrupts. The interrupt handler for each
channel uses a lookup table to figure the direction increment
represented by the current channel signal levels, adding or
subtracting one from a running counter.
A fast-moving plunger can result in extremely rapid signal transitions
on the channels - fast enough to overwhelm the KL25Z's interrupt
response time. The quadrature sensor software interface in the
Pinscape firmware uses custom hardware interrupt handlers to optimize
the response time, and with that it requires 6.5µs to process
each channel interrupt. When considering new quadrature sensors, we
have to calculate the signal rate at peak plunger speeds (about 4.5
mm/ms) to make sure it doesn't exceed the 6.5µs response time,
or equivalently, about 150kHz. In many cases, the quadrature sensor
itself might be the limiting factor - most of the ones I've looked at
quote peak signal rates in their data sheet far below 150kHz (it's
usually closer to 20kHz to 30kHz).
The AEDR-8300 is a reflective optical sensor. It has an LED emitter
that shines a narrow light beam towards the scale, and a pair of
photoreceptors that capture the light reflected back from the scale.
The photoreceptors use the usual quadrature arrangement where they're
slightly offset from one another.
The AEDR-8300 product line has parts available with different bar
spacings. The particular sensor we use has 75 line-per-inch bars,
meaning that each black/white pair is 1/75" wide. The nature of
quadrature sensing means that we can tell our position to within 1/4
of a line pair, so we effectively get 1/300" resolution.
At peak speeds, the 75 LPI spacing results in quadrature pulses from
the sensor about every 19µs. That's safely above the
6.5µs interrupt response time I've measured on the KL25Z. Note
that the finer-pitched sensors in the AEDR-8300 line would likely
overwhelm the KL25Z, and probably wouldn't be able to keep up with the
peak plunger speeds anyway, as these sensors have their own maximum
signal rates that are below the KL25Z's limit. But that's okay, since
the 75 LPI spacing gives us such high precision that we really have
no need for a finer pitch.
Linear image sensors
The first Pinscape plunger sensor was based on a linear image sensor,
the TSL1410R (and the similar TSL1412S). These sensors are no longer
available. The TCD1103 works on a similar principle, but it requires
a focusing lens, which makes it more complex to set up.
The principal of operation of these sensors is pretty simple. The
sensor consisted of a single row of light sensor pixels about the same
length as the plunger travel distance. We arranged the sensor so that
the row of pixels ran along the axis of the plunger travel, and placed
it directly adjacent to the plunger, with the pixels facing the
plunger. We put a light source on the opposite side of the plunger,
facing the pixels. This caused the plunger to cast a shadow on the
pixel array. We'd then read the pixel array and find the location of
the shadow, by looking for an edge between a light area and a dark
area in the image. The edge tells us where the plunger is currently
In principle, a sensor of this type could achieve spatial resolution
equal to its pixel size. In practice, though, the shadow cast by the
plunger isn't perfectly sharp. Shadows always have a little fuzzy
area when the light source isn't a perfect point source, because the
light source is only partially blocked at the leading edge of the
shadow. So we can't tell exactly where the plunger was; we have to
guess based on the midpoint of the shadow. The best possible
resolution in my setup is about 1/50". That's a bit below the ideal
needed for pixel-level resolution on the TV display, so there's a
little bit of jitter (by a pixel or two) as the guess about the shadow
position would vary from frame to frame.
The TCD1103 can perform much closer to its theoretical pixel limit
thanks to the requirement for focusing optics.
The Pinscape software uses a simple edge-detection algorithm with
these sensors, where it looks for a region with a rapid transition
from a run of bright pixels to a run of dark pixels. This algorithm
inherently compensates to some extent for exposure levels, since it
works based on the difference in brightness across pixels rather than
looking for absolute brightness levels.
The TSL1410R happened to be perfectly designed for this application.
Its pixel row was 3" long, with 1280 pixels across the file. That's
400 pixels per inch.
The TSL1412S was almost exactly the same, with the only difference
being a slightly longer sensor window and a correspondingly larger
number of pixels (1536). The pixel spacing was the same on both
sensors, and they were identical in their electronic interface.
These sensors work by using photoreceptors to charge capacitors. The
electronic interface lets the host microcontroller connect the
individual integrating capacitors to an analog output port, one at a
time through a shift register. The capacitor charge is an analog
voltage level, so we use the KL25Z's ADC to sample each pixel's charge
level and convert it to to a digital reading.
The KL25Z has the capability to control the ADC through its DMA
(direct memory access) controller, which was key to making the image
capture fast enough to work as a plunger sensor. The DMA runs
concurrently with the CPU, so the firmware was able to start the DMA
reading process and then return to other work while the pixels were
clocked into memory by the DMA controller. This allowed a full
reading to be taken in about 2.5ms, or 400 frames per second, which is
fast enough to keep up with the peak plunger release speed.
This is a tiny CCD sensor made by Toshiba, with 1500 pixels arranged
in a single linear file. It works using the same edge detection
algorithm as the TSL1410R/TSL1412S, but its pixel window is only about
8mm long, so it requires a lens to focus a reduced image of the
plunger on the sensor. If the lens is properly aimed and focused,
this sensor can resolve the edge at the end of the plunger to a single
pixel, so it achieves spatial resolution of nearly its full 1500
pixels across the 80mm travel range of the plunger, which translates
to about 1/400" resolution.
The electronic interface to this sensor is similar to that of the
TSL141x sensors. Like those sensors, the TCD1103 has an electronic
shutter function that moves the pixel charges onto capacitors, which
the microcontroller reads out by sampling an analog voltage output one
pixel at a time. With DMA transfer, the KL25Z can transfer the pixel
file in about 3ms.
Distance and proximity sensors
The original commercial plunger kits (e.g., the Nanotech Mot-ION
controller, and the various generations of the VirtuaPin plunger kits)
and all used IR-based proximity sensors. IR proximity sensors work by
emitting an IR light signal and sensing the brightness of the
reflection from a nearby object via a photoreceptor.
Technically, proximity sensors are only meant to detect
proximity - a yes/no question, "is an object is within range of
the sensor?" However, most of these sensors don't answer the yes/no
question directly, but rather just give you their raw analog
brightness reading, leaving it up to the application to interpret that
by comparing it to a calibrated threshold. The commercial plunger
kits don't just treat the brightness as a binary value above or below
a threshold, however. They instead interpret it as a continuous
quantity that correlates to the distance to the target (which, in this
case, is the end of the plunger rod). At a basic physics level, the
brightness of a light source (or of a reflection) varies inversely
with the distance to the source, so by applying some math to the
brightness reading, we can infer the distance.
Proximity sensors as a class aren't meant to be used this way, though.
Their brightness sensors aren't designed to be fine measurement
instruments, and attempting to interpret the brightness reading as a
proxy for distance doesn't always yield very good results. The
relationship between reflected brightness and distance is inherently
non-linear at the physics level, even with an idealized theoretical
model. It's worse in a practical setup, since the sensor is subjected
to interference from stray light, reflections from other surfaces
besides the target, variations due to ambient temperature, and
electronic noise. The early commercial plungers, which were based on
Sharp analog IR proximity sensors, could only achieve a spatial
resolution about 1/2".
A newer IR proximity sensor chip, Vishay's VCNL4010, performs quite a
lot better. This chip has its own on-board ADC for the brightness
signal (the older Sharp chips produced an analog voltage that had to
be sampled externally, on the microcontroller), which seems to make
for much higher resolutions. This is reportedly the sensor used in
the VirtuaPin v3 plunger kit, so I recently (May 2021) added support
for it to the Pinscape firmware, to help out some VirtuaPin customers
who had requested it because they switched to the Pinscape firmware on
their controller boards. This sensor is actually pretty good: in my
testing, it reliably resolved distances to less than 1mm over most of
its range. (It gets coarser at the "far" end where the plunger is
farthest away from the sensor; this region is the most challenging for
the sensor because very little light is reflected back at that
distance.) That's not as good as some of the other sensors
(potentiometer, quadrature, linear imaging), but it's good enough to
be usable. The tricky part of this sensor is that its response curve
(the relationship between measured brightness and object distance) is
a little bit erratic. But it's close enough to a power law
relationship that the distance conversions come out looking plausibly
linear, if you don't look too closely.
There's a related but different type of sensor that uses reflected IR
light to actually measure distance - by design, not just incidentally.
These are called "time-of-flight" sensors, because they measure
distance by timing the round-trip time for light pulses to be returned
from the target, instead of just measuring the brightness of the
reflection. In principle, this should yield much more precise
distance measurements, because the time measurement isn't affected by
the reflectivity of the target, which is obviously a huge factor for
the brightness sensors. In addition, the underlying physical quantity
being measured - round-trip travel time of the IR photons - has an
inherently linear relationship with the distance, so the conversion
from measured quantity to distance is straightforward and doesn't lose
precision or magnify uncertainties, the way that the inverse power-law
relationship does for brightness-to-distance conversions.
The Pinscape software supports the current best-of-breed sensor in the
time-of-flight class (as far as I've found), the VL6180X.
Unfortunately, in my testing, this sensor is inferior to the VCNL4010,
despite the more sophisticated technology. The VL6180X has a nominal
resolution of 1mm (1/25"), which I'd consider just barely usable.
Unfortunately, that's only the nominal resolution; the actual accuracy
in my measurements is more like 5mm to 10mm. That's too coarse to be
usable, in my view; it gives you some semblance of plunger operation,
but isn't good enough for smooth animation, and definitely isn't good
enough for skill shots. The sensor is also too slow; it takes it at
least 14ms to produce a sample, in its fastest and least accurate
I'm planning to keep an eye out for new time-of-flight sensors coming
onto the market, since this seems like a promising design approach
that could eventually yield high-precision non-contact distance
sensors. But right now there doesn't seem to be a production chip
available that performs well enough for our purposes. By the same
token, given that the VCNL4010 is already passably good, it would be
worth monitoring developments in that product line; it wouldn't take a
huge amount of improvement for that type of sensor to become a top
Bar code absolution position sensing
This is an experimental approach that I've been looking at but haven't
yet made work well enough. The idea is to do absolute position
sensing using an optical Gray code and a suitable small image sensor.
We create an optical scale with a Gray code printed on it with a
unique code in each position across the 3" plunger travel range, then
we use an optical sensor to reach the code at the current position.
We translate the bar code by looking it up in a table to get the
The principle here is simple, and a suitable sensor is available:
TSL1401CL. As you might guess from the name, this sensor comes from
the same series as the late, great TSL1410R that we mentioned earlier,
but it has a much smaller window - only about 128 pixels over 1cm.
That makes it unsuitable for the straightforward "shadow edge" method
we used with the larger sensor. But 128 pixels is more than enough to
read a bar code. With 128 pixels to work with, we could easily come
up with a bar code that could represent perhaps 20 bits. That would
be much more than we need; just 10 bits would be enough to encode 1000
unique positions along a scale. If we spread 1000 codes over 3",
we'd be able to resolve about 300 positions per inch. That's at the
high end of the resolution requirements we laid out earlier.
This all works nicely in principle, and the Pinscape firmware already
has support for a form of this, since I've done some experiments with
it. The challenge is making the optics work. I haven't been able to
find a way to get a sharp enough image of the bar code to read it
reliably at the required resolution. So the open area of research is
how to arrange a lens or other optics to get a good enough image on
If I can get this working, I think it would make a really great sensor
option. It should have the excellent spatial resolution and
sample-to-sample stability of the quadrature sensors, plus the
absolute position sensing of all of the other types, which would be
a powerful combination.
Rotary absolute position sensing
Absolute sensing like that described above is available in commercial
position sensors that do rotary position sensing - that is,
they measure the turn angle of a shaft, rather than a linear offset.
There are some magnetic rotary absolute sensors available with very
high angular resolutions.
The trick is to translate the linear motion of the plunger into a
One possibility is a lever between the plunger and rotating shaft. A
lever connects to a shaft at one end and to the plunger at the other
end; moving the plunger rotates the shaft through the lever. One
complication is that the distance between the shaft and plunger would
vary over the plunger's range of motion, so a sliding connector at one
end would be required. The other complication is that the rotational
angle wouldn't vary linearly with the plunger's position - it would be
sinusoidal. The sine curve approaches closer to linearity the longer
you make the lever, so one solution could be to make a very long
lever. On the other hand, that would require a very high-res sensor,
since you'd only be using a small fraction of its angular range. A
better solution might be to use calibration in the software to figure
out where you are on the sine curve, and translate mathematically from
the sine curve to the linear position. That's easy in principle, but
it seems challenging to make the mechanics of the calibration
Another possibility is to translate the linear motion to angular motion
through a belt that wraps around a pair of wheels. The belt moves
with the plunger, and as it moves, it turns the wheels. The angular
sensor is connected to the axle of one of the wheels. This would
yield a very straightforward linear relationship between position and
angle, so it wouldn't have any of the calibration problems of the
lever approach. This seems like a pretty straightforward mechanism,
but I haven't tried to realize it physically yet. I think the main
challenge would be ensuring a solid connection between the plunger,
belt, and wheels, so that the plunger motion directly translates to
wheel motion without any play or hysteresis. Any mechanical play
in the system would manifest as loss of precision in the readings,
so this would all have to be very solidly connected.
If the mechanics could be worked out, selecting a suitable absolute
rotary encoder and connecting to the software should be relatively
simple. There are a number of high-res magnetic encoders available
with 12-bit or higher resolution, which means 4096 counts per turn.
With the wheel arrangement describe above and 1" diameter wheels, the
3" of plunger motion would turn into almost one full turn, so we'd get
perhaps 75% of the range of the sensor. That means we could achieve
as many as 1000 counts on the sensor per inch, or 1/1000" linear
resolution. That would be far higher than any of the other sensors.
Interfacing one of these sensors to the software should be pretty
easy, as the newer ones use modern microcontroller-friendly interfaces
like SPI or I2C.