The overview, with examples running, is on the board page and The Arduino Uno model (every register).
What it is
The Arduino Uno R3, with a complete ATmega328P behind it running on our own AVR core. The core carries the datasheet's cycle counts for all 131 instructions, which is why timing behaves the way it does on the real chip rather than approximately.
Firmware talks to the peripherals at their real ATmega328P addresses, so a program built here runs on a real Uno.
The pins
31 of them, in the order the real board has them.
Top header, left to right: SCL, SDA, AREF, GND, 13 down to 0.
Bottom header: IOREF, RESET, 3V3, 5V, GNDb, GNDc, VIN, then A0
to A5. Duplicate names carry a letter, because a pin name has to be unique.
Digital 0 to 13 and A0 to A5 are GPIO. They map to ports the way the
chip does: 0..7 is PD0 to PD7, 8..13 is PB0 to PB5, A0..A5 is PC0 to PC5.
SDA is strapped to A4 and SCL to A5, so they are the same net.
An output drives 5 V or 0 V. An input is high impedance, with a 35 k pull-up to 5 V when you ask for one. The threshold is 2.5 V.
Pin 13 has the on-board LED on it, which is why LED_BUILTIN is 13 and why
blink needs no wiring at all.
5V and IOREF supply 5 V, 3V3 supplies 3.3 V, the grounds supply 0 V, and
VIN is ignored because the board is always USB powered.
Why it sits beside the breadboard
Its headers are two inches apart, which is wider than a breadboard's center channel. A real Uno is wired to a breadboard with jumpers, and so is this one.
What is modeled
The three timers in every waveform mode, USART0, the ADC on A0 to A5 at ten
bits, external and pin-change interrupts, sleep, EEPROM and SPM. That is the
set the Arduino API needs for pinMode, digitalWrite, analogWrite,
analogRead, millis, delay, Serial and attachInterrupt.
analogWrite uses the timers the way the Arduino core does: pins 5 and 6 at
976 Hz, pins 3, 9, 10 and 11 at 490 Hz.
Serial sends through a 64-byte ring, as the core's HardwareSerial does:
print returns as soon as its bytes are queued and the USART's interrupt sends
them behind the sketch at the baud rate, so a line shorter than the ring costs
the sketch almost nothing. The sketch waits only when the ring is full, and
Serial.flush() waits for the last stop bit. Serial.availableForWrite() is
the room left, 63 when it is empty. The same goes for the Nano and the Pro Mini.
What is not
SPI and I2C as peripherals, the boot section and its fuses, the analog comparator, the clock prescaler, asynchronous timer 2, and the USB-to-serial bridge.
The watchdog is modeled: wdt_enable() with no wdt_reset() in time resets
the board, and MCUSR shows WDRF afterwards. No bootloader runs first, so
clear MCUSR before wdt_disable() after such a reset.
Every register address here comes from the ATmega328P data sheet and nothing is guessed at, but several behaviors are approximations, and section 7 of the Arduino Uno model lists them all. The three worth knowing at the bench: the ADC has no error in it (no sample-and-hold, no nonlinearity, no noise, no offset), so a divider reads the same count every time, where a real one wobbles a count or two; the 16 MHz crystal is exact, with no drift or jitter; and the 5 V rail is an ideal source that cannot sag, so a circuit that would brown a real board out runs cleanly here.
Stock Arduino libraries
A tutorial that includes Servo.h, Wire.h, SPI.h, EEPROM.h,
LiquidCrystal_I2C.h, Adafruit_GFX.h with Adafruit_SSD1306.h and DHT.h
compiles here as it stands. Each is Mokxi's own header under the upstream name,
written on the drivers for the parts in the bin, and none of it is the upstream
library's code.
Wire.begin()puts the I2C bus onA4(SDA) andA5(SCL), which theSDAandSCLheader pins are strapped to.EEPROM.huses the chip's own 1 KB of EEPROM, through its real registers. It keeps what you wrote across a press of the board's reset, and a fresh Run starts it erased, every byte255, because a Run is a new board.SoftwareSerial.hgives a second serial port on any two pins, for an HC-05 or a GPS, as the Arduino library does: a pin-change interrupt catches each start bit and counted loops time the rest, on this model's real cycle counts. One port listens at a time, and it cannot receive while it sends.Adafruit_NeoPixel.hdrives a WS2812 strip. The bit is timed in AVR assembly, the way every AVR NeoPixel library does it, and at 16 MHz each high lands inside the data sheet's window. Interrupts are off while a frame goes out, somillis()loses a tick for every millisecond a long strip takes to send, as on the bench. The colors take three bytes an LED of the chip's 2 KB of RAM.
The code editor and compiling lists what each one covers and how it differs from the upstream library.
The examples
The Uno ships with more prebuilt sketches than any other board: Blink, Button, Serial, Fade, Analog, Counter and Interrupt to start with, then Dimmer, Night lamp, Thermometer, Parking sensor, Matrix ball, OLED text and shapes, Pong console, D-pad pong, Bar graph, Chaser, Commands, Electronic dice, Reaction duel, Keypad lock, Listener, Metronome, Motor ramp, Night light, PWM steps, Reaction timer, Servo fader, Snake, Tilt alarm, Toggle, Traffic light, Two lamps, Two rates and Watchful, plus thirteen C++ lessons.
Pick one in the Firmware section of the board's properties panel, or write your own and press Run.
Assembly
The same Firmware section has a group called Assembly (no Arduino), with a
Blink, a Button to LED, a UART hello and a Timer interrupt written in AVR
assembly. Pick one and the board's files become a single main.S with no
Arduino core under it, linked against the startup code alone, the way
avr-gcc main.S is. A .S tab beside an ordinary sketch works too. See
Writing assembly.
Elsewhere
- The board page: /boards/arduino-uno
- The contract document: the Arduino Uno model
- The learning path: Embedded on the Arduino Uno, at /learn
- The same chip on a breadboard: the Arduino Nano and the bare ATmega328P
- The Arm Uno: the Uno R4 Minima