PWM frequency library

junktronix:
I'm curious what you fixed. I've noticed that occasionally the PWM doesn't start immediately. The PWM output will be high or low for 5-10mS before the pulses start.

I am using an Arduino Uno with this library. Does anyone know what causes these errors or how to fix them? Attached is an image showing the significant error periodically occurring at the beginning of the PWM signal of an output when viewed on a logic analyzer.

PWM Error.jpg

Hi,

I have to make a project where PWM frequency should be around 8-9kHz on one pin and also servo library is involved. To test how PWM frequency library works with servo library I whipped together simple sketch with a few lines borrowed from examples. I used Arduino Nano.

When servo is attached to the pin 9 and SetPinFrequencySafe to pins 10 or 11, there is no PWM on these pins; servo works OK
When servo is attached to the pin 9 and SetPinFrequencySafe to pin 3, there is 9kHz PWM on pin 3, but when I turn the pot to change the duty cycle, the actual change happens with delay of 3-4 seconds, very weird indeed; servo works OK

So the question is, can PWM frequency library and servo library work reliably together and what pins should I use. I need 1 pin for PWM and 1 pin for servo.

Thank you beforehand,
Fred

Here is the code I used for testing

#include <PWM.h>
#include <Servo.h>  

int32_t frequency = 9000; //frequency (in Hz)

int servoPin = 9;
Servo servo; 
int angle = 0; // servo position in degrees 

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

  //sets the frequency for the specified pin
  bool success = SetPinFrequencySafe(10, frequency);
  
  //if the pin frequency was set successfully, turn pin 13 on
  if(success) {
    pinMode(13, OUTPUT);
    digitalWrite(13, HIGH);   
	
  }

  
  servo.attach(servoPin); 
  
}

void loop()
{
  
  int sensorValue = analogRead(A0);
  pwmWrite (10, sensorValue / 4);
  
  delay(30);   
  
// scan from 0 to 180 degrees
  for(angle = 0; angle < 180; angle++)  
  {                                  
    servo.write(angle);               
    delay(15);                   
  } 
  // now scan back from 180 to 0 degrees
  for(angle = 180; angle > 0; angle--)    
  {                                
    servo.write(angle);           
    delay(15);       
  } 

  
}

Please Help! I got the code below to work. I sent the PWM signal into Motor Driver BTS7960 43A. The motor speeds up and slows down as expected. But I want to control the DUTY CYCLE to change speed NOT the frequency. PWM Noise must not be heard so I have set the PWM frequency to 21,000hz.

Thanks

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 fadeAmount = 5; // how many points to fade the LED by
int32_t frequency = 35; //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 + fadeAmount;

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

delay(30);
}

hi,
I have read every post of every page but can not able to compile library with ide 1.8
getting, 'InitTimersSafe' was not declared in this scope
can someone run it in latest ides ?

Hi,
I'm seeing strange behavior of the pwmWriteHR() function on a Mega (not an official Arduino one). I'm not 100% what the board model is. It has an ATmega1280 processor though.

With attached code I see that pin 3 is getting the PWM set for pin 2 and pin 8 gets the output set for pin 7. Though I have to set a PWM value for 3 and 8 or no output will be given. So setting a value for a pin enables output but it gets the value set for the previous pin.

When I use analogWrite() I'm seeing normal behavior.

Arduino IDE 1.8.1 on Win10.

Is it my code or a library bug?

#include <PWM.h>

int led = 11;

void setup() {

 Serial.begin(115200);

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

  //SetPinFrequency(led, 15625);  //setting the frequency
  SetPinFrequency(2, 31250);
  SetPinFrequency(3, 31250);
  SetPinFrequency(5, 31250);
  SetPinFrequency(6, 31250);
  SetPinFrequency(7, 31250);
  SetPinFrequency(8, 31250);
  
  Serial.println("TIMER1");
  uint16_t frequency = Timer1_GetFrequency();
  uint16_t decimalResolution = Timer1_GetTop() + 1;
  uint16_t binaryResolution = GetPinResolution(led); //this number will be inaccurately low because the float is being truncated to a int

  char strOut[75];
  sprintf(strOut, "Frequency: %u Hz\r\n Number of Possible Duties: %u\r\n Resolution: %u bit\r\n", frequency, decimalResolution, binaryResolution );

  Serial.println(strOut);

  Serial.println("TIMER2");
   frequency = Timer2_GetFrequency();
   decimalResolution = Timer2_GetTop() + 1;
   binaryResolution = GetPinResolution(led); //this number will be inaccurately low because the float is being truncated to a int

   strOut[75];
  sprintf(strOut, "Frequency: %u Hz\r\n Number of Possible Duties: %u\r\n Resolution: %u bit\r\n", frequency, decimalResolution, binaryResolution );

  Serial.println(strOut);

  Serial.println("TIMER3");
   frequency = Timer3_GetFrequency();
   decimalResolution = Timer3_GetTop() + 1;
   binaryResolution = GetPinResolution(led); //this number will be inaccurately low because the float is being truncated to a int

   strOut[75];
  sprintf(strOut, "Frequency: %u Hz\r\n Number of Possible Duties: %u\r\n Resolution: %u bit\r\n", frequency, decimalResolution, binaryResolution );

  Serial.println(strOut);
  
  Serial.println("TIMER4");
   frequency = Timer4_GetFrequency();
   decimalResolution = Timer4_GetTop() + 1;
   binaryResolution = GetPinResolution(led); //this number will be inaccurately low because the float is being truncated to a int

   strOut[75];
  sprintf(strOut, "Frequency: %u Hz\r\n Number of Possible Duties: %u\r\n Resolution: %u bit\r\n", frequency, decimalResolution, binaryResolution );

  Serial.println(strOut);

 
}


