In short: The Arduino Uno is an ATmega328P running at 16 MHz and 5 V with 32 KB flash, 2 KB SRAM and 1 KB EEPROM, and every I/O pin is limited to about 20 mA, so the real design work is budgeting memory, cycles and current rather than chasing headline numbers.
The core: what the ATmega328P actually gives you
The Uno board is mostly packaging. The brain is an 8-bit AVR microcontroller, the ATmega328P, with a modified Harvard architecture: program lives in flash, data lives in SRAM, and the two have separate buses. Most instructions finish in one clock cycle, so a 16 MHz clock yields roughly 16 MIPS peak. That is a few thousand times less than a phone processor, but it is perfectly deterministic: with no cache, no pipeline surprises and no operating system, you can count cycles and predict timing to the microsecond.
That determinism is why the Uno is still a favourite for teaching. If you want the supply side of the story, read our companion piece on the Arduino Uno power supply.
The specification table
| Parameter | Value | Design implication |
|---|---|---|
| Clock | 16 MHz (ceramic resonator) | 62.5 ns per cycle; resonator is about 0.5% accurate, so avoid it for precise UART at high baud rates |
| Logic level | 5 V (VIH about 3.0 V, VIL about 1.5 V) | 3.3 V sensors can drive it high; the reverse needs level shifting |
| Flash | 32 KB (about 0.5 KB used by bootloader) | Roughly 15,000 simple instructions of code space |
| SRAM | 2 KB | Globals, stack and heap share it; the tightest resource |
| EEPROM | 1 KB, about 100,000 writes per cell | Fine for calibration, wrong for logging |
| Digital I/O | 14 pins (6 PWM) | Pins 0 and 1 are shared with USB serial |
| Analog inputs | 6 channels, 10-bit ADC | 1024 steps; about 4.9 mV per step at 5 V reference |
| Current per I/O pin | 20 mA recommended, 40 mA absolute max | Drive LEDs directly, but never motors or relays |
| Current from 3.3 V pin | 50 mA | Powers a small sensor, not a radio module under load |
Key fact: The 40 mA figure is an absolute maximum, not an operating point. Design to 20 mA or less per pin, or the output voltage sags and the part ages faster.
Memory: SRAM is the real limit
32 KB of flash feels generous until you add a display library. SRAM is the true ceiling. A single char buf[512] eats a quarter of it. String literals are copied into SRAM at boot unless you wrap them in F() or use PROGMEM, which keeps them in flash. A common beginner crash: dozens of Serial.println("long message") lines silently consume hundreds of bytes and the stack then collides with the heap, producing random resets with no error message.
- Prefer
uint8_toverintwhere the range allows; the AVR is 8-bit and 16-bit math costs extra cycles. - Avoid
Stringconcatenation in loops; heap fragmentation is fatal on 2 KB. - Write to EEPROM only when a value changes. At one write per second a cell lasts about 28 hours of continuous overwrite, so spread writes or wear-level.
Key fact: Arduino reports flash and global-variable use at compile time, but not stack growth. Leave at least 25% of SRAM free for runtime.
5 V logic and what it means for interfacing
With VCC at 5 V, the input-high threshold is about 0.6 x VCC, which is 3.0 V, and input-low is 0.3 x VCC, which is 1.5 V. A 3.3 V sensor output (high of 3.3 V) is therefore read correctly. The danger runs the other way: a 5 V Uno output driving a 3.3 V-only chip, such as many Wi-Fi or SD modules, exceeds its absolute maximum. Use a resistor divider (for example 1 kohm over 2 kohm gives 3.3 V) for slow signals or a proper level-shifter IC for I2C and SPI.
The same thresholds govern noise margin. A 5 V CMOS output swings near rail to rail, giving you nearly 2 V of margin on the high side, which is why long jumper wires on a breadboard still work at low speed.
Current limits and pin budgeting
Each pin can source or sink 20 mA comfortably, but the package has aggregate limits too: about 200 mA total through VCC and GND pins, and the datasheet restricts the sum per port group to roughly 100 mA. Eight LEDs at 15 mA each is 120 mA, which already breaks the per-port rule if they share one port.
Worked example: a red LED with a 2 V forward drop on a 5 V pin and a 220 ohm resistor draws (5 - 2) / 220 = 13.6 mA. That is safe. A 5 V relay coil at 70 mA is not, so drive it through an NPN transistor or logic-level MOSFET, with a flyback diode across the coil.
Clock, timing and the cost of 16 MHz
Because one cycle is 62.5 ns, a bare digitalWrite() call takes roughly 3 to 5 microseconds on Arduino because of its pin-lookup overhead, versus about 125 ns with direct port writes such as PORTB |= (1 << 5). That is a 30x difference, which matters when bit-banging a protocol. The three hardware timers (two 8-bit, one 16-bit) generate PWM at about 490 Hz or 980 Hz by default, and millis() uses Timer0, so changing its prescaler also changes delay behaviour.
The 10-bit ADC needs 13 ADC clocks per conversion. With the default 128 prescaler (125 kHz ADC clock) that is about 104 microseconds, so analogRead tops out near 9.6 kSPS. Fast signals need a lower prescaler or an external converter.
What these specs imply for real designs
- Budget pins and current first. List every load, sum the milliamps per port and decide where transistors or driver ICs go.
- Treat 2 KB as a hard budget. Track it like silicon area: reserve, measure, then optimise.
- Know when to graduate. Needing floating point at speed, 3.3 V logic, or more than a few KB of RAM points to an ARM Cortex-M or ESP32 part. The same discipline of budgeting timing and power appears in ASIC flows, where tools like Synopsys PrimeTime and Cadence Voltus do the same sums for billions of transistors.
For practical builds that apply these limits, see our guide on Arduino Uno GPIO and PWM. If you plan to move from boards into chip design, the ChipXpert VLSI training programmes pick up where embedded ends, and our CourseTron courses cover both sides.
Ready to go beyond blinking LEDs? Explore the embedded track in our CourseTron courses and build timing-accurate firmware with confidence.
Frequently asked questions
Why is the Uno clock 16 MHz and not faster?
The ATmega328P is rated to 20 MHz at 4.5 to 5.5 V, but 16 MHz divides evenly for common UART baud rates and timer ticks. Running above 4.5 V is also required for 16 MHz and above; at 3.3 V the safe maximum is about 8 MHz.
Can the Uno read 3.3 V sensors?
Yes for inputs, since 3.3 V exceeds the 3.0 V high threshold. For outputs to 3.3 V-only chips, add level shifting.
How much current can the whole board supply?
The chip allows about 200 mA total through its supply pins, and the 5 V pin can supply more only when powered from a good USB or barrel source. Check the regulator's thermal limit.
Is 2 KB of SRAM enough?
For sensor reading, simple control and small displays, yes. For networking stacks, large buffers or JSON parsing, no.