Numitron · Volume 4
Timebase & Logic
The PIC16F876A brain, the two crystals, the interrupt/timer architecture, EEPROM persistence, and the 60-LED ring multiplex
Vol 3 dealt with the muscles of the Numitron clock — the CD4511 decoder/latches that heat the filaments, the shift register that fans control out to six of them, the reason a filament refuses to be multiplexed. This volume is about the brain and the clock in the literal sense: the single eight-bit microcontroller that runs everything, the two crystals that give it both a heartbeat and an accurate sense of time, the interrupt and timer machinery that lets one small chip appear to do six things at once, and the way that brain drives the other display in this clock — the ring of sixty LEDs that is everything the Numitrons are not. Where the tubes cannot be multiplexed, the ring is multiplexed to the hilt. Holding both ideas in one design is exactly what makes the worked build instructive, and this volume is where the two strategies meet.
Everything here is grounded in Bill van Dijk’s Nuts & Volts six-digit clock — the
construction article, the user manual’s “Geek Info” section, and the MPASM firmware source
(60L-Numitron.asm, version 3.2, December 2015) held in this hub. Where the article and
the firmware comments disagree on a detail, the firmware wins, because the firmware is what
actually runs.
4.1 The brain: a Microchip PIC16F876A
The “brains” of the clock is a Microchip PIC16F876A — an eight-bit microcontroller from the long-lived PIC16F family. In the designer’s words it “is a very busy fellow in this project; it’s in control of everything happening on the board.”1 That is not marketing: a single 28-pin PIC, with no support logic beyond decoders and drivers, is the only active intelligence in the clock. It keeps the time, decodes and dispatches each Numitron digit, animates sixty LEDs, debounces nothing (that is done in hardware — Vol 3), reads two buttons, and remembers your preferences across a power cut.
A few facts shape everything downstream:
- Eight-bit core, ~5 V logic. The PIC’s I/O swings the same 0–5 V the rest of the clock runs at, which is the whole reason a Numitron clock needs no level translation anywhere: the microcontroller, the CD4511 decoders, the CD4017 counter, the ULN2803 array, and the LEDs all live on one 5 V rail (Vol 5 covers the LM2575 buck supply that produces it).
- Three I/O ports, every pin spoken for. PORTA, PORTB, and PORTC carry the lamp-test and blanking lines, the 74HC164 serial data and clock, the CD4017 clock and reset, the four-bit BCD bus, the eight LED row drives, the two button inputs, and the two crystal oscillator pins. The designer notes he was “rapidly running out of ports,” which is precisely why the Numitron digits are addressed through a shift register and the LED ring through a counter rather than wired one-pin-per-output (Vol 3).1
- SO28 surface-mount in this build. The bill of materials calls for the
PIC16F876A-I/SO— the wide SO28 (SOIC) surface-mount package — to match the board’s surface-mount aesthetic, the same reason the CD4511s were chosen in SMD.2 A DIP-28 variant of the same die exists and is electrically identical; if you re-spin the board for through-hole parts, it drops straight in.
4.1.1 Programming it: ICSP, PICkit 3, MPLAB IPE
The PIC is programmed in-circuit, through the board’s ICSP (In-Circuit Serial
Programming) connector — the five-pin angled header JP3 in the parts list.2 The
designer uses a PICkit 3 programmer driven by MPLAB IPE (Microchip’s Integrated
Programming Environment), the same toolchain that ships free with MPLAB X.1 In-circuit
programming matters here because the chip is a surface-mount part soldered to the board:
there is no socket to pull it from, and “programming SMD devices off-board often requires a
special adapter.”1 ICSP sidesteps that entirely — you flash the soldered-down chip in
place over five wires (clock, data, VPP/MCLR, VDD, VSS).
Vol 5 walks the flash-and-verify step; the production 60L-Numitron.hex and the MPASM
source are both in this hub, so you can either flash the released firmware as-is or rebuild
it from source.
4.2 Two crystals, two jobs
The most important sentence in this entire volume is the designer’s own warning, and it is worth stating before anything else: the 32 kHz watch crystal is the critical part for clock accuracy — do not use an unknown or salvaged one.1 Understanding why the clock carries two crystals, and why one of them is sacred, is the heart of the timebase.
The PIC runs two independent oscillators at once:
- A 4 MHz system crystal (
X1) on the main oscillator pins. This is the microcontroller’s heartbeat — it clocks the CPU, sets how fast instructions execute, and times all the fast housekeeping. It does not need to be especially accurate; a 4 MHz crystal a few hundred ppm off makes no visible difference to a clock, because the time is not derived from it. - A 32.768 kHz watch crystal (
X2) on the PIC’s Timer1 oscillator pins (RC0/RC1 in this design). This is the accurate timebase — the part that actually decides whether the clock gains or loses seconds over a week.3
This split — a fast, sloppy system clock plus a slow, precise timekeeping clock — is the standard architecture for any microcontroller clock, and the PIC16F family supports it directly: Timer1 has its own low-power oscillator designed expressly to be driven by a 32.768 kHz tuning-fork crystal while the main CPU clock runs from something faster.
4.2.1 Why 32.768 kHz is the magic number
A watch crystal is cut for 32.768 kHz for one beautiful reason: 32768 = 215. Feed those pulses into a binary counter and divide by two fifteen times and you arrive at exactly 1 Hz — one tick per second — with no fractional remainder and no rounding error to accumulate. Every quartz wristwatch on earth uses this crystal for exactly this reason.
The PIC reaches 1 Hz the same way, using Timer1 as a 16-bit divider. Timer1 counts up; when it rolls over from 0xFFFF it generates an overflow interrupt. The trick is to preload the count so the overflow lands precisely one second later:
Timer1 clock: 32 768 Hz (= 2^15 Hz, from the watch crystal)
Timer1 is 16-bit: rolls over after 65 536 (2^16) counts
Preload value: 65 536 − 32 768 = 32 768 → load 0x8000
Counts to overflow: 65 536 − 32 768 = 32 768
Time to overflow: 32 768 counts ÷ 32 768 Hz = 1.000000 s
So Timer1 is preloaded with 0x8000 at each reload, counts 32 768 crystal cycles, and
overflows once per second on the nose. The firmware’s own note records the intent exactly:
“TMR1 Clock time base xternal 32.768kHz xtal for 1 sec overflow.”4 Every second-hand
advance in the whole clock hangs off that one interrupt.
4.2.2 The two 12 pF load capacitors — matched, or the clock is wrong
A quartz crystal only oscillates at its rated frequency when it sees the load
capacitance it was cut for. The clock places two 12 pF ceramic capacitors (C16,
C17) across the 32.768 kHz crystal, and the designer is emphatic that they “determine its
frequency accuracy, and must be matched with the part.”1 Get them right and “accuracy
of one second per day or less is possible.” Get them wrong — or substitute a mystery
salvaged crystal whose load spec you do not know — and the clock will drift, steadily and
unfixably in software.
One second per day is a useful number to feel the size of. There are 86 400 seconds in a day, so:
1 s/day = 1 / 86 400 ≈ 1.16 × 10⁻⁵ = 11.6 ppm
That is the accuracy you are buying with two correctly matched 12 pF capacitors and a known-good watch crystal — about a part in a hundred thousand, or under half a minute a month. The build article makes the dependency explicit: “If you use a different crystal than listed, be sure to change the load capacitor values to the specification of your part.”1 This is the single calibration-sensitive decision in the whole build, and Vol 5 returns to it at power-up.
4.3 The interrupt and timer architecture
The PIC16F876A carries three hardware timers — two 8-bit (Timer0 and Timer2) and one 16-bit (Timer1) — and each can raise an overflow interrupt.1 This clock uses all three at once, and the elegance of the design is that each timer owns one job and runs independently of the others. The firmware’s header lays the assignment out plainly:4
Table 1 — 4.3 The interrupt and timer architecture
| Timer | Width | Job in this clock | Fires |
|---|---|---|---|
| Timer0 | 8-bit | Numitron display sequencing — schedules digit updates | periodically, fast |
| Timer1 | 16-bit | Timekeeping base — the 32.768 kHz / 1 Hz heartbeat | once per second |
| Timer2 | 8-bit | LED-ring sequencing — drives the multiplex and the animation | variable rate (see 4.3.1) |
The payoff is that the slow, sacred one-second tick (Timer1) is completely decoupled from the fast, busy display work (Timer0 and Timer2). The clock never “loses time” because it is busy painting LEDs: timekeeping is an interrupt that interrupts everything else. Meanwhile the CPU itself runs at 4 MHz, which on a PIC means an instruction cycle of Fosc/4:
Instruction cycle = 4 MHz ÷ 4 = 1 MHz → 1 µs per instruction
The designer puts the same number in plain English in the user manual: the chip “can do 1,000,000 individual things each second.”5 That budget — a million instructions a second — is what buys the illusion that one chip drives six tubes and sixty LEDs simultaneously.
4.3.1 Timer2’s trick: the PR2 period register
Timer0 and Timer1 are free-running — they always count the full way to overflow. Timer2 is different, and the difference is the key to the LED animation. Timer2 has a dedicated period register, PR2: instead of counting all the way to 0xFF, Timer2 resets (and fires its interrupt) when it reaches whatever value you have written into PR2. Change PR2 and you change the timer’s period on the fly, without stopping or reloading the timer.1
The clock uses this to make the flying-dot LED animations breathe. In several patterns a lit “dot” travels around the ring, filling it one position at a time as the minute progresses; at the 60-second mark the ring is full and resets for the new minute. But the dots do not move at a constant rate: “The dot at the start of the minute must make 60 steps to reach the end, and each subsequent dot makes one step less than the previous one. That means the timing of each step changes with each subsequent second.”1 Rather than compute that timing live, the firmware stores the per-step period values in a lookup table and writes the next one into PR2 for each step — so Timer2’s interval marches through the table, and the animation slows and speeds exactly as designed. The dot positions are likewise held in a lookup table.1 (The eight patterns themselves are catalogued at a high level in 4.6.3 and detailed in Vol 8.)
4.4 Timekeeping logic
With Timer1 delivering one interrupt per second (4.2.1), the timekeeping code itself is almost anticlimactically simple — which is the point. Once a second the overflow handler does the obvious cascade:
- Advance seconds. A seconds counter increments. The LED ring’s “current dot” follows the seconds, which is why the ring fills as the minute passes.
- Roll seconds → minutes. At 60 seconds, seconds reset to zero and minutes increment.
- Roll minutes → hours. At 60 minutes, minutes reset and hours increment.
- Roll hours. The firmware keeps the canonical time as a 24-hour value (
HOURS_24) and rolls it at 24; for display it derives either the 24-hour figure or the 12-hour figure depending on the saved mode.4
12- or 24-hour display is therefore a presentation choice, not a timekeeping one: the clock always counts in 24-hour internally and converts at display time, so switching modes never disturbs the running time. The mode is user-selectable at start-up and saved in EEPROM (4.5).5
The one genuinely clever economy is in how the Numitrons are refreshed. Because the displayed time changes slowly — at most one digit changes per second — the firmware updates only one Numitron digit per second, synchronized to the LED-ring update:
“Since the time only changes every second, only one Numitron digit is updated for each time the LED circle is updated. This made the software easier, and it is still much faster than actually required.”1
There is no need to repaint all six tubes continuously — they are latched (Vol 3), so a digit holds its numeral until the next time it is addressed. Touching one digit per second is both far less work than the CPU can afford and entirely sufficient, which keeps the timekeeping path short and leaves the million-instruction-per-second budget free for the LED multiplex.
4.5 EEPROM persistence
A clock you have to reconfigure every time the power blinks is a nuisance, so the PIC stores the two user preferences — the 12/24-hour mode and the chosen LED pattern — in its internal EEPROM. The user manual states the guarantee in capitals: “THE CURRENT MODE AND PATTERN SETTING ARE NOT LOST EVEN WHEN POWER HAS BEEN OFF FOR AN EXTENDED PERIOD OF TIME.”5 The time-of-day itself is not saved — there is no battery, so the clock asks to be set after a power cut (the start-up flashing-8s state) — but your preferences survive, because EEPROM is non-volatile.
The PIC16F876A’s EEPROM is read through a small bank-switched register dance, and the user
manual reproduces the actual _READ_EEP routine from the firmware as a worked example.5
Annotated:
_READ_EEP MOVF EEP_ADR,W ; put the desired EEPROM address in W
BANKSEL EEADR ; switch to the bank holding EEADR (Bank 2)
MOVWF EEADR ; load the address into the EEPROM address register
BANKSEL EECON1 ; switch to the control bank (Bank 3)
BCF EECON1,EEPGD ; EEPGD = 0 → point at DATA EEPROM (not program memory)
BSF EECON1,RD ; RD = 1 → start the read
BCF STATUS,RP0 ; drop back to Bank 2; the data is ready now
MOVF EEDATA,W ; copy the read byte into W
BANKSEL BANK0 ; return to Bank 0
RETURN
The shape is worth recognizing because it is the canonical PIC16F idiom: select the bank,
write the address to EEADR, clear EECON1’s EEPGD bit to address data EEPROM rather
than program flash, set the RD bit to launch the read, and the byte appears in EEDATA
ready to copy out. The firmware keeps shadow copies of both preferences in RAM
(MODE_12_24 and PATTERN in the variable block) so the running code reads from fast RAM
and only touches EEPROM when a setting actually changes.4 That keeps EEPROM writes
rare — important, because EEPROM cells have a finite write-endurance and there is no reason
to rewrite a setting that has not changed.
4.6 The 60-LED ring multiplex — the opposite strategy
Around the six Numitrons runs a ring of sixty LEDs that animates the passing minute, and it is driven on exactly the principle the Numitrons forbid. Vol 1 and Vol 3 made the contrast the centerpiece of the design: a filament cannot be multiplexed (switch it fast and you only dim it), so every tube gets its own continuous driver; an LED can be multiplexed beautifully (it lights and extinguishes instantly), so sixty of them are run from a handful of pins by lighting only a few at a time, very fast. Two display technologies, two opposite drive strategies, one chip — that is the lesson of this clock.
4.6.1 Seven rows of eight, plus one short row of four
The sixty LEDs are wired as a matrix of seven rows of eight LEDs, plus one additional short row of four — 7 × 8 + 4 = 60.1 The PIC drives one row at a time, presenting one byte (eight bits, one per LED in the row) on PORTB and lighting only that row’s LEDs. Because only one row is ever active, never more than eight LEDs are lit at any instant:
LEDs in the ring: 60
Rows scanned: 8 (seven of 8 + one of 4)
Max lit simultaneously: 8 → duty per LED ≈ 8 / 60 at most, far less per individual LED
At a couple of milliamps per LED, eight at a time is “well within the specifications for the
PIC,” so the row data can be sourced essentially straight from the port.1 The firmware
keeps eight row variables (ROW_1…ROW_8) plus clockwise and counter-clockwise shadow sets
(ROW1_CW…ROW8_CW, ROW1_CCW…ROW8_CCW) so a pattern can be rotated in either direction
just by choosing which set to scan out.4
4.6.2 Persistence of vision makes it whole
Scanning one row of eight at a time would show a crawling band of light — unless you do it fast enough that the eye cannot follow. It cannot. The ring is refreshed far faster than the roughly fifty-to-sixty cycles a second below which the human eye starts to see flicker, so persistence of vision fuses the eight momentary rows into one steady, fully-lit circle. The user manual makes POV the headline trick: “you think you see a whole circle (60) of LEDS. In reality, there are never more than eight max lit at the same time… The trick is to switch them so fast that your eyes (and even many cheap cameras) cannot follow it anymore.”5 Only a high-shutter-speed camera reveals the scan. This is the same perceptual trick behind every multiplexed LED display, every scanning CRT (the Scope-clock deep dive in this hub), and every persistence-of-vision toy.
4.6.3 The row-select chain: CD4017 + ULN2803
Selecting which of the eight rows is active, and sinking that row’s current, takes two support chips working with the PIC:
- The CD4017 decade counter (
IC2) does the row selection. It counts pulses sent from the PIC and steps one of its decoded outputs high for each count, activating the corresponding row. The PIC sends one clock pulse per row (RA4= CLK-4017); after the eighth row the PIC asserts the counter’s reset (RA5= RESET-4017) so the sequence starts over from the first row.14 The counter, in effect, walks the active row around the ring while the PIC feeds the matching row data — and “synchronization of data and row select is controlled in software,” the same software-synchronization principle used for the Numitron shift register in Vol 3.1 - The ULN2803 Darlington transistor array (
IC11) does the current sinking. A PIC pin can comfortably supply one LED, but lighting all eight LEDs in a row means sinking the combined current of the row, which “exceeds the current output capacity of the CD4017.”1 The ULN2803’s eight Darlington pairs sit between the row and ground and sink that combined current on command, so the CD4017 only has to select a row, never to power it. Each Darlington output also includes the array’s built-in flyback protection — useful insurance on any switched load.
The division of labor mirrors the Numitron side exactly: a counter (CD4017) or a shift register (74HC164) chooses which output is active; a current device (ULN2803, or the CD4511’s own outputs) does the driving; and the PIC keeps the two in step in software. Recognizing that one pattern in both halves of the clock is most of understanding the whole board.
4.7 Software scale and structure
The firmware is written in MPASM, Microchip’s PIC assembler, as absolute code (fixed addresses rather than a relocatable/linked build), and it is sizeable for a clock: about 2,300 lines of assembly.15 The split of effort is telling — “Aside from the rather simple section of code that runs the clock, there is a LOT of stuff involved in running the LED displays.”1 The timekeeping is a few dozen lines hanging off the Timer1 interrupt; the bulk of the 2,300 lines is the eight LED patterns and the lookup tables that drive them.
The code is, by the author’s account and by inspection, heavily commented — deliberately so, “to help those who wish to dig further into that aspect of the project.”1 The version history in the source header tracks the patterns being added one at a time (pendulum in V2.2, random/cycle in V2.3, Newton in V3.0, rain in V3.1) up to the released V3.2, with two explicit “clean up code” passes — the marks of firmware that grew feature by feature and was tidied between releases.4
Two structural ideas carry most of the weight:
- Lookup tables for positions and timing. The dot positions around the ring live in one table; the per-step timing values (the PR2 values of 4.3.1) live in another. Animation becomes table-walking rather than live computation — cheap, deterministic, and easy to retune.1
- Shadowed state. The active mode and pattern are held in RAM shadows of their EEPROM values (4.5), and the LED rows are held in dedicated row variables with clockwise and counter-clockwise variants (4.6.1), so the fast interrupt paths read RAM and never wait on EEPROM or recompute geometry.4
4.7.1 The eight LED patterns, in brief
The user manual lists eight selectable behaviors (plus a cycle mode); they are detailed in the project walk-through (Vol 8), but for completeness the menu is: 0 — cycle (the default; randomly changes among patterns 1–7 each hour); 1 / 2 — a single LED running clockwise / counter-clockwise, filling the ring as the minute progresses; 3 — a single LED running clockwise without filling; 4 / 5 — counter-clockwise running/filling variants; 6 — pendulum; 7 — Newton (a Newton’s-cradle motif); 8 — rain.5 Most are built on the one-minute fill cycle whose variable step timing is what Timer2’s PR2 register and the timing lookup table exist to serve (4.3.1). The visual design of each — and the math behind the flying dot — belongs to Vol 8.
4.8 What to carry into the rest of the series
- The clock has two clocks: a 4 MHz system oscillator that runs the program and a 32.768 kHz watch crystal that keeps the time. Only the second one must be accurate, and its two 12 pF load capacitors must be matched to it — that single choice sets whether you reach the one-second-per-day (≈ 11.6 ppm) accuracy the design is capable of. Never fit a salvaged crystal of unknown load. (Calibration at power-up: Vol 5.)
- Three timers, three jobs: Timer1 (16-bit) is the once-per-second timebase; Timer0 schedules Numitron digit updates; Timer2 — with its on-the-fly PR2 period — drives the LED multiplex and steps the animation through a timing lookup table.
- The clock counts in 24-hour internally and converts for display, so 12/24 mode never disturbs the time; both that mode and the chosen LED pattern persist in EEPROM across power loss.
- The two displays in this one clock are deliberate opposites: the Numitrons get six continuous, latched drivers because filaments cannot be multiplexed (Vol 3); the sixty LEDs are run one row of ≤ 8 at a time via a CD4017 + ULN2803, fused into a whole circle by persistence of vision. Understanding that contrast is understanding the board.
The next volume (Vol 5) puts all of this on a workbench: schematic to BOM to PCB fab to surface-mount assembly to flashing the PIC over ICSP to the one calibration step that matters — matching the crystal’s load capacitors.
4.9 References (Vol 4)
- Bill van Dijk, “Build the Numitron — A Six-Digit Clock,” Nuts & Volts, September 2016 — construction manual, user manual, full schematic, Eagle/Gerber board files, IV-9 datasheet, MPASM firmware (
60L-Numitron.asm, V3.2) + production HEX, pattern video. Held in02-inputs/TheNumetron/. - Cross-references: Vol 1 (overview & subsystems), Vol 3 (driving the Numitrons — CD4511, 74HC164, why no multiplexing), Vol 5 (the worked build, flashing, and crystal calibration), Vol 8 (project walk-through — UI and the eight LED patterns in detail).
Footnotes
-
Bill van Dijk, “Build the Numitron — A Six-Digit Clock,” Nuts & Volts, September 2016 — sections “The PIC,” “The LEDs,” “The Numitrons,” and “Software.” Source of: the PIC as system controller; ICSP via PICkit 3 + MPLAB IPE; the 4 MHz system crystal and 32.768 kHz watch crystal; the watch crystal as the critical accuracy part and the warning against salvaged/unknown parts; the two matched 12 pF load capacitors and the ≈ 1 s/day accuracy claim; the two 8-bit timers and one 16-bit timer each generating an overflow interrupt (one per second for time, one for display scheduling, one for LEDs); Timer2’s PR2 register changeable on the fly with timing values in lookup tables; dot positions in a lookup table; one Numitron digit updated per second; preferences stored in internal EEPROM; the 60 LEDs as seven rows of eight plus one short row of four; never more than eight LEDs lit at once; persistence of vision; CD4017 decade counter counting PIC pulses and reset after eight rows; ULN2803 sinking combined row current beyond the CD4017’s capacity; data/row-select synchronization in software; ~2,300 lines of heavily-commented MPASM absolute code. Held in
02-inputs/TheNumetron/. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9 ↩10 ↩11 ↩12 ↩13 ↩14 ↩15 ↩16 ↩17 ↩18 ↩19 ↩20 ↩21 -
Nuts & Volts parts list (same article):
IC1 = PIC16F876A-I/SO(eight-bit Microchip PIC, SO28W surface-mount package, Mouser 579-PIC16F876A-I/SO);JP3five-pin angled ICSP header;X1 = 4 MHzlow-profile crystal;X2 = 32 kHzwatch crystal (Mouser 732-C002RX32.76K-APB);C16 + C17 = 12 pF0805 SMD load capacitors;IC2 = CD4017BEdecade counter;IC4 = SN74HC164Nshift register;IC11 = ULN2803ADarlington array. Held in02-inputs/TheNumetron/. ↩ ↩2 -
The PIC16F876A’s Timer1 has a dedicated low-power oscillator intended for a 32.768 kHz crystal, run independently of the main (4 MHz) oscillator — the standard “fast CPU clock + slow accurate timebase” arrangement for microcontroller clocks. Pin map per the firmware HARDWARE SETUP comments: RC0/RC1 = OSC1/OSC2 for the 32.768 kHz crystal (
60L-Numitron.asm). 32768 = 2¹⁵, so dividing the crystal down to 1 Hz is an exact binary division. ↩ -
Firmware source,
60L-Numitron.asm(Main program), File Version V3.2, December 2015, Bill van Dijk. Header “Notes” assign the timers: “TMR0 Display sequencing / TMR1 Clock time base xternal 32.768kHz xtal for 1 sec overflow / TMR2 LED display sequencing / Main clock crystal 4MHz.” HARDWARE SETUP block documents the port pin map (RA0 = LT, RA1 = BI on the six CD4511s; RA2/RA3 = 74164 data/clock; RA4/RA5 = CD4017 clock/reset; RB0–RB7 = the eight LED rows; RC0/RC1 = 32.768 kHz crystal; RC2/RC3 = hour/minute buttons; RC4–RC7 = BCD bus to the CD4511s). Variable block showsHOURS_24, theROW_1…ROW_8plus…_CW/…_CCWrow shadows, and theMODE_12_24/PATTERNEEPROM shadows. Revision history records patterns added incrementally (pendulum V2.2, random V2.3, Newton V3.0, rain V3.1) to V3.2. Held in02-inputs/TheNumetron/Firmware/. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 -
Nuts & Volts user manual, “Geek Info” section, and the
_READ_EEPEEPROM-read snippet (V3.1, December 2015, Bill van Dijk). Source of: the eight-bit Microchip controller at 4 MHz doing “1,000,000 individual things each second”; ~2,300 lines of MPASM; persistence of vision (the camera-flash analogy) and “never more than eight max lit at the same time”; preferences not lost across extended power-off; the eight LED patterns (0 cycle / 1–2 run-and-fill CW/CCW / 3 run CW / 4–5 CCW / 6 pendulum / 7 Newton / 8 rain); the BANKSEL/EEADR/EECON1(EEPGD,RD)/EEDATA EEPROM read idiom. Held in02-inputs/TheNumetron/. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7