unsigned int value = 0;
 int value2 = 0;
 int value3 = 0;
int dir = 0;


void loop() {


  pwmWriteHR(2, 32000); // ?
  pwmWriteHR(3, 0); // ?

  pwmWriteHR(7, 5000);
  pwmWriteHR(8, value);

  value = (value + 10) % 65536;
  value2 = (value2 + 5) % 65536;

//delay(1);

}

My problem posted just above is solved by texmit's fix earlier in this thread: PWM frequency library - #136 by texmit - Libraries - Arduino Forum

That fix was posted almost a year ago. Too bad the library owner seems to have orphaned it. It's a mighty useful one.

(deleted)

Dear Brothers, firstly sorry for bad english, my arduino is Arduino MEGA 2560, i want to learn how to change frequency and search the library for it, and find the google code link below :

https://code.google.com/p/arduino-pwm-frequency-library/downloads/list

and downloaded the 5th Version of it >> unzip it in the arduino.ide library on my computer, im sure that i follow this step of adding library :

btw my arduino.ide version is 1.8.2

why i cannot compile or even upload the example program ?
it said :

Arduino: 1.8.2 (Windows Store 1.8.3.0) (Windows 10), Board: "Arduino/Genuino Mega or Mega 2560, ATmega2560 (Mega 2560)"

C:\Users*****\Arduino\sketch_jun07a\sketch_jun07a.ino:1:17: fatal error: PWM.h: No such file or directory

#include <PWM.h>

^

compilation terminated.

exit status 1
Error compiling for board Arduino/Genuino Mega or Mega 2560.

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

my teacher said that i must search the library for arduino mega instead of arduino uno (?), is that right ? is there any solution ?

Your teacher is wrong i'm afraid as both the UNO and MEGA use similar AVR architecture.

There is a good comparison link HERE

Clearly The mega has more pins due to the difference in processor but the lib should still be capable of handling that aspect.

More likely the library has been put in the wrong location.
Using <PWM.h> requires the files to be in the /libraries folder.
Using "PWM.h" requires the files to be in same folder as the sketch.

Hi Everyone, I'm new here ;]

Just wanted to say that this is an excellent PWM library and you guys are an awesome community!

I was wondering if anyone has tried using interrupts with this library? Let's say to just count the number of positive-edge pulses, then if a threshold is reached, stop the pwm?

Perhaps something along the lines of ISR(Timer1_compa_vect)?

Thanks,
Oyakodon

Hi there,

Do you guys think that's possible to make a Frequency sweep with this librarie?

I was trying to build one, but I'm not sure of what I am missing, or if it is possible indeed.

please, If you want to take a look in my code bellow:

     FPWM = lgf[lx]; // This is the frequency of the PWM that im obtainning from another function.

     Init: InitTimersSafe();
   //sets the frequency for the specified pin
     success = SetPinFrequencySafe(SPWM, FPWM);
   //initialize all timers except for 0, to save time keeping functions
   
   if (success)   //here its where I would change my PWM frequency, if success.
   {
     cdelay = 1;
     VL = 0;
     sumvL = 0;
     if (readFlag == 1)
     {
       readFlag = 0;
     }
     while (VL <= cdelay)
     {
       //use this functions instead of analogWrite on 'initialized' pins
       pwmWrite(SPWM, LPWM);  // more precisely here.
       if (readFlag == 1)
       {
         sumvL = sumvL + analogVal;
         VL++;
         readFlag = 0;
       }
     }
     Vs[lx] = sumvL / VL;
   }
   else 
   goto Init; //If success is not ok I would go back to InitTimersSafe() line.

