PWM frequency library

Hi guys,

I did post in another area of the forum, but in hindsight really should have posted here.

I'm not sure how I go about getting the thread moved, so thought I would post a very brief summary:

I have an Uno and need to output two squarewaves - one at 3040Hz and one at 2010Hz. I'm having problems doing it using this library and must be doing something really stupid!

Anyway, the post is here: Uno - 2 Separate PWM Frequency Outputs - Programming Questions - Arduino Forum

Thanks Jay :slight_smile:

Thank you very much for this library runnerup. I am making a project where I will need more than the normal 256 steps of PWM resolution, and this is exactly what I needed.

One question though, I'm a little confused by why the resolution has to decrease as frequency increases. Is this an actual limitation having to do with the clock speed of the chip and how quickly it runs through the timers?

You said earlier it had to do with the way the library is set up to allow variability of both the resolution and the frequency. Does this mean that if I manually set the registers in my program that I could achieve the full 16 bits of resolution that the 16 bit timers are capable of? I really don't care much about changing the frequency, just the resolution.

The more resolution the better for this project.

Hi, I have some code that uses this awesome library to independently control 3 computer fans via their pwm wires at 25khz using an Arduino Uno. Pins 3, 9, and 10 are currently used.
I am an arduino noob and this code was not written by me though. I have been trying to understand how this pwm and timing stuff works, but am still having trouble understanding.
Is there another pin I can use to independently control a 4th pwm fan without messing things up with the other arduino functions?

Thanks.

Ok, I have a another question now that I've played around with this library a little.

Looking at that chart that is shown in the serial monitor for what the maximum resolution is for a given frequency, it doesn't seem to be a steady correlation where resolution decreases as frequency increases. From 1Hz to 131Hz it actually appears that the maximum resolution increases. It peaks at 131Hz, and then goes down from there. Is that accurate? I don't understand why the maximum resolution goes up to a point and then starts going back down. Is 131Hz really the frequency to use to achieve the highest resolution?

Hello,
This seems like it is a very useful library, but I am having trouble with it.

I imported the library and loaded up one of the examples - PWM_lib_example. It is curious that some commands , such as
" InitTimersSafe();" do not turn orange, as if the software does not recognize it as a legitimate comman
d. I have seen examples on the internet where the line, in fact is orange.
The compiler comes up with several errors, such as:

PWM_lib_example:24: error: 'InitTimersSafe' was not declared in this scope

The reason I find this curious, is that I am using the example provided with the library, without modifying the code, and it doesn't verify. Am I doing something wrong? Could the fact that I am on a Mac have anything to do with it?

UPDATE

After checking it on two Macs and getting the same problem I tested it on a Windows machine.
The command still didn't turn orange, but the out-of-the-box example compiled.
Therefore it might just be a Mac thing....

I am new and trying to use this, I get an error

...document\arduino/libraries/PWM\BtimersDefs.h: 58 eroor: 'int16_t' does not name a type.
it says that for line 58 and 59.

clues?

I just discovered this library and installed its latest version. I, too, have the same problem. The out-of-the-box example does not verify clean. there are three errors all relating to undeclared variables.
WASSUP??

hi i am using this same library in arduino uno to generate 50Hz at a pwm pin. but i need the same signal to be generated at 4 pwm pins. can i simply use the same code to generate 50 Hz on 4 pwm pins, because different pins are associated with different timers, (8 bit or 16 bit) so will it be okay if i use same code?

hi i am using this same library in arduino uno to generate 50Hz at a pwm pin. but i need the same signal to be generated at 4 pwm pins. can i simply use the same code to generate 50 Hz on 4 pwm pins, because different pins are associated with different timers, (8 bit or 16 bit) so will it be okay if i use same code?

imdafaddah:
I just discovered this library and installed its latest version. I, too, have the same problem. The out-of-the-box example does not verify clean. there are three errors all relating to undeclared variables.
WASSUP??

I had the same problem at first.

That is because the examples are outside the actual PWM library folder. Just cut the contents of the PWM library such as PWM.h, keywords and the utility folder and paste it outside the PWM folder, restart your arduino, it should be fine

