Go Down

Topic: PWM frequency library (Read 273336 times) previous topic - next topic

Uup115

Very nice library indeed!

Regarding the frequency sweep, hugoabreu mentioned...  I'm actually doing that for a project, using the Arduino Pro Mini (sweeping from 1 Hz to 500 Hz, with a 1 Hz step size, transitioning steps every 1000 - 2000 msec).  Simply set the frequency and duty cycle for each frequency step:

Code: [Select]

if (SetPinFrequencySafe(led, frequency))
{
       pwmWrite(led, brightness);
}


Only one problem...  The frequency steps sometimes do not transition smoothly.  Meaning, the output will glitch and stick in the high or low state, for up to a second, before stabilizing at the new frequency/duty cycle.   In my use case, the duty cycle remains constant throughout the sweep.  

Unfortunately, for me, this is not good.  Sweeping with these glitches is causing problems with connected device(s).  Has anyone else encountered this problem?  Is there a fix for it?  Any assistance is appreciated.

phatpaul

I noticed the same issue that Uup115 reported.  The frequency does not transition smoothly.  Also the frequency is not exact (off by ~0.5%).  This is due to the ceramic osc. used on the Uno and Mega.  The Leonardo has a crystal osc. with much higher accuracy, but was not supported by this library.

So I forked the library and improved it with the following.

  • Added support for ATmega16U4/32U4 (Leonardo) by "Pierre" Oct 23, 2013. Copied from https://code.google.com/archive/p/arduino-pwm-frequency-library/issues/2
  • Modified to avoid changing prescaler when changing frequency by Paul Abbott - 2017


You can find the updated code here: https://github.com/phatpaul/arduino-pwm-frequency-library

Hope it helps,
Paul

Briney_Eye

It would seem that you changed things so that InitTimers() and InitTimersSafe() now require a minimum frequency argument, breaking everyone's existing code.  Could you explain that?  I'm just getting started reading through the timer section of the ATmega data sheet.

sthudium

#183
Dec 18, 2017, 07:18 pm Last Edit: Dec 18, 2017, 07:52 pm by sthudium
Does this library work with the Arduino Zero, which has a SAMD processor?

If not, can someone make the necessary changes?
I study the use of cognitive dissonance and confirmation bias to manipulate gullible people.

usertogo

#184
Dec 26, 2017, 02:13 pm Last Edit: Dec 26, 2017, 03:23 pm by usertogo
Aloha very happy to see that people are still using the library successfully! I once tested it out and all worked great, but now years later different IDE version (latest on Linux arduino-1.8.5-linux64.tar ) I have a problem getting the library to install, I am using V_05 from: https://code.google.com/archive/p/arduino-pwm-frequency-library/downloads
Regardless of how I put it the IDE complains about the package 'does not contain a valid library'...
It seems nobody has worked on the code since the end of 2012, what could cause this error in my IDE? Any suggestions or workarounds are highly appreciated!

PS: I think I just found the solution in post #126 of this thread (tab 9) a user posted a fixed PWM.zip library, which installed fine and I am onto troubleshooting the rest of my adventure...

usertogo

Hi i have tried to contact the supporter of the library "runnerup". i have some minor fixes to the library i have created a zip compatible with newer versions of arduino. does anyone knows how to contact runnerup?
Would be great if you could upload it at a Git site or so, if the license permits?
And we are all very curious what it was that caused the library to fail to install in those newer IDEs?

Trimjohan

It would seem that you changed things so that InitTimers() and InitTimersSafe() now require a minimum frequency argument, breaking everyone's existing code.  Could you explain that?  I'm just getting started reading through the timer section of the ATmega data sheet.

+1
Yes that is wierd...

Trimjohan

#187
Jan 09, 2018, 11:15 am Last Edit: Jan 09, 2018, 11:25 am by Trimjohan
Hi i have tried to contact the supporter of the library "runnerup". i have some minor fixes to the library i have created a zip compatible with newer versions of arduino. does anyone knows how to contact runnerup?
Great Job with the library! Meninas's version above works flawless for me.

Here is a neat example how to use PWM frequency library by Riham.

