attiny85 with 3 PWN pins

is there any way to get a third PWM pin from attiny85 using arduino, maybe more? I have read up on it and it seems some people are saying you have to go straight to AVR. I am using arduino as an ISP but there isn't much info on it. There are some people saying that OC1B can be turned into PWM, but not sure if current version of programmer handles this.

It's nothing to do with the programmer, either the chip does it or it doesn't. The documentation seems to say that Timer 1 will run in PWM mode.

ah, I was reading: http://forums.adafruit.com/viewtopic.php?f=24&t=23937 and they said only two are PWM.

what pin would timer 1 be? I'm looking at the documentation, but am new to going straight to the doc, so not sure where to find this info. I am using http://www.atmel.com/Images/doc2586.pdf not sure if that is correct one to reference since it has a few ICs in it.

hilukasz:
is there any way to get a third PWM pin from attiny85 using arduino, maybe more?

The ATtiny85 processor has three pins capable of normal PWM. Use this core...
http://code.google.com/p/arduino-tiny/

I have read up on it and it seems some people are saying you have to go straight to AVR.

Not necessary.

hilukasz:
ah, I was reading: http://forums.adafruit.com/viewtopic.php?f=24&t=23937 and they said only two are PWM.

They are wrong.

what pin would timer 1 be? I'm looking at the documentation, but am new to going straight to the doc, so not sure where to find this info.

Datasheet for ATtiny85. "1. Pin Configurations" section. Pins labeled with "OC" are Output Compare pins which are capable of PWM. Pins with a bar over the label are inverted output and are not used.

OC1B (PB4), OC0A (PB0), OC0B (PB1) are the three PWM pins.

If core is what you put on the arduino to program it, I think I was already using attiny. used the one suggested here though http://hlt.media.mit.edu/?p=1695

by core do you mean what you upload to arduino to program the attiny?

hilukasz:
If core is what you put on the arduino to program it.../quote]

Yes. That is what I mean.

ok cool, thank you. I have downloaded them all (there are 3), however I am just seeing C++ files. am I missing something? Wiki on that page doesn't seem to offer much insight.

Hi,

ATTiny85 has 3 PWM capable pins, all addressable from inside the IDE. Here's the pin declarations from a sketch I used for a halloween decoration that responded with RGB lighting effects to audio from a Wave Sheild on a Uno (ATTiny was mounted on a shield).

// note these LED pins are ATtiny locations
const int redPin = 1;                  // IC leg 6 (PB1), output to red channel
const int greenPin = 0;                // IC leg 5 (PB0), output to green channel
const int bluePin = 4;                 // IC leg 3 (PB4), output to blue channel
const int audioPin = 3;                // IC leg 2 (PB3), audio level from wave shield
const int activePin = 2;               // IC leg 7 (PB2), activation trigger from Arduino

While strictly speaking ATTiny85 leg 2 (D3/PB3) is also capable of PWM, internally it shares the same timer used on leg 3.

Alternatively, you can create PWM effects in software. Something like this will allow you to fade 5 LEDs or other PWM activities where accuracy isn't probably so important (likely you could do something on leg 1 which is D5 also, but I typically try to avoid reusing the reset pin):

void softwarePWM(int PWMfreq, int outputPin, int PWMdelay){
  //PWM on
  digitalWrite(outputPin,HIGH);
  delayMicroseconds(PWMdelay*PWMfreq);

  //PWM off
  digitalWrite(outputPin,LOW);
  delayMicroseconds(PWMdelay*(255-PWMfreq));
} //softwarePWM

Call that function repeatedly on each leg you need to PWM and you have something that (at least for fading LEDs) is perfectly useful. I also used the Arduino-Tiny cores for these.

Cheers ! Geoff

hilukasz:
ok cool, thank you. I have downloaded them all (there are 3), ...

http://code.google.com/p/arduino-tiny/downloads/list
...the first download (Arduino Tiny for 1.0) is the core.

