Meter Movement · Volume 4
Driving the Meter
Turning a desired time into the right needle deflection — PWM and a resistor, filtering, current sources, and the scale-adjust calibration that makes three needles tell the truth
A moving-coil meter is an honest device: its needle deflects through an angle set by the current in its coil — θ = (N·B·A / k)·I, the linear law derived in Vol 2 — and nothing else. The whole job of a meter-movement clock’s driver is therefore to put a calculated current through each coil, the current that points the needle at the right number on a re-faced dial. The timekeeping core (Vol 5) decides what deflection each meter should show ten times a second; this volume is about how that deflection is produced as a coil current, how cheaply you can get away with it, and how you trim three real meters so they agree.
The collected build — abbtech’s Multimeter Clock — answers the “how” in the simplest way the physics allows: a microcontroller PWM output pin, a single current-limiting resistor, the meter to ground, and the meter’s own mechanical sluggishness doing the filtering for free.1 Most of this volume unpacks why that works, where it stops working, and what you reach for instead — an explicit RC filter, a transistor buffer, an op-amp current pump, or a DAC — when you want more current, more precision, or more meters that behave identically. The volume ends on calibration, which is what actually separates a meter clock that reads true from one that reads visibly wrong at the top of the scale.
4.1 Current drive vs. voltage drive — what you are really aiming at
Because deflection tracks coil current, the conceptually clean target is a current: decide the current, force it through the coil, and the needle goes where it must regardless of anything else. A true current source does exactly that — it adjusts its own output voltage to whatever the coil’s internal resistance Rm demands so that the current is the controlled quantity (§4.6).
But there is a cheaper truth. A moving-coil meter has a fixed internal resistance Rm (Vol 2, Vol 3 — a few hundred ohms for a 0.5 mA movement), so if you drive a voltage V through a known series resistor R, the current is simply
I = V / (R + Rm).
Within the tolerance of Rm, a controlled voltage through a fixed resistor is a controlled current. This is the trade-off at the heart of the whole volume:
- Voltage-through-a-resistor (the collected build). Trivially cheap — one MCU pin, one resistor. The current depends on Rm and on the supply, so it drifts if either drifts, and it differs meter-to-meter because Rm has unit spread (Vol 3). You absorb that drift and spread with per-meter calibration (§4.9). Good enough for a clock, and what abbtech ships.
- True current drive (§4.6). The current is set by the driver alone, immune to Rm spread and supply sag — no per-meter resistor trim needed, all meters behave alike. Costs an op-amp (or a couple of transistors) per meter. Worth it when you want precision, identical channels, or a supply you do not trust.
The rest of §4.2–§4.5 develops the cheap path in full, because it is the one in the schematic; §4.6–§4.7 give the precise alternatives.
4.2 The simplest drive: a PWM pin, a resistor, and the needle’s own inertia
In the collected build each meter’s positive lead is connected to a dedicated PIC16F628A output pin through a 4.7 kΩ current-limiting resistor; the negative lead is grounded.1 The PIC has no analog output, so it manufactures an analog level the way small microcontrollers always do — pulse-width modulation (PWM): it switches the pin hard between 0 V and the 5 V rail (Vol 6’s LM7805) at a fixed high frequency, and varies the duty cycle D (the fraction of each period the pin is high). The average voltage at the pin is
V_avg = D · Vcc = D · 5 V.
At D = 0 the pin sits at 0 V (needle at rest); at D = 1 it sits at 5 V (maximum drive); at D = 0.5 it averages 2.5 V. That average, across the series resistor and into the coil, sets the average coil current and therefore the needle angle.
4.2.1 Why the needle sees the average, not the switching
A PWM pin is never at 2.5 V — it is a 0 V/5 V square wave. What turns that square wave into a smooth 2.5 V level is a low-pass filter, and the moving-coil meter is one for free. Its needle is a pivoted mass on a hairspring with eddy-current damping (Vol 2): a second-order mechanical system whose natural period is on the order of a second and whose response is deliberately damped near critical. Its mechanical bandwidth is therefore a fraction of a hertz — thousands of times below any sensible PWM frequency. The coil’s torque responds to the time-average of the current over many PWM cycles; the needle simply cannot move fast enough to follow individual pulses, so it settles at the angle the average current commands. The same sluggishness that makes the analog sweep charming (Vol 1) is the filter that makes naked PWM drive work. This is the single most important idea in the cheap drive: the meter filters its own drive signal.
4.2.2 An explicit RC filter, when you want one
Mechanical filtering is enough for a clock, but if you want a genuinely steady coil current — for instance to measure the drive on a bench, to feed a high-impedance buffer or current source, or to quiet a meter with unusually light damping — add a passive RC low-pass that turns the PWM into a DC level before it reaches the load. Its corner frequency is
f_c = 1 / (2π · R · C).
The design rule has two ends. The corner must sit well below the PWM frequency so that the switching ripple is crushed, yet well above the rate at which the displayed time changes so the filtered level — and then the needle — still settles promptly. With a PWM frequency of, say, 5 kHz and a buffered filter using R = 10 kΩ and C = 10 µF:
f_c = 1 / (2π · 10 kΩ · 10 µF) = 1 / (2π · 0.10 s) ≈ 1.6 Hz.
The ripple at 5 kHz is attenuated by roughly f_PWM / f_c ≈ 5000 / 1.6 ≈ 3000×, i.e. into the millivolts — invisible to the needle. Yet the filter’s time constant τ = RC = 0.10 s means it settles to within 1 % in about 5τ ≈ 0.5 s, faster than the needle’s own mechanical response and far faster than the once-a-second time update, so nothing is sluggish that was not already sluggish. Buffer the RC (an op-amp follower, or the transistor of §4.5) before the meter: if instead you hang the capacitor directly across the meter, the coil’s low Rm (a few hundred ohms) sits in parallel with C and the corner becomes f_c = 1 / (2π · (R∥Rm) · C), which forces a much larger capacitor for the same corner. For the collected direct drive abbtech simply omits the cap and lets the movement do the filtering — the legitimate, parts-free choice.
4.3 Sizing the current-limiting resistor
The resistor’s job is to set the full-scale current: when the firmware commands its maximum drive, the meter should read exactly full scale (the top of the time dial — 12 o’clock, 60 minutes, 60 seconds), and never more. To reach a full-scale current I_fs at full duty (V_avg = Vcc), the series resistor must satisfy Vcc = I_fs·(R + Rm), so
R = (Vcc − I_fs · Rm) / I_fs.
Work it for the collected build’s meters — Vcc = 5 V, I_fs = 0.5 mA — and assume a coil resistance Rm ≈ 200 Ω (a typical mid-value for a 0.5 mA movement; Vol 3 notes the range is roughly 100–300 Ω and varies unit to unit):
R = (5 V − 0.5 mA · 200 Ω) / 0.5 mA R = (5 V − 0.10 V) / 0.5 mA R = 4.90 V / 0.5 mA R ≈ 9.8 kΩ.
So the “textbook” resistor that puts a nominal 0.5 mA / 200 Ω meter at exactly full scale at exactly 100 % duty is about 9.8 kΩ — and the collected build uses 4.7 kΩ, roughly half that. That is not an error; it is a design choice, and reconciling it is the most instructive calculation in this volume.
4.3.1 Reconciling the 4.7 kΩ resistor with a 0.5 mA full scale
Put 4.7 kΩ back into the current law and see what full duty actually delivers into the same nominal meter:
I(D=1) = Vcc / (R + Rm) = 5 V / (4.7 kΩ + 200 Ω) = 5 V / 4.9 kΩ ≈ 1.02 mA.
Full duty would drive about 1.0 mA — roughly twice the 0.5 mA full scale — which would slam the needle hard against its end stop. The driver therefore must never run at full duty; the duty that produces a true full-scale reading is
V needed for 0.5 mA = 0.5 mA · 4.9 kΩ = 2.45 V → D_fs = 2.45 V / 5 V ≈ 0.49.
i.e. about 49 % duty reads full scale through a 4.7 kΩ resistor. This lands exactly on the behaviour the article documents: “when the clock is first powered up the PWM outputs will default to about 50 % of max output,” after which you trim each meter to full scale.1 The 50 % power-up default is, to within the tolerance of Rm, the full-scale operating point for a 0.5 mA / ~200 Ω meter on a 4.7 kΩ resistor — the firmware comes up pre-aimed at the top of the scale, and you trim down from there.
Why deliberately undersize the resistor so the usable duty span is only 0–~50 %? Three honest reasons, and they are the same reason the clock has a calibration mode at all:
- Reach, guaranteed. Cheap “0.5 mA” panel meters are not all truly 0.5 mA, and Rm varies widely (the article’s own author jokes about the quality of the meters he bought). A 4.7 kΩ resistor can push up to ~1 mA, so it can drive a more sensitive or higher-Rm meter to full scale where a 9.8 kΩ resistor would run out of voltage. The article says as much: the 4.7 kΩ “can be adjusted depending on the meter current scale available.”1 It is a one-size-fits- a-range default, not a value optimised for one exact meter.
- Calibration headroom, both ways. Because full scale sits near mid-duty, the firmware can trim up or down from ~50 % to chase each meter’s true full scale — there is room on both sides for unit-to-unit spread. A 9.8 kΩ resistor aimed at 100 % duty would have headroom only downward; a meter that read slightly low at full duty could never be brought up.
- The trim absorbs the rest. Whatever the exact Rm and sensitivity of the meter actually installed, the scale-adjust mode (§4.9) finds the duty that reads exactly full scale and stores it. The fixed resistor only has to get every plausible meter within reach of full scale; the per-meter EEPROM trim does the precision. This is precisely why a scale-adjust trim exists — it is the cheap voltage-drive path (§4.1) paying for its cheapness with calibration.
The cost is PWM resolution: using only ~0–50 % of the duty range halves the number of distinct levels. With an 8-bit PWM (256 steps) that still leaves ~128 steps from rest to full scale — about two steps per minute on a 60-minute dial — finer than the needle or the eye can resolve, so the cost is invisible. If you wanted the full duty span you would fit the ~9.8 kΩ resistor and calibrate near 100 % duty; abbtech’s 4.7 kΩ trades resolution you do not need for reach and trim-room you do.
4.4 The 25 mA pin limit
A PIC output pin can source only so much current — about 25 mA per pin for the PIC16F628A — and that ceiling decides whether a meter can be driven straight from a pin or needs a buffer.1 For the collected build it is a non-issue: a 0.5 mA meter draws 1/50 of the limit, so the pin loafs. But meters come in many full-scale currents (Vol 3), and the rule is simply:
If I_fs < ~20 mA (leaving margin below 25 mA), drive the meter directly from the pin through a resistor. If I_fs approaches or exceeds 25 mA, the pin cannot source enough — add a buffer.
A 1 mA or even 10 mA meter is still comfortably pin-drivable through an appropriately smaller resistor (re-run §4.3 with the new I_fs). A 30 mA edgewise meter, a large vintage instrument on a high current range, or any movement specified above ~25 mA full scale needs the buffer of §4.5. abbtech states the limit explicitly: “a meter with a lowest setting above 25 mA would not work without additional circuitry.”1
4.5 Buffering for higher current — a transistor current sink
The simplest buffer is a single transistor configured as a current sink, which both supplies the larger current the pin cannot and (as a bonus) makes the current depend on the drive voltage and an emitter resistor rather than on the meter’s Rm. Take an NPN transistor with the meter in its collector lead (meter’s high side to the supply) and an emitter resistor R_E to ground; drive the base from the PWM pin through an RC filter (§4.2.2) so the base sees a steady V_B. Then
I_E ≈ (V_B − V_BE) / R_E, and I_meter ≈ I_E (for reasonable transistor gain),
with V_BE ≈ 0.7 V. The collector current — and thus the meter — is set by V_B and R_E and is nearly independent of Rm and of the supply, while the transistor, not the pin, carries the meter current. A power supply rail, not the 25 mA pin, now does the work; choose a transistor rated for the meter’s full-scale current with margin. For currents into hundreds of mA a small MOSFET (gate from the filtered PWM, source resistor sets the current) does the same job with no base current draw. Either way the pin only has to control, not supply, the meter. A simple two-transistor or op-amp current mirror / sink generalises this when you want several identical higher-current channels.
4.6 Load-independent drive — the op-amp current pump
The voltage-through-a-resistor scheme (§4.2) leaks the meter’s Rm and the supply voltage into the reading, which is why it needs per-meter calibration. For the builder who wants the current to be set by the driver alone — immune to Rm spread, immune to supply sag, identical across every channel — the standard answer is the Howland current pump: one op-amp and four matched resistors that turn an input voltage into an output current independent of the load.
With the four resistors matched to a common value R, the Howland source delivers
I_out = V_in / R,
into the meter regardless of the meter’s resistance, as long as the op-amp stays within its output compliance (it raises or lowers its output voltage to hold the current constant as Rm varies). Feed V_in from a filtered PWM level or a DAC (§4.7) and you have a clean, calibrated-by- construction current drive: no per-meter resistor trim, every meter behaves the same, and a drooping 5 V rail no longer shifts the reading. The price is an op-amp and a set of matched resistors per channel — the current-source accuracy is only as good as the resistor matching, so use 0.1 % parts or a trimmed network. It is worth it when you are building more than a one-off, when you want all three needles to track without individual fuss, or when your supply is not as solid as a regulated 5 V. For a single hobby clock on a clean LM7805 rail, the cheap resistor drive plus calibration (the collected build’s choice) is the pragmatic winner; the current pump is the precision upgrade.
4.7 A DAC instead of PWM
PWM makes an analog level out of a digital pin by time-averaging a square wave; a digital-to-analog converter (DAC) makes one directly, as a true steady voltage. Substituting a DAC for PWM removes the ripple problem at its root:
- Cleaner. A DAC output is already DC — no switching ripple, so no reliance on the meter’s inertia or an RC filter to smooth anything. The level is rock-steady the instant it is written.
- Resolution. A 10- or 12-bit DAC gives 1024–4096 levels in hardware, finer than typical 8-bit PWM, with no resolution-vs-duty-span trade (§4.3.1).
- Trade-offs. The PIC16F628A has no DAC, so this means an external part — e.g. an SPI DAC such as an MCP49xx — costing board space, a few pins (SPI clock/data/CS), and money, plus firmware to drive it. For three channels you would use a dual/quad DAC or three singles. You still need a buffer (§4.5) or current pump (§4.6) if the meter draws more than the DAC can source, and you still calibrate for Rm unless you pair it with a current source.
For the collected build, PWM is the right call precisely because it is free — the 16F628A already has the timer hardware and an output pin, and the meter already filters it. A DAC is the upgrade you choose when you have moved to a richer MCU (one with an on-chip DAC) or want bench- measurable steadiness; on the 16F628A it is parts you do not need.
4.8 Sources of reading error and how each is handled
The movement itself is linear (Vol 2): equal current steps give equal angle steps, so equal time steps give equal needle steps (Figure 4.2, bottom). Visible error in a finished clock comes not from the movement but from the drive and the dial art. The honest inventory:
Table 1 — not from the movement but from the drive and the dial art. The honest inventory
| Error source | Effect on the reading | How it is handled |
|---|---|---|
| Supply variation (5 V rail droops or shifts) | Voltage-drive current scales with Vcc → whole scale reads high or low | Regulate the rail (LM7805, Vol 6); or use a current source (§4.6) that ignores Vcc |
| Rm spread (meters differ unit-to-unit) | Same duty → different current → each meter reads a bit differently at full scale | Calibrate per meter and store the trim (§4.9); or use a current source so Rm drops out |
| PWM ripple (switching not fully averaged) | Needle jitter / slight bias | Meter’s mechanical filter (§4.2.1); add RC (§4.2.2) if needed |
| Non-linearity of the drive (e.g. transistor V_BE offset, op-amp limits) | Slight bow in the scale | Linear topologies (resistor, Howland); calibration sets only full scale, so mid-scale rides on the movement’s own linearity |
| Dial-art / parallax (scale drawn or read imperfectly) | Reads wrong even with perfect current | Draw the face precisely (Vol 8, MeterBasic); knife-edge pointer + mirror scale on good meters |
| Mechanical zero (needle not resting at 0) | Constant offset across the scale | Set the meter’s mechanical zero screw (§4.9.3) |
The pattern: regulate the supply, calibrate the current, filter the ripple, and draw the face honestly — and because the movement is linear, fixing the full-scale point fixes the whole scale. Non-linearity is a face-and-drive problem, not a movement problem; Vol 8 owns the face.
4.9 Calibration in depth
Calibration is where the cheap voltage drive earns its keep. Because the resistor drive lets Rm and supply into the reading (§4.1), each meter must be told which drive level equals full scale, and that per-meter number stored where it survives a power cycle. The collected build does this with a dedicated scale-adjust mode.
4.9.1 The collected build’s scale-adjust mode
On first power-up the firmware sets every PWM output to ~50 % of maximum — which, per §4.3.1, is approximately the full-scale operating point for a 0.5 mA / ~200 Ω meter on a 4.7 kΩ resistor. You then enter calibration by fitting the shorting jumper across the scale-adjust pin header; in this mode only the one meter being adjusted is powered, so you tune them one at a time.1 The three time-set buttons are reused as calibration controls:
- Button 1 (normally “advance hours”) — selects which meter is being adjusted.
- Button 2 (normally “advance minutes”) — decreases the powered meter’s full-scale duty.
- Button 3 (normally “reset seconds”) — increases the powered meter’s full-scale duty.
The procedure is to select each meter in turn and press decrease/increase until its needle sits exactly on full scale — the very top of the re-faced dial. When all three read true, remove the scale-adjust jumper; on returning to normal clock mode the firmware writes the three full-scale settings to non-volatile (EEPROM) memory, so the calibration survives power-down and need not be repeated.1 From then on the time-to-deflection map (Vol 5) scales every reading against each meter’s stored full-scale point, and the three needles agree.
This is the whole reason §4.3’s resistor could be a loose one-size-fits-a-range value: the fixed resistor only gets each meter within reach of full scale; the scale-adjust mode finds the exact duty and the EEPROM remembers it.
4.9.2 A manual trim-pot alternative
If you build your own driver without a calibration mode, the analog equivalent is to make the current-limiting resistor adjustable: replace the fixed R (or add a series trimmer) with a multi-turn trim-pot per meter, and turn it until the needle reads full scale at the firmware’s maximum drive. This trades EEPROM and firmware for three small pots and a screwdriver — simpler to build, but the trim is mechanical (it can drift, and it cannot be re-found automatically) and it consumes a little of the drive voltage as you turn it down. The digital scale-adjust mode is strictly nicer for a repeatable build, but a trim-pot is the honest minimum.
4.9.3 Zeroing
Full-scale calibration sets the top of the scale; the bottom is the mechanical zero. A panel meter has a small zero-adjust screw on the bezel that mechanically biases the hairspring so the needle rests on 0 with no current. Set it with the meter powered off (or at zero drive): turn the screw until the unpowered needle sits exactly on the dial’s zero. Because the movement is linear, a correct zero plus a correct full scale pins both ends and the whole scale falls into place — there is no separate mid-scale trim to do, which is the quiet luxury of a linear movement.
4.9.4 A gentle power-up ramp
The one mechanical hazard in this otherwise-safe clock (Vol 1, §1.10) is slamming the needle past its end stop. A moving-coil movement is fragile; a sudden full-drive step can fling the needle hard against the stop and bend the pointer or stress the hairspring. Two disciplines avoid it: (1) the firmware brings the PWM up to its ~50 % default and then to the computed level rather than jumping straight to a possibly-high value, and the meter’s own damping further softens the rise; and (2) the deliberately undersized 4.7 kΩ resistor means the firmware operates in the lower half of the duty range, so a stuck-high bug reaches ~1 mA (≈2× full scale, a hard hit) but not the tens of milliamps a low-resistance fault could deliver. A driver of your own design should ramp the drive on power-up — step the level up over a fraction of a second rather than applying it instantly — both to protect the movement and because a gentle sweep-to-position on power-up looks far better than a needle snapping across the dial. The blue power-up LED in the collected build (steady during the power-up phase, then a 1 s on/off flash once running)1 is the visible cue that this brief settling phase is happening.
FIGURE SLOT 4.4 — A perfboard close-up of the collected build’s driver section: the PIC16F628A in its socket, the four 4.7 kΩ current-limiting resistors, and the three meter output leads, of the kind shown in abbtech’s construction photos. To be fetched license-clean via the Photo Helper in the figure pass, or used from the owner’s collected build photos with credit verbatim; confirm provenance before embedding.
4.10 Where this leaves us
The driver is the engineering core of a meter-movement clock, and the collected build shows how little it needs to be: a PWM pin, a 4.7 kΩ resistor, the meter to ground, and the needle’s own inertia smoothing the rest. Everything richer — an RC filter, a transistor or MOSFET buffer past the 25 mA pin limit, an op-amp current pump that ignores Rm and supply sag, a DAC with no ripple at all — is an upgrade you reach for only when a specific need (more current, more precision, more identical channels) demands it. The cheap path pays for its cheapness honestly, in one place: calibration, where the scale-adjust mode finds each meter’s true full-scale duty and the EEPROM remembers it, turning three loosely-specified meters into three needles that tell the truth. Vol 5 picks up the other half of the driver’s brief — how the timekeeping core decides, ten times a second, what deflection each needle should show — and Vol 8 owns the dial faces that the deflection is read against. Vols 2 and 3 are the movement and the meter selection that everything here assumes.
4.11 References (Vol 4)
- Cross-references: Vol 2 (moving-coil physics, θ = (N·B·A/k)·I, damping and the needle’s mechanical low-pass), Vol 3 (full-scale current, internal resistance Rm and its spread, meter selection), Vol 5 (the PIC16F628A timebase, the 1/10 s interrupt, time→deflection mapping and the EEPROM trims), Vol 6 (the collected build: LM7805 5 V rail, perfboard, parts list, flashing, calibration), and Vol 8 (MeterBasic dial faces — where scale non-linearity actually lives).
Footnotes
-
Multimeter Clock by abbtech (Alan Parekh, Hacked Gadgets), Instructables, 2010 — construction article, “How it Works,” parts list, schematic, and “How to use” steps held in this hub’s
02-inputs/Simpson/. Key drive facts used here: each meter on its 0.5 mA DC range, negative lead grounded, positive lead driven from a PIC16F628A output pin through a 4.7 kΩ current-limiting resistor (“this can be adjusted depending on the meter current scale available”); the PIC sources a maximum of ~25 mA per pin, so a meter whose lowest range is above 25 mA needs additional circuitry; PWM outputs default to ~50 % of maximum on power-up; the scale-adjust jumper enters a per-meter full-scale trim mode (button 1 selects the meter, button 2 decreases, button 3 increases the full-scale setting) and the settings are written to non-volatile memory on exit; a blue LED is steady during power-up and then flashes 1 s on / 1 s off in normal run. Source: http://www.instructables.com/id/Multimeter-Clock/; author blog: http://hackedgadgets.com. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9