Go Down

Topic: attiny85 with 3 PWN pins (Read 13 times) previous topic - next topic

hilukasz

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.
for(i = 0, i < 820480075, i++){ Design(); Code(); delay(1000); } // hellowoo.com

Nick Gammon

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.
http://www.gammon.com.au/electronics

hilukasz

#2
Nov 29, 2012, 02:39 am Last Edit: Nov 29, 2012, 02:45 am by hilukasz Reason: 1
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.
for(i = 0, i < 820480075, i++){ Design(); Code(); delay(1000); } // hellowoo.com

Coding Badly

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/

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


Not necessary.

Coding Badly

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


They are wrong.

Quote
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.

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/

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


Not necessary.



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?
for(i = 0, i < 820480075, i++){ Design(); Code(); delay(1000); } // hellowoo.com

Coding Badly

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

Yes.  That is what I mean.

hilukasz

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.
for(i = 0, i < 820480075, i++){ Design(); Code(); delay(1000); } // hellowoo.com

strykeroz

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).
Code: [Select]
// 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):
Code: [Select]
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
"There is no problem so bad you can't make it worse"
- retired astronaut Chris Hadfield

Coding Badly

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.

Quote
...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

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.

Quote
...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.
for(i = 0, i < 820480075, i++){ Design(); Code(); delay(1000); } // hellowoo.com

Nick Gammon

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:

Code: [Select]

// 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() { }
http://www.gammon.com.au/electronics

hilukasz

#12
Nov 29, 2012, 05:21 am Last Edit: Nov 29, 2012, 06:01 am by hilukasz Reason: 1
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:


Code: [Select]
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);
 }
}
for(i = 0, i < 820480075, i++){ Design(); Code(); delay(1000); } // hellowoo.com

hilukasz


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:

Code: [Select]

// 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() { }



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.
for(i = 0, i < 820480075, i++){ Design(); Code(); delay(1000); } // hellowoo.com

Nick Gammon

The short form is, vary these three lines:

Code: [Select]

  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.
http://www.gammon.com.au/electronics

Go Up