Scope / CRT Clocks · Volume 5

Timebase & Vector-Drawing Firmware

The MCU, the DACs, and how the face is actually drawn — keeping time, steering the beam, and beating flicker

Up to this point the project has been an exercise in physics and high voltage: a tube that emits a beam (Vol 2), a supply that feeds it (Vol 3), and a pair of amplifiers that fling it around the screen (Vol 4). None of that knows what time it is, and none of it knows the shape of a numeral. This volume is about the small digital brain that sits in front of those amplifiers and turns the current time into a picture of the current time, point by point, dozens of times a second. It has two jobs that look unrelated but share the same silicon: it has to keep accurate time — counting seconds against a crystal that drifts with temperature, optionally disciplined by GPS or NTP — and it has to draw, which on a vector display means computing a stream of X/Y coordinates, pushing them through digital-to-analog converters into the deflection amplifiers, and gating the beam on and off with the Z (blanking) line so the picture looks like hands and digits instead of a tangle of glowing wires. Everything interesting about a scope clock’s software lives in the tension between those two jobs and a hard physical constraint: the phosphor only glows briefly, so the whole face has to be redrawn fast enough that persistence of vision fuses it into a steady image — and that refresh budget is the thing every design decision in this volume is ultimately spending.

5.1 Keeping time: crystals, RTCs, drift, and discipline

A clock is only as good as its timebase, and the timebase is almost always a quartz crystal somewhere. The question is which crystal, how it is compensated, and whether anything external corrects it. There are three tiers in common scope-clock practice, in ascending order of accuracy and cost.

The cheapest tier is the microcontroller’s own clock — a bare crystal or even an internal RC oscillator driving the MCU, with software counting cycles to make seconds. This is fine for a toy but poor for a clock: a generic ±50 ppm watch crystal drifts roughly ±50 µs per second, which is about ±4.3 seconds per day, and that error swings with temperature because an uncompensated tuning-fork crystal has a parabolic frequency-vs-temperature curve centred near 25 °C, falling off as roughly −0.034 ppm/°C². A clock on a warm shelf in summer and a cold one in winter will keep visibly different time.

The standard tier — and what both owned units lean on — is a dedicated real-time-clock (RTC) chip with a temperature-compensated crystal oscillator (TCXO). The Sgitheach sin/cos clock and many AVR designs use the DS3232 (and the closely related DS3231), which integrates the crystal, a temperature sensor, and compensation logic, and is specified to roughly ±2 ppm from 0–40 °C — about ±0.17 s/day, two orders of magnitude better than a bare crystal. It speaks I2C, holds the time across power loss on a coin cell, and provides a 1 Hz square-wave output that the firmware uses as a hardware seconds interrupt (so the display of seconds is locked to the counting of seconds, not to a software loop that the drawing code might stall). The OSC4.4 carries its own RTC function on the main board around the PIC18F26K20, set and trimmed from the front-panel buttons (S1 fast-set, S2 slow-set; see Vol 8 for the full button map).

The top tier disciplines the local crystal against an external reference so that drift is corrected continuously instead of merely being small. The OSC4.4 supports two optional discipline modules, and the choice between them is a real trade-off:

Discipline sourceHow it connects (OSC4.4)AccuracyNeedsFailure mode
Free-running TCXO/RTCnone — onboard~±2 ppm (±0.17 s/day)nothingslow drift, must hand-set
GPS module5-pin socket behind Relay2absolute, sub-µs PPSclear sky / window viewno fix indoors, cold-start delay
Wi-Fi / NTP moduleseparate module assembly~10–50 ms typical over LANnetwork + credentialsdead without Wi-Fi/Internet

GPS gives the best raw accuracy — a one-pulse-per-second (PPS) edge tied directly to atomic time, plus date and time over a serial NMEA stream — and it needs no network, but it wants sky: a GPS clock buried in an interior room may never get a fix. Wi-Fi/NTP needs no antenna view but does need a working network and is only as good as the round-trip latency and the chosen time server, typically tens of milliseconds — far better than a human can read off an analog face anyway. In both cases the firmware’s job is the same: treat the local RTC as the thing that actually drives the display (because the face must redraw hundreds of times a second and you cannot wait on a satellite for each frame), and periodically slew the RTC toward the disciplined reference rather than jumping it, so the second hand never visibly jerks backward. The OSC4.4 assembly notes are explicit that the GPS and Wi-Fi modules are added last, only after the bare clock is drawing a face from its own timebase — discipline is a refinement layered on a working clock, not a prerequisite for one.

