Sometimes quantity has a quality all its own

The Numbotron is the culmination of my multi-year effort to build a more practical, impractical computer. The FIBIAC and the Turbo Entabulator were closer to performance art than being real computers. They were hilariously slow, incredibly unreliable, and effectively limited to a single program (despite being ‘programmable’), due to having a mere three counters. The Numbotron changes all that – it’s got more counters, it’s faster, holds more instructions and can run for hours without issue, while preserving and extending the hilariously bad architecture of the previous machines. This machine is a workhorse (or maybe strandbeest?) of amusing computation.

The Specs

This electromechanical marvel is sporting the following:

8 x 3-Digit, Base-10 Counters (equivalent to nearly 80 bits of memory!)

Improved Instruction Drum – can hold up to 20 instructions of 28 bits each (560 glorious, read-only bits)

4 increment/decrement operations per second (!!!)



Giant Green User Input Button – It’s giant! It’s green! It lets the program halt and get input from the operator!

Ignition Key (for the unnecessarily complicated startup sequence)



The Control System

This is probably the most disappointing part of the project for me. As a general rule, I try to keep as much ‘intelligence’ out of my projects as possible. Doing things with a microcontroller or FPGA is always straightforward and simple (and hence not nearly as fun). The actual control loop at the heart of the Numbotron (and the FIBIAC, for that matter) is basically the following:

Step instruction drum until ‘instruction valid’ signal is asserted. Step counters until ‘instruction done’ signal gets grounded (if signal is asserted immediately after step 1, this step is skipped). Step instruction drum until ‘instruction valid’ signal is de-asserted. Go back to 1.

I actually constructed two completely separate electro-optical state machines to do this in a ‘dumb’ way. The actual control loop is slightly more complicated – the counters are driven by 200 step/revolution stepper motors, so to increment/decrement a counter by 1 base-10 digit, the stepper driver needs to see 20 pulses. The instruction drum is driven by a similar (although more powerful) motor, but the drum can actually hold 20 instructions, so it only needs to see 10 pulses to advance to the next instruction. Additionally, since these are real mechanical parts that have things like inertia, there are limits to how fast things can move. To make things even trickier, the ‘valid’ signal from the instruction drum, like all the other signals, is controlled by a SPDT momentary switch on the drum ‘reader’ (and hence suffers from mechanical bouncing and such). The three magnetically-actuated reed switches in each counter similarly suffer from bouncing and ‘centering’ (triggering too early/late) issues.

The basic idea was to use a set of spinning, slotted discs, along with optical break sensors and a handful of latching relays, to generate the needed stepper motor pulses. In theory, this is quite simple. In practice, I spent ~2 years tinkering with different schemes to try to get this to work, and never got it to execute more than 10 instructions without glitching and going off in the weeds. To do this reliably, it turns out, requires a lot more components and wiring than I cared to do (and quickly departed from the ‘simple’ scheme I had initially hoped would work).

This is what failure looks like

I finally got so tired of having this hulking machine not actually working that I just grabbed the arduino I used in the (now-dismembered) FIBIAC, wired up a quick shield for it, and had it running in a day or two. The nice thing about using a microcontroller is that fancy controls are now pretty trivial, so I was able to speed it up by a factor of 4 or so by carefully controlling the pulse sequencing to accelerate and decelerate the motors without losing any steps. Voila! It’s now much faster and more reliable (although now people will read about this and just say “He used an arduino . . . lame!”). Still, I will miss watching the beautiful spinning discs…

Super lame Arduino-based control system w/ custom Numboduino shield

The new control system also benefits from a sweet new control panel. The ignition key powers up the machine, and it can then either be single-stepped for debugging/demo purposes (via the big red button), or set to run continuously (via the toggle switch).

Serious computers need control panels

The Instruction Drum

The card-chain that I used in the FIBIAC, while cute, turned out to be its primary weakness. Reliably reading punch cards is tricky business, and the tight spacing of the pogo pins meant that it could rarely operate for more than half an hour or so before something was off by 1/16″ and some crucial pin didn’t make contact. Slop in the mechanism got worse with more instructions, so despite the theoretically unlimited program length supported by a punch card chain, in practice it turned out it could do either 4 or 12 instructions (with 12 being pretty unreliable). The heavy-duty instruction drum of the Numbotron drastically increases the reliability, while providing space for 20 instructions (and being pretty quick to remove and change/service, if necessary).

