You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The function pwmWriteHR(PIN, brightness(0-65535) replaces analogWrite()
5
+
Download "PWM_lib_resolution_example.ino" to the arduino and look at the serial monitor to see examples of frequency/resolution combinations that you can use.
6
+
For LED applications to get better than 8 bits of resolution, I've found that a frequency of 240hz that gives 15.1 bits works very well.
7
+
Note that pwmWriteHR takes an unsigned integer from 0-65535, you won't see a change for each increment depending on the resolution.
8
+
I.E at a frequency of 240hz which translates to a resolution of 15.1bits this is 35119 steps, so at most you'll only see a difference every other increment(i.e 15000 to 15002)
9
+
10
+
*/
11
+
12
+
#include<PWM.h>
13
+
14
+
//use pin 11 on the Mega instead, otherwise there is a frequency cap at 31 Hz
15
+
int led = 9; // the pin that the LED is attached to
16
+
unsignedint brightness; // how bright the LED is
17
+
int fadeAmount = 32; // how many points to fade the LED by. 32 was choosen as this gives a fade over about 12 seconds on an arduino uno uC
18
+
unsignedint frequency = 240; //frequency (in Hz), gives approx 15.1 bits of PWM resolution
19
+
float Max = 65535.0; //Maximum of a 16bit integer which is what pwmWriteHR wants
By default Arduino's analogWrite (and consequently pwmWrite() since it mimics analogWrite()) uses 8 bit
3
+
pwm across all timers. 8 bit PWM allows for a total of 256 possible values. This library has some methods
4
+
for fine tuning resolution if a higher resolution is needed:
5
+
6
+
void pwmWriteHR(uint8_t pin, uint16_t duty)
7
+
Same a pwmWrite, except the range is 0 - 65535 (16 bit) instead
8
+
of 0 - 255 (8 bit)
9
+
10
+
float TimerX_GetResolution() (replace X with a timer number)
11
+
Gets the timer's resolution in base 2. The value returned in other words
12
+
represents the number of bits required to represent the timer's range. ie
13
+
the value 7 means it takes 7 bits to represent all possible pin duties at
14
+
that frequency, or 7-bit resolution. Note that a float is returned, not
15
+
an int.
16
+
17
+
float GetPinResolution(uint8_t pin)
18
+
Returns the same value as TimerX_GetResolution(), but takes a pin number
19
+
as a parameter so that the caller is timer agnostic.
20
+
21
+
There are several things to keep in mind when trying to optimize resolution:
22
+
-pwmWriteHR() is only useful for 16 bit timers, since 8 bit timers are inherently limited to 8 bit pwm
23
+
-The higher the frequency, the lower the resolution. pwmWriteHR() will automatically map input to the
24
+
actual timer resolution
25
+
-Resolution can be optimized in this way for 2 pins on the Uno (9 and 10), and 11 pins on the Mega (2,
26
+
3, 5, 6, 7, 8, 11, 12, 44, 45, and 46)
27
+
28
+
Use the serial moniter to see output from this program
29
+
This example runs on mega and uno.
30
+
*/
31
+
32
+
#include<PWM.h>
33
+
34
+
//use pin 11 on the mega for this example to work
35
+
int led = 9; // the pin that the LED is attached to
36
+
37
+
voidsetup()
38
+
{
39
+
InitTimersSafe(); //initialize all timers except for 0, to save time keeping functions
40
+
Serial.begin(115200);
41
+
Serial.println();
42
+
43
+
demonstrateFrequencysEffectOnResolution();
44
+
settingHighResolutionDuty();
45
+
}
46
+
47
+
voiddemonstrateFrequencysEffectOnResolution()
48
+
{
49
+
Serial.println("As frequency increases, resolution will decrease...");
50
+
for(int i = 1; i < 10000; i+=10)
51
+
{
52
+
SetPinFrequency(led, i); //setting the frequency
53
+
54
+
uint16_t frequency = Timer1_GetFrequency();
55
+
uint16_t decimalResolution = Timer1_GetTop() + 1;
56
+
uint16_t binaryResolution = GetPinResolution(led); //this number will be inaccurately low because the float is being truncated to a int
57
+
58
+
char strOut[75];
59
+
sprintf(strOut, "Frequency: %u Hz\r\n Number of Possible Duties: %u\r\n Resolution: %u bit\r\n", frequency, decimalResolution, binaryResolution );
60
+
61
+
Serial.println(strOut);
62
+
}
63
+
64
+
Serial.println("...Finished");
65
+
}
66
+
67
+
voidsettingHighResolutionDuty()
68
+
{
69
+
SetPinFrequency(led, 10); //setting the frequency to 10 Hz
70
+
Serial.println("\r\npwmWrite() and pwmWriteHR() are identical except for the valid range of inputs.\r\nThe following loop calls both functions to produce the same result on the \r\nLED pin. The pin should to run 10Hz at 50% duty regardless of the function called.\r\n");
71
+
72
+
//the led should flicker (10Hz 50% duty) for 1 second before calling
73
+
//the other function. This demonstrates the use of pwmWriteHR() and how its
74
+
//use is nearly identical to pwmWrite()
75
+
while(true)
76
+
{
77
+
//setting the duty to 50% with 8 bit pwm. 128 is 1/2 of 256
78
+
pwmWrite(led, 128);
79
+
Serial.println("8-Bit PWM");
80
+
delay(1000);
81
+
82
+
//setting the duty to 50% with the highest possible resolution that
83
+
//can be applied to the timer (up to 16 bit). 1/2 of 65536 is 32768.
0 commit comments