Go Down

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

texmit

Does anyone know if this library broke on arduino 1.6?

I've used this library for outputting 4 PWM signals for my custom aquarium LEDs, it worked fine for over a year.
(running on an arduino mega2560 with a WizNet 5500 ethernet board on top)
Now I wanted to make some changes, recompiled the code using the latest arduino libraries on Arch linux and it simply doesn't work anymore. No errors, but only pin 11 seems to work (but not properly), pins 5 / 6 and 44 simply give no signal as far as I can tell.
Using analogWrite instead of pwmWriteHR turns on the LEDs without problems.

Does anyone have any clue as to what the cause might be?

Wouter
I have been able to fix this problem. The ATTimerDefs.h file in the PWM library has a TimerData structure and it appears that a new TIMER1C has been added so the wrong timers are being accessed now. To fix this problem, add a row to the timer_to_pwm_data[] array after line 107:
{0, 0, 0, 0, 0}, //TIMER1C

This will shift all the rows after TIMER1 (which is working - pins 11 and 12) down by 1 and then all the pwm pins will work again.

lcw1125

#136
Aug 20, 2016, 10:45 am Last Edit: Aug 20, 2016, 02:14 pm by lcw1125
Thanks runnerup for the awesome library.

I've tested the pwmWriteHR on my Uno with different frequencies (10Hz, 10KHz, 1MHz, 10MHz for example). The "resolution reduce when frequency increase" case seems not happening because the resolution is still 16bit no matter what frequency i set.

I connect pin 3 and pin 9 to LED for comparing its light because i don't have an oscillator. I only need 10 bit resolution, with fixed frequency lets say about 50KHz (or any fixed freq). Can anyone help check on my program to find out what i missed, or is there any other way to get adjustable resolution?

Thanks.


#include <PWM.h>

int led = 9;
int VRef = 0;
int32_t AAA = 0;
int32_t TestFreq = 50000;  //change frequency here

void setup() {
InitTimersSafe();
SetPinFrequency (led,TestFreq);
pinMode (3, OUTPUT);
Serial.begin (115200);
}

void loop() {    
VRef = analogRead(A0);
pwmWriteHR (led, AAA);
analogWrite (3, VRef/4);
AAA = AAA + 1;
if (AAA == 65536){
 AAA = 0;
}
Serial.print ("VR: ");
Serial.print (VRef);
Serial.print ("AAA: ");
Serial.println (AAA);
}

bill_lask

Awesome library!!!


I have one problem

i have an arduino mega and i run this code
Code: [Select]

