Each key floats over a pressure pad. When the key is pressed, the pad is activated and an electrical signal gets sent to the motherboard (operating system) that the letter is being pressed. The motherboard processes the data, then sends a signal to the monitor, effectively making the letter appear on the screen relative to what key you pressed. That’s how I understand it at least.
Computers run code, but also do input and output, or I/O. There are way too many ways this happens to even summarize. Input devices convert whatever they are doing into numerical information, then code running on the computer interprets it. It then can send data to an output device. These devices use a wide variety of circuits. In the case of a keyboard, there are matrix decoders, shift registers, and others. There are lots of books on computer basics and digital electronics, I’d check one of those out.
Each button is an electric switch. When you press it, it sends an electrical signal. This signal might or might not get processed or modified by the circuitry in the mouse/keyboard.
That signal travels through the wire connecting your mouse or keyboard to your computer.
Whatever plug your mouse or keyboard is plugged into (say, a USB) receives that signal.
Your operating system frequently checks each of the inputs that it’s aware of to check for a signal. It notices that a signal is present and checks which signal is present.
Your operating system checks for programs that are listening for input. (Mechanically, those programs have a loop in them that says “every frame, if the user has pressed the left mouse button then…”). It then sends the input to those programs.
The programs decide what to do with the input. If it’s a word processor, for example, pressing “w” instructs it to add a “w” to the end of the data in your current document. If it’s a video game, pressing “w” might cause it to increase the vertical speed of your character. And so on.
The most basic electrical component of a computer is a transistor. A transistor controls the flow of electrical signal. It can be in an “on” state or “off” state. These two states are binary, where 1 is on (send signal) and 0 is off (no signal).
Now think of how Morse code works. You can tap down or lift up. It can be a short tap, long tap, rapid short taps, long pause between taps, etc. The actual signal is binary, tap or not tap. However, it can be combined in a number of ways to encode a message. As long as the receiver has the same understanding they can decode the message.
Similar to Morse code, a computer can have a lot of controllers, lots of combinations of switches in on and off state, and a programming language is the shared understanding between all the components.
Way tooo many things are happening, but its a combination of electrical circuits having a change in voltage or current, then it is sampled, then converted to different types of code, ran through a CPU, then changes to different codes again, goes to RAM, leaves RAM, goes back to Gpu, gets read again in different code, the new code is sent to the monitor, and then changed to voltage current again. Wayyyy too many things to explain, but it takes a lot to make a computer work 🙂
How deep down the rabbit hole do you want to go? Computers are complicated Rube-Goldberg machines with many layers of abstraction from decades of advancement. There are lots of different points of view to look at, this is just one:
1. You press the “E” button on your keyboard.
2. Your button press closes an electric circuit which activates a certain combination of wires.
3. A micro-controller in the keyboard converts that signal to one or more packets of the USB protocol.
4. Those packets are sent to the USB controller inside the computer (or rather, I believe the controller regularly polls for those packets from the keyboard).
5. The USB controller sends an interrupt signal to the CPU.
6. The software running on the CPU (eg. the Operating System) determines what to do with those interrupts.
7. The OS receives data (via USB drivers) that a USB Human Interface Device sent an “E” key event (at this point it has probably interpreted a combination of “key down”/”key up” events as a single “press” event).
8. The OS sends the “E” key press to the application with the active window (and potentially other processes which are registered to receive such events).
9. The application tells the OS to render the letter “E” at a certain position on screen.
10. The OS tells the graphics processor (via graphics drivers) what image to display.
11. The CPU sends signals via the PCI bus to the GPU about what image data to render.
12. The GPU outputs electric signals via the HDMI interface to the monitor about what pixels to render.
13. The micro-controller in the monitor activates certain wires in its circuitry to change the colour and brightness of specific pixels.
Do you want to know which specific wires/pins are being activated? How much charge is going through them on each clock cycle? How the charge passes through the electric field?
When you count, it’s 1, 2, 3, …, 9, 10, etc. What happened at 9? You ran out of unique numbers, so you carry over one place and keep counting, now instead using two digits: …, 10, 11, 12, etc.
What does a two-digit number like 12 mean? It means “1 ten and 2 one’s.” You can break any number down this way, 3 thousands, 5 hundreds, no tens, and 7 ones is 3507. Since each place signifies a power of ten, we call this the base-10 numbering system, it’s “based on 10.”
Now imagine you have a bunch of wires lined up, let’s say four of them. The left most wire represents thousands, the next one hundreds, then tens, and ones. Each one can have a certain amount of current flowing through it: no power, 1 amp, 2 amps, etc, up to 9 amps. So if you want to represent the number 3507, the left-most wire has 3A, the next one 5A, then no power, then 7A.
This collection of wires is called a “register” in a CPU. The reason your computer needs to be plugged in all the time is that if it’s holding this number in a register and you shut off the power, then all those wires go to no current. When you plug it back in, there’s nothing there and the information has been lost. It takes constant power to represent a number.
So what? Why do this? Well, let’s say you have two registers. That means you can represent two different four-digit numbers. Now let’s add a third register, but this one is special, the number in this register corresponds to an instruction like “ADD” or “SUBTRACT”, and this chip is designed so that when there are two numbers in the first and second registers, if the third one has the instruction for “ADD”, the CPU automatically figures out how to adjust the value in the first register to become the sum of the two numbers (and maybe it clears the second register, maybe it doesn’t … depends on how you design your chip).
Now you have a very basic idea of how a CPU works. But how do you get data in and out of these registers? Well, there’s instructions in that special third register that mean “load a number from memory into register 1” and “write the number in register 1 to memory.” Memory is RAM, random access memory, and it’s just a big bank of registers that does nothing but store values the CPU might want to read and write. How do these instructions know where to look in memory? Good question! They use register 2. The value in register 2 tells the instruction the memory location to read or write.
A simple program might be (R1 is register 1, R2 is register 2):
PUT 1, R2; // puts the value 1 in R2
LOAD1; // loads the value from memory location R2 into R1
PUT 5, R2; // puts the value 5 in R2
LOAD2; // loads the value from memory location in R2 into R1
ADD; // adds values in R1 and R2, replacing value in R1 with sum
PUT 2, R2; // puts the value 2 in R2
WRITE1; // writes the value in R1 to memory at location in R2
This program loads the value from memory location 1 into register 1, the value at memory location 5 into R2, adds those values, then writes the result to memory location 2. (All of the choices of memory locations are arbitrary, they don’t mean anything, just to demonstrate how to read and write values at different memory locations.)
This is all very simple, right? Notice that this only allows a computer to execute one program at a time. Your computer does lots of things at a time, though, right? How?
A single CPU actually *can* only do one thing at a time. It makes it seem like it’s doing multiple things at once by a technique called “multitasking,” and it works like this…
Each program, like the one above, thinks it has the entire computer to itself. In fact, the operating system is the granddaddy program that is only making it seem this way. When the user requests the OS to start up a program, the OS declares a chunk of memory to belong to that program and, as far as the program knows, that’s all of the memory. Then, the OS runs that program for a bit, then suspends it, writes out all of the values in the CPU to its own memory block (allocated to the OS itself), then it swaps in the values for some other program, runs that one for a little bit, etc. It just keeps running all the different programs a bit at a time, and it happens so fast that it seems to you as if all the programs are running at once.
Now finally to get to the question you asked. When a computer starts up, the first thing it does is load the operating system, which is basically just a program itself. The job of the OS is to run other programs. When it starts up, one bunch of programs it always runs are called “device drivers.” A device driver is a little program that controls a single device. For instance, your keyboard has a device driver, and when you install the operating system the first time, it figures out which keyboard you have and it adds that keyboard’s device driver to the list of programs it will start automatically once it’s done starting up.
Once the device driver for your keyboard starts up, what it does is look at a small bit of memory that holds keystrokes and, if it sees that there’s nothing there, it goes to sleep. When the user hits a key on the keyboard, like ‘L’, an electrical connection is physically made under the key which triggers a chip on the motherboard (not the CPU, but a chip in the chipset) to read the value of that key (‘L’) and write it to the memory belonging to the device driver.
The CPU goes on its merry way, eventually getting around to swapping in the device driver program, which sees that there’s something to read in its little memory buffer. How exciting! So at that point it sends a signal to the OS called an “interrupt”, which tells it to deliver this bit of data to whatever program is currently the one “with focus” (the one that the user would expect input to go to). So then the OS swaps out the device driver, swaps in the program with focus, and says, here you go, here’s an ‘L’.
Now at some point, if this program is expecting input, then it already registered a listener that is waiting for user input, and when that event comes in, it triggers that event listener, which does whatever it’s supposed to do (which in this case is probably stick that ‘L’ into some bit of memory and display it on the screen, probably where the cursor currently is). If the program didn’t expect any user input, then there is no listener and the input just gets discarded with no effect.
Interrupts are how at the lowest level computers deal with events happening. Like if your network card suddenly starts receiving data, it might have a small amount of memory to buffer that data, but it can’t store like an entire YouTube video or whatever. So it sends an interrupt to the CPU telling it “you better stop what you’re doing right now and deal with this,” and the CPU does.
In the old days, with early computers, it was common to see your computer freeze up when something happened, and then all of a sudden it would tell you “download complete” and things would go back to normal. Nowadays, almost all of this kind of processing is done using chips in the chipset so the CPU can keep on going uninterrupted. Also, each “CPU” today is actually many CPUs packed into one (this is what “cores” are, just multiple CPUs stuck in the same chip).
Finally, all throughout this post I took some liberties with the truth. Registers don’t actually store 0 through 9 on a single wire, that actually turns out to be an electrical engineering nightmare. Instead, computers use base-2 number system so that each wire in a register is either on (representing a 1) or off (representing a 0), and numbers in binary are:
0 = 000
1 = 001
2 = 010
3 = 011
4 = 100
5 = 101
etc.
The number of wires in a register these days is 64, meaning that each register can store a binary value with up to 64 digits. This is what it means when someone says your computer is 64-bit.
It might seem impossible that a computer can actually work this way, like the sample program I put up at the top. It seems like there would have to be billions and billions of these instructions running across thousands of different programs on a modern computer—and that’s exactly what’s happening. The way it all works is by building up layer upon layer of abstraction, so a computer programmer (such as myself) doesn’t actually write programs like the one above. We use programming languages that are much more expressive, and we use a huge technology stack consisting of interpreters, compilers, linkers, etc, to do all the work of turning the program we write into the program the computer can actually run. So a few lines of code in a modern program can translate into a whole lot of complicated instructions at the level of the CPU.
There’s a lot of layers to what’s going on, and each one of them is interesting!
When you press a key on a keyboard, you complete a circuit which allows electricity to flow through that key. Through complicated circuits, this becomes an electrical signal that travels through the wire to get to the motherboard of the computer. That signal then traverses even more complex circuits in the motherboard. Eventually electricity flows through to your monitor and lights up some pixels on the screen the right color.
These complex circuits are made up of things called “logic gates.” An “and” gate takes in two wires, and outputs one wire. If both input wires have a high charge, the output wire has a high charge. An “or” gate has two inputs and if either one or both have a charge, it will output a charge. A “not” gate has one input and simply outputs the opposite, meaning a charge becomes no charge or no charge becomes a charge. There are other gates too with their own inputs, outputs, and rules.
When you get millions and millions of these gates together wired up the right way, you do some amazing electrical signal processing. That’s basically how computers work. Millions and millions of tiny little circuit pieces causing small charges of electricity to flow the right way.
In my Logic Design class in college we used a program to simulate 1000s of these gates and designed a very basic calculator out of them. The calculator took in 16 signals to represent the equation. It had 4 operations. It could add two numbers, subtract, invert (multiple by -1), or double.
> the basics of how a computer works
This is a huge topic that’s not going to be answered in a single Reddit post.
I highly recommend [Ben Eater’s YouTube series](https://www.youtube.com/playlist?list=PLowKtXNTBypGqImE405J2565dvjafglHU), a bunch of videos where he builds a CPU from scratch. If you’re looking for a book, I’d recommend “But How Do It Know?” for something more ELI5-level, or if you’re into hands-on programming, [nand2tetris](https://www.nand2tetris.org/).
> What happens physically when the user interacts with the computer, when a button is pressed on the keyboard for example?
You have a computer (CPU) and a button, and when you press the button, the CPU “knows” that the button was pressed, and the program it’s running does something with that information.
What exactly happens depends on what kind of CPU, what kind of button, and how the system designer’s chosen to connect the button to the CPU.
The simplest possible setup is to have a button connected to one of the CPU pins. (Any chip will always have its delicate silicon parts factory-sealed inside a protective plastic case. By “CPU pins” I mean a bunch of literal pieces of metal sticking out of the case, for example [like this](https://en.wikipedia.org/wiki/File:Intel_80486DX2_bottom.jpg).)
The pins all look the same from the outside, but inside they’re connected to different parts of the CPU’s internal silicon circuits. If you read the manual published by the CPU manufacturer, you’ll find it needs to be powered by connecting two specific pins to a DC power supply, and some other pins can be (or in some cases, must be) connected to particular devices. But many of the remaining pins are “GPIO pins.” A GPIO pin is connected by default to a voltage sensing circuit. It’s a “digital” or “logic” sensing circuit, meaning it’s very simple and registers “off” for low voltages (0-2 V) or “on” for high voltages (like 3-5 V).
So the simplest possible setup is to have a button wired to the pin in such a way that it connects to the + terminal of the power supply when pressed, or the – terminal of the power supply when released. The CPU’s voltage sensing circuit then “knows” whenever the button’s pressed. When you’re writing the program running on the CPU, the GPIO pin usually appears as a “place in memory” that “changes on its own”. Meaning your program can check that place in memory, and do something when it changes.
There are a couple improvements that are typically done. First problem is the button is *incredibly slow* compared to the computer. It takes like 0.02 seconds for the button’s spring mechanism to move the contact from the – terminal to the + terminal. In that 0.02 second period the pin’s not connected to anything, and it can make the CPU’s internal voltage sensing circuit do some weird stuff.
The way to fix this is to re-wire the pin so it’s *always* connected to the + terminal — but not directly, you put a resistor with 10,000 ohms of resistance in the way. You then re-wire the button so that, when pressed, it connects the pin *directly* to the – terminal *in addition* to its existing connection to the + terminal. Since it’s a direct connection (copper wire has only like 0.2 ohms of resistance), the – terminal will “win” whenever the button’s pressed and the voltage sense circuit will read “off”.
This “pull up resistor” is so commonly needed that CPU designers usually put an internal resistor that your program can request it to connect. This means you don’t actually need to add the extra resistor to your circuit, if you just write your software to tell the CPU to use the internal one.
The next thing that needs fixed is your program is repeatedly asking “Is the button pressed?” (0.01 seconds later) “Is the button pressed?” (0.02 seconds later) “What about that button?” (0.03 seconds later) “Is it pressed *now*?”
It would be a lot more efficient and less annoying to program if you could just have your program tell the CPU once at the beginning while it’s setting up, “Hey, if the voltage sense circuit for pin #17 ever changes, please stop what I’m currently doing and run this subroutine instead.” And the CPU usually includes an “interrupt” mechanism that lets you set up exactly that kind of arrangement.
Now if you’re asking about how a PC keyboard works, well, it’s different and more complicated. A standard US PC keyboard has 104 keys. You can’t connect them all to individual pins: A CPU typically *doesn’t have* that many GPIO pins, and even if it did, to connect them all you’d need an impractically huge cable and a lot of complicated circuit board paths on the motherboard. So typically there’s a simple chip inside the keyboard that converts key-presses to coded pulses, that way you just need maybe 4 or 5 wires for power and signals, and only 2 or 3 of those wires need to be connected to CPU pins [1]. If you’re interested in the details [Ben Eater has a video about that](https://www.youtube.com/watch?v=7aXbh9VUB3U). (Actually several videos.)
[1] While my post and Ben Eater’s video are written as if the keyboard’s directly connected to CPU pins, I think in actual PC’s, keyboard pins for a PS/2 keyboard are probably not directly connected to the CPU. I’d assume they’d be connected to some separate chip on the motherboard that decodes the keypresses and sends them into the bus or something but I’m not 100% sure about that.
Latest Answers