A prime-number finding program!

The design of this is vaguely inspired by the ‘micro-program’ drums Charles Babbage envisioned for his analytical engine (although my implementation is closer to the drum in a music box than his was). The best part is that the 3d-printed ‘bits’ can be fairly easily snapped/unsnapped into place to alter the program. The worst part is that a complicated program requires printing out a *lot* of bits. It took ~5 minutes per bit to print out on my Thing-o-Matic! It also took me quite a few tries to get the profile the ‘bit’ just right, so that the alignment of all 28 bits was fairly reliable. An electromechanical system like this suffers from something analogous to ‘bit skew’ on parallel electrical buses, where you need to make sure to sample all of the bits at the same point in their rotation. The drum itself can be adjusted laterally, and the switch array can be adjusted to be closer/further from the drum, as well as adjusted up/down. Once properly calibrated, it actually works pretty well.

From right-to-left, the instruction encoding is:

{RESERVED[2:0],Valid,Zero[7:0],Down[7:0],Enable[7:0]}

The Enable[] and Down[] switches are wired directly to the stepper motor controllers, and control the ‘enable’ and ‘dir’ signals respectively. Since each register grounds an output when it is reading 0-0-0, the ‘zero’ signals allow any subset of the registers to be connected, in wired-OR fashion, to generate the ‘instruction done’ signal. Pressing the Giant Green Input Button will also short the wire to ground, allowing a program to halt and wait for user input (i.e. manually setting a register to be some value) by ensuring that none of the selected registers will be zero.

Memory

The memory uses the same 3-digit electromechanical counter used by the FIBIAC, just in greater quantity. I mean, if it’s only slightly broke, why fix it? All of the counters for this machine were actually printed on the Makerbot Botfarm shortly after I built my FIBIAC machine, as a favor from my friend Bre (the delightful color scheme is actually a result of a miscommunication between a Makerbot support engineer and myself . . . I couldn’t be happier with how it turned out though!).

What can it actually do?



This question frequently comes up when discussing my various projects – the Numbotron is the rare machine from Fenton Heavy Industries that actually is more than a one-trick pony. When initially building this machine, I had a ‘digital difference engine’ in mind as my end-application. The algorithm used by Babbage’s difference engine is quite simple, and since it only requires nicely sequenced addition operations, works beautifully on the Numbotron. With its 8 counters, it can compute 6th-order polynomials with 3-digit accuracy (versus 7th-order polynomials with 31 digit accuracy for Babbage’s real machine). The machine can also compute the fibonacci sequence – for backwards compatibility, of course.

The above programs are fun, but not terribly interesting, as every instruction is executed unconditionally every time the program loops. This machine actually has enough memory that some of it can be devoted to state registers, allowing programs to make use of branch predication to implement flow control. As mentioned earlier, instructions become NOPs if the ‘Zero’ condition is already true when they begin execution, so you can make instructions that look like “if(R0!==0 && R1!==0){do something}” quite easily.

In a beautiful example of this, my coworker JP submitted two programs: The first one finds all of the prime numbers under 1000 (over the course of approximately 30 years), while the second one attempts to prove the Collatz Conjecture for a given number.

Seeing it in action

Here is a video clip of the aforementioned prime-number-finding program in action. Relax to its soothing sounds as you are mesmerized by the spinning wheels!

The Numbotron Challenge – Try programming it yourself!

I like to make my projects as open as possible, but this one is sufficiently physically complicated (and useless) that the odds of anyone else ever building one are quite low. That doesn’t mean others must miss out on the fun though! Download the Numbotron simulator, and get hacking! I’ll post any cool software people come up with here for other people to play with, and if it’s *really* cool, I might even construct a program for the real machine. Physically building a new program drum is actually fairly expensive / time consuming, so I won’t bother for just anything, but you never know.

Instructions for the simulator are in comments at the top of the code. To try out a new program, just copy/paste to replace the initialization code at the top. Have fun!

The Simulator

Numbotron Simulator

Software

Fibonacci Sequence

Difference Engine Emulator

Prime Number Finder

Collatz Conjecture Prover

Other fun ideas for programs that could probably be implemented: