Arduino Forum

Using Arduino => General Electronics => Topic started by: luxy on Jun 27, 2013, 12:10 pm

Title: PWM frequency change (ATtiny85)
Post by: luxy on Jun 27, 2013, 12:10 pm
If i use line "TCCR0B = TCCR0B & 0b11111000 | 0b001;" it change PWM frequency on port D0 and D1 of ATtiny85 (i read that on forum). What if i want to change PWM frequency on port D3 and D4?

I tried with line "TCCR1B = TCCR1B & 0b11111000 | 0b001;" but it doesn't work. On ATmega328 line TCCR0B change PWM on port 5 and 6, TCCR1B on port 9 and 10 and TCCR2B on port 11 and 3, but not with ATtiny85.

So, how to change PWM on port D3 and D4?
Title: Re: PWM frequency change (ATtiny85)
Post by: fungus on Jun 27, 2013, 02:26 pm

If i use line "TCCR0B = TCCR0B & 0b11111000 | 0b001;" it change PWM frequency on port D0 and D1 of ATtiny85 (i read that on forum). What if i want to change PWM frequency on port D3 and D4?

I tried with line "TCCR1B = TCCR1B & 0b11111000 | 0b001;" but it doesn't work. On ATmega328 line TCCR0B change PWM on port 5 and 6, TCCR1B on port 9 and 10 and TCCR2B on port 11 and 3, but not with ATtiny85.

So, how to change PWM on port D3 and D4?


Tiny85 doesn't have the same timers as a Mega328.

Look for TCCR1 in the datasheet.
Title: Re: PWM frequency change (ATtiny85)
Post by: luxy on Jun 28, 2013, 12:11 pm

Tiny85 doesn't have the same timers as a Mega328.

Look for TCCR1 in the datasheet.


I read datasheet and some other topics with changing PWM frequency but i don't understand it correctly..

Since ATtiny85 have 2 PWM outputs (PB0 and PB1) it probably have one PWM timer (TCCR1). This timer has two output compare registers that control the PWM (TCCR0A and TCCR0B).. Is that correct?

From http://playground.arduino.cc/Main/TimerPWMCheatsheet playground i can understand that i should set correct settings for wanted frequency.

