2

I'd like illuminate my room solely with several RGB LED strips using Arduino's PWM (together with LED amplifier and few transistors).

I want the Arduino to control 2 independent chains of LED strips, and I want to make sure, that the LEDs would not blink simultaneously, creating a very strong stroboscopic effect in my room.

How to delay three Arduino's PWM pins half a phase relative to the other three?

12
  • Why do you think you'll observe led blink? Commented Apr 22, 2015 at 12:42
  • @MertGülsoy I will not see LED blinking, but I will see that the stroboscopic effect the blinking would produce. Commented Apr 22, 2015 at 16:44
  • How much of a delay do you have in mind? A few microseconds? Half a second? What is the PWM frequency? What is its duty cycle? Which pins are you using?
    – Nick Gammon
    Commented Jun 30, 2015 at 2:08
  • @NickGammon I need to shift for half of the phase, so if I'd run PWN @ 32Hz, it would mean 1/64th of a second. I plan to use standard PWM pins, but now really consider an external PWM generator which could give me a much higher, not audible frequency (to avoid the annoying buzzing sound from the power source). Commented Jun 30, 2015 at 10:52
  • 1
    You can, see effects of mains frequency in LED's under some conditions. I used to have an RC plane charger with a bi-color LED that would be green for one battery pack, red for the other, and amber for both. The amber was almost indistinguishable from the red, but I found if I shook my head I could see it as a distinct red and green. I also noticed that my LED clock's digits would "swim" when I played low notes on the trumpet (later I had to replace the supply capacitor in that clock - I suspect it had been slowly failing for years, allowing the line frequency to modulate the LED brightness) Commented Jul 4, 2015 at 1:30

2 Answers 2

5

This (short) code below will achieve what I think you are asking for, on the Atmega328 (eg. the Uno, Duemilanove, etc.).

byte dutyCycle = 80;

void setup() 
 {
  pinMode (3, OUTPUT);    // Timer 2 "B" output: OC2B
  pinMode (11, OUTPUT);   // Timer 2 "A" output: OC2A

  // Set OC2A on Compare Match when up-counting.
  // Clear OC2B on Compare Match when up-counting.
  TCCR2A = bit (WGM20) | bit (COM2B1) | bit (COM2A1) | bit (COM2A0);       
  TCCR2B = bit (CS21);         // phase correct PWM, prescaler of 8
  OCR2A = dutyCycle;           // duty cycle out of 255 
  OCR2B = 255 - dutyCycle;     // duty cycle out of 255
  }  // end of setup

void loop() { }

How it works

The code uses Timer 2 (an 8-bit timer) to count up to 255 in phase-correct PWM mode. Outputs are to OC2A (the "A" output - pin D11) and OC2B (the "B" output - pin D3). The duty cycle is in variable dutyCycle which must be in the range 0 to 255. The timer counts up to 255 and sets OC2A on compare-equal to the dutyCycle number, and it also clears OC2B on compare-equal, when counting up. The second half of the phase-correct cycle does the reverse. Thus the two cycles are of opposite phase.

Frequency

The frequency of the timer is 3.9 kHz. This is because the timer has a prescaler of 8, then it counts up to 255, then it takes two cycles per period (one up, one down):

16000000 / 8 / 255 / 2 = 3921.56 Hz

As Edgar Bonet pointed out in the comments, phase-correct PWM counts are not zero-relative, unlike other counting modes. Thus you divide by 255 to work out the frequency, not 256.

You could select other frequencies by choosing different prescalers.

Proof of operation

The oscilloscope screen here shows the two outputs, out of phase with each other by 50%.

Timer output

You can see from the circled cursor measurement that the OC2B pin is off for exactly the requested duty cycle (80 µs).

 1/ 16000000 * 80 * 8 * 2 = 8e-005 (0.00008)  --> 80 µs
4
  • Just nitpicking: the counter does not count up to 256: it stops at 255. It's frequency, according to the datasheet, is 16 MHz ÷ (8 × 510) = 3921.57 Hz. Commented Jul 3, 2015 at 8:38
  • grumble - In non-PWM modes a count of zero gives you one cycle, however observed results (from the screenshot above) appear to agree with your assessment. I must admit that the 80 µs on the screen seemed a little low. FWIW the counter is normally zero-relative, so a count of 255 is 256 cycles.
    – Nick Gammon
    Commented Jul 3, 2015 at 9:28
  • This is a feature of phase-correct PWM: it takes 255 (prescaled) cycles to count up from 0 to 255, then 255 cycles to get back to zero. In contrast, both normal counting (mode 0) and fast PWM (mode 3) have a period of 256 cycles: 255 cycles to count up, and then one extra cycle to roll back to zero. Commented Jul 3, 2015 at 9:46
  • @EdgarBonet - thanks for the correction, I have amended the answer.
    – Nick Gammon
    Commented Jul 3, 2015 at 21:08
0

Why not put a capacitor (and current limiting resistor) in the circuit for each color of each LED? (The output from the Arduino would lead first to a current limiting resistor, value picked to limit the current to the LED to it's max, as usual. Then a small capacitor between the signal line and ground.) That will average out the output and change a square wave output to a DC output (With a fair amount of ripple in it.) The ripple shouldn't matter, but the LEDs won't turn fully off, so the strobe effect should be all but eliminated, and the apparent brightness of each output should be the same.

Then you can use unmodified PWM and don't have to mess with the timers on your Arduino (which affects other things besides PWM.)

6
  • This is a very bad idea. Putting a capacitor on PWM signal kills the dimming effect - the light will stay simply ON for most dimming settings and will put a very high load on the driver especially on low light settings. The driver will frantically try to keep the capacitor full by providing increasingly large charging current during the shorter "on" phase (due to dimming). Commented Feb 28, 2019 at 13:38
  • I just edited my answer to add that you would also need a current limiting resistor. If you limit the max current to the capacitor to the max current for the LED, then lowering the duty cycle of the PWM should lower the average voltage coming out of the capacitor.
    – Duncan C
    Commented Feb 28, 2019 at 14:37
  • Current limiting resistor - is just a resistor that will limit the current by means of consumption. Something tells me, that to get a noticeable effect of dimming you would need such a resistor that would significantly reduce the voltage to the LEDS. Did you actually try what you propose? Commented Mar 1, 2019 at 17:37
  • No, you misunderstand. Put a current limiting resistor BEFORE a capacitor. The current limiting resistor would limit the max current that would flow out of the output pin to the max on current of the LED. Then any PWM duty cycle below 100% would further limit the average current flowing into the capacitor, which should reduce the brightness of the LED and create a (admittedly noisy) steady-state voltage to the LED, all but eliminating the strobing effect.
    – Duncan C
    Commented Mar 1, 2019 at 17:51
  • And no, current limiting resistors do not "limit current by means of consumption." They drop voltage by means of emitting heat (consumption). They also limit the total current through the circuit, as described by Ohms law.
    – Duncan C
    Commented Mar 1, 2019 at 18:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.