Tuesday, 5 July 2011

Arduino: Out of sync PWMs


Follow up to my last article, here is an application which helps run out of sync PWMs. This only works on Arduino Mega, as it requires more control over timers. The application would be anything that requires 2 sets of PWMs that work out of sync and in sync with each other. There are 3 groups of three PWMs on the Mega which can be configured, so you can have six running against three, or all nine running in sync.

The last article can be found here: http://smacula.blogspot.com/2011/04/creating-variable-frequency-pwm-output.html

The simple technique to do this is to set one timer in invert mode, using the same logic as applied in the last article, and one in non-invert mode.

E.g. the code I use is:

TCCR3A = _BV(COM3A1) | _BV(COM3B1) | _BV(COM3C1);
TCCR4A = _BV(COM4A1) | _BV(COM4B1) | _BV(COM4C1) | _BV(COM4A0) | _BV(COM4B0) | _BV(COM4C0);

Which sets Timer 3 (pins 2,4,5) in non-invert mode and Timer 4 (pins 6,7,8) in invert mode.
Later on in the code, when PWM is applied, make sure you subtract the required percentage by a 100.
So say, you want 33% on pins 2 and pins 6, 180 degrees out of sync with each other.
So
PWM on pin 2 = 33
PWM on pin 6 = 100 – 33 = 67.
Which would mean that both pins are giving 180 degrees out of sync PWM output of 33%.
Refer to the last article for rest of the maths involved. But as a quick summary:

After above statements, apply pre-scalar if required:

TCCR3B = _BV(WGM33) | _BV(CS31); // Divides by 8
TCCR4B = _BV(WGM43) | _BV(CS41);

Set frequency:

ICR3 = 1000; // Set to 1kHz
ICR4 = ICR3;

Insert required PWM:

PWM2 = 33
PWM6 = 67

Apply the values to the required variables:

OCR3B = PWM2 * ICR3 / 100;
OCR4A = PWM6 * ICR3 / 100;

Alternatively, the 100 – PWM6 might be applied at the later stage:

OCR4A = (100 – PWM6) * ICR3 / 100;

Which means the above lines can be changed to:

PWM2 = 33;
PWM6 = 33;

Which is easier to manage.
Give me a shout if you have any questions/suggestions

2 comments :

  1. Electronic stuff, no idea :P

    ReplyDelete
  2. bloody hell you commented even before I had posted a link to this any where! lol

    ReplyDelete