3

I have been using an Arduino Nano as a PWM controller for a heating element.

I am currently using D11 (PB3). I could change, although all pins with PWM are in use, and would require a re-write and re-wire.

This produces a signal at ~490Hz, but I would like to experiment with changing this to a higher frequesncy.

I gather it its possible to vary the frequency by changing the divisor from its default 64.

My sketch uses Uses http://playground.arduino.cc/Main/SevenSegmentLibrary and calls millis() - will changing PWM divisor impact on either of these?

NOTE I have read the setPwmFrequency documentation, but find "disrupts the normal operation" unhelpful - I am actually after some explanation of the concrete effect. I only use millis() to time button presses and flash a LED, which are not time critical

Please keep in mind that changing the PWM frequency changes the Atmega's timers and disrupts the normal operation of many functions that rely on time (delay(), millis(), Servo library).

I have been doing some further study. http://playground.arduino.cc/Code/PwmFrequency states Changes on pins 3, 5, 6, or 11 may cause the delay() and millis() functions to stop working.

Other references say 3, 11 use timer 2 so do they affect millis() or not as other references claim timer 0 is used for these.

1
  • Yes and no, depending on the pwm timer used.
    – dannyf
    Nov 21, 2017 at 11:54

3 Answers 3

2

I don't know where this misinformation comes from... The answer is no, reconfiguring Timer 2 does not affect millis() nor delay(), as these functions rely on Timer 0. AFAIK the Arduino core does not use Timer 2 at all. But note that there may be other Arduino or third party libraries that rely on Timer 2.

You can see here the source code of millis() and delay().

As MITU RAJ correctly states in his answer, the PWM signal on pin 11 is provided by Timer 2, so you can use it safely.

1
  • 1
    The misinformation comes from playground.arduino.cc/Code/PwmFrequency. I am sure I am not the only user to have been mislead. The other answer just published an extract of the misleading documentation.
    – Milliways
    Nov 22, 2017 at 22:58
2

Depends on the pin you used for the PWM.

Arduino UNO/NANO specs say following things:

The base frequency for pins 3, 9, 10, and 11 is 31250 Hz.

The base frequency for pins 5 and 6 is 62500 Hz.

The divisors available on pins 5, 6, 9 and 10 are: 1, 8, 64, 256, and 1024.

The divisors available on pins 3 and 11 are: 1, 8, 32, 64, 128, 256, and 1024.

PWM frequencies are tied together in pairs of pins. If one in a pair is changed, the other is also changed to match.

Pins 5 and 6 are paired on timer0.

Pins 9 and 10 are paired on timer1.

Pins 3 and 11 are paired on timer2.

Changes on pins 3, 5, 6, or 11 may cause the delay() and millis() functions to stop working. Other timing-related functions may also be affected.

1
  • Since you're quoting the specs, it'd be nice if you could also link to them? :)
    – Sixtyfive
    Sep 26, 2020 at 8:59
2

The answer is NO, changing the PWM divider for pin 11 will not affect the millis() function (nor delay()).


Explanation:
The Arduino Nano uses the ATMega328P microcontroller, same as the Arduino Uno.

Pin 11's PWM is controlled by Timer 2. By default Timer 2 has a prescale of 64 (ie. setting 0x04). The base frequency of Timer 2 is 31372.55 Hz resulting in a frequency of 490.2 Hz (ie. 31372.55/64 = 490.1961).

On the other hand, the microsecond timer (ie. the one used by millis(), micros(), delay() and delayMicroseconds()) is controlled by Timer 0.

So changing the prescaler of Timer 2 will not affect millis().

It will however change the PWM frequency of Pin 3.


Back to your question:
The possible PWM frequencies of Pin 11 (higher than 488 Hz) are:

31373 / 32 = 980.4 Hz
31373 / 8 = 3921.6 Hz
31373 / 1 = 31373 Hz

Where 32, 8, 1 are the prescaler.
Which equates to a setting value of 0x03, 0x02 & 0x01 respectively.

Add this line of code:

TCCR2B = TCCR2B & 0b11111000 | setting;

Where setting is the value of the setting for the respective prescaler.

============================================  
|| Frequency [Hz] || Prescaler || Setting ||  
============================================  
|| 31373.55       || 1         || 0x01    ||  
|| 3921.57        || 8         || 0x02    ||  
|| 980.39         || 32        || 0x03    ||  
|| 490.20         || 64        || 0x04    ||  
|| 245.10         || 128       || 0x05    ||  
|| 122.55         || 256       || 0x06    ||  
|| 30.64          || 1024      || 0x07    ||  
============================================  

Source code: https://github.com/arduino/ArduinoCore-avr/blob/master/cores/arduino/wiring.c

3
  • Just nitpicking but... the timer's base frequency in phase correct PWM mode is F_CPU/510 (31373 Hz), not F_CPU/512: it takes 255 cycles to count from 0 to 255, then 255 more to count back to zero. C.f. the equation for the PWM frequency in the datasheet. Jan 11, 2019 at 10:03
  • @EdgarBonet Good point. The answer has now been corrected.
    – sa_leinad
    Jan 12, 2019 at 14:33
  • would it be possible to go down a step slower to 15.31 HZ? Oct 15, 2019 at 3:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.