Thank you for the attention and sorry for bad english.

@ hugoabreu

sudo code ?

Hi.

This code I've put its inside the for loop. I didn't put everything couse, its too long and it doesn't matter.

My main question is if you think that we can change frequencies of PWM inside a for loop.

Ty

@hugoabreu

All code matters.
Without it nobody can tell if its good or bad or could be improved in any way or even broken into better segments etc.

And yes it should be possible to call a change inside a loop.
However you should realise that in doing so timers and interrupts could also be changed with unforeseen results unless you account for them.

Thanks a lot. This library is AWESOME.

I was able to get 100kHz PWM with 16 bit resolution!

I'm experiencing an issue between a UNO and MEGA - my problem is described in a new post (did not notice this thread was still active, assumed it was too old)

Hi all,
this is really a great library - very helpful :slight_smile:

There's just one thing, that's bugging me. Each time, i include the lib in any of my programs, i get some warnings during the compiling.

/Users/philipp/Documents/Arduino/libraries/PWM/utility/BTimerDefs.cpp:26:0: warning: "UINT16_MAX" redefined
 #define UINT16_MAX 65535

 ^
In file included from /Applications/Arduino.app/Contents/Java/hardware/tools/avr/lib/gcc/avr/4.9.2/include/stdint.h:9:0,
                 from /Applications/Arduino.app/Contents/Java/hardware/tools/avr/avr/include/inttypes.h:37,
                 from /Applications/Arduino.app/Contents/Java/hardware/tools/avr/avr/include/avr/sfr_defs.h:126,
                 from /Applications/Arduino.app/Contents/Java/hardware/tools/avr/avr/include/avr/io.h:99,
                 from /Applications/Arduino.app/Contents/Java/hardware/arduino/avr/cores/arduino/wiring_private.h:26,
                 from /Users/philipp/Documents/Arduino/libraries/PWM/utility/BTimerDefs.cpp:23:
/Applications/Arduino.app/Contents/Java/hardware/tools/avr/avr/include/stdint.h:346:0: note: this is the location of the previous definition
 #define UINT16_MAX (__CONCAT(INT16_MAX, U) * 2U + 1U)
 ^
/Users/philipp/Documents/Arduino/libraries/PWM/utility/BTimerDefs.cpp:27:0: warning: "UINT8_MAX" redefined
 #define UINT8_MAX 255

 ^
In file included from /Applications/Arduino.app/Contents/Java/hardware/tools/avr/lib/gcc/avr/4.9.2/include/stdint.h:9:0,
                 from /Applications/Arduino.app/Contents/Java/hardware/tools/avr/avr/include/inttypes.h:37,
                 from /Applications/Arduino.app/Contents/Java/hardware/tools/avr/avr/include/avr/sfr_defs.h:126,
                 from /Applications/Arduino.app/Contents/Java/hardware/tools/avr/avr/include/avr/io.h:99,
                 from /Applications/Arduino.app/Contents/Java/hardware/arduino/avr/cores/arduino/wiring_private.h:26,
                 from /Users/philipp/Documents/Arduino/libraries/PWM/utility/BTimerDefs.cpp:23:
/Applications/Arduino.app/Contents/Java/hardware/tools/avr/avr/include/stdint.h:331:0: note: this is the location of the previous definition
 #define UINT8_MAX (INT8_MAX * 2 + 1)
 ^
Sketch uses 6508 bytes (20%) of program storage space. Maximum is 32256 bytes.
Global variables use 258 bytes (12%) of dynamic memory, leaving 1790 bytes for local variables. Maximum is 2048 bytes.

Nevertheless the code compiles and works fine.

Is someone else having the same problems and how can i solve this?

Thank you all!

Philipp

looks like two developers got the same name idea for a #define... the second one reinventing the wheel from stdint.h which has been here for more than 18 years and is better written....(it's a header file in the C standard library introduced in the C99 standard library section 7.18 to allow programmers to write more portable code)

you could go modify the library and put a test to see if it's already defined, something like

#ifndef UINT8_MAX
#define UINT8_MAX 255
#endif

but you could also simply remove them (possibly #include <stdint.h> but I think is added automatically hence the compiler barking at the redefinition - to be tested)

Thank you!
I just altered ATimerDefs.cpp and BTimerDefs.cpp.

Changed

#define UINT16_MAX 65535
#define UINT8_MAX 255

to

#ifndef UINT16_MAX
#define UINT16_MAX 65535
#endif
#ifndef UINT8_MAX
#define UINT8_MAX 255
#endif

in both files.

Works and the compiler is not barking anymore :slight_smile: