Skip to content


Folders and files

Last commit message
Last commit date

Latest commit



12 Commits

Repository files navigation

I2C libraries for attiny85-like AVR micros

A pair of I2C libraries for AVR micros with USI two-wire mode capabilities (developed and tested on attiny85's, but portable - in theory! - to similar devices with the proper pin changes) + a bunch of examples both with primary and secondary devices.

The goal here is to use them as the main entry point when dealing with I2C in future projects (and improve them over time, of course!), so here's a fully functional micro-example of a primary device reading from a secondary device and writing into a third secondary one (bonus: connection with a a ssd1306 oled screen!).

More info on my project page.

I2C attiny85 TWI

I2C primary / secondary

The i2c/ folder contains both the primary and secondary libs that allows sending and reading bytes.

For primary devices the approach is the regular one: start the transaction, send the address, send something or read whatever and finish the transaction.

The secondary lib works with interrupts as a simple state machine: each overflow on USISIF or USIOIF (flags from internal status on TWI mode) triggers an interrupt that performs the read or write operation according to the protocol logic.


Both primary/ and secondary/ folders contains a couple of simple examples that shows the whole process:

  1. The primary device reads info from the first secondary one: a "button device" that puts that button value into a buffer that is being sent when asked (classic "read from secondary" operation).
  2. Based on the given value, the primary one changes it's own status led and
  3. also sends to a second secondary device (one with three different leds) the specific command to turn on or off those leds ("write to secondary" operation).

The example, even being silly, covers the basics of sending, reading (single and multiple bytes) and acting both as a primary and secondary devices. There's also another connection to a ssd1306 oled screen that prompts a picture at the beginning using the same libs (another proof of concept without any "real application" :_ D).

I tried to comment everything I could on the libs itself and the examples, since I wanted to know exactly why something needs to be done (and sometimes it's kinda hard and that's when the trial and error appears! :D) so I think it's pretty self-explanatory.

(buuuut I'm not an expert on this field, so maybe there're things that can be done easily or some mistakes on my side!)


Here's a schematic for the wiring used on the example code (or check the schematic.pdf on the main folder). Also keep in mind the following:

  • Remember to use 10k (or similar) resistors to pull-up the SDA and SCL lines (some devices - like the NES Mini Controller! - seems to use it's own internal resistors, so there's no need to add anything if you're just working with one of those).
  • The libs are set with the attiny85 pins in mind: SDA and SCL on PB0 and PB2. Needless to say, this needs to be changed for other micros if required.

TODO, pending, work in progress, etc.

  • Test on different micros (working on attiny85's only, at least for now)
  • There's no arbitration implemented for primary devices
  • Testing, testing, testing (and bugfixing)
  • More learning: why is this exactly happening at that moment, etc.


While working with some NES Mini Controllers I started tinkering with the I2C protocol in order to connect them into some attiny85's micros I usually use on my projects (I managed to do something interesting here!).

First I used a pure software implementation approach and made a bit-banging small driver to act as a primary device and being able to control multiple I2C devices I had (those controllers, some ssd1306 oled screens and so on); but then I started reading about the "native" AVR approach: the Two-Wire mode.

After more reading, poking and trying lots of external references (there're lots of I2C implementations out there, some of them worked, others didn't, another ones are more Arduino-intended, maybe a bunch of them are made on C++...) I wrote this pair of C basic libraries that allows me to manage the I2C protocol on my attiny85's both from primary and secondary sides.


With no particular order, here's a bunch of links and documentation I found useful when writing this. Some of the code provided there is wrong or broken, but I used it as a reference to start fixing and debugging my own approach (other parts are more similar, like the state machine on the secondary side that can also be found here.


I2C libraries for attiny85-like AVR micros







No releases published