Introduction: ATtiny85 & ATtiny84 Analog Pins, Serial Communication, Etc.

About: We sell DIY kits for electronics. Please check out our website: http://www.jouletime.com/
I like using an ATtiny84 or ATtiny85 on my projects. They can save a few pennies and make the design a little smaller. The best instruction for setting up these chips to be used with the Arduino IDE is on the MIT, High Low Tech, website http://highlowtech.org/?p=1695. They show you how to wire the chip to an Arduino for burning the bootloader and uploading sketches.

The chips work similar to the Arduino Uno with a some limitations. I found that advice on the web was sometimes confusing or in a few cases wrong. You are left to figure the rest out on your own.

I put together details on some aspects. I hope you find there is enough detail to make using a ‘tiny easy.

Step 1: Problems With Counting

When you use an ATtiny84 or ATtiny85, you are most likely using a breadboard or circuit of your own design. Unlike an Arduino Uno, that has the pins at the headers numbered to match the pin numbers in the Arduino IDE, you will have to wire your ‘tiny to the actual physical pins.

The physical pins and the pin numbers in the software are very different. For example, on an ATtiny84, physical pin 1 is for Vcc while, in the software, digital pin 1 is actually physical pin 12. You have to understand from context which pin (physical or software) is being talked about (hint, most references are for the software pin). It is best to refer to a diagram as you go through the explanation.

To add more confusion, the analog pins can have different numbers than the digital pins at the same physical location. This is happens with the ATtiny85. For example, the physical pin 7 is both the digital pin 2 and the analog pin 1. Digital pin 1 is the physical pin 6, and it has no analog input. (I only hope that the chip designers saved the company a lot of money for the confusion this can cause.)

This situation is due to the chip designers and not caused by the Arduino software. The pin numbers are based on how port B and the ADC is mapped. Pin 7 is PB2 (digital pin 2) and ADC1 (analog pin 1).

Step 2: Glitches With the Arduino Software

When you are using a Mac with Arduino v1.0+, if you enter a variable statement for “A1”, it will give you an error, 'A1 has not been declared', see code below. Strangely, the analog pin references “A1”, “A2”, etc. work when programing the Arduino Uno.

int analogPin1 = A1; // this will give an error when you verify

int analogPin1 = 1; // instead this will work to select A1, physical pin 7

int val = 0;

void loop()

