ATtiny i2c Slave

I’m working on a project where I need several sensors that communicate back to a central processor.  Since I’ll have several of these sensors I need them to be cheap and the ATtiny85 jumped to mind.  The only problem is that I’ve never used i2c with the ATtiny series before.  I read dozens of “tutorials” about it from around the web and couldn’t find a nice simple example.  This is my solution.

The first thing to do is download the ATtiny85 i2c slave library.  You can find this library here: https://github.com/rambo/TinyWire/tree/master/TinyWireS.  Click the download zip button and then unzip the folder into the libraries folder in your Arduino folder.  This is by default in Documents/Arduino/libraries.  If this folder doesn’t already exist, create it.

Image

Next, connect the circuit.  As a refresher, here is the pinout for the ATtiny85.

Image

And here is the SDA and SCL pins for various microcontrollers.

Controller SDA SCL
ATtiny85 5 7
Arduino Uno A4 A5
Arduino Mega 20 21
Arduino Leonardo 2 3
Arduino Due 20 21

For my example, I’m using an ATtiny85 and an Arduino Mega2560.  Connect the SDA pin on one to the SDA pin on the other and the SCL pin on one to the SCL pin on the other.  This isn’t like RX/TX pins where you need to cross them.

Image

Now, just program the ATtiny 85 and the Arduino Mega with the following code and voila.  The Mega requests data from the ATtiny, which returns a number and then increments it.

// Code for the ATtiny85
#define I2C_SLAVE_ADDRESS 0x4 // Address of the slave

#include <TinyWireS.h>

int i=0;

void setup()
{
    TinyWireS.begin(I2C_SLAVE_ADDRESS); // join i2c network
    //TinyWireS.onReceive(receiveEvent); // not using this
    TinyWireS.onRequest(requestEvent);

    // Turn on LED when program starts
    pinMode(1, OUTPUT);
    digitalWrite(1, HIGH);
}

void loop()
{
    // This needs to be here
    TinyWireS_stop_check();
}

// Gets called when the ATtiny receives an i2c request
void requestEvent()
{
    TinyWireS.send(i);
    i++;
}

 

//Code for the Arduino Mega<
#include <Wire.h>

void setup()
{
 Wire.begin(); // join i2c bus (address optional for master)
 Serial.begin(9600); // start serial for output
}

void loop()
{
 Wire.requestFrom(4, 1); // request 1 byte from slave device address 4

while(Wire.available()) // slave may send less than requested
 {
 int i = Wire.read(); // receive a byte as character
 Serial.println(i); // print the character
 }

delay(500);
}

 

If you enjoyed this post you might also enjoy these posts:
This post is about a problem sending more than 1 byte with the Arduino I2C.
This post is about sending 16 bit and 32 bit numbers over I2C.

a

Advertisement

18 thoughts on “ATtiny i2c Slave

  1. Hi, thanks for the explanation. This works great.
    If I want to return two float variables to the master, do I need to create a routine that sends every single byte?

  2. The TinyWireS.onRequest and the TinyWireS.onReceive commands aren’t in my library. How can I use them? Is there a way to these two commands?

  3. Hi I have downloaded the TinyWireS library from the URL that you list but the sketch does not compile with a myriad of errors. If I comment out the onReceive and onRequest lines of code on my sketch the sketch compiles under the original TinyWireS which unfortunately did not implement onReceive and onRequest. Can you help?

  4. Hi,

    I am using attiny85 along with HC-05(bluetooth(soft serial)) and oled(two wire protocol). Individually each of these works perfectly but once i combine both oled and bluetooth in single projects it fails. I am using pin 3, 4 (tx, rx ) and pin 0, 3 (sda, scl) for communication. Any idea whats going wrong

  5. Thank you for putting this together. I only hope I can help this climb in the search results. I spent hours thinking I know I am not trying to do something new.

  6. Do you have to compile and upload the atTiny code and Arduino code separately? Meaning, upload first the code to atTiny then disconnect it from arduino then upload code to Arduino? Thank you.

    1. Yes, you first have program them individually (in either order) then they can talk. The attiny could be programmed using an arduino, an external programmer, etc.

  7. I’ve been trying all week to find a working example of I2C communication between an Uno and a Trinket. This works flawlessly. I used the .zip library installation method for the TinyWireS library. I also had an Adafruit Wire.h library the compiler was trying to use instead of the Arduino one. I just renamed the folder containing the Adafruit version and all was well.

  8. Hello! Thank you for providing info about at tiny and i2c. I have the same problem, a lot of info out-there, but not much practical… anyway, I would like to use the tiny as a master, so that tiny read data from the sensor. How would you approach that?

    Any info is very much appreciated!

    PS I am using Arduino UNO for programming Tiny and so-far it work with the library // I2C Master lib for ATTinys which use USI, I guess the tiny is the master, not slave like in your case…

  9. I just did this tutorial and found two issues. The most current tinywireS library isn’t working; you need to download an older version or you’ll just get 255 over and over (see the repo issues for details). My UNO now has dedicated SCL and SDA lines, but they are not marked on the top silkscreen (weird!). Flip the UNO over to determine where these pins are located. See notes on my process here: http://taylorhokanson.com/2018/04/30/diy-i2c-modules/

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s