Figure 5.1 — Timebase accuracy ladder. Accumulated clock error grows linearly with elapsed time at each part's ppm rate: a bare crystal (±50 ppm ≈ 4.3 s/day) blows past the ±1 min band within days,…
Figure 5.1 — Timebase accuracy ladder. Accumulated clock error grows linearly with elapsed time at each part's ppm rate: a bare crystal (±50 ppm ≈ 4.3 s/day) blows past the ±1 min band within days, a TCXO RTC (±2 ppm ≈ 0.17 s/day) stays near the ±1 s band, and a GPS/NTP-disciplined timebase (PPS) holds essentially flat. Diagram: project original.

5.2 Generating X and Y: a DAC per axis

A vector display has no pixels and no frame buffer in the raster sense. The “image” is a pair of voltages — one for horizontal deflection, one for vertical — and changing those two voltages over time is the drawing. So the firmware’s most basic output primitive is “put the beam at coordinate (x, y),” and that means handing two numbers to two digital-to-analog converters, one per axis, whose outputs feed the deflection amplifiers of Vol 4.

5.2.1 The OSC4.4 approach: a dual 8-bit DAC

On the OSC4.4 the brain is a PIC18F26K20 (the 28-pin part at U1), and the X/Y DAC is a dual 8-bit converter of the 7528 class (the 20-pin part at U3 — a DAC7528-family device that packs two independent 8-bit channels, one for X and one for Y). A small 8-pin 12F629 at U6 acts as a shifter that moves the dot around during bring-up and testing, and two 8-pin parts of the 4132 class at U4 and U5 complete the analog front end between the DAC and the deflection stage. The published bring-up sequence is a beautiful illustration of the signal chain because you build it up one stage at a time: jumper two pins of U1 to force a single static dot on the screen; insert the two 4132 parts at U5/U4 and the dot survives; insert the 12F629 at U6 and the dot starts moving (proof the shifter is alive); finally insert the 7528 DAC at U3 and the PIC at U1, press S2 once, and a complete clock face appears.

Eight bits per axis means each coordinate is an integer 0–255, so the addressable grid is 256 × 256 = 65,536 distinct beam positions. That is the single most consequential number in the whole drawing architecture, because it sets the granularity of every line, arc, and character:

8-bit DAC, full-scale deflection across (say) a 60 mm usable screen width:
  step size  = 60 mm / 256  ≈ 0.234 mm per code
  diagonal   = 256 codes corner-to-corner  →  visible "staircase" on slow diagonals

Consequence: straight horizontal/vertical strokes are clean (one code = one row/col),
but diagonals and curves are quantised — the classic vector-DAC "jaggies." Smoothness
is bought with MORE codes (more DAC bits), not with cleverer software.

A 256-step axis is plenty for blocky digits and recognisable hands, and it keeps the data small and the update loop fast, but it is visibly stepped on shallow diagonals and on the flanks of large characters. This is the deliberate trade the OSC4.4 makes: an 8-bit point-stepped design is cheap, simple, and fast, at the cost of obvious quantisation.

5.2.2 The Dutchtronix / R-2R approach

The classic Dutchtronix AVR Scope Clock (the other owned unit, covered in Vol 7) takes a philosophically identical but cheaper-still path: instead of a dedicated DAC chip it builds an 8-bit R-2R resistor-ladder DAC on each axis, driven straight from an AVR output port. An R-2R ladder needs only two resistor values (R and 2R — e.g. 500 Ω and 1 kΩ) and about 16 resistors per channel to weight eight digital bits into an analog voltage. It is the same 256-level grid as the 7528, just made of passive parts hanging off the microcontroller’s GPIO. The NYC Resistor vector-display write-up documents exactly this — two 8-bit R-2R DACs wired to a Teensy’s PORTB and PORTD — and notes the alternative of a dedicated current-output DAC such as the MC1408/MC1508 if you prefer a chip. Either way the resolution is the same; the R-2R version simply trades board area and a resistor count for not buying a converter.

5.2.3 The 12-bit lineage and what extra bits buy

