Relay Logic: A Better Memory Cell
While attempting to build a computer out of relay logic, I needed to make a memory cell, mainly to support registers, tiny pieces of memory (each stores one number) at the very heart of a CPU.
Previous Work: D Flip-Flop
Classically, each bit of a register gets stored in something called a 'D flip-flop' (the 'D' is for 'Data').
There are many ways to do this with relay logic, but because relays are expensive, the most desirable designs involve the fewest relays. The best design I found was here (see Figure 1).
This schematic, like all relay-logic schematics, is tricky to understand, and is especially so because it relies on a subtle oddity of the physics of relays: hysteresis. The key point is that relays have two important voltages: a 'set' voltage (where the relay closes if it is open), and a 'release' voltage (where the relay opens if it is closed). These voltages are not the same (see Figure 2, further down).

Figure 1
: D flip-flop schematic presented with the 'Relay Trainer' computer, and ingeniously relying on hysteresis. (Image by me after diagram therein.)Let's suppose the CLK
signal (to be understood instead as the 'write' signal) starts low. K1
switches on, disconnecting the capacitor C1
from the 'latch' side. Thus, in steady state, +12 V flows through resistor R2
and the coil of the 'latch' relay K2
. Because of the drop across R2
, the voltage across the coil is a voltage divider circuit, and experiences a voltage between the 'set' and 'release' voltages of the V23105A5003A201 relay they're using[1]. That is, a voltage both below the 'set' voltage (and so not enough to turn K2
on if it is currently off) while simultaneously a voltage above the 'release' voltage (and so too high to allow K2
to turn off if it is currently on). Thus, K2
is stable in either state—a memory cell!
During this time, the capacitor C1
has been disconnected from the latch—and therefore connected to the data bit D
through R1
. That's an RC circuit, and the capacitor has either charged or discharged according to the value of data D
.
Now consider what happens when CLK
rises. Relay K1
turns off, and capacitor C1
is disconnected from data D
and connected to the intermediate voltage powering the latch relay K2
. If the capacitor is charged (because D
was '1'), the latch relay coil experiences a voltage spike, pushing it over the 'set' voltage and ensuring that K2
is switched on. Similarly, if the capacitor is discharged (because D
was '0'), the coil experiences a downward voltage spike, pushing it below the 'release' voltage and ensuring that K2
is switched off. Thus, data D
is set onto the latch relay K2
. The capacitor voltage then equalizes, and when CLK
goes low again, the cycle can begin anew.

Figure 2
: Set (blue) and release (orange) voltages measured experimentally for the J104D2C12VDC.15S relay. 5 V is separated off by nearly 6σ between the set and release voltages. A benchtop power supply controlled by Python was used to determine these results, sample size of 19. (Experiment / data / image by me.)It is also worth noting that half of K1
isn't used, and so could drive a second latch relay holding a second bit of data. That is, the relay cost is 3 relays per 2 bits (or 1.5 relays/bit). Also, if you don't need Q
, you can use that side of the relay for something else (for example, to switch an LED to indicate the status of the bit).
Issues With the D Flip-Flop
This is all surely quite ingenious. However, the specification is tightly coupled to the relay[2], and one wants to determine optimal values of the components anyway, to get the best performance. I quickly surmised in analysis that the concept of the above design is quite finicky:
First, R1
and C1
should be as small as possible, because that means C1
records the value of data D
faster, and so the clock speed of the circuit can be faster. However, C1
must also be large enough that the voltage spike sustains long enough for the latch relay K2
to switch if necessary: it must hold the voltage up to set, and hold the voltage down to release. At higher clock speeds and larger capacitances, we cannot assume C1
fully charges or discharges. The 'set' and 'release' voltages as well as trip timings of the relay need to be characterized accurately. R2
needs to be selected to produce the voltage that works best both above and below for the capacitor's nonlinear (dis)charge curve. All of this needs an appropriate margin so that it works reliably.
The result of all this is that the design is 'fragile' and must be carefully fine-tuned to work at all. The best way to tackle all this complexity is with constrained numerical optimization, for which I wrote a hacky Python script. However, I was frustrated with the narrow design space, and the resultant relatively low maximum clock speed[3].
A New Memory Cell
So, I tried to do better myself, and I quickly came up with an alternative design (Figure 3). Indeed, this design is, as far as I can tell, better, albeit it doesn't have quite the same semantics as a D flip-flop (I believe it is a gated D-latch, or synchronous SR latch). Also as far as I know, I invented this circuit.

