Let's Make Robots!

ATtiny Adventure -- I2C on ATtiny 84/85

ATTiny 84/85 stuff
AttachmentSize
Arduino_to_ATtiny_85__through_I2C_2_4.zip2.27 KB

UPDATE: Added info on making SPI programming jig (makes life a lot easier).

UPDATE: Added ATtiny 84 info (though, the post is meant for the ATtiny 85).

I've been non-traditional microcontroller curious for a bit.  Then, I had to put a Digi-Key order together for some real cheap stupid stuff (some SOT-23 N-Channels for the LiPo charger circuit) and I thought, "What the hell, let's order some ATTiny 85s."  Being cheap like I am, I ordered SMD:

I then ran over to OSHPark and made a little breakout for it:

This brought the price for one ATTiny 85 board to $1.53 each.  This is great, since the ATTiny 85 has an internal oscillator up to  8mhz, allowing it run without any passives.

I was pretty excited the day they came in.  I soldered them together, put some headers on them, and tossed them into a bread board.  I switched over to Goggle and searched how to program these little guys.  The first article I hit was the one I eventually used, I just warn you, dear reader, read careful not to miss the bit about ignoring the error.  Personally, like the dumb-arse I am, programmed my first little ATtiny 85 a hundred times thinking it wasn't working before I caught the caveat in the instructable:

"It should give the following error twice: avrdude: please define PAGEL and BS2 signals in the configuration file for part ATtiny 85"

This error means you programmed it successfully. 

 

But you all probably got that.