The Nuts & Volts Arduino Graphics Interface (AGI) design shows what happens when you spend more bits. It uses the two on-chip 12-bit DACs of the Arduino Due’s ATSAM processor, giving a 4096 × 4096 grid — sixteen times finer per axis than the 8-bit clocks. The author measured the Due’s DAC output at 0.5 V for code 0 and 2.75 V for code 4095, i.e. a 2.25 V span over 4096 steps, or about 550 µV per code. At that granularity the staircase on a diagonal is far below what the eye or the CRT spot size can resolve, and the article’s own summary is blunt about the payoff: 12-bit DACs “beautifully render smooth step-free lines, arcs, and characters.” The lesson for a builder choosing an architecture is direct — effective on-screen resolution is set by DAC bits first and everything else second. Eight bits is enough to read the time; twelve bits is enough to make it pretty.

Figure 5.2 — DAC resolution sets how finely the beam can be placed. The same numeral "2" drawn on a coarse 256×256 grid (8-bit DAC, 1/256 of full screen) shows stepped jaggies, while the fine 4096×…
Figure 5.2 — DAC resolution sets how finely the beam can be placed. The same numeral "2" drawn on a coarse 256×256 grid (8-bit DAC, 1/256 of full screen) shows stepped jaggies, while the fine 4096×4096 grid (12-bit DAC, 1/4096 of full screen) renders it smoothly. Diagram: project original.

5.3 The draw loop: turning shapes into a beam path

Having a way to place the beam at (x, y) is not yet a clock. The firmware needs (a) a description of the face as a set of shapes, (b) a renderer that turns each shape into an ordered list of points the beam visits, and (c) a loop that pushes that list to the DACs over and over, blanking between strokes. This is the heart of vector-drawing firmware, and it is organised as a layered library in every mature design — for example the Sgitheach code splits cleanly into crt.*/crtasm.S (the lowest layer that bangs the DACs and blanking), draw.*/font.* (lines, circles, characters, scaling, kerning), and faces (the dozen-plus clock-face styles, from Roman and digital to Klingon and a Pong game).

5.3.1 Shape lists and the vector font

The face is stored as data, not code: a list of strokes, where each stroke is a move (beam off) to a start point followed by a draw (beam on) to an end point, or a parametric shape (circle, arc, ellipse) the renderer expands into many short segments. Characters come from a vector font, the same idea the old Hershey fonts pioneered: each glyph is a tiny list of relative coordinate pairs, with sentinel values marking “lift the beam and jump” and “end of glyph.” The NYC Resistor implementation stores each glyph as a path_t {int8_t x, y} array of at most 32 points held in program memory (PROGMEM), using (-1, 1) to mean pen-up move and (0, 0) to mean end of character:

glyph '1' (illustrative):
   ( 2, 0)  move/draw points, beam ON between consecutive draw points
   ( 2, 8)
   (-1, 1)  -> pen up: next point is a jump, beam OFF
   ( 0, 6)
   ( 2, 8)
   ( 0, 0)  -> end of glyph

The renderer walks the glyph, converts the relative coordinates to absolute DAC codes via the current scale/position, and emits the point list. Scaling and kerning are just arithmetic on those relative coordinates, which is why a vector font can be drawn at any size without the blockiness a bitmap font would show.

5.3.2 Three ways to draw the same minute

A scope clock can render the time in fundamentally different visual idioms, and they put very different loads on the draw loop:

StyleWhat is drawnBeam-path costNotes
Analog handsthree radial lines from centre + a tick ringlow (few long strokes)classic; hands are just drawLine from the hub
7-segment / vector digitsglyph strokes from the vector fontmediumcrisp, readable; cost scales with character count
Sine-wave seconds sweepa moving dot or a swept analog arcvery lowsmooth motion without stepping a hand each second

Analog hands are cheap to draw — a hand is one long line, computed as the endpoint of a vector at the current angle — but a thin one-pixel-wide hand can look faint (more on that in § 5.4). Vector digits cost more strokes but read instantly. The seconds sweep is the showcase of the sin/cos school (§ 5.5): instead of jumping a hand to a new tick each second, the beam glides along an arc, which both looks elegant and sidesteps the quantisation of a stepped hand.

5.3.3 Stroke ordering, beam settling, and Z-blanking

Given a pile of strokes, the order you draw them in matters, because every time the beam jumps from the end of one stroke to the start of the next it has to slew across the screen, and during that slew two bad things can happen: the deflection amplifier takes finite time to settle at the new coordinate, and if the beam is left on during the jump you get a bright retrace line smeared across the face. Both are cured by the same three habits:

For each stroke in the (ordered) face list:
    Z := BLANK                     ; beam OFF
    set DAC_X, DAC_Y := stroke.start
    wait settle_delay              ; let deflection amp arrive (the "beam-settling delay")
    Z := UNBLANK                   ; beam ON
    for each segment to stroke.end:
        set DAC_X, DAC_Y := next_point
    Z := BLANK                     ; beam OFF before the jump to the next stroke