Can anyone tell me the right pins for PWM in ardiuno R3 uno? Cause last night i set the frequency to pin 5 at 1000 Hz but it was giving me 5000 Hz. Does anyone know about this issue? By the way I am not sure it was pin 5 but it was some pin which was giving out 5000 Hz. I checked it on a digital oscilloscope and I am sure i was giving it 1000 Hz.

Further more I will post a reply for Ardiuno Uno R3 right pins tomorrow after I have checked all pins. As we all know that pwm is used for motors but the actual pwm is given to a H-bridge and most H-bridges have a certain frequency at which they operate. If a higher frequency is given the h-bridge becomes unstable and may cause the frequency generator to fry. Well my h-bridge is sensitive as I have made it myself for 24V motors/5A. I will post the pins and their responses tomorrow after I have checked all the pins. Will post it with pictures.

breslopez:
Hi, thank you so much for your help, I already solve the problem....now, I'm traying to manipulate the "frequency" value from the Serial monitor...but I can't make it work, here's the code:
PD: Any help, THANKS!!!

/************************** TEC -2013 **************************

Este sketch es una variacion del PWM_lib_example de la biblioteca PWM,
donde se controla la frecuencia desde el monitor serial del IDE,
dando con ello un poco mas de practicidad, y mayor manejo sobre la
frecuencia deseada.


*/

#include <PWM.h>

int brightness = 0; //how bright the LED is.
int fadeAmount = 5; //how many points to fade the LED by

void setup()
{
//Inicializa todos los timers del Arduino, excepto el 0, para mantener las funciones de tiempo del micro
Serial.begin(9600);
InitTimersSafe();

}

void loop()
{
int32_t frequency;
if (Serial.available())
{

frequency = Serial.read();
SetPinFrequency(led, frequency);

}
pwmWrite(led, brightness);

brightness = brightness + fadeAmount;

if (brightness == 0 || brightness == 255) {
fadeAmount = -fadeAmount ;
}

delay(30);

}

Hi, could you explain how did you solve your problem please?
I'm having the same problem and I have loaded the library with the tool of the IDE.
Also I have noticed that there's no PWM.cpp file. I'm a beginner at this and don't know if it would be the reason.

Is anyone able to modify this to work on an attiny85

Wonderful library!! Very much needed!
I'm curious as to whether there is any way it can be used to control PWM frequency of two pins independently. From what I've discovered, I'm only able to successfully initialize frequency when it's using pin 9 or 10 (assuming you used timer 1). Would it be possible to use your library to have one PWM pin set to, say, 600Hz, and another pin set to 700Hz?
Thanks again!

As an edit: I played around with this a bit more and found something curious. Timer2 is tied to pins 3 and 11, while Timer1 is tied to pins 9 and 10 on my Uno. So, I tried making pin 11 600Hz and pin 10 700Hz with the library. Pin 10 initialized just fine, but pin 11 would not give me a true return (SetPinFrequencySafe). Switched to pin 3 instead of 11 and it worked like a charm. Anybody know what gives?

Also, is there an easy way to directly measure the number of pulses that occur between calling pwmWrite and stopping it? Obviously I could do math with the elapsed time and frequency, but getting some empirical data would be just that much better.

Thank you for the library.

I used your example to try to use Scope to test the signal coming out and this is what i got

it has a few spikes and the amplitude changes greatly. What would I need to do to...:

  1. Control the speed using a program on my computer?
    2)Fix the PWM signal to be a constant 89hz with a controlled duty cycle that I can control by clicking on buttons or something of the like?

the code I used is:

/*

Mimics the fade example but with an extra parameter for frequency. It should dim but with a flicker
because the frequency has been set low enough for the human eye to detect. This flicker is easiest to see when
the LED is moving with respect to the eye and when it is between about 20% - 60% brighness. The library
allows for a frequency range from 1Hz - 2MHz on 16 bit timers and 31Hz - 2 MHz on 8 bit timers. When
SetPinFrequency()/SetPinFrequencySafe() is called, a bool is returned which can be tested to verify the
frequency was actually changed.

This example runs on mega and uno.
*/

