The overview, with examples running, is on the board page and The ATtiny85 model (every register).

The ATtiny85

A whole microcontroller in an eight-pin DIP: six I/O, two timers, a four-channel ADC, the USI, and a serial port the runtime bit-bangs for itself.

What it is

The ATtiny85 in its 8-pin DIP package, on the tinyAVR instruction set with the datasheet cycle count of every instruction. It is the first microcontroller in Mokxi that is not a board, and it behaves like the chip it is rather than like a module with a USB socket on the end.

The tinyAVR core has no MUL, no JMP and no CALL. Reaching for one is an illegal opcode here as it is on the part, and the firmware runtime is built with -mmcu=attiny85 so the compiler never emits one.

It goes in the breadboard, and you wire its power

An ATtiny85 pushes into the breadboard across the center channel, the way the 555 and the 74HC chips do, with pin 1 top left and the notch pointing up.

Power is a pin. VCC on pin 8 and GND on pin 4 are inputs, not supplies: the chip is a load. Until both are driven and the difference is at least 1.8 volts, every pin is high impedance and nothing runs. That is not a limitation, it is the lesson: an ATtiny85 sitting in a breadboard with no rails does nothing at all.

Levels follow the supply you gave it. On a 3.3 volt rail it reads and drives 3.3 volt logic, and the ADC's VCC reference moves with it.

The pins

Package order, pin 1 first, counter-clockwise:

pin name what it also is
1 RESET PB5, ADC0, and the reset pin
2 PB3 ADC3, serial transmit
3 PB4 ADC2, serial receive
4 GND ground
5 PB0 OC0A, DI/SDA, AREF
6 PB1 OC0B, OC1A, DO
7 PB2 INT0, ADC1, USCK/SCL
8 VCC supply

RESET carries a 10 k pull-up; hold it below half the supply and the core stops. PB5 is a GPIO only with the RSTDISBL fuse programmed, which makes the part unprogrammable over ISP, so Mokxi keeps it as the reset pin: DDRB and PORTB bit 5 are stored and read back, and the pad never moves.

PB0 to PB4 are ordinary GPIO with the internal 35 k pull-ups.

Serial, with no USART on the chip

There is no USART on an ATtiny85, so nothing here pretends there is. The runtime bit-bangs 8N1 on PB3 (transmit) and PB4 (receive), and the chip part decodes those two pins the way a USB-serial adapter clipped to them would, at a baud property that defaults to 9600.

Printing therefore costs real time (about a millisecond a byte at 9600 baud), and it costs it in your sketch's own loop, which is exactly what it costs on the part.

What is modeled

Port B with its pull-ups, timer 0 in all four waveform modes with hardware PWM on PB0 and PB1, the high-speed timer 1 with OCR1C as TOP and its fourteen-entry prescaler, a four-channel ADC with the 1.1 V and 2.56 V internal references, the USI as a shift register with its four-bit counter, INT0 on PB2, the pin-change interrupt on every pin, 512 bytes of EEPROM, and SLEEP that really does park the core.

What is not

The 64 MHz PLL: PLLCSR reports a lock so firmware that waits for one gets going, but timer 1 keeps counting at the system clock. The analog comparator, the watchdog, the clock prescaler, and the differential ADC channels with their gain stages. The USI counts, shifts and reports start and stop conditions, but it does not drive SDA as a two-wire bus master.

The ATtiny25 and ATtiny45 are the same part with less memory and are not separate entries; the ATtiny84 and its relatives are a different part and are not modeled.

The 8 MHz clock here is exact, and on a real ATtiny85 it is the least trustworthy thing on the chip. The internal RC oscillator is calibrated to about ten percent at the factory and moves several percent more with supply and temperature, which is why a real one usually needs its OSCCAL trimmed before the bit-banged serial port works at all. This model has no drift and no jitter, so the serial port here is far more forgiving than the part. The model also assumes the CKDIV8 fuse is unprogrammed; a chip out of the packet runs at 1 MHz until you change it.

Like every board here, the ADC has no error in it (no sample-and-hold, no nonlinearity, no noise, no offset), and the RESET pull-up the model provides is not inside a real chip: you have to fit one.

The register tables are in the ATtiny85 model, whose section 7 sorts every address and every approximation.

Stock Arduino libraries

A tutorial that includes Servo.h, Wire.h, SPI.h, EEPROM.h, LiquidCrystal_I2C.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 on PB0 (SDA) and PB2 (SCL).
  • EEPROM.h uses the chip's own 512 bytes 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 byte 255, because a Run is a new board.
  • Adafruit_SSD1306.h is not for this chip: the OLED's frame is 1 KB and the ATtiny85 has 512 bytes of RAM, so the header says so when it is included.
  • Adafruit_NeoPixel.h stops with a message: a WS2812 bit is too short to make by hand on this board, and only the ESP32-C3 and ESP32-C6 drive the strip.
  • DHT.h works, and a sketch that prints a reading fits. The whole Adafruit tutorial, with three readings and two heat indexes all printed as floats, is bigger than the chip's 8 KB of flash, and the build says so.
  • Floating point, String and the math library are there, as on every board, but they are big for this chip: much of either and a sketch outgrows the 8 KB, or its calls outgrow the 4 KB the ATtiny85's short calls reach, and the build stops with relocation R_AVR_13_PCREL out of range. Work in whole numbers here, as ATtiny sketches usually do.

The code editor and compiling lists what each one covers and how it differs from the upstream library.

The examples

Blink, Button, Knob and Hello.

Elsewhere