PWM frequency library

Does this library work with the Arduino Zero, which has a SAMD processor?

If not, can someone make the necessary changes?

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: Google Code Archive - Long-term storage for Google Code Project Hosting.
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...

meninas92:
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?

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.

+1
Yes that is wierd...

meninas92:
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.

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.

You can find the updated code here: GitHub - 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

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:

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:

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

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:

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.

antec_arduino.ino (2.74 KB)

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?

Hi,
I am working on a light control project, and i need 16 PWM pins with exactly 100Hz, and individually alter the dutycycle. I need to Control 16 dimmers this way, so I can co it either with 3 UNO´s or 2 Mega´s.
On Uno, 4 pins work, and 2 gives me error.
On Mega I experience weird behaviour on most of the pins, and 2 gives me error. They do not give the correct DutyCycle. Here follows the code examples for both boards. I have measured the dutycycle with picoscope, and written the results commented into the code below. Do you have Any Idea how I can achieve my goal using this Library?

//CODE FOR MEGA

#include <PWM.h>


void setup() {

 Serial.begin(9600);
 InitTimers();
 if (!SetPinFrequency(2, 100))Serial.println("PWM pin 2 failed.");
 if (!SetPinFrequency(3, 100))Serial.println("PWM pin 3 failed.");
 if (!SetPinFrequency(4, 100))Serial.println("PWM pin 4 failed.");
 if (!SetPinFrequency(5, 100))Serial.println("PWM pin 5 failed.");
 if (!SetPinFrequency(6, 100))Serial.println("PWM pin 6 failed.");
 if (!SetPinFrequency(8, 100))Serial.println("PWM pin 7 failed.");
 if (!SetPinFrequency(9, 100))Serial.println("PWM pin 8 failed.");
 if (!SetPinFrequency(10, 100))Serial.println("PWM pin 9 failed.");
 if (!SetPinFrequency(11, 100))Serial.println("PWM pin 10 failed.");
 if (!SetPinFrequency(12, 100))Serial.println("PWM pin 11 failed.");
 if (!SetPinFrequency(13, 100))Serial.println("PWM pin 12 failed.");
 Serial.println("Running..");
}
void loop() {

 pwmWrite(2, 25);    //Should have been ca 10%, actual is 40% not changed by changing 25 
 pwmWrite(3, 51);    //Should have been ca 20%, actual is 10% seemes to be changing with pin 2
 pwmWrite(4, 76);    //Should have been ca 30%, actual is 30%
 pwmWrite(5, 102);   //Should have been ca 40%, actual is 80%
 pwmWrite(6, 127);   //Should have been ca 50%, actual is 20%
 pwmWrite(7, 153);   //Should have been ca 60%, actual is50%
 pwmWrite(8, 177);   //Should have been ca 70%, actual is60%
 pwmWrite(9, 204);   //Should have been ca 80%, actual is90%
 pwmWrite(10, 230);  //No duty cycle
 pwmWrite(11, 204);  //Should have been ca 80%, actual is80%
 pwmWrite(12, 177);  //Should have been ca 70%, actual is70%
 pwmWrite(13, 153);  //No duty cycle

 delay(30);
}

//CODE FOR UNO

#include <PWM.h>


void setup() {

 Serial.begin(9600);
 InitTimers();
 if (!SetPinFrequency(3, 100))Serial.println("PWM pin 3 failed.");
 if (!SetPinFrequency(5, 100))Serial.println("PWM pin 5 failed.");
 if (!SetPinFrequency(6, 100))Serial.println("PWM pin 6 failed.");
 if (!SetPinFrequency(9, 100))Serial.println("PWM pin 9 failed.");
 if (!SetPinFrequency(10, 100))Serial.println("PWM pin 10 failed.");
 if (!SetPinFrequency(11, 100))Serial.println("PWM pin 11 failed.");
 Serial.println("Running..");
}
void loop() {

 pwmWrite(3, 26);    //DutyCycle 10% OK
 pwmWrite(5, 51);    //DutyCycle 20% OK
 pwmWrite(6, 76);    //No duty cycle
 pwmWrite(9, 102);   //DutyCycle 40% OK
 pwmWrite(10, 127);  //DutyCycle 50% OK
 pwmWrite(11, 153);  //No duty cycle
 delay(30);
}

