PWM frequency library

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

hallo !
i'm using the arduno uno r3
if iwant to run the sevro motor (hg-kr053) and driver is Mitsubishi mr-j4-10a
how do i run this motor by arduino ?
_________ __20K Hz
/
/ \
/ \
/
rising time 0.2s and run 1s (20K Hz) down time 0.2s
and reten is the same.

i need the code!

go see this ... AccelStepper: AccelStepper library for Arduino

I used PWM library to generate PWM signals of desired frequency. The problem is i am not able to give a phase shift to the PWM. For example i am generating a PWM of frequency of 25Khz on PIN 9 and i need a phase shift of 90 degrees(i.e a phase shift of 40 microseconds) of the same PWM on PIN10. 'delay' command is not working. Please suggest a solution and thank you.

Thanks for this library!

Petit-Jean:
Thank you runnerup for this nice piece of work!

I have some questions for you, since I really need to expand this library for the Micro/Leonardo.
So that is what I will do, but maybe you can help me in the right direction.

  • In your estimation, can I better build of of ATimerDefs or BTimerDefs?
  • Do you have any idea how I could implement the difference in structure of the new 8 - 10 - 16 bit pins and fast PWM?
  • I want to change some of the timer—pin assignments for my project. Is that something that you think will work correctly with the construction you used for the library?
  • I will find my way in the end, but can you give me some places to start looking for the registers and stuff?

Any hint is welcome.

Many thanks in advance!
Christophe aka Petit Jean

Any luck with Arduino Leonardo?
Thank you

@Talhaamjad,
Please don't crosspost. I see this same request in Project Guidance. Duplicate is being deleted.
Moderator.

Anyone have any ideas how to get this library to work with the 1.6.0 version of the IDE? I am having trouble getting it to recognize the library if it is in the "libraries" directory. I tried moving the files to a src directory but that did not help.

I finally gave up and put the files into the same directory as my sketch. That way I can get it to compile, but the output pin no longer has any output.

For reference, this sketch worked in the older version if the IDE. The sketch only stopped working when I upgrade to 1.6.0.

i think is the new library system, it need to be updated

I want six pins pwm output.
I use your library.
The pin6 and pin11 always duty=100%.
Why they didn`t work correctly like other pin?
Here is my code,please give me an answer,thanks.

#include <PWM.h>
void setup()
{
InitTimers();
Serial.begin(115200);
Serial.println();

Timer0_SetFrequency(400000);
Timer0_SetPrescaler(ps_8);

Timer1_SetFrequency(50000);

Timer2_SetFrequency(400000);
Timer2_SetPrescaler(psalt_8);

}

void loop()
{
int x=32768;
pwmWrite(5,128);//timer0
pwmWrite(6,128);

pwmWriteHR(9,x);//timer1
pwmWriteHR(10,x);

pwmWrite(3,128);//timer2
pwmWrite(11,128);
Serial.println("High Resolution PWM");
}

I am trying to get the library to work and am very new to programming. I am receiving these errors. Does anyone know how to remedy these problems?

1)Arduino\libraries\PWM/ATimerDefs.h:179:3 error: #error "ATimerDefs.h only supports ATMega640, ATMega1280, ATMega1281, ATMega2560, and ATMega2561"

2)Arduino\libraries\PWM/PWM.h:36:33: error: utility/BTimerDefs.h: No such file or directory

3)Arduino\libraries\PWM/BTimerDefs.h:56: error: 'uint16_t' does not name a type

4)Arduino\libraries\PWM/BTimerDefs.h:57: error: 'uint16_t' does not name a type

Much appreciated!

Thank you for the great library!

I have a beginner question, how do I invert one of the outputs e.g. on Timer1 (Pin12 non-invertet, and pinPin11 inverted) on a MEGA.

And 2nd, how do I add an lokking so that Pin 12 and 11 never be HIGH at the same time.

So far I was playing with code from, with limited Frequenzy up to 32kHz:

My Code so far:

/*  
Phase correct inverted 2CH (HS and LS) PWM, 32kHz, 0-255 DutyCycle

http://playground.arduino.cc/Main/TimerPWMCheatsheet
https://www.youtube.com/watch?v=D826h-YQun4&feature=youtu.be
http://arduino.cc/en/Tutorial/SecretsOfArduinoPWM

lock   ns Verriegelung
-----------------
1       34         
2       95
3      162
4      225
5      284
6      342
7      411
8      470
9      535
10     600
20    1220
30    1840

FRQ: 32,377kHz

Mega: 
Timer 0 - Pin 13,4  - 64kHz - NO lock! - millis()!
Timer 1 - Pin 12,11 - 32kHz
Timer 2 - Pin 10(HighSide) ,9(LowSide) - 32kHz
Timer 3 - Pin 5,3,2 - ?
Timer 4 - Pin 8,7,6 - ?

x = % / 2.55;
% = x * 2.55

*/


//--- Global Variables ---------------------
byte x = 0;                     // Aussteuerung 0-255 (0 LS OFF; 1 HS ON
const byte lock = 10;           // Verriegelung (s.o.)
int delta = -1;                 // Duty Cycle verschieben 


//--- FCN Declarations ----------------------
void setInvPWM(byte x=127, byte lock=10);  


//--- Setup ---------------------------------
void setup() {   
TCCR2A = TCCR2A | 0x30;         // Set Timer 2 inverted
TCCR2B = TCCR2B & 0xF8 | 0x01;  // Set Timer 2 Prescaler FRQ 
//Serial.begin(115200);         // Debug
}


//--- Main loop -----------------------------
void loop() {   

  setInvPWM(x,lock);            // Set Inverted HalfBridge PWM and lock on Mega Timer2
    
  if(x==255 || x==0){
    delay(2000);                // extra Pause
    delta = -delta; 
  }   
  
  x +=delta;;                   // Tastverhältniss durchzaehlen, autorollover 
  
  delay(50); 
} 


//--- set Inverted PWM Chanels -------------
void setInvPWM(byte x, byte lock){
  int y;                        // Helper for LS
  
  if(x<1) y = 255;              // Set LS to 0
  else if(x>(254-lock)) y = 0;  // Set LS to 1
  else y = x+lock;              // Verrieglung
  
  if(y<0) y=0;                  // limt to 0
  else if(y>255) y=255;         // limt to 255
  
  // Timer 2 on Mega Pins: 10,9
  analogWrite (10, (x));        // write PWM HS
  analogWrite (9, (y));         // write PWM LS
}

And thats what I want it to look like, but with higer frequency:

What do I need to do if I use this nice lib?
Thanks a lot!