Let's Make Robots!

Arduino PWM output frequencies and Tone command

I've been playing with a new oscilloscope Dagu bought after the old one died. I decided to check out the Arduino PWM outputs because I'm using an Arduino in my new speed controller and wanted to check if there were any differences as the brake function requires two PWM outputs to be be in sync so that both input are high or low at the same time.

The PWM outputs on pins 5 and 6 share a timer with timing functions such as millis() and delay() run at about 976Hz while PWM outputs on pins 3,9,10 and 11 run at about 488Hz.

Fortunately I was already avoiding the PWM pins 5 and 6 because of their interaction with the time functions. All other PWM outputs sync nicely when set to the same dutycycle, good news for my speed controller :D

After some recent problems I have also discovered that the tone command kills PWM on pins 3 and 11. This is because the tone command uses the same timer. Unfortunately the noTone command does not reset the timer back to default settings.

This is unfortunate because I need all the PWM outputs for a robot I'm building and I also wanted to play tunes. Does anyone know how to undo the changes made by the tone command to reactivate the PWM command on those pins?

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

I've not tested it but it seems, that only 3 Timer2 registers were influenced by the Tone lib.

TCCR2A, TCCR2B and TIMSK2.

Just init the registers to default values (found in wiring.c) and PWM should work again.

TCCR2B = CS22;    // set timer2 prescale factor to 64
TCCR2A = WGM20;  // configure timer2 for phase correct pwm (8-Bit)
TIMSK2 = 0;          // disable all timer2 interrupts

 

I'll give it a whirl tomorrow if I'm not too hung over. I have guest to entertain tonight :D

Oops, wrong code. The register defines are bits. This is (maybe) the correct code:

TCCR2B = (1 << CS22);    // set timer2 prescale factor to 64
TCCR2A = ( 1 << WGM20) ;  // configure timer2 for phase correct pwm (8-Bit)
TIMSK2 = 0;          // disable all timer2 interrupts

Thanks for that. It seems to work fine. On the oscilloscope the affected outputs are no longer in sync with the unaffected outputs after your fix but that is not normally an issue. Below are before and after shots of 25% PWM on pins 3 and 9, yellow is pin 9 and cyan is pin 3.

Before:

After:

I suspect all the timers would need to be reset at the same time to correct this.

Yes, you're right. The timers should be resetted.

if you use the servo library then you can have 12 servos on one arduino so you can use a servo on any pin, not just on the few PWM pins.http://www.arduino.cc/en/Reference/Servo. I know you are not driving servos, but this may or may no help.

Sorry, no this is not for servos, I need the PWM functions to vary the speed of motors driven with H bridges and calibrating an RGB sensor. For now I am just not using the tone command until I can find a fix.