How to change ATTINY85 PWM Pin Frequency

Hello,

Im using the ATTINY85-20U IC PWM pins 5 & 6 in an audio circuit, is there a way to change the frequency of both pin to be over 30Khz, (Out of human hearing).

This code which i found on a forum somewhere changes the pwm of pin 5 to around 31khz, but it doesnt affect pin 6. I need both to be like this.


OSCCAL = 181;
TCCR1 = 1<<CTC1 | 0<<COM1A0 | 1<<CS10; // CTC mode, /1
GTCCR = 1<<COM1B0;                     // Toggle OC1B
PLLCSR = 0<<PCKE;                      // System clock as clock source
OCR1C = 0;
CLKPR = 0x80;
CLKPR = 0x00;

TCCR0B = TCCR0B & 0b11111000 | 0x01;

Which board (or Arduino core) are you using?
If you need PWM with same frequency at (physical)pin 5(PB0) and 6(PB1) , I think it's better to use only Timer0 than to use both Timer1 and Timer0.

Also, can I post all the code?

What would be the code for timer0 to make both pins above 30khz?

Sorry all of this timer set up stuff is way over my head! Im still a beginner when it comes to arduino code.

The PWM frequency is not completely determined as you hasn't provide what frequency you are using for the ATtiny85 main clock.
The code below assumes that it is running at 16MHz using the built-in PLL.
In that case, this code uses timer 0 to provide pins 5 and 6 with an 8-bit PWM output of approximately 31kHz.

// Timer0 setup
DDRB  |= 0x03; // PB0(pin5) and PB1(pin5) force OUTPUT
TCCR0A = 0xA1; // Use both OCR0A and OCR0B output, Phase correct PWM mode
TCCR0B = 0x01; // Prescaler not used

// Output value
OCR0A = 0; // This register controls the OUTPUT of pin 5
OCR0B = 0; // This register controls the OUTPUT of pin 6
/*
  set to 0, outputs continuous LOW
  set to 255, outputs continuous HIGH
  set to between 1 and 254, outputs PWMs for each duty at about 31KHz
*/

Which Arduino core are you using?

My core vs almost all others one distribute PWM pins differently between the timers so this could be a key factor in determining the way forward.

Also, pin naming convention:
Refer to pins via the Pxn names, or by the arduino pin numbers (depending on which the pinout charts you use encourage). if you must use the physical pin numbers instead, explicitly say "Physical pin 6".

Final edit: Next time you have question specific to a microcontroller not used in official boards, I suggest using the Microcontrollers section. Its a closer matcjh

I have the internal clock set to 16Mhz.
If use that code in my setup will it make physical pins 5 and 6 PWM above 30khz?

Yup.
It will output about 31.4kHz.
The duty cycle can be set from 0% to 100% by writing a value from 0 to 255 in OCR0A and OCR0B.

I coped this code into setup, and kept the duty cycle at 0 for both.
I still am reading 1.9khz for both pins. Am i doing something wrong?

Im just trying to test out the freq at the moment so this is the code im using for reference:

void setup() {

DDRB  |= 0x03; // PB0(pin5) and PB1(pin5) force OUTPUT
TCCR0A = 0xA1; // Use both OCR0A and OCR0B output, Phase correct PWM mode
TCCR0B = 0x01; // Prescaler not used

OCR0A = 0; // This register controls the OUTPUT of pin 5
OCR0B = 0; // This register controls the OUTPUT of pin 6

pinMode(0, OUTPUT);
pinMode(1, OUTPUT);

}

void loop() {

  analogWrite(0, HIGH);
  analogWrite(1, HIGH);

}

Don't use pinMode() and analogWrite().

void setup() {
  DDRB  |= 0x03; // This is an alternative to pinMode()
  TCCR0A = 0xA1;
  TCCR0B = 0x01;
}
void loop() {
  OCR0A = 0; // This is an alternative to analogWrite to pin 5. but 0 is outputs continuous LOW.
  OCR0B = 1; // This is an alternative to analogWrite to pin 6. output is 1/255 duty cycle.
}
1 Like

Oh right thats a new concept to me haha!
Okay, i changed up the example code a bit and used a pot to change the duty cycle, and its still output 1.9khz.
What am i doing wrong?

void setup() {
  DDRB  |= 0x03; // This is an alternative to pinMode()
  TCCR0A = 0xA1;
  TCCR0B = 0x01;

  pinMode(A1, INPUT);
}
void loop() {

  int test = map(analogRead(A1), 0, 1023, 0, 255);
  
  OCR0A = test; // This is an alternative to analogWrite to pin 5. but 0 is outputs continuous LOW.
  OCR0B = test; // This is an alternative to analogWrite to pin 6. output is 1/255 duty cycle.
}

Perhaps your ATtiny85 is running at 1MHz instead of 16MHz

Oh god, I didn't load the bootloader correctly onto the ATtiny...
Thanks so much for your help, I've got it sorted now!