When Code Spins a Motor
a quiet reflection on how software meets the physical world
I still remember the first time I used an Arduino.
Wrote a tiny sketch. Uploaded it. Watched a servo motor twitch and rotate.
And I just sat there thinking, Wait what? How did that happen?
I typed some text into a computer. Hit upload. And the next thing I know, something in the physical world moved. Like, actually moved. That single moment unlocked a kind of wonder that never really left me.
Representation of a servo motor
We talk a lot about software eating the world. But what still blows my mind is how software touches it.
Like, Take this line for example:
servo.write(90);
To us, that’s just a function call. A high-level instruction.
But the more you zoom in, the more surreal it gets.
How does this instruction, typed as text on my laptop - somehow become a physical voltage signal on a wire, which then moves a motor?
What’s the bridge between code and atoms?
Let’s go all the way down.
I'm here for balance.
Step 1: From text to binary
When I hit "Compile" in the Arduino IDE, my C++ code gets compiled.
It’s first translated into assembly, a low-level set of instructions specific to the ATmega328 chip (used in the Arduino Uno).
That assembly is then converted into machine code - just raw binary. A stream of 1s and 0s. The actual opcodes the microcontroller understands. All of this is done using a tool called avr-gcc.
After this, the binary is then converted into a .hex file.
C++ Code
servo.write(90);
Click on the 'Compile' button to see the process in action.
Still even after all of this, it's just bits on my laptop.
I'm here for balance.
Step 2: Flashing into memory
Now we need to get those bits transferred into the microcontroller.
Not "uploaded". Not "installed".
"Transferred". Bit by bit. Electrically.
This is where the Arduino bootloader comes in. It's a small piece of code that runs when the Arduino is powered on. It's responsible for loading the program from the .hex
file into the microcontroller's flash memory.

Connection between the Arduino and the USB-to-serial chip
Here's how it works:
→ It starts with a signal.
→ When I hit upload, my laptop sends a command over USB.
→ The Arduino has a tiny second chip - a USB-to-serial converter (like ATmega16U2) - whose only job is to listen for these commands and translate them into a simpler protocol the main chip understands: UART.
→ That chip briefly pulls a pin on the main microcontroller low - the RESET pin.
→ That low voltage pulse is enough to reboot the entire chip.
→ Not restart our code, at least not yet.
→ The microcontroller boots into a special mode.
→ It jumps to a small area of memory - a region burned during manufacturing - where the bootloader lives. This isn’t our program. This is a separate, pre-written piece of code whose only job is to say:
“Is someone trying to send me new instructions?”
So it waits.
1void setup() {
2 Serial.begin(9600);
3}
And then the stream begins.
I'm here for balance.
The .hex
file - a human-readable format of our machine code - starts flowing in over the serial connection.
Each line contains bytes. Each byte contains 8 bits. Each bit is a single high ↑ or low ↓ voltage signal.
1s and 0s. Fast, tiny pulses of electricity. Like Morse code, but smaller.
The bootloader receives each byte, parses it, and figures out where it should go in flash memory. Then it writes it.
And this is where it stops being just “software.”
What does it mean to write to flash memory?
Inside the microcontroller are thousands of microscopic transistors - specifically, floating-gate MOSFETs. Each one represents a bit of data.
To store a "1", the chip applies a higher-than-normal voltage to that transistor.
This voltage creates an electric field strong enough to push electrons through an insulating layer - something that shouldn't be penetrated.
But the voltage is so high, some electrons make it through. They tunnel into a small, isolated region - the floating gate.
Once there, they get trapped. And because they're negatively charged, they slightly alter the behavior of that transistor.
That's it. That's a "1". To write a "0", no extra voltage. The gate stays empty.
This is called hot electron injection. Yes, that's the actual term.
We are literally slamming electrons into a cage and leaving them there until further notice.
The bootloader does this over and over, for every byte in our program.
A cascade of high voltage pulses. Thousands of gates, each either filled with electrons or left empty.
And when it’s done, our entire programm the one we typed, compiled, and sent, is now physically etched into the chip.
Not metaphorically. Not symbolically. But physically, in silicon :)
In trapped charge. In electrons that are now sitting inside a gate that will remember them even when the power is gone.
Imagine there’s no hard disk. No file system. No OS. Just raw memory cells. Charged or not. Beauty 🤌🏻
We didn’t just send code. We rearranged matter.
I'm here for balance.
Step 3: CPU starts executing
When the board powers up, the chip’s program counter starts at memory address 0x0000.
The CPU fetches the instruction stored there. Decodes it. Executes it. Then moves to the next.
Fetch → Decode → Execute → Repeat.
Forever.
That’s how programs “run.” Not because of some magic, but because a control circuit is hardwired to read bytes from memory, interpret them as instructions, and toggle internal signals accordingly.
Everything we write eventually becomes this: a pattern of voltage inside silicon.
I'm here for balance.
What actually happens when we call servo.write(90)
?
Here’s the fun part.
When we call servo.write(90)
, we’re not telling the motor to rotate 90°. We’re telling the chip to start generating a PWM (Pulse Width Modulated) signal i.e. a series of HIGH and LOW pulses on a digital pin.
Servos are hardcoded to interpret the pulse width like this:
So that line of code sets up a timer inside the chip. That timer toggles a pin ON for 1.5ms, then OFF, repeatedly, in a 20ms cycle.
That’s it. That’s what the servo understands. It doesn’t speak English. It listens to pulse width.
All we did was flick a wire on and off in rhythm. And the motor moved.
I'm here for balance.
Let’s go even deeper
How does the chip actually flick that pin?
Each I/O pin on a microcontroller is mapped to a specific memory address. When we call something like:
digitalWrite(9, HIGH);
Under the hood, we’re just writing a 1
into a particular bit in a register.
PORTB |= (1 << PB1); // Example: turn on pin 9
And that causes a transistor to switch on. Current flows. Voltage on the pin goes HIGH.
That’s all it is.
Software writing into memory. Memory controlling wires. Wires toggling voltage. Voltage creating meaning.
No layers. No metaphors. Just electricity.
I'm here for balance.
The real stack
We often talk about “the stack” in software, frontend, backend, databases, infra.
But there is another one as well, The one that actually moves things :)
It's still wild, isn't it?
We didn’t write “rotate to 90 degrees.” We wrote a rhythm of voltage. And that rhythm made something move.
I'm here for balance.
Why this still blows my mind?
Most of the code I write today lives inside browsers. React. Next.js. Animations. Design systems. All abstract stuff.
But every now and then, it’s nice to remember,
Underneath all of it, it’s still just current.
Still just electrons moving through a wire...
We don’t think about it much. But every time we write a loop, or a conditional, or a return statement, we’re shaping how current flows through silicon.
Even the highest abstractions end here: A chip. A wire. A voltage. A decision.
And sometimes I think back to that moment, when a little motor turned because I asked it to in one line of code. For me, that’s still one of the coolest things I’ve ever built :)
I'm here for balance.
P.S. There’s so much we take for granted. Sometimes I forget how magical this world already is.