Figure 3
: My schematic for a memory cell. It doesn't have quite the same semantics as a proper D flip-flop (data is captured immediately whenCLK
high, and is saved on a falling edge), but it is significantly simpler and depends less on the physical properties of the relay. (Image by me.)Suppose CLK
is low, and therefore K1
is off. In this state, the output Q
of latch relay K2
connects back to itself through K1
. Observe that K2
is stable in steady state: if K2
is off, then Q
is low and K2
doesn't power itself, and so K2
remains off. Similarly, if K2
is on, then Q
is high and K2
powers itself, and so K2
remains on.
When CLK
becomes high, K1
switches on. This connects data D
to the RC network formed by R1
and C1
, as well as to the latch relay K2
. The capacitor charges or discharges according to the value of data D
. When CLK
falls again, the capacitor powers or doesn't-power K2
until such time as K1
releases, allowing K2
to either power or not-power itself.
Similarly to the previous design, K1
has an unused side, which can be used to drive a second latch relay for an efficient 1.5 relays/bit, and the latch relay offers Q
, which can be replaced with a different circuit (for Mr. Clicky-Clack, I designed it to switch the cathode between red and green for an RGB LED to indicate the bit's status).
The major advantage of this circuit is simplicity, which translates into robustness, which translates into performance. We only really have to care about one side of the range: the 'difficult' case, which is latching in a '1' bit. Capacitor C1
must hold K2
on, through resistor R1
, for the time it takes for K1
to release and connect K2
back to itself. This is straightforward to spec directly, at least in theory. Hysteresis doesn't enter into it because K2
is always clearly on or clearly off; we don't have the delicate balancing of some intermediary voltage between the set and release voltages.
Latching the bit is designed to be a 'release' of K1
, not a 'set', because releasing a relay is faster than setting it, so the demand on the capacitor is less and the switching speed is higher (connecting the pole of K1
to +12 V instead of to ground makes it work on sets, if you really do prefer that).
Yes, R1
does introduce an annoying voltage drop when C1
powers K2
, but R1
does have to be on the right side of K1
to protect against high (dis)charge currents through the capacitor after K2
latches over.
Resistor R1
keeps the (dis)charge current through the capacitor safe. It should be as small as possible, so that the voltage on capacitor C1
changes promptly and so that there's less voltage drop when powering the relay K2
, but R1
must also be large enough to limit current. 240 Ω results in a peak current of 50 mA; at 12 V, this is a power of 0.6 W, so a high-power resistor should be selected[4].
Because the capacitor C1
is only really necessary for holding the voltage in one direction, it can be much smaller than in the previous circuit. Its value is ultimately selected through experiment, as discussed in the following section.
Of Capacitors and Noise

Figure 4
: The voltage across the relay coil with different capacitor sizes when setting a '1' bit and the capacitorC1
has to hold the voltage up through latching. (Images by me.)In the first practical test of the circuit (Figure 4), I found that a much smaller capacitor was needed than theoretical calculations would suggest. Probing with an oscilloscope reveals several important effects. Consider the 'difficult' case, of setting a '1' bit. The capacitor C1
must hold the voltage up while K1
releases, until it can go fully open and K2
can power itself.
(Look, for example, at the 4.7 μF case in the figure.) As soon as K1
opens, we see an immediate voltage drop, because K2
is now being powered from C1
through resistor R1
. The capacitor discharges, holding K2
set, with a voltage well above the 'release' voltage. When K1
fully opens, K2
powers itself and the voltage becomes the nominal +12 V.
The first thing we notice is the noise. The most likely explanation is "switch wiping", which is where a switch is design to deliberately grind the contacts against each other a little bit when flipping to try to keep them clean[5]. At first I thought it was instrumentation error due to my janky antique oscilloscope, but (look e.g. at the 1 μF case) after periods of noise, the capacitor voltage is higher, because it has been charged, slightly. This is repeatable, and practically speaking means we can use a smaller capacitor.
Of particular note is what happens when you use a capacitor C1
that is too small (look e.g. at the 10 pF case). Here, the capacitor is drained, and the inductive property of the relay coil comes into effect. The coil keeps current flowing out of the capacitor, pulling the voltage into a strongly negative spike[6]. Naturally, K2
opens and the final latched value is erroneously a '0'.
Because of the time for the magnetic field of K2
to change and its switch to mechanically disengage, the voltage can actually be lower than the 'release' voltage without the relay disengaging, so long as it's only for a brief moment. The practical effect of this is again that capacitor C1
can be smaller.
It is possible to characterize an RLC circuit mathematically. With my LCR meter and the J104D2C12VDC.15S relay, I got (typical result):
Test Frequency | L [H] | C [nF] | R [kΩ] |
---|---|---|---|
100 Hz | 1.986 | 1272.1 | 01.3421 |
120 Hz | 1.890 | 0929.2 | 01.4472 |
1 kHz | 0.7291 | 0034.69 | 04.425 |
10 kHz | 0.4402 | 0000.5727 | 28.020 |
100 kHz | 0 | 0000.00488 | 89.410 |
It's a pity there aren't more frequencies available, but it seems at least that at low frequencies the result is maybe a bit shy of 2 H[7]. I flatly don't understand the rest of the results. Any electronic component will change with frequency, which is why you probe at different frequencies in the first place. However, this doesn't seem to look like what a coil should do.
I had trouble getting the math of the RLC circuit right, and the known parameters of the circuit weren't matching the experimental results. Combined with the noise phenomenon above, and the availability of experimental data, one should probably not try to get the right answer from theory.
Practically speaking, 1 μF works reliably. The oscilloscope trace shows it's also getting close to the release voltage and the inductance is starting to come into play, so it's probably not good to go much lower.
Back to Electronics Projects.