Three things to notice. First, the beam is blanked across every jump (the Z line) — without this, the screen fills with a web of retrace lines between every stroke. The AGI design generalises this: it blanks the beam, moves to the new point, waits for the DACs and sample-and-hold to settle, then unblanks for exactly the dwell of that point, which it calls the SHOW_POINT pulse. Second, you order strokes to minimise total jump distance — drawing the twelve hour-ticks in angular order, and grouping a digit’s strokes together, keeps the beam from flinging corner-to-corner and reduces both wasted settling time and any residual smear. Third, there is an irreducible beam-settling delay after each large jump; the AGI author measured the Due’s DAC full-scale slew at about 300 ns and found that pushing point updates faster than ~800 kHz let the amplifier’s own settling lag distort points whenever consecutive list entries were far apart. The settling delay is the tax you pay for moving the beam a long way, and it is the hidden reason stroke ordering is a performance feature and not just tidiness.

5.3.4 The refresh / flicker / brightness budget

All of the above happens inside a hard real-time loop: the entire face must be redrawn fast enough to fuse via persistence of vision, which for most viewers means a refresh rate of about 50–60 Hz or higher. That is the budget every design is spending. There is a three-way tension:

  • More objects on the face = more points per frame = longer to draw one frame = lower refresh rate = flicker once you drop below the fusion threshold.
  • Faster point rate buys back refresh headroom, but the DAC slew and amplifier settling cap how fast you can step points (the AGI’s ~800 kHz / ~300 ns ceiling).
  • Brightness competes for the same time: a point is only as bright as the dwell time the beam spends on it, so making the face brighter by dwelling longer also slows the frame.

A clever twist seen in the Sgitheach and AGI designs is to synchronise the refresh to the AC mains — one full redraw per mains cycle, i.e. every 20 ms at 50 Hz or 16.66 ms at 60 Hz (50 or 60 frames per second). This is not about flicker per se; it is about image stability. Stray 50/60 Hz magnetic fields from nearby transformers wobble the beam slightly, and if the redraw is asynchronous to the mains that wobble crawls around the screen and the image appears to “swim.” Lock the redraw to the mains (the Sgitheach uses a mains-derived external interrupt; the AGI uses a 20 ms refresh timer) and the wobble is frozen in place where the eye ignores it.

5.4 Anti-flicker and beauty tricks

Flicker is the enemy, and brightness is its currency, so most of the firmware craft in a scope clock is about spending the refresh budget wisely. A handful of techniques recur.

Variable brightness without a brightness control. On a binary-blanked display (beam is either full-on or full-off, as on the OSC4.4 and AGI), you cannot make one stroke dimmer than another by lowering its voltage — there is no grey. Instead you modulate dwell/point-density: a feature drawn from more closely spaced points, or drawn more than once per frame, glows brighter because the beam spends more time there. The AGI relies exactly on this — “variable brightness is easily achieved by varying the point-density of the dots that make up each graphic feature.”

Multi-orbit drawing proportional to path length. The sin/cos school formalises this. A long line and a small circle, drawn once each per frame, would glow at different brightnesses because the beam spends a different fraction of the frame on each. The Sgitheach firmware computes each object’s path length — πD for a circle, √(A² + B²) for a line, the Ramanujan approximation π[3(A+B) − √((3A+B)(A+3B))] for an ellipse — and draws each object a number of times (“orbits”) proportional to that length, so every shape ends up with the same brightness per frame regardless of size. (It keeps these lengths as 16-bit signed integers, which is plenty for a 256-grid face.) This is “method 1” of two brightness-equalising schemes; the alternative is to vary the orbit frequency (how fast the dot traverses the shape) instead of the orbit count.

PWM beam-current modulation. Where the hardware supports a true analog intensity input (a Z amplifier that can do more than blank — see Vol 4), the firmware can PWM the beam current per segment, giving real greyscale and another lever on the brightness-vs-time trade.

Octant character drawing. David Forbes’ design (the ancestor of the Sgitheach clock) draws characters out of circle pieces by splitting a circle into 8 octants and selectively blanking the ones it does not want. A numeral is then assembled from a few straight strokes plus a few lit octants of an arc — the Sgitheach notes give the numeral “5” as a horizontal line, a +slope line, and octants 1–5 and 8 of an arc. This produces rounded, smooth-looking digits from a sin/cos beam without a stroke font at all.