https://codebender.cc/sketch:211750#PWM%20Frequency%20Library%20Example.ino

This library really is perfect if you need a lower PWM frequency for solenoids.
As we we all know they need PWM frequencies around 8-40 hz to function properly.


Uup115

I noticed the same issue that Uup115 reported.  The frequency does not transition smoothly.  Also the frequency is not exact (off by ~0.5%).  This is due to the ceramic osc. used on the Uno and Mega.  The Leonardo has a crystal osc. with much higher accuracy, but was not supported by this library.

So I forked the library and improved it with the following.

  • Added support for ATmega16U4/32U4 (Leonardo) by "Pierre" Oct 23, 2013. Copied from https://code.google.com/archive/p/arduino-pwm-frequency-library/issues/2
  • Modified to avoid changing prescaler when changing frequency by Paul Abbott - 2017


You can find the updated code here: https://github.com/phatpaul/arduino-pwm-frequency-library

Hope it helps,
Paul
Paul, nice work!  I've been reluctantly accepting these glitches, until I could find another solution.  Unfortunately, I'm not savvy enough to do what you did.

Many thanks!

Best Regards,
Uup115


rholk

#189
Jan 16, 2018, 05:29 pm Last Edit: Jan 17, 2018, 10:07 am by rholk
Hi,

I have some problem with this library using an arduino mega:

I want to pilot 4 fans (classic pc pwm).


On my setup() i have:
Code: [Select]

InitTimersSafe();

tryF(2, frequency); // Front fan 1 t3B
tryF(3, frequency); // Front fan 2 t3C
tryF(5, frequency); // Front fan 3 t3A
tryF(6, frequency); // Front fan 4 t4A
  Serial.print("t3:");
  Serial.print(Timer3_GetFrequency());
  Serial.print("\nt4:");
  Serial.print(Timer4_GetFrequency());



tryF function:
Code: [Select]

void tryF(int8_t pin, int32_t freq)
{
  //sets the frequency for the specified pin
  bool success = SetPinFrequencySafe(pin, freq);

  if (success) {
    set(pin, 0);
    Serial.print(pin);
    Serial.print("=>");
    Serial.print(freq);
    Serial.print(": SUCCESS\n");
  } else {
    Serial.print(pin);
    Serial.print("=>");
    Serial.print(freq);
    Serial.print(": FAIL\n");
  }
}


And then, i have  a set function callable by serial
Code: [Select]

void set(uint8_t pin, uint16_t val)
{
  Serial.print("Applicating ");
  Serial.print(pin);
  Serial.print("/");
  Serial.print(val);
  Serial.print("\n");
  pwmWriteHR(pin, val);
}





At the begin of my soft i have:
Code: [Select]

mega: init...
mega: Applicating 2/0
mega: 2=>25000: SUCCESS
mega: Applicating 3/0
mega: 3=>25000: SUCCESS
mega: Applicating 5/0
mega: 5=>25000: SUCCESS
mega: Applicating 6/0
mega: 6=>25000: SUCCESS
mega: init done (pwm)
mega: t3:25000
mega: t4:25000


So everything is fine and i see my fan throttle down to 500 rpm (hall detection on pins 21 20 19 18).
If i call set(2, 65535), my fan 1 goes to max speed (~1600 rpm) and not the others.
RPM:1695,540,570,525
If i call set(5, 65535), my fan 3 goes to max speed (~1600 rpm).
RPM:1650,540,1605,510

My problem is when i use for example:
set(5, 32767), my rpm report is strange:
RPM:1050,555,1620,525 => fan 1 on pin 2 have it's speed reduced!

I don't know where is the bad behavior of my soft. can someone help me?

Electricaly, pins of the arduino are directly connected to the pwm of the fan. Ground / 12v is supplied by an ATX power supply.
Same supply powers the PC piloting the arduino, threw usb.
Possibly ground issue?

Complete code linked.

Jelmer_

Hi,
Is there also a way to get a more precise frequency. Because i need a frequency of about 80.4 hz. Can i send a float in the function or is there some other method?

Go Up