The easiest way to get going with I2C with the ATtiny 85 is using the TinyWireS and TinyWireM libraries for Arduino.  

  • TinyWireS (this is Rambo's library, he updated the original with onRequest, onReceive functions) 
  • TinyWireM

To get the ATtiny 84 to work you'll need to add support:

They were developed to be comparable to the Wire library for Arduino.  To install them, just unzip them and place them in your Arduino libraries folder (e.g., C:\Program Files\Arduino\libraries).


(Here's the pinoutfor the ATtiny 84)

The I2C connections are pretty straight forward:

  • Arduino SDA <--- 4.7k Resistor Tied to 5v ----> ATtiny 85 -- PB0 
  • Arduino SCL <--- 4.7k Resistor Tied to 5v ----> ATtiny 85 -- PB3 
  • ATtiny 85 -- PB1 <--- 330 Resistor ---- LED ---- > GND

Below is code meant to demonstrate the purpose of this project.  It sets the ATtiny 85 as an I2C slave.  It receives data over the I2C line, parses it into an integer, then writes this value of the integer to pin 1 (PB1).

// the 7-bit address (remember to change this when adapting this example)
#define I2C_SLAVE_ADDRESS 0x4 

// Get this from https://github.com/rambo/TinyWire
#include <TinyWireS.h>

// The default buffer size, Can't recall the scope of defines right now
#ifndef TWI_RX_BUFFER_SIZE
#define TWI_RX_BUFFER_SIZE ( 16 )
#endif

//Character variable used to echo data back. 
char chrSendData;

//Variables used in getting and parsing data.
char rxChrData; //Receives the data.
char rxString[12];  //Varbiable for holding one string of data.
int rxIndex = 0; //Used to index rxString.

//Integer for holding the pwm value received from master.
int pwmValA;

void requestEvent(){  
  TinyWireS.send(chrSendData);
}

//Handles receiving i2c data.
void receiveEvent(uint8_t howMany)
{
    if (TinyWireS.available()){  
      if (howMany < 1)
      {   // Sanity-check
          return;
      }
      if (howMany > TWI_RX_BUFFER_SIZE)
      {   // Also insane number
          return;
      }
  
      howMany--;
      if (!howMany)
      {   // This write was only to set the buffer for next read
          return;
      }
      while(howMany--)
      {   //Gets i2c data. 
          rxChrData = TinyWireS.receive();
          //Places the characters in an array one at a time.
          rxString[rxIndex] = char(rxChrData);
          //Increment the data array.
          rxIndex++;
          //If a stop character is read, parse the char array and convert it to a single integer.  
          if (rxChrData == ':'){
              //This is a low memory form of parsing the char array into an intger
              pwmValA = int(100*rxString[2]+10*rxString[3]+rxString[4]);
              //Prints the parsed value.
              Serial.println(pwmValA);
              //Writes the parsed value to pin 1 (PB1).
              analogWrite(1, pwmValA);
              //Resets the char array index.
              rxIndex = 0;  
         }
      }
    }
}

void setup()
{
    Serial.begin(9600);
    pinMode(1, OUTPUT); // OC1A, also The only HW-PWM -pin supported by the tiny core analogWrite
    TinyWireS.begin(I2C_SLAVE_ADDRESS);
    //Sets up the onReceive function (what we do if we get stuff).
    TinyWireS.onReceive(receiveEvent);
    //Sets up the onRequest function (what we do if asked to send something).
    TinyWireS.onRequest(requestEvent);
}

void loop()
{
//Detects a stop sending command.
TinyWireS_stop_check();

//Puts the data we got into a variable to send back for error checking.
chrSendData = char(rxChrData);

}

 

I've also included the code I used on my Arduino Mega, which was setup as the master.

Your setup should not look like this :P

I've got several ideas I'd like to attempt with this setup.  But, it is somewhat silly.  The I2C reduces the ATtiny 85 to four pins.  But one of those is the reset pin (PB5), so really, only 3 usable pins.  

Before I started working with the Tiny I was lurking in the shoutbox and oversaw Protowrx chatting about making an ATtiny into a serially controlled motor driver.  So, I set to it.  I had chosen I2C because I wanted to make a setup like the DRV8830 (Spark fun has a breakout). Of course, like the numbskull I am I didn't do the simple math before sinking hours into interfacing with a chip.

Most H-Bridge ICs require three pins a motor.  Two digital pins for direction and one for PWM.  Even cheaping out and using one PWM pin for both motors, that's still five.  And...the ATtiny 85 has 8 pins.  1 x Power, 1 x Ground, 2 x I2C line, which leaves us with....4 pins. Oh wait! One of those is the reset pin and cannot be used without losing the ability to program it without an AVR programmer (which I have, but what a pain in the ass).  So! In short, there are 3 usable pins after interfacing with the ATtiny. I'd have done myself a favor if I had remembered an 80s classic.

Still, I've I got it in my head to attempt doing something like this: 2 Pin HBridge control. Only, tying the PWM line together.  Not having much luck right now (only spent about 20 minutes, wanted to get this typed up before I forgot crap).

Another idea is to use a Software Serial to send one way communication through the serial line.  But it doesn't make much sense, since 4 pins aren't much better than 3, given my intentions.

Ok. In conclusion, I'm not sure why I did this.  It really doesn't make much sense, other than the adventure.  I'm sure it's one of those things I work out now and I won't find a use until much later.  The real killer is thinking about how you can buy a full Arduino Pro Mini on the eBay for $3.45. A little more than double the cost of an ATtiny 85 but triple the pins and utility.  Eh!

 

Making a ATtiny Jig:

I hate breadboarding.  Let me admit that.  Mainly, it is having wires everywhere, my little dyslexic brain can't keep up.  And when I first started working with the ATtiny uCs I found it to be a pain to have to move my little ATtiny's between my full circuit and the SPI programming circuit.  So, I thought, "Why not make a SMD programming pad and jig interface?"

Well, here is the crude son-of-a-bitch: 

It's nothing fancy, but it is a time saver.

I put both the interface pads and the jig in my Eagle library.

POGO_PIN_JIG_SPI

POGO_PIN_SPI_PAD

Ladvien's Eagle Library

Here is my ATtiny 84 with the pads and the Jig PCB:

Jig ($.60

ATtiny 84 PCB ($1.85)

These are the pogo pins I used:

P100-B1 -- 1.36mm diameter

 

 

 

It was not too hard to put together, I set it up something like this.  Then, it is all about added flux to where the pins meet the PCB and soldering like you would usual header pins.  

 

 

 

 

 

 

 

 

 

 

 

And here it is in action.  It surprised the hell out of me, worked exactly like I wanted it.

I'm sure I'll eventually add some stabilizer bars between the two-PCBs and maybe a guide pin to prevent me from pressing the pins in the wrong holes :(

Still, it is MUCH easier than pulling it from the breadboard and moving it to a new circuit.  Makes me happy.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
This is the most perfect use for pogo pins yet. I can't wait to see the rest. The stabilizer rig, but there is something so gratifying about a project where the implementation is as elegant as you plan it to be and it just works the first time!
Thank you. I needed a win. I apparently made two documenting mistakes on my HM-10 work that cost a couple guys some time. Sigh. I feel like an ass. Hope you're well, sir! :)

There's enough pins on the 84 to run two servos, and take readings from two MaxSonar EZ, offloading this function ...

 

Hmm...  I think I might just do this over the holidays!  Free up much of that resource from my main Arduino!

 

 

Hello Mr. Guru, sir.

I hope you share when you get it working--I'd like do what you described, but right now my focus is too split to get it done.

By the way, I love your robot :)

In my head it is the vehicle Mad Max is driving, but instead of Mel Gibson, ChickenParmi is Mad Max.

While I'm waiting for my Tiny84s to show up at my door, I've started this working on an Arduino Pro Mini.

Thank you for the feedback on my bot.   Hmmm.. now if someone would 3d print me a little Parmi to stuff onboard..... LOL

 

 

How large is the final SOIC+breakout? The dip8 is only about $1.25 most places. I know you are a big fan of sm (and my hands shame too much to even consider it,) but as a strictly economical concern I thought I'd mention it...

Hello, sir.

I see your point :)

My writing lacks a lot of logic connections; for instance, checking other sites, like Mouser.  I simply compared the DIP to SOIC on Digi.  Also, I was thinking the size once embedded into a circuit board, rather than on a breadboard. The breadboard was only to let me work with a chip I'd then remove and embed.

For instance, the design here I believe would be much smaller (if we include volume) as compared to the DIP.

Those are the best rebuttals I got. Oh! And I smoke crack.

Hope you're well, sir.

I've been down the same road. Have some ATtiny85 samples. My conclusion is also that it's not worth the trouble. I recently designed a board (my Bajduino Mini) that can take an ATmega8/168/328 in tqfp. Lots more pins/possibilities... My board may be a lot bigger (42x42mm) but I don't need really small :)

I hear you.

The ATtiny 84 ($1.33) actually has my attention now.  And the ATtinyWire libraries are supported on the 84.

 

Some time ago I went down the same alley - http://letsmakerobots.com/node/31379 - and then concluded it were not worth the trouble. The tinys simply arent cheap enough! I have since settled on using ATmega8 when I want to go really cheap. The only parameters where I see the ATtiny85 superior to the ATmega8 are

  • size, but we sorta wreck this when we solder them on a breakout board
  • power supply, the tiny go all the way down to 1.8v but it might require you to clock it really low
  • power consumption. the tiny isn't spendy. But then again, on a motor controller then a few mA more or less..

and then the other way around

  • the ATmega8 have plenty I/O

Just checked ebay. today I can get an ATMEGA8-16PU for US $1.47. including

  • free shipping
  • 28 sharp pins to trample on when walking barefooted in the workshop
  • lovely +4 weeks of waiting for the slow boat from China