ATtiny85 Limitations?

Today's my first day tinkering with the ATtiny85 -- I've got a nifty program that works on the Uno, and I'm trying to shrink everything down so it can be run off off an ATtiny85. Here it is... it reads the temperature from a TMP36 and applies a fading on-off effect to an RGB LED, the color of which depends on the temperature read. I think I'm limited to the ATtiny85's number of I/O ports, but I'm not sure. On the Uno, I ran it all off of the 3.3V source and used 270 ohm resistors on each leg of the RGB LED. Is this possible to shrink down, or does the ATtiny85 just not have the I/O for this application? Also, can I use the Do...While structure on a Tiny85?

Here's the code that works swimmingly on the Uno:

const int inPin = 0; // analog pin for temp sensor
const int bluePin = 3; // analog output on Uno pin ~3
const int greenPin = 5; // analog output on Uno pin ~5
const int redPin = 6; // analog output on Uno pin ~6

const int LL = 64; // Lower Limit of acceptable temperature range; below this the light is blue
const int UL = 68; // Upper Limit of acceptable temperature range; above this the light is red

void setup()
{
pinMode(bluePin, OUTPUT);
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
}

void loop()
{
// Read temperature sensor
int value = analogRead(inPin);
float millivolts = (value / 1024.0) * 5000;
float celsius = (millivolts / 10.0) - 50; // this equation from a guy on the SparkFun site
float fahrenheit = (celsius *9)/5 + 32;

// Decide what to do with the temperature reading
if (fahrenheit < LL) // then light the blue LED - it's cold!
{
analogWrite(greenPin, 0);
analogWrite(redPin, 0);
GlowLightOnce(bluePin);
}
else if (fahrenheit >= LL && fahrenheit <= UL) // then light the green LED
{
analogWrite(bluePin, 0);
analogWrite(redPin, 0);
GlowLightOnce(greenPin);
}
else // light the red LED
{
analogWrite(bluePin, 0);
analogWrite(greenPin, 0);
GlowLightOnce(redPin);
}
}

void GlowLightOnce(int bulb) // subroutine applies one fade in - fade out blink of an LED
{
int brightness = 0;
int fadeAmount = 5;
int totalcount = 0;
do
{
analogWrite(bulb, brightness);
brightness = brightness + fadeAmount;
totalcount++;
if (brightness == 255)
{
fadeAmount = -fadeAmount;
}
delay(35);
} while (totalcount < 103);
delay(1000); // pause for a second while the bulb is dark
}

Most likely, the floating-point lib is your issue...
Try int just to determine in it will compile and fit into the t85.

  • Ray

You're saying is that the ATtiny85 has problems using float variables? Ok, I'll give using integers a whirl.

Currently, the code does fit (only about 3k) but I'm unsure what ports (pins) to use on the ATtiny85 to get three analog outputs and one analog input.

tlharv:
You're saying is that the ATtiny85 has problems using float variables?

It does not.

Currently, the code does fit (only about 3k) but I'm unsure what ports (pins) to use on the ATtiny85 to get three analog outputs and one analog input.

Open the ATtiny85 datasheet...

Navigate to 1. Pin Configurations. Pins labeled with "OC" (oh-see) are Output Compare pins. Focus your attention on pins that do not have a bar over the label (the bar indicates inverted output). PB0, PB1, and PB4 are the pins of interest. Those pins support analog output.

