I need to set TIMER3, controlling pins 2 and 3 on an Arduino Mega to either fast PWM mode (acceptable) or faster (higher frequency)(preferable).
I use this PWM to control an audio signal through a Silonex light sensitive resistor/LED unint and some audio contamination can be heard because of the speed at which the Silonex reacts. I used TIMER0 in tests with a prescaler of 1 and it works OK. But TIMER1 is "fast" PWM and TIMER3 is "phase correct".
So, either I make TIMER3 "fast" or even better, I set TIMER3 even faster (I would like to try a maximum frequency of 125000 or 250000 Hz if that's possible. A "fast" PWM does 62500 max).
I have read the whole "Arduino 101: Timers and Interrupts"a few times, but I'm just not good enough to "get it".
Here is a great timer tutorial for AVR, and a breif PWM tutorial. Its doesn’t reference Arduino but it probably has the information you need at a lower level still using C programming.
It does work for the Mega, but what I’m trying to do is convert TIMER3 from a phase-correct to a FAST PWM. These instructions change the pre-scaler and top off at 32K on the pins I need.
These are great tutorials. Unfortunately the second one was never completed. But it gives me an incentive to read the datasheet for the atMega processors and try to figure which but does what in these timer registers.
In the mean time, if anyone can supply me with the instructions to set TIMER3 as in my question, it would save me a lot of reading. That datasheet is 448 pages long…
I understand the first line (I went through the code in the library). I don 't understand the relation between duty cycle and period. And the relation between duty cycle and the PWM value that analogWrite(pin, value) sends to the pin. (Maybe I just don’t understand duty cycle…)
You will need to call Timer3.initialize(), otherwise it will not work. Using analogWrite() will not work here, because the Arduino core initialize Timer 1,3,4,5 to use 8bit pwm mode.The value range for 8bit pwm is 0…255. Timer3 lib is using 10bit pwm mode, with a value range of 0…1023.
I won’t have to test it (analogWrite) then. The timer3.pwm() will be it.
Question: The pwm() has 3 params in the library. Omiting the last one (period) makes it similar to setpwm()?
Thanks for the library and all the pointers to the reading material.I wouldn’t have undestood the code in the library without all the reading (there are still some nebulous stuff in there…)
The pwm() function is using a C++ trick to accept different parameter lists. When you look in the function declaration in the header file:
void pwm(char pin, int duty, long microseconds=-1);
You see, the last parameter has a default value of -1. If you call the function with only 2 parameters, the timer period will not be changed. Because this is already been done in the initialization function.
The difference between pwm() and the setPwmDuty() function is, setPwmDuty doesn’t initialize the PWM pin. If you only call setPwmDuty() in your program, the PWM output pin will not work.
Conclusion:
In every program you need to call in your setup() function the initialize() function once and the pwm() function for each needed PWM output . In the loop function you can change everything you want with the setPwmDuty() or setPeriod() function to change PWM duty and PWM period time.
I mustconfessthat I also do notunderstandeverything about timers and their different modes. It’s the most complicated stuff in Arduino programming.