CASCADE
FROM A VOLTAGE TO A COMPUTER — ARDUINO, ESP32, RASPBERRY PI, FPGA, ASIC
Seventeen chapters tracing one continuous physical chain: a voltage crossing a threshold, a transistor switching, a gate deciding, a flip-flop remembering, a clock synchronizing, a processor executing — up through what actually happens when an Arduino sketch calls digitalWrite(), why an ESP32 is not just 'an Arduino with Wi-Fi,' why a Raspberry Pi can boot Linux and a microcontroller cannot, and why an FPGA or an ASIC sometimes beats a CPU outright. This picks up where THRESHOLD (Common Ground & Basic Logic) left off — that chapter already covers voltage thresholds, the three basic gates, binary numbers, and the adder in depth, so this one starts at the transistor and heads toward real hardware. Scroll to begin.
BEGIN — CHAPTER 01 →A “0” and a “1” are not abstract objects living inside a chip
Every bit a computer handles is, physically, a range of some continuous quantity — almost always a voltage, sometimes a current, a charge, a magnetic domain's orientation, or a light pulse's presence — that engineers have agreed to interpret as one of exactly two logical states. Nothing about electricity itself is binary; a wire's voltage can sit at any value a circuit allows. The '0' and '1' are an interpretation laid on top of that continuum, not a property the physics hands you for free.
THRESHOLD's own first chapter already covers why: a shared ground reference, a LOW band near 0V, a HIGH band near the supply rail, and a deliberately undefined gap between them — the noise margin. This chapter takes that agreement as given and asks the next question: given that a wire only ever carries a continuous voltage, what physical machinery actually forces it to snap toward one of two clean states, cascade after cascade, without drifting into nonsense after the first few stages? That machinery is the rest of this article.
A square wave is not, physically, a square
Draw a '1' followed by a '0' on paper and you get a perfect vertical drop. On a real wire, that transition takes a finite time to happen, because the wire and every gate along it have capacitance that must be charged or discharged first. The result has a measurable rise time and fall time, can overshoot past the target voltage and ring before settling, and only starts moving after a propagation delay from whatever triggered it — all of it governed by ordinary electromagnetic behavior, not by anything specific to computing.
A repeating digital signal is a periodic waveform like any other: it has a frequency, a phase, and — for signals that spend unequal time HIGH and LOW — a duty cycle, exactly the quantity a PWM-driven LED's brightness depends on. Digital design's real achievement is not eliminating this analog mess; it's defining logic thresholds generous enough that the mess never matters, as long as every rise, fall, and settle finishes before the next clock edge asks the wire a question.
Every gate throws away the noise and rebuilds a clean signal
An analog amplifier chain degrades: pass a noisy signal through enough analog stages and the noise accumulates until the original information is gone. A digital chain does not, because every gate performs the same operation on its input: read a fuzzy, slightly-noisy voltage, decide which side of the threshold it falls on, and output a fresh, full-strength HIGH or LOW of its own — regardless of exactly how clean or dirty the input voltage actually was, as long as it landed on the correct side of the threshold.
That regeneration is what lets a modern chip cascade billions of gates without the signal ever visibly decaying — a property no chain of analog stages could match at anywhere near that length. It's also exactly why the noise margin from Chapter 1 has to exist: it's the safety buffer that keeps ordinary electrical noise — a neighboring wire's crosstalk, a power-supply ripple, thermal noise — from occasionally landing on the wrong side of the threshold and regenerating the wrong bit instead of the right one.
One field, one channel, one switch — repeated billions of times
A MOSFET (metal-oxide-semiconductor field-effect transistor) has three terminals that matter here: gate, source, and drain. The gate sits above the channel, separated from it by a thin insulator, and never draws meaningful current — it works purely by electric field. Raise the gate's voltage far enough above the source, and that field pulls charge carriers into the channel underneath it, opening a conductive path between source and drain. Drop the gate voltage back down, and the channel disappears, and the path is broken.
That is the entire mechanism: a control voltage decides whether current can flow between two other terminals. Wire the drain of one transistor to the gate of the next, and a switching event in the first becomes a control signal for the second — one switch's decision physically propagates into the next switch's decision. Every logic gate, every register, every processor on this page is that same three-terminal switch, wired into patterns, repeated somewhere between a few thousand and tens of billions of times on a single chip.
NAND and NOR are the two gates that can build everything else
Modern chips build logic from CMOS (complementary MOS) pairs: for every job, one network of transistors that conducts only when the output should be pulled HIGH (a 'pull-up' network), and a complementary network that conducts only when it should be pulled LOW (a 'pull-down' network) — never both at once, which is exactly what keeps CMOS gates drawing almost no static current. Wire a single transistor of each type gate-to-gate and you get the simplest possible logic: an inverter, output the opposite of the input.
Add one more transistor of each type in the right arrangement and the inverter becomes a NAND or a NOR gate — and it turns out either one, alone, is enough to build every other gate that exists, AND, OR, XOR included, simply by wiring several of them together and feeding some of their own outputs back as inputs. That's what 'functionally complete' means: an entire processor could, in principle, be built from nothing but NAND gates. Real chips use the fuller AND/OR/NOT/XOR family from THRESHOLD purely because it's more convenient to design with, not because anything more is strictly required.
Feed a gate's output back into its own input, and it stops forgetting
Every gate so far is combinational logic: its output depends only on its current inputs, with no memory of what came before. Cross-couple two NOR gates — feed the first gate's output into the second gate's input, and the second gate's output back into the first gate's input — and the circuit becomes sequential logic: it now has two inputs, SET and RESET, and an output, Q, that holds whichever state it was last pushed into even after both inputs return to LOW. That circuit is an SR latch, and it is, physically, the simplest possible memory cell.
A D flip-flop refines the same idea: instead of separate SET/RESET lines, it takes one data input and copies it to its output only at a clock edge, then holds that value steady until the next edge — the building block every register in Chapter 8 is made from. Stack flip-flops side by side and you get a register holding a whole word; feed a register's own output back through an adder into its own input and you get a counter; add more feedback and comparison logic and you get a state machine. Memory, at this level, is never anything more exotic than a loop.
A clock is a synchronization signal, not the source of a computer's thought
THRESHOLD already gives the clock's basic formula, f = 1/T. What matters more than the number is the job the clock actually does: millions of flip-flops across a chip are updated by combinational logic that takes a little time to settle after every change, and if each flip-flop captured its new value whenever it happened to be ready, different parts of the chip would drift out of step with each other within microseconds. The clock edge is a single shared instant, distributed everywhere, at which every flip-flop agrees to capture its input simultaneously — nothing 'happens' between edges except combinational logic quietly settling toward its next answer.
That agreement has real fine print: a flip-flop's data input has to arrive and stay stable for a setup time before the clock edge and a hold time after it, or the flip-flop can enter metastability — briefly settling at neither a clean HIGH nor a clean LOW, like a coin balanced on its edge, before resolving unpredictably a little later. Designers don't eliminate this risk; they bound it, by keeping every signal's arrival time safely inside the setup/hold window and by adding extra synchronizing flip-flops on any signal that genuinely crosses from one clock's timing domain into another's.
A CPU has no idea what “move this object” means. It only knows encoded states.
THRESHOLD already covers how a row of bits becomes an unsigned integer and how two's complement gives it a sign; the same fixed-width pattern, split differently, gives fixed-point fractions, and — via a sign bit, an exponent field, and a fraction field defined by IEEE 754 — floating point, trading some precision for an enormous range. None of these representations mean anything to the hardware beyond 'a pattern of HIGH and LOW wires'; meaning is something software and the programmer supply.
An instruction is itself just such a pattern: an opcode field telling the control logic which operation to perform, and operand fields naming which registers or memory addresses it applies to. A CPU runs each one through the same five-stage cycle — fetch the instruction from memory, decode which opcode and operands it names, execute the operation in the ALU, access memory if the instruction needs to, and write the result back to a register — over and over, at clock speed. Accumulator machines keep one implicit working register; RISC designs (ARM, RISC-V) favor many explicit registers and simple, uniform instructions; CISC designs (x86) allow denser, more varied instructions that do more per fetch. All three run the same fetch–decode–execute cycle underneath.
The difference is how much of the computer lives on one piece of silicon
A microcontroller (MCU) packs a CPU, its own flash memory for program storage, its own RAM for working data, GPIO pins, timers, an ADC, PWM outputs, and communication peripherals (UART/SPI/I²C) onto a single chip, built to run one program, forever, the moment power is applied. A microprocessor (MPU), as used in a single-board computer (SBC), is usually just the CPU and a small set of high-speed interfaces — it depends on external RAM, external storage, and a full operating system loaded from that storage to do anything at all.
That's the entire reason an Arduino feels fundamentally different from a Raspberry Pi within seconds of touching either one: power an Arduino and its one program is running within milliseconds, deterministically, with every pin's behavior traceable straight back to that program; power a Raspberry Pi and a bootloader has to find, load, and hand control to an entire Linux kernel before anything resembling 'your program' can even start. Chapters 10–12 walk both paths in detail.
One line of C++ becomes a real voltage on a real pin — click through every step
digitalWrite(pin, HIGH) reads like a single instruction, but it is a whole chain of physical events, each one built entirely from the previous chapters. This is the single most important demonstration on this page — every layer discussed so far, from transistor to instruction cycle, actually happens, in order, every time this one line runs.
Click through the chain below. The same underlying mechanism, read backward, is exactly how digitalRead() and analogRead() work (a comparator or an analog-to-digital converter, instead of an output driver, reporting the pin's voltage back into a register); PWM is this same GPIO toggling on a hardware timer's schedule instead of software's; an interrupt is a peripheral flagging the CPU the instant a pin's voltage crosses a threshold, instead of the program having to keep asking; and UART, SPI, and I²C are all just agreed-upon timing patterns for toggling and reading pins like this one, fast enough and structured enough that another chip can decode them as data.
Arduino is a programming model. ESP32 is a family of chips.
'Arduino' names an ecosystem — a board layout, a simplified C++ library, an IDE — that can sit on top of very different microcontrollers. 'ESP32' names an actual family of system-on-chip devices from Espressif, most commonly built around one or two Xtensa LX6 CPU cores, that can run the Arduino programming model as one option among several, alongside Espressif's own ESP-IDF framework or a full real-time operating system.
What actually sets an ESP32 apart from a classic 8-bit Arduino board is integration: on-chip SRAM measured in hundreds of kilobytes rather than a few kilobytes, external SPI flash for program and file storage, a full 802.11 Wi-Fi radio and Bluetooth Classic/BLE radio on the same die, hardware DMA so peripherals can move data without stopping the CPU cores to babysit every byte, plus the same GPIO, ADC, PWM, timer, interrupt, UART, SPI, and I²C peripherals a smaller MCU has, just more of them and often more flexible. It's genuinely a small, self-contained computer with radios built in — not merely a bigger Arduino.
Before a Raspberry Pi runs “your program,” it has to become a Linux computer
A Raspberry Pi is a single-board computer, not a microcontroller board: on power-up, an on-chip boot ROM runs first and looks for a bootloader (on a Pi 4 and later, code held in a small SPI EEPROM, replacing the SD-card bootcode.bin older models used); that bootloader reads the device tree and firmware, and finally hands control to the Linux kernel, which mounts a filesystem, starts a scheduler, and only then launches whatever process the user actually wanted — a full stack that has to complete, in order, before anything the user wrote runs at all.
A microcontroller skips essentially all of that: reset runs a few lines of startup code that set up the stack and clear memory, then jumps straight into the program's main loop (or a small real-time operating system's scheduler, at most), often in well under a millisecond. That's the real tradeoff — an MCU trades away an operating system, a filesystem, networking stacks, and a vast software ecosystem in exchange for deterministic timing, genuinely low power, near-instant startup, and direct, unmediated control over its own hardware; an SBC trades startup time and determinism for a real CPU, real memory, and everything Linux brings with it.
Stop treating the microcontroller as a magic black box
The engineering culture behind semiconductor datasheets and application notes — from Texas Instruments, Microchip, STMicroelectronics, and every other silicon vendor — treats every chip as a stack of layers an engineer can move through in either direction: physics, device, circuit, logic, architecture, register, instruction, firmware, application. Reading downward from software explains why a line of code works; reading upward from physics explains why the chip can exist at all. Neither direction is 'more real' than the other.
This is why a real engineer can debug a stuck LED from either end: downward, from 'the application calls a driver, which writes a register, which drives a peripheral, which toggles a transistor, which is just physics'; or upward, from 'this electron behavior enables a switch, which composes into a gate, which composes into a state machine, which composes into a processor, which runs firmware, which runs the application.' Vendors from AVR and PIC to STM32, RP2040, MSP430, and RISC-V-based microcontrollers all sit somewhere on this same stack — different tradeoffs at every layer, never a different set of layers.
An FPGA configures hardware for the problem instead of running instructions
Every CPU so far, from an 8-bit MCU to a desktop chip, computes the same way: a fixed hardware datapath repeatedly fetches and executes a stream of instructions. A field-programmable gate array (FPGA) inverts that relationship — it's an array of configurable logic blocks, programmable routing between them, flip-flops, small memory blocks, and dedicated DSP blocks, and instead of running instructions on a fixed circuit, it configures an actual, fixed circuit shaped around one specific problem, with no fetch-decode-execute overhead at all. Signal processing, software-defined radio, robotics control loops, high-speed interfaces, and scientific instruments reach for FPGAs precisely because a purpose-built hardware datapath can do their one job every clock cycle, deterministically, with nothing else competing for the CPU's attention.
An application-specific integrated circuit (ASIC) takes the same idea one step further and freezes it permanently into silicon: instead of sensor → CPU → software algorithm → result, an ASIC can implement sensor → dedicated hardware pipeline → result directly, often at a fraction of the power and latency. The price is real — design, verification, and mask/fabrication costs that only make sense at high manufacturing volume, a long time-to-market, and the fact that a bug found after fabrication is a bug baked into physical silicon, not a patch. Between a CPU and an ASIC sit DSPs (instruction sets tuned specifically for signal-processing math) and GPUs (thousands of simple cores tuned for the same operation repeated over massive, parallel data) — each one trading generality for exactly the kind of efficiency its target workload needs.
Moving a bit can cost more energy than computing with it
Every switching event in this whole article costs real energy: charging and discharging a gate's capacitance, driving current through a channel, and — at the memory cells from Chapter 6 — reading and writing state. None of that is free, and on a modern chip, the energy to move a piece of data from off-chip DRAM to the CPU core routinely costs far more than the energy of the arithmetic the core then performs on it — a gap that only widens the farther the data has to travel.
That single fact explains an entire layer of computer design most programmers never see directly: a small, fast cache sitting physically close to the CPU core specifically to avoid the expensive trip to DRAM; DMA hardware that moves data between memory and peripherals without waking the CPU core for every byte; dedicated accelerators placed right next to the data they process instead of shipping that data across the chip; and edge computing, which processes sensor data physically near the sensor instead of paying the much larger energy cost of sending it somewhere else first.
An ESP32, a Raspberry Pi, an FPGA, and an ASIC can all be “correct” — for different jobs
Every chapter so far adds up to one practical question: given a task's required computation, latency, power budget, memory, connectivity, and determinism, which architecture actually fits? A tiny MCU blinking an LED needs none of an SBC's power draw or boot time; a battery-powered Wi-Fi sensor node needs an ESP32's radios more than raw compute; a web server needs an SBC's operating system and networking stack far more than deterministic timing.
Machine vision leans on a GPU or a dedicated neural accelerator for its parallel arithmetic, usually riding on an SBC's OS for everything else; high-speed deterministic signal processing leans on an FPGA or a DSP specifically because a general CPU's instruction overhead is the one thing that workload can't tolerate; and a mass-produced, ultra-low-power, single-purpose device is exactly when an ASIC's high non-recurring cost finally pays for itself, amortized across millions of units. Click a task below.
A computer is not separate from physics
Every chapter of this article has been one continuous hierarchy, read forward: physical phenomena become electrical signals, signals become voltage and current, voltage crosses a threshold, a threshold becomes a 0 or a 1, a 0 or a 1 switches a transistor, transistors become logic, logic gains memory, a clock synchronizes it all, a processor — microcontroller, CPU, FPGA, or ASIC — runs a program, and a program makes a decision that finally becomes a physical action in the world again: a motor turning, a display lighting, a radio transmitting.
Read backward, from any application, the same map explains why the application works at all: firmware runs on instructions, instructions execute as register transfers, register transfers are logic, logic is transistors switching, and transistors switching is nothing more than electric fields controlling where charge is allowed to go. There is no point on this map where 'the physics stops and the computer starts.' A computer is an engineered hierarchy of physical state transformations that we have learned, carefully, layer by layer, to interpret as information and computation.
“A computer is not separate from physics. It is an engineered hierarchy of physical state transformations that we have learned to interpret as information and computation.”
CASCADE — CLOSING STATEMENT