Dot fonts vs vector fonts. A character can be a cloud of dots or a set of strokes. Dot characters are trivial to draw and can be made arbitrarily bright by point density, but look coarse; vector/stroke characters look crisp but cost more beam-jumps. The choice is a direct flicker-vs-legibility trade and depends on how many characters share the frame.

Why too many objects flickers — the arithmetic. All of these tricks exist because the frame budget is finite. The next section makes the budget concrete.

Figure 5.3 — The octant character scheme. Characters are built from a fixed stroke library indexed by octant: a circle is split into eight numbered 45° wedges and each glyph lights a subset. The nu…
Figure 5.3 — The octant character scheme. Characters are built from a fixed stroke library indexed by octant: a circle is split into eight numbered 45° wedges and each glyph lights a subset. The numeral "5" is a horizontal top bar plus a positive-slope diagonal that sweeps octants 1–5 and 8, leaving octants 6 and 7 dark. Diagram: project original.

5.5 Open-source firmware lineage

A builder does not start from a blank page; there is a well-trodden family tree of scope- clock firmware, and the two owned units sit on two different branches of it.

The point-stepped branch (Dutchtronix → OSC4.4 → AGI). This branch treats the screen as a grid of addressable points and steps the beam from point to point through per-axis DACs (8-bit on the older clocks, 12-bit on the AGI). The Nuts & Volts Arduino Graphics Interface articles (Edward Andrews, Parts 1 and 2) are the most thoroughly documented modern example: Part 1 builds the hardware (the dual on-chip DACs, sample-and-hold to align the X and Y conversions, and the Z-blanking logic), and Part 2 introduces the XYscope library that renders POINT / LINE / RECTANGLE / CIRCLE / ELLIPSE / ARC and text into a display list of up to ~15,000 points. This branch’s signature artefact is the display list: build an array of XY integers, and a background process (DMA on the Due) streams it to the DACs. It is also the branch that makes a CRT happily render not just clock faces but arbitrary vector graphics and games — the NYC Resistor vectorscope project famously ports Asteroids and Spacewar! to exactly this kind of XY display, because once you can draw an ordered list of lit segments, a clock face and a vector game are the same problem.

The sin/cos branch (David Forbes → Sgitheach Scope Clock II). This branch refuses the staircase entirely by generating motion analogically. Instead of stepping a DAC through 256 codes to approximate a circle, it feeds the X and Y deflection with B·cos(φ) and A·sin(φ) — a true Lissajous circle — so circles and arcs are mathematically smooth at any size. The Sgitheach Scope Clock II (Grahame Marsh, derived from Forbes’ cathodecorner.com design) uses an ATmega1284P at 22.1184 MHz as the main processor and a small ATtiny26 at 16 MHz doing nothing but generating the ~32 kHz sin/cos square waves; a 4052 analog switch selects the shape, an AD7304 quad multiplying DAC sets size and offset (its multiplying inputs let the same DAC scale the sine reference), and adder stages combine the swept sine with the X/Y offset to position the shape. Lines come from running x = B·sin(φ) against y = A·sin(φ) (a degenerate Lissajous that collapses to a line), and slope is chosen by phase: +slope uses B·sin(φ), slope uses B·sin(φ + π). Characters are the octant scheme of § 5.4. The price of all this smoothness is hardware complexity and an assembly-language inner loop (the sine/ directory is hand-written ASM); the reward is a face with no jaggies anywhere.

Shared ancestry. Both branches share the lower-level ideas this volume has already covered: a vector font of relative coordinates (Hershey-style), Bresenham’s line algorithm for diagonal strokes on the point-stepped branch (the NYC Resistor code carries a full C implementation), mains-locked refresh, and Z-blanking across jumps. A builder picking a codebase to start from is really picking a branch: point-stepped if you want simplicity, display-lists, and games; sin/cos if you want analog-smooth curves and you are comfortable with more analog hardware. Roll-your-own from the open-source crt-driver lineage is Vol 10’s subject; the firmware that ships on the two owned units is detailed in Vol 7 (Dutchtronix) and Vol 8 (OSC4.4).

5.6 DAC resolution and update-rate math

It is worth doing the arithmetic that the previous sections kept gesturing at, because the numbers decide what a given design can actually put on screen without flicker. Two numbers govern everything: the point rate (how many beam positions per second the hardware can reliably output) and the refresh rate (how many full redraws per second you need for flicker-free viewing).