...however I am just seeing C++ files. am I missing something?

Instructions are in readme.txt. They are also available here...
http://code.google.com/p/arduino-tiny/source/browse/trunk/readme.txt

oh duh...I had to do this for the other core too. appreciate it.

Out of interest, I set up a test. I definitely got 3 PWM outputs from the Attiny85.

You can see from the screenshot that we got a frequency of 31.5 KHz which is slightly off from the predicated 31.25 KHz (it's just running off the internal oscillator). The duty cycle is exactly 50%.

For Timer 1, I was able to adjust the frequency (the count-up-to is in OCR1C) and get a 25% duty cycle (32 / 128).

Code to generate the above:

// For Attiny85
// Author: Nick Gammon
// Date: 29 November 2012

void setup() 
 {
  pinMode (0, OUTPUT);  // pin 5  // OC0A
  pinMode (1, OUTPUT);  // pin 6  // OC0B
  pinMode (4, OUTPUT);  // pin 3  // OC1B
  
  // Timer 0, A side
  TCCR0A = _BV (WGM00) | _BV (WGM01) | _BV (COM0A1); // fast PWM, clear OC0A on compare
  TCCR0B = _BV (CS00);           // fast PWM, top at 0xFF, no prescaler
  OCR0A = 127;                   // duty cycle (50%)

  // Timer 0, B side
  TCCR0A |= _BV (COM0B1);        // clear OC0B on compare
  OCR0B = 63;                    // duty cycle (25%)

  // Timer 1
  TCCR1 = _BV (CS10);           // no prescaler
  GTCCR = _BV (COM1B1) | _BV (PWM1B);  //  clear OC1B on compare
  OCR1B = 31;                   // duty cycle (25%)
  OCR1C = 127;                  // frequency
  }  // end of setup

void loop() { }

ah, this with strykeroz suggestion seemed to work perfect. Earlier I was just getting a faint glow from last led that was constant.

I have all 3 LEDs working now, however I am trying to do a simple fade, but there is some really weird things going on with the timing. this code basically only produces an on and off state every 30seconds or so:

void setup(){
  pinMode(0,OUTPUT); 
}

void loop(){
  for(int i = 0; i < 255; i++){
    digitalWrite(0, i);
    delay(50);
  }
  for(int i = 255; i > 0; i--){
    digitalWrite(0,i);
    delay(50);
  }
}

Nick you're always giving me good stuff to go and read up on. hah, I am totally lost here, but I will try to read up on it. Really appreciate the info though. hopefully soon I will understand what that all says.

The short form is, vary these three lines:

  OCR0A = 127;                   // duty cycle (50%)
...
  OCR0B = 63;                    // duty cycle (25%)
...
  OCR1B = 31;                   // duty cycle (25%)

They control the duty cycle. In the case of the first two, 100% is 255, and 0% is 0. The third one counts up to 127, so the duty cycle is half that (or change the line "OCR1C = 127;" to be "OCR1C = 255;" and they will all be the same).

Put your LEDs on pins 3, 5 and 6. Change the duty cycle as required and the LEDs will change brightness.

I have all 3 LEDs working now,

You are only setting one pin as output, for one thing.


  for(int i = 0; i < 255; i++){
    digitalWrite(0, i);
    delay(50);
  }

but there is some really weird things going on with the timing. this code basically only produces an on and off state every 30seconds or so:

That's what digitalWrite does. Turn the pin on or off.

You'd probably like to look at analogWrite() if you are using hardware PWM. Digitalwrite was needed in the software PWM example because it can be used on any pin, even those where analogWrite is unsupported.

aha, ok that is very helpful. is this to save battery life? ie set duty cycle to half at 127

sorry I meant the original project I was working on. I used your references to get it working. It was the new library that fixed it.

That's what digitalWrite does. Turn the pin on or off.

hah... yeah you are totally right, I was silly and had digital instead of analog.