#include <PWM.h>

//use pin 11 on the Mega instead, otherwise there is a frequency cap at 31 Hz
int led = 9; // the pin that the LED is attached to
int brightness = 0; // how bright the LED is
int speedcontrol = 5; // how many points to fade the LED by
int32_t frequency = 89; //frequency (in Hz)

void setup()
{
//initialize all timers except for 0, to save time keeping functions
InitTimersSafe();

//sets the frequency for the specified pin
bool success = SetPinFrequencySafe(led, frequency);

//if the pin frequency was set successfully, turn pin 13 on
if(success) {
pinMode(13, OUTPUT);
digitalWrite(13, HIGH);
}
}

void loop()
{
//use this functions instead of analogWrite on 'initialized' pins
pwmWrite(led, brightness);

brightness = brightness + speedcontrol;

if (brightness == 0 || brightness == 255) {
speedcontrol = -speedcontrol ;
}

delay(30);
}

While I know its not right code, I wanted to test to see if it was getting a solid 89hz, which it was getting 89, but not solid (as in it spiked to above 200hz) possibly because of the programming not being right?

If this frequency library does not work for you... Try this from a previous thread. I have spent weeks trying to figure this stuff out...

I believe that there is a lot of confusion as to what the original author was trying to say.

According the the library TimerOne.h you can set certain pins to do whatever frequency you want (within capability of the board).

He is referring to this - Arduino Playground - Timer1

using the coding from the website directly I had a lot of problems. You have to download the timer files, leave them in the zip and put them directly into the libraries folder, no subfolders, dont extract them. Once you are done doing this open up your sketch and import the libraries (ZIP FILE NEED TO BE IN THE LIBRARIES FOLDER) - I say all caps because I messed up several times and once I did this, everything worked perfectly. then... "#Include <TimerOne.h> which you type in or click "Sketch" and Import Library --> click file and it will automatically add it.

Mine looks like this

#include <TimerOne.h>

void setup() {
// put your setup code here, to run once:
pinMode(9, OUTPUT);
Timer1.initialize(11230); // Intialize timer1, and set a 89hz frequency
Timer1.pwm(9,300); // setup pwm on pin 9, with a 50% duty cycle

}

void loop() {
// put your main code here, to run repeatedly:

}

** In my sketch it says 50% Duty cycle in the notes but right now its actually at something else i just didnt change the notes on it. It is using 10 bits so instead of 255 its like 1054 or something like that.

** Also
Figuring out HERTZ

  • go to: Convert hertz to milliseconds - frequency converter
  • Enter in desired hertz and it outputs how many milliseconds you need
  • take your milli seconds and conver them to microseconds by going to google and saying "convert milliseconds to microseconds" it will then give you a google calculator and does the calculations for you
  • Use these calculations in your sketch, for example mine says 11230 - that is the microseconds needed to create an 89hz frequency because herz is how many cycles per second the signal is 1000000(1 second in Microseconds) / 11230 = 89.04 hz

AND it works. My pin 9 is outputting an 89hz frequency.

I could not be more excited.

The the original Author, I hope you got it working... I dont know anything about creating advanced algorithms, but I hope this helps.

The arduino CAN make its own PWM frequency and is not limited like most of the posters have said. Using the Timer1 for Uno and Timer3 for Mega, you can unlock the PWM potential :slight_smile: Hope this helps someone.

It looks like this library uses Macros to set the frequency.

If I'm reading this correctly, that means I can not change frequency 'in the loop'.

Does anyone know of a way to change frequency and duty cycle after compile time? Or do I have to port this library to not use Macros/precompiler directives?

Hi thanks for a great library i find it works well on the uno. I am varying the frequency and pulse width by reading 2 pots on the analog inputs and mapping that reading to suit the registers for frequency and pulse width. I am using pin 9 and 10 and invert 10 also control its pulse width with another pot. Great library.

Hi, a simple question. Can I have 4 outputs with high resolution on a Arduino UNO?
Excellent library runnerup. Thank you!

Anyone know why pin 11 on timer2 doesn't work?

All the rest work great.

I'm using the Uno.

Cheers