Definitions:
  Rp  = point rate            (points / second the DAC + amp chain can sustain)
  Rf  = refresh rate          (frames / second, must be >= ~50 for fusion)
  N   = points in the face    (sum of all stroke segments + character points)

Core relation:
  points available per frame  =  Rp / Rf
  flicker-free  requires      :  N  <=  Rp / Rf

Worked example (AGI / Arduino Due, point-stepped):
  Rp  = 800,000 points/s      (measured DMA_CLK ceiling before DAC slew distorts)
  Rf  = 50 frames/s           (one redraw per 20 ms mains period)
  N_max = 800,000 / 50        =  16,000 points per frame  (theoretical)
  Observed: clean to ~10,000 pts; flicker onset noticeable past ~12,000 pts
            (phosphor decay + DAC settling eat the difference)

Effect of more objects:
  add a second full clock face (double N) at fixed Rp:
      Rf = Rp / N  =  800,000 / 20,000  =  40 Hz   -> below ~50 Hz fusion -> FLICKER
  => the firmware must either thin the face, raise Rp, or accept flicker.

That last block is why too many objects flickers: refresh rate is just point rate divided by point count, and once you cross below the fusion threshold the eye sees the redraw. The brightness tricks of § 5.4 make the problem worse, not better — drawing an object multiple orbits to brighten it multiplies its contribution to N. So the budget is genuinely three-way: legibility (enough points to read), brightness (enough dwell/orbits to see), and flicker (enough refresh to fuse), all competing for one fixed point-rate. Spending more DAC bits (§ 5.2) buys spatial smoothness but not temporal headroom; only a faster point rate or a thinner face buys back refresh. This is the single most important design intuition in scope-clock firmware, and it is the reason the simplest readable faces — a few hands, a tick ring, maybe a digital readout — are also the most rock-steady ones.

Figure 5.4 — Refresh rate vs point count. With a fixed point rate Rp = 800 kHz, the frame refresh Rf = Rp / N falls as a hyperbola in the points-per-frame N: drawing 10 000 points yields 80 Hz and …
Figure 5.4 — Refresh rate vs point count. With a fixed point rate Rp = 800 kHz, the frame refresh Rf = Rp / N falls as a hyperbola in the points-per-frame N: drawing 10 000 points yields 80 Hz and 12 000 points yields ~67 Hz, but the curve drops below the 50 Hz flicker-fusion threshold once N exceeds 16 000. Diagram: project original.

5.7 References (Vol 5)

  • Assembly Instructions for OSC4.4 — IC complement (U1 PIC18F26K20, U3 7528-class dual 8-bit DAC, U6 12F629 shifter, U4/U5 4132-class), bring-up sequence, GPS/Wi-Fi module options. 02-inputs/OSC4_4 (I have this)/AssemblyInstructionsForOSC4.4.txt.
  • Grahame Marsh, Scope Clock Sin Cos (Sgitheach), derived from David Forbes’ cathodecorner.com design — ATmega1284P + ATtiny26 sin/cos generation, AD7304 multiplying DAC, DS3232 TCXO RTC, octant characters, multi-orbit brightness, path-length math, mains- locked refresh. 02-inputs/Scope Clock Sin Cos - Sgitheach.pdf. https://www.sgitheach.org.uk/
  • Vector Display Introduction (NYC Resistor) — 8-bit R-2R ladder DACs, MC1408/1508 alternative, Bresenham lines, Hershey/PROGMEM vector fonts, Z-blanking, beam-dwell artefacts, Asteroids/Spacewar vector ports. 02-inputs/PDF Resources, Ideas, and Schematics/Vector Display Introduction » NYC Resistor.pdf. Project source: https://bitbucket.org/hudson/vectorscope
  • Edward Andrews, The Arduino Graphics Interface — Parts 1 & 2, Nuts & Volts — Arduino Due dual 12-bit on-chip DACs (4096×4096, ~550 µV/code, ~300 ns slew, ~800 kHz point rate), DMA display list (~15k points), sample-and-hold X/Y alignment, Z-blanking (SHOW_POINT), 20 ms mains-locked refresh, XYscope library. 02-inputs/Arduino XY Graphics Interface/.
  • Maxim/Analog Devices DS3232/DS3231 datasheet — temperature-compensated crystal oscillator (TCXO) RTC, ~±2 ppm 0–40 °C, 1 Hz output. (Manufacturer datasheet.)