I don't know why, but i feel this library is deprecated somehow. The github repository do no allow to send messages / issue to the owner.

Possibly the library work with an older arduino IDE?

Has anyone been able to compile this for the Atmega1284? I'm using the MightyCore bootloader and I get the following message every time I try and compile:

Arduino: 1.8.4 (Mac OS X), Board: "ATmega1284, Standard, 1284, 2.7v, Disabled (default), 20 MHz external"

Build options changed, rebuilding all
sketch/PWM_lib_example.ino.cpp.o: In function setup': /Users/BradJackson/Google Drive/Jackson Ampworks/Arduino/PWM_lib_example/PWM_lib_example.ino:24: undefined reference to InitTimersSafe()'
/Users/BradJackson/Google Drive/Jackson Ampworks/Arduino/PWM_lib_example/PWM_lib_example.ino:27: undefined reference to SetPinFrequencySafe(signed char, unsigned long)' sketch/PWM_lib_example.ino.cpp.o: In function loop':
/Users/BradJackson/Google Drive/Jackson Ampworks/Arduino/PWM_lib_example/PWM_lib_example.ino:39: undefined reference to `pwmWrite(unsigned char, unsigned char)'
collect2: error: ld returned 1 exit status
exit status 1
Error compiling for board ATmega1284.

Hello

I am using arduino nano can i generate 7 mhz pwm signal with 50%duty cycle ?
if yes then guide me How Can i generate ?

Best Regards
seggi.

This Library didn't work. The following message was appeared:

The library "Arduino PWM Frequency Library v_05" cannot be used.
Library names must contain only basic letters and numbers.
(ASCII only and no spaces, and it cannot start with a number)

Please, I need it!

Hi, could anyone help me?
I have noticed that there's no PWM.cpp file. The library wasn't installed.

You extracted the filename of the zip file directly into your library directory as "Arduino PWM Frequency Library v_05"
You should simply make a directory under libraries and call it PWM for example.
C:\Program Files\arduino-1.8.1\libraries\PWM

Then copy all the stuff in under the PWM directory into this new library PWM directory, and copy PWM_lib_example and PWM_lib_resolution_example into there as well.

It should look like this when your done ...

Directory of C:\Program Files\arduino-1.8.1\libraries\PWM

11-May-2018 16:49 .
11-May-2018 16:49 ..
16-Aug-2012 16:55 2,208 keywords.txt
24-Sep-2012 15:24 4,873 PWM.h
11-May-2018 14:38 PWM_lib_example
11-May-2018 14:38 PWM_lib_resolution_example
11-May-2018 16:49 0 showDir.txt
11-May-2018 14:38 utility
3 File(s) 7,081 bytes
5 Dir(s) 113,831,374,848 bytes free

Hello
I like to using this pwm.h librari variable phase shifting arduino between two pwm chanel.
I like the shifing variable 0-180 degrees.

Somebody doing same?

thanks!

Cannot compile the code for Atmega8. While I tried compiling for Atmega168, the code uses 2720 bytes of space and compiles successfully and works fine. Anyone please help me.

post your code if you want help

Hi

I am trying to lower the Arduino Uno PWM frequencies to drive 4 x solenoid valves. Ideally, pins 5 & 6 are untouched to retain timer0 function. However, understand that creating custom frequencies would sacrifice 2 pins on Arduino, which I have found out to be pins 6 and 11.

In the original post by runnerup:
"If you don't want to sacrifice any 8bit PWM pins, don't call the initialize function for that timer, try changing the prescaler to manipulate frequency instead. "

So if I would like to leave pins 5 and 6 untouched and change PWM frequency for pins 3, 9, 10 AND 11 to 31Hz? Do I simply use this setup to change the timer prescaler and the PWM frequencies for the 4 pins would be lowered to 31Hz?

void setup()
{
Timer1_SetPrescaler(ps_1024);
Timer2_SetPrescaler(psalt_1024);
}

I tried doing that and alternatively using this function PwmFrequency to also change the prescaler. But neither works.

So is this a limitation such pins 6 and 11 cannot be used?

Appreciate some clarification/ advice, thanks!

Great Library

Some problems i am facing:
1- Cannot modify the frequency of pin 11, the bool doesn't return success
2- Can't get the resolution on pin 3 and 11 although the timer gives me resolution