If i would like to set PWM frequency on this two PWM ports (PB0 and PB1) to around 30 kHz (i would like to drive fans and don't want too much noise because of PWM) i should write this lines in void setup.

TCCR0A = TCCR0A & 0b11111000 | 0x01;  <-- for PB0
TCCR0B = TCCR0B & 0b11111000 | 0x01;  <-- for PB1

Because i am using internal CPU clock with 8 MHz, i will get around 15 kHz with this setting, not 30 kHz.

Is that correct? Also, is possible to get 30 kHz with internal 8 MHz clock? I would realy like to understand this settings.
Title: Re: PWM frequency change (ATtiny85)
Post by: fungus on Jun 28, 2013, 01:12 pm

Since ATtiny85 have 2 PWM outputs (PB0 and PB1) it probably have one PWM timer (TCCR1). This timer has two output compare registers that control the PWM (TCCR0A and TCCR0B).. Is that correct?


It has three, two on timer 0 and one on timer 1. The number in the register name tells you which timer the register belongs to, so anything with a '1' in it (eg TCCR1) doesn't refer to timer 0.


TCCR0A = TCCR0A & 0b11111000 | 0x01;  <-- for PB0
TCCR0B = TCCR0B & 0b11111000 | 0x01;  <-- for PB1


TCCR0A has no effect on timer0 frequency.
TCCR0B does - look at CS02, CS01 and CS00 in the datasheet.
Title: Re: PWM frequency change (ATtiny85)
Post by: luxy on Jun 28, 2013, 02:26 pm

It has three, two on timer 0 and one on timer 1. The number in the register name tells you which timer the register belongs to, so anything with a '1' in it (eg TCCR1) doesn't refer to timer 0.


Ok, TCCR0A and TCCR0B for timer 0 (first PWM port PB0) and TCCR1 for timer 1 (second PWM port PB1). So, if i change TCCR0B it will affect only on PWM frequency of first PWM port (PB0)? Btw, why timer 0 has two output compare registers and timer 1 only one?

Quote

TCCR0A has no effect on timer0 frequency.
TCCR0B does - look at CS02, CS01 and CS00 in the datasheet.


If i look into table from datasheet for CS02, CS01 and CS00 this line should look like this "TCCR0B = TCCR0B & 0b11111001 | 0x01;" for clk/no prescaling? But how can i set PWM frequency? What in that case mens "setting" 0x01?
Title: Re: PWM frequency change (ATtiny85)
Post by: fungus on Jun 28, 2013, 04:02 pm

Ok, TCCR0A and TCCR0B for timer 0 (first PWM port PB0) and TCCR1 for timer 1 (second PWM port PB1). So, if i change TCCR0B it will affect only on PWM frequency of first PWM port (PB0)?


No, it will affect the frequency of both PB0 and PB1. Timer 0 has two outputs but only one counter. You can change the pulse width independently but both will have the same frequency.


If i look into table from datasheet for CS02, CS01 and CS00 this line should look like this "TCCR0B = TCCR0B & 0b11111001 | 0x01;" for clk/no prescaling? But how can i set PWM frequency? What in that case mens "setting" 0x01?


it means timer0 counts at the speed of the CPU clock (it's not divided by anything). You can divide by 1, 8, 64, 256, etc., using CS02, CS01 and CS00.

Remember though, each PWM pulse will be 256 clock ticks long because it's an 8-bit timer. The output goes high at when the counter is 0 and low when it matches the number in the compare register (OCR0A for the output on PB0, OCR0B for the output on PB1). You set the pulse width by changing OCR0A and OCR0B.

If your chip is running at 8MHz then 0x01 in TCCR0B means your PWM frequency is 8000000/256 = 31.24kHz
Title: Re: PWM frequency change (ATtiny85)
Post by: luxy on Jun 29, 2013, 01:21 pm

it means timer0 counts at the speed of the CPU clock (it's not divided by anything). You can divide by 1, 8, 64, 256, etc., using CS02, CS01 and CS00.


Ok, with last three bits in line 0b11111001 i set divider using CS02, CS01 and CS00. I found table fot that in datasheet and i can understand that.

Quote

If your chip is running at 8MHz then 0x01 in TCCR0B means your PWM frequency is 8000000/256 = 31.24kHz


8000000/256 = 31.24kHz but why "0x01" (binary 0000 0001) means 256? Is there also a table for that 0x01 means mode "divide with 256"?

If i make a conclusion..

With line "TCCR0B = TCCR0B & 0b11111001 | 0x01;" in void setup() i set frequency on port PB0 and PB1 to 31,24 kHz since my CPU speed is 8 MHz. Period of PWM is set with line "analogWrite(port, value)".. (value 255 is max or equal to HIGH, always on).

***

I test it with this line "TCCR0B = TCCR0B & 0b11111001 | 0x01;" but it doesn't work.. Fan have the same speed, no matter what PWM period i choose.

With line analogWrite(fan, 128); or analogWrite(fan, 255); speed of fan is the same.. If i remove upper "TCCR0B ..." line it works (just with annoyng noise at half speed) so hardware wiring should be ok.
Title: Re: PWM frequency change (ATtiny85)
Post by: luxy on Jun 30, 2013, 12:23 pm

You set the pulse width by changing OCR0A and OCR0B.


Somehow i missed this part.. I though that with line "TCCR..." in setup i change only frequency of PWM and pulse width is still set with analogWrite(port, pulse_width).
Title: Re: PWM frequency change (ATtiny85)
Post by: MarkT on Jun 30, 2013, 01:07 pm
Quote

8000000/256 = 31.24kHz but why "0x01" (binary 0000 0001) means 256? Is there also a table for that 0x01 means mode "divide with 256"?


The timer is counting 0..255, so repeats every 256 clock cycles, so its output is clock / 256 ??
Title: Re: PWM frequency change (ATtiny85)
Post by: luxy on Jun 30, 2013, 01:27 pm

The timer is counting 0..255, so repeats every 256 clock cycles, so its output is clock / 256 ??


Ok.. So 0x02 mean 2x256=512 and clock output would be clock/512.. True?

Anyway, i don't understand why but this line don't work. With "TCCR0B = TCCR0B & 0b11111001 | 0x01;" i should get frequency 31,25 kHz (my cpu slock is 8 MHz) but speed of fan is always on 100%. If i change last three bits to 010 (to prescaler 8, so frequency should be around 4 kHz) it works, but this is too low. I can still hear annoying sound from fan.
Title: Re: PWM frequency change (ATtiny85)
Post by: luxy on Jul 02, 2013, 01:07 pm
I think i found the problem.. Line for changing PWM frequency is ok, it looks like my FET and transistor are not capable of switching at this frequency. I am driving fan with P-Channel FET and transistor. FET is SUD50P04 and transistor is 2n3904.

If i run this testing code with line "TCCR0B = TCCR0B & 0b11111000 | 0x01;" in setup it looks like fan is always on 100% (255). The same was with LED diode, but when i tried to put LED directly on output port of ATtiny i can easily saw fading. 

So that probably means that this combination of FET and transistor is not capable of running PWM at this frequency?

Testing code:

Code: [Select]

analogWrite(fet, 128);
delay(3000);
analogWrite(fet, 255);
delay(3000);
Title: Re: PWM frequency change (ATtiny85)
Post by: fungus on Jul 02, 2013, 01:38 pm

I am driving fan with P-Channel FET and transistor. FET is SUD50P04 and transistor is 2n3904.


Why would you need 32kHz PWM for a fan? A mechanical device like a fan isn't going to respond any better to 32kHz than 100Hz.

Title: Re: PWM frequency change (ATtiny85)
Post by: luxy on Jul 02, 2013, 02:58 pm

Why would you need 32kHz PWM for a fan? A mechanical device like a fan isn't going to respond any better to 32kHz than 100Hz.


Because of annoying noise while driving fan at lower speeds. I read that low PWM frequency produce that noise.

Quote from http://pcbheaven.com/circuitpages/High_Frequency_PWM_Fan_Controller/

"The PWM controllers usually generate acoustic noises, when the PWM frequency is within the acoustic spectrum (20Hz to 20KHz). A high frequency PWM controller usually operates above the 20KHz, thus the human ear cannot hear this sound. Moreover, PWM controllers can achieve very stable and low speeds without the possibility of a fan stall."


************
Ok, now that's funny. I set frequency to 30 Hz and annoying noise disappeared! :)
Title: Re: PWM frequency change (ATtiny85)
Post by: strykeroz on Jul 02, 2013, 04:57 pm

Ok, now that's funny. I set frequency to 30 Hz and annoying noise disappeared! :)
Do you think that could be because it's getting down to the lower end of the range you can hear (approx 20Hz in adults) so it's less intrusive?
Title: Re: PWM frequency change (ATtiny85)
Post by: luxy on Jul 02, 2013, 05:45 pm

Do you think that could be because it's getting down to the lower end of the range you can hear (approx 20Hz in adults) so it's less intrusive?


I thought of that as soon as I wrote the last post  :smiley-red: XD