{ val = analogRead(analogPin1); //this gives an analog reading of A1, at physical pin 7.}

Here is the confusion thing; you can also call out a digital pin 1.

int digitalPin1 = 1; // this is physical pin 6

void setup()

{ pinMode(digitalPin1, OUTPUT); // declare pin 1 as an output}

void loop()

{ digitalWrite(digitalPin1, HIGH); // turn ON}

If you have Windows or Mac with Arduino 1.5.6, then you can instead use “A1” and reduce some confusion between it and digital pin1. But if you get used to the other way, it should continue to work.

Step 3: Using SoftwareSerial for Communication

Suppose, you want to use an ATtiny85 to send the readings from its analog pins, how would you do it? It has limited serial communication. There is a software library included with Arduino that allows you to add serial communication to your sketch, SoftwareSerial. It is easy to add, but it does take up program space and you have to declare a few details.

For the ATtiny85 example below, burn the bootloader to use the 8 MHz internal crystal. Otherwise the same pins for serial are needed for the crystal.

First you must include the library with your sketch by using the #include at the start.

#include "SoftwareSerial.h"

Then you create variables for the function and call the function.

const int Rx = 3; // this is physical pin 2

const int Tx = 4; // this is physical pin 3

SoftwareSerial mySerial(Rx, Tx);

In the setup(), you enter whether the pins are input or output, and specify the baud rate.

void setup()

{ pinMode(Rx, INPUT);

pinMode(Tx, OUTPUT);

mySerial.begin(9600); // send serial data at 9600 bits/sec }

When you call the serial print statement you add “my”.

void loop()

{ mySerial.println(val); // send the value to Serial Monitor, ^Cmd-M}

Now, open the serial monitor to see the values coming from the ‘tiny.

The same instruction can apply to the ATtiny84. With this chip you have more pins to support both an external clock and serial communication. If you do, then you will need to pick other pins for the serial lines.

Step 4: Sample Code. ATtiny85_SoftwareSerial_Test

// For ATtiny85 Turn on LED and Analog Read
//RESET | pin 1 pin 8| 5V

// 3/A3 | pin 2 pin 7| 2/A1

// 4/A2 | pin 3 pin 6| 1/PWM

// GND | pin 4 pin 5| 0/PWM

// for SoftwareSerial you must set up as internal clock // to free up physical pins 2 and 3.

// This will flash an LED on physical pin 6, read the analog value on pin 7, and send the

// analog value to the Serial Monitor for display.

#include "SoftwareSerial.h"

const int LED = 1; // this is physical pin 6 for the LED

const int ANTENNA = 2; // this is physical pin 7, connect wire as antenna

const int Rx = 3; // this is physical pin 2

const int Tx = 4; // this is physical pin 3

SoftwareSerial mySerial(Rx, Tx);

int val = 0; // variable to store antenna readings

void setup()

{

pinMode(LED, OUTPUT); // tell Arduino LED is an output

pinMode(Rx, INPUT);

pinMode(Tx, OUTPUT);

mySerial.begin(9600); // send serial data at 9600 bits/sec

}

void loop()

{

digitalWrite(LED, HIGH); // turn LED ON

delay(500);

digitalWrite(LED, LOW); // turn off

delay(500);

val = analogRead(ANTENNA); // read the ANTENNA

mySerial.println(val); // send the value to Serial Monitor, ^Cmd-M

digitalWrite(LED, HIGH); // turn LED ON

delay(10); digitalWrite(LED, LOW); // turn off

delay(500);

}

Step 5: Sample Code, ATtiny84_SoftwareSerial

// For ATtiny84 Turn on LED and Analog Read

// 5V | pin 1 pin 14| Gnd

//10/X1 | pin 2 pin 13| 0/A0

// 9/X2 | pin 3 pin 12| 1/A1

//RESET | pin 4 pin 11| 2/A2

// 8 | pin 5 pin 10| 3/A3

// A7/7 | pin 6 pin 9| 4/A4

// A6/6 | pin 7 pin 8| 5/A5

// for SoftwareSerial you can use external clock since physical pins 2 and 3 are free.

#include "SoftwareSerial.h"

const int LED = 5; // this is physical pin 8 for the LED

const int ANTENNA = 1; // this is physical pin 12, connect wire as antenna

const int Rx = 7; // this is physical pin 6

const int Tx = 6; // this is physical pin 7

SoftwareSerial mySerial(Rx, Tx);

int val = 0; // variable to store antenna readings

void setup()

{

pinMode(LED, OUTPUT); // tell Arduino LED is an output

pinMode(Rx, INPUT);

pinMode(Tx, OUTPUT);

mySerial.begin(9600); // send serial data at 9600 bits/sec

}

void loop()

{

digitalWrite(LED, HIGH); // turn LED ON

delay(500);

digitalWrite(LED, LOW); // turn off

delay(500);

val = analogRead(ANTENNA); // read the ANTENNA

mySerial.println(val); // send the value to Serial Monitor, ^Cmd-M

digitalWrite(LED, HIGH); // turn LED ON

delay(10);

digitalWrite(LED, LOW); // turn off

delay(500);

}

Step 6: Electrical Issues

In testing, I found that the serial communication works only with a common power and ground. In practice this means getting the power from the USB – serial communication device. The USB – serial communication device can be an Arduino Uno board, a standalone USB – Serial board, or an AVR programmer like the Reactor Core 3-in-1 programmer.

Wiring is like you would expect. Power from the Arduino/USB device goes to power on the ‘tiny (pin 1 for ’84, and pin 8 for ’85). The same type of connection applies for ground (pin 14 for ’84, and pin 4 for ’85). The pin you assigned to Rx (pin 3 in sample code) goes to the Rx line on the Arduino, pin 0/Rx. Do the same to the pin you assigned to Tx (pin 4 in sample code) goes to the Tx line on the Arduino, pin 1/Tx.

I have read about adding resistors in series with the serial connection. I don’t think this is needed. FTDI does not list using resistors to hook up their FT232RL USB/serial chip. From the ‘tiny to the USB/serial device, it should all be TTL. You can add 200 – 2K ohm resistors if you want to be extra careful.

If someone knows a good reason for this, please post it.

I have also seen the addition of a capacitor across the reset and ground on the Uno board. I am not sure what this is supposed to do. It may keep the ATmega328P on the Uno board reset so that the serial lines are not being used by the Uno. I would think a jumper may work.

If you are using an Arduino Uno to bridge the serial communication with your computer, it needs to be loaded with a sketch that won’t interfere. If you get weird characters on your serial monitor, then that shows corruption of the signal. You need to isolate the serial line to only the ‘tiny. If you are using a Reactor Core programmer, then disconnect the serial jumpers. That will isolate the serial from the on board ATmega.

Step 7: Miscellaneous

Do you have to use the internal clock for serial communication? No, for the Attiny85, instead of pin 3 & 4 that are required for the external clock, you can use another two pins. If two pins are used for serial, and two pins are used for the external crystal, then you have one free pin unless you disable the reset. That is why it is better to use the internal clock. It will free up two pins.

Where can you get an awesome Reactor Core 3-in-1 programmer for Arduino/AVR microcontrollers? They were originally only available through a Kickstarter campaign https://www.kickstarter.com/projects/1257390142/re.... Once those boards are delivered, they will be for sale on Amazon. Check back in June 2014, Amazon, ReactorCore, Link.

Step 8: Appreciation