Pins labeled with "ADC" (ay-dee-see) are Analog to Digital Converter pins. PB2, PB3, and PB4 are the pins of interest (we're going to ignore PB5 because we need it to remain RESET). Those pins support analog input.

The number after the bit label (PB#) is the number to use for the analogWrite function (i.e. analogWrite(1,127) writes 127 to PB1). The number after the ADC label (ADC#) is the number to use for the analogRead function (i.e. analogRead(3) reads from ADC3 [aka PB3]).

tlharv:
You're saying is that the ATtiny85 has problems using float variables? Ok, I'll give using integers a whirl.

No, it doesn't have any more problems than a Mega328.

tlharv:
Currently, the code does fit (only about 3k) but I'm unsure what ports (pins) to use on the ATtiny85 to get three analog outputs and one analog input.

The Tiny85 has three pins with hardware PWM output, PB0, PB1 and PB4 (hardware pins 5,6,3). They're the best choice for the analog outs.

Thanks everyone. I'll tinker more with it today.

What's PWM stand for? I saw that on the maps and couldn't decipher it.

Pulse-width modulation

PWM is what analogWrite() does (it's not really an analog output).

Well, the good thing is that I now understand how to read the ATtiny85 pin diagram better. My pin arrangements are now:

const int inPin = 3; // analog in, to ADC3 for temp sensor, pin 7 on ATtiny85
const int redPin = 0; // analog out, to PB0 for red LED, pin 5 on ATtiny85
const int bluePin = 1; // analog out, to PB1 for blue LED, pin 6 on ATtiny85
const int greenPin = 4; // analog out, to PB4 for green LED, pin 3 on ATtiny85

And I was able to get it to do the nice fade in/out style of blink I was looking for. However, the input from the TMP36 sensor isn't being used at all, and only the red LED (PB0) is blinking, regardless of whether I run the signal lead from the TMP36 to ADC3 or just leave it unplugged. Am I missing something?

Thanks,
Tom

const int inPin = 3; // analog in, to ADC3 for temp sensor, pin 7 on ATtiny85

It is Pin 2 on Attiny85

Right - that's a typo. Moved the lead to pin 7 and the problem persists. Still not seeing an input.

Can you get an input on any pin? Try them all. Disconnect LEDs if you have to.

Make sure it's not some weird bug in the core for that pin.

I tried your code on my ATtiny85@1MHz with a TMP36 and it ran fine. I set my range for 74 and 78. I was able to make it blink blue when cold and green when in-between and then red when hot.

The TMP36 middle pin-2 is connected to physical pin-2 (PB3 - ADC3) on the ATtiny85. Also make sure you have the TMP36 power and GND connection correct and not backwards. It's very easy to make that mistake. With the flat-side facing you, power is to the left pin-1, GND is to the right pin-3.

Which ATtiny core are you using?
I'm using the Google Code Archive - Long-term storage for Google Code Project Hosting. core.
It's only using:

Binary sketch size: 2,220 bytes (of a 8,192 byte maximum)

Ok, good to know that what I'm trying to do is possible on this chip, i.e. have one analog sensor input and three analog outputs. Looks like from here I just have to figure out the wiring.

Hiduino, mind if I ping you via message to get more specific wiring help on this?

Thanks, everyone. I'm learning a lot through this process.

Okay, your wiring may be correct because, I've tried using the ATtiny85 @8MHz and @16MHz internal, and it appears it doesn't work correctly. It does work correctly @1MHz.

I then added some 100nF decoupling capacitors near the ATtiny85 and it is working correctly now @8MHz and @16MHz internal clocking. The ADC measurements in the ATtiny are much more susceptible to internal electrical noise especially at higher clock rates. The decoupling capacitors help filter the noise.

Hiduino, I set up the ATtiny85 chip core per the link you provided earlier. In order to get the same setup that you managed to make work, after I select the "ATtiny85 @ 1 MHz (internal oscillator; BOD disabled)", should I burn a bootloader before uploading my code?

Yes, whenever you change the ATtiny clock speed selection in the IDE, you need to burn the bootloader to set the appropriate fuse bits. Then you need to follow with the upload the sketch.

Also note, I was able to get the 8MHz and 16MHz to run properly, but you need the decoupling capacitors to make it work. See my previous response reply#14. You should also use the decoupling capacitors even when running at 1MHz to get better ADC readings.

hiduino:
I then added some 100nF decoupling capacitors near the ATtiny85 and it is working correctly now @8MHz and @16MHz internal clocking. The ADC measurements in the ATtiny are much more susceptible to internal electrical noise especially at higher clock rates. The decoupling capacitors help filter the noise.

How many of these capacitors did you use, and where do you place them? Do they bridge the TMP36 pin 1 (V_in) and pin 3 (GND)?

Yes, a couple near the ATtiny85 between Vcc and GND pins. The TMP36 datasheet does recommend a 100nF bypass (decoupling) capacitor across those pins to reduce radio frequency interference.

hiduino:
The ADC measurements in the ATtiny are much more susceptible to internal electrical noise especially at higher clock rates.

The chip has a special sleep mode for making ADC measurements.

Look for "ADC Noise Reduction Mode" in the datasheet.