ATTiny84 - I2C Slave - Arduino UNO




About: I have been working in IT since the mid 1980's. Most of that has been database and application development. I've been working on Internet application development since the late 1980's. I've just moved back ...

I've been working on building the pieces that I need to make myself a CNC PCB Mill for a little while now and the next part of the puzzle is trying to get the Arduino to control 3 step motors simultaneously. Since the architecture doesn't support multi-threading or multi-tasking, my solution is to outsource the control of each of the step motors to slaved devices.

This is where this instructable comes in.

The goal with this mini project is pretty simple, really ... connect three ATTiny84 microprocessors to an Arduino UNO via I2C (or TWI in Arduino parlance). While this sounds simple, there were some hurdles that I had to overcome along the way, these hurdles are really more about my knowledge and understanding than anything else.

Anyway, as with my other instructables, I'll try to explain what I've done and why and what I learned along the way.

The above breadboard image is an annotated photo of the prototype that I put together ... this was the easiest bit.

If you want to do this yourself, you're going to need:

  • 1 x Arduino UNO
  • 3 x ATTiny84
  • 2 x 4.7k ohm resistors
  • 3 x 220 ohm resistors
  • 3 x 3mm LED
  • a bunch of jumper wires (I cut mine for this project so's they'd be all purty

Teacher Notes

Teachers! Did you use this instructable in your classroom?
Add a Teacher Note to share how you incorporated it into your lesson.

Step 1: Breadboard Prototype

The three ATTiny84 chips are set into the breadboard so that there are 5 holes separating them and so that the Vcc and GND pins (1 and 14) are lined up with the rail holes.

I've jumpered the two RED and BLUE rails together across the board so that I can access the rail closest to the pin.

Pin 14 on the three ATTiny84 are connected to the BLUE rail, and Pin 1 is connected to the RED rail.


Pin 13 of the ATTiny84 is connected (with the yellow jumper) to the anode of the LED and the cathode of the LED is connected to the BLUE rail via a 220 ohm resistor.

The SCL of the ATTiny84 (pin 9) are brought together (green wire) and connected to the RED rail via a 4.7k ohm resistor.

The SDA of the ATTiny84 (pin 7) are also brought together (blue wire) and connected to the RED rail via a 4.7 k ohm resistor.

The Arduino is connected to the breadboard as follows:

5V is connected to the RED rail, GND is connected to the BLUE rail. Analog 5 (A5) of the Arduino is connected to the SCL jumpers and Analog 4 (A4) is connected to the SDA jumpers.

This gives us a nice I2C network with the ATTiny84 clock and the Data line communicating with the Arduino to it's compatible pins. The other important shared wires in I2C are the power and ground ...

If you follow the breadboard layout image, you'd be just fine. You can ignore the pin headers in the diagram, they are for a PCB implementation (which I'll show you later).

Step 2: Program the Slaves

Because I'm using ATTiny84 chips, it is necessary to use the TinyWireS header (google it, it isn't hard to find). Also, because the ATTiny84 is acting as a slave only, this is all that it needs.

Each of the three ATTiny84 chips are given a unique address in the network:

#define I2C_SLAVE_ADDRESS 0x1

#define I2C_SLAVE_ADDRESS 0x2

#define I2C_SLAVE_ADDRESS 0x3

The #define line in the sketch is the only line that differs in this example.

My example differs from the source sketch that I took from The Wandering Engineer in that I am connecting three ATTiny84 and I have included an indicator LED that toggles on and off when it receives instruction from the I2C Master.

In the attached sketch, I've added some logic that determines the state of the LED based on the divisibility of "i" by 2, using a simple modulo trick:

void requestEvent()
{ if(i%2==0) {digitalWrite(LEDPin, LOW);} else {digitalWrite(LEDPin, HIGH);} TinyWireS.send(i); i++; }

if i divided by 2 results in 0, then turn the LED off, otherwise ... turn it on, then send i to the I2C Master.

Step 3: Program the Master

Again, this is derived from The Wandering Engineer and remains mostly unchanged.

The main difference, again, is that there are 3 slaves that I want to control, not just one.

I've included a simple for loop to control the three slaves sequentially and then some string concatenation to manage the serial alerts sent back from the Slaves to the Master

The for loop

for(int x = 1; x < 4; x++)

The message back to Serial

String rString = "";
rString.concat(x); rString.concat(" value is "); rString.concat(i); Serial.println(rString);

Simply echo back which slave sent back which iteration of the code.

Step 4: All Hooked Up

Here it is in action.

The Arduino UNO is connected to SCK, SDA, 5V and GND as promised and the UNO is given some power via a 9V battery.

The lights go on ... the lights go off.

When connected to power via USB rather than 9V, I can open the serial monitor and get some highly influential messages back from the slaves.

Most illuminating indeed!

As it stands, this prototype works and I am pleased that it wasn't as much trouble as I thought it would be. To be honest, reading through some of the articles on the interweb left me thinking that I wouldn't be able to get the library working with the ATTiny84 ... but then, I figured, meh, what the hell ... give it a go.

I'll be extending this with more functionality later on so that the ATTiny84 will be able to receive more pertinent instructions from the UNO in order to control some step motors.

Step 5: PCB Design

Above is the promised PCB design that I've cobbled together as a simple circuit that will carry the 3 ATTiny84 boards and provide some breakout connections to the Tiny's. The circuit also has a connection bridge to the Arduino Uno.

I prefer the ATTiny84 to the ATTiny85 in this design for two main reasons:

  1. The ATTiny84 provides me with more pins to connect to;
  2. The ATTiny84 pin-out arrangement makes placing the microprocessor and traces much easier, the ATTiny85, with its Pin 4 GND pin 8 Vcc arrangement makes the design a bit of a hassle ... not one that is insurmountable, but enough of a pain that I didn't bother (with the reason 1 taken into consideration)

So, there you have it. Three ATTiny84 microprocessors in an I2C slave circuit, all that's left now is to program these little champions in a more useful way ;)

I've added the Fritzing file so that you can make one for yourself.

By the way, I used two Arduino Uno for this project, one was set up as a programmer for the ATTiny84 (using the ATTiny84 modified Arduino As ISP from a previous instructable). This made programming the ATTiny84 and Arduino UNO much easier while I was prototyping the sketches).

Step 6: Design to PCB

I've built the I2C board for the three ATTiny84 microprocessors and connected the A0 pins of the ATTiny84 chips to the LED that were used in the breadboarded example and also connected Vcc, GND, SDA and SCL from the Arduino to the I2C board and it all worked just dandy.

The next step was to build the PCB version of the Arduino I2C Master board (Fritzing design attached).

The Arduino I2C Master board uses a Freetronics USB Serial module to allow me to run the sketch and monitor the Serial output to screen.

I am pleased to say that the Arduino I2C Master board works a treat, doing exactly what I planned for it to do.

Now I have both the I2C Slave board and the I2C Master board, I can move on to my next project along the path to building my CNC Etching Mill ...

If you liked this instructable, please feel free to vote ;)

Home Automation

Participated in the
Home Automation

1 Person Made This Project!


  • Made with Math Contest

    Made with Math Contest
  • Multi-Discipline Contest

    Multi-Discipline Contest
  • Robotics Contest

    Robotics Contest

23 Discussions


Question 1 year ago

I get an issue with the ".onRequest()" bit. Arduino has an issue compiling this. In addition, the complier doesn't recognize this function. Could you please help me understand why?

1 answer

Answer 1 year ago

Hi nas476, onRequest is a library function of the TinyWireS library. To include this library in your sketch you'll need to locate and download the library. Good luck!


2 years ago

Hi! Thank you for this, it's very useful. Did you manage to control the steppers? Would love to check that out, I need some help for a project i'm working on :)

2 replies

Reply 2 years ago

Hi NicoleL37, nope, using an Arduino I2C and ATTiny84 wasn't successful for controlling three steppers simultaneously, it's great for other stuff, just not so much for that purpose. I ended up making a controller using Arduino, 3 x EasyDrivers and a bunch of other stuff and then using the GRBL library. I'm still working on CNC, I've prototyped a couple of different solutions and still working on a simple and cheap solution.

All that aside ... how can I help?

The Lost Puppybaelza.bubba

Reply 2 years ago

This is a very neat project which I may have to try in the future. I read your reply to NicoleL37 and would like to know what exactly was the issue when trying to control 3 stepper motors simultaneously?


Reply 4 years ago on Introduction

Hi Clapoti, it's a pretty useful project and surprisingly easy to implement. I2C can be a useful part of an overall home automation architecture ... add in some really cheap RF modules (like the nordic NRF24L01+) and you can get some nifty interoperability happening. I've just received 3 of these modules and I'm doing some experimentation.


Reply 4 years ago on Introduction

You're welcome ... I've just started playing with the NRF today ... soon I'll do something with it ;)


4 years ago

Since you are breadboarding everything else... why not breadboard in the atmega328 in place of an external uno?

2 replies

Reply 4 years ago on Introduction

Here's a breadboarded ATMega328P-PU running a simple Blink sketch. I've used the SMD version of my 5V Regulated power supply instead of breadboarding it (a cheat). You can see that running the 328P doesn't take many components and is quite straight forward.


Reply 4 years ago on Introduction

Hi x1134, true, very true. I have a ATMega328P-PU breadboarded, I'm planning on having all of the circuit "native". I'm building up the separate workflow parts as discrete circuits which I will pull together as one when I've proven the separate parts work according to my goals and design. This is still prototype, so I don't mind using the uno in the design, but I don't want to incorporate the uno into the finished project.


4 years ago

Good job! I was planning to use a few ATTiny841 for a similar project. The 841 has real SPI and I2C instead of USI on the 84 chip. The drawback is the lack of "support" for the newer 841 chip from the open source community.

1 reply

Reply 4 years ago on Introduction

Hey Dr_L, thanks ... the lack of support is sometimes a pain. I bought these chips a while ago with plans to tinker and play ... seems I got my wish, good luck with yours ;)


Reply 4 years ago on Introduction

lol, the yellow jumper is a bit hard to see ... I should be more considerate, being colour-blind myself, I know what a hassle that can be.


4 years ago on Introduction

In Step 1, the fritzing of your prototype board, you do not appear to have connected the anodes of each of the LEDs to anything?


4 years ago on Introduction

This looks useful for assorted applications.