Introduction: 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. And, we're back in Tass…

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

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