/*

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 = 3;                // 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(6, OUTPUT);
   digitalWrite(6, LOW);    
 }
}

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);      
}




i have set the pin 6 low but did the same with pin 3 with pwm library
can anybody help me to slove my problem?

hanslanda

#138
Sep 14, 2016, 05:52 am Last Edit: Sep 14, 2016, 03:16 pm by hanslanda
Hey there guys,

First and foremost, thanks for writing this library. I'm still new to the Arduino world but i can already tell this was much needed by the community even by my basic need of it.


I've not even gone through the testing of this code yet because there are some fundamentals i wish to understand about this library first. Once i get the basic understanding i'm looking for, i will test the code in my current project i'm working on.


Let me start with this. I'm attempting to control a PC water cooling pump thats pwm controlled. The pump itself has a molex connector for its 12v and gnd. It also breaks out to a 4 pin connector which contains the PWM signal and Temp out. So all i need to do is tie into the PWM-in on the pump. Temp pin isn't necessary here and you'll read why below.



1) I'm using a TFT LCD shield on an Arduino mega 2560.


2) The TFT shield uses pins D0 to D7 and i would assume changing the clock on any of those would not be a good thing.

ref.

http://elecfreaks.com/store/download/datasheet/shield/TFT_MEGA_V2.0.pdf


3) I'm also currently using D8 for DallasTemp/oneWire on (3) DB18 temp sensors. Again, prefer not to mess with that, but it would not be a big deal to have to move it as i'm still in breadboard mode.




So here's my real question. According to the "timerpwmcheatsheet" my mega has 5 timers?

timer 0 (controls pin 13, 4)
timer 1 (controls pin 12, 11)
timer 2 (controls pin 10, 9)
timer 3 (controls pin 5, 3, 2)
timer 4 (controls pin 8, 7, 6)



Okay, simple for me. I want to tie into pin 9. If i'm still following here that means i'm going to change timer 2 which should only affect pins 9, 10... neither of which i'm using now. If i'm not lost and this is the case... i can't help but stumble on the way this library describes its global functions. See below


Code: [Select]


InitTimers() Initializes all timers. Needs to be called before changing the timers frequency or setting the duty on a pin

//Okay no problem.


InitTimersSafe() Same as InitTimers() except timer 0 is not initialized in order to preserve time keeping functions

//This. If you are not changing timer 0, why would this be important? Or are you 'changing' timer 0 JUST by initializing it?


SetPinFrequencySafe(int8_t pin, int32_t frequency) Same as SetPinFrequency except it does not affect timer 0

//I have the exact same question here. If i change the frequency of pins on timer 2, it wouldn't affect timer 0... so why would i need this?




Next:


Code: [Select]


Timer1_GetFrequency() Gets the timer's frequency in Hz
//Simple enough


Timer1_SetFrequency(int frequency) Sets the timer's frequency in Hz
//Wonderfully simple


Timer1_GetPrescaler() Gets the value (not bits) of the prescaler. Don't know what this means? Don't worry about it, just use SetFrequency(int frequency)
//I read a limited amount on this, but from my limited need, i shouldn't need to use this.


Timer1_SetPrescaler(enum value) Sets the prescaler*
//Same as above


Timer1_GetTop() Gets the timer register's maximum value
//Debug function more or less?


Timer1_SetTop(int top) Sets the timer register's maximum value
//I'm not sure how to use this. I thought timers already had fixed maximum values.


Timer1_Initialize() Initializes the timer
//A way to initialize a single timer? Seems ideal for me since i'm only interested in changing one?





Please correct me on my lack of understanding where it exists. The goal is simply to get this pump to run 100% speed. Since currently it appears to be running at its slowest possible speed. I also read motherboard PWM outputs run at 25kHz. So i simply want to change pin 9 to 25kHz with 100% duty cycle. I assume this will accomplish my needs. Again correct me if i'm wrong lol.



So i guess by my rudimentary understanding, here is what ill add for code.



In setup:


Code: [Select]


Timer2_Initialize()

Timer2_SetFrequency(25000)

pwmWrite(9, 255)





Otherwise i guess i could do this?



Code: [Select]


InitTimersSafe()

SetPinFrequencySafe(9, 25000)

pwmWrite(9, 255)




Again my main concern is that initializing the timers does something to the timer i guess i'm not understanding, which is why you require this safe function? My real fear, given the previous sentence is a reality, and i am affecting other timers, then my concern is that could affect pwm pins 0-7, which are used by my LCD shield.


Any comments greatly appreciated. If i should post this elsewhere please let me know.



*update*

I tested both code segments i posted above as examples. Either i have the quietest pump on the planet, which Also was already running at full speed, or it didn't change anything in my situation.

raschemmel

Use CODE TAGS [</>] button for code.
Arduino UNOs, Pro-Minis, ATMega328, ATtiny85, LCDs, MCP4162, keypads,<br />DS18B20s,74c922,nRF24L01, RS232, SD card, RC fixed wing, quadcopter

hanslanda

Use CODE TAGS [</>] button for code.
I barely posted any code at all. But i added the code tags for your viewing pleasure.

raschemmel

Thanks. It helps make the code stand out from everything else. (among other things, like scrolling)
Arduino UNOs, Pro-Minis, ATMega328, ATtiny85, LCDs, MCP4162, keypads,<br />DS18B20s,74c922,nRF24L01, RS232, SD card, RC fixed wing, quadcopter

hanslanda

Thanks. It helps make the code stand out from everything else. (among other things, like scrolling)
I keep failing on adding the code tags :P


Do you see anything i could be doing wrong off the bat with my above description? Using the two code segments at the bottom of my post, i was unable to see any difference in motor speed. I do need to test this on a fan or another device to make sure the pump isn't giving me grief, but until i can do that.. i would just like to know my code is correct. For reference changing the pin timers i changed did not interfere with my touch screen/lcd.

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy