Synchronising PWM cycles

Hi,

I have two separate strips of 24v white LEDs being lit using MOSFETs, each at 50% brightness using a 50% PWM duty cycle. They both turn on for a fraction of a second then both turn off, and repeat. But I want them to alternate such that when one is on, the other is off, and vice versa - both still driven at a 50% PWM duty cycle, just offset by half a cycle.

Any tips on how this can this can be achieved?

Any advice / thoughts would be very much appreciated - thanks!


I've got as far as this:

analogWrite(led_one, round(65535 * 0.5));
delayMicroseconds(1024);
analogWrite(led_two, round(65535 * 0.5));

I need to use a 16-bit PWM resolution for reasons outside the scope of the question, but this is the reason for the 65535 * 0.5 duty cycle.

I calculated a 1024 microseconds delay because my microcontroller (a Teensy 3.1) has a PWM frequency of 488.28 Hz (see here - if I understand this correctly). That means the PWM period (cycle length) is 1 / 488.28 seconds. But I need half of that so that the second strip starts it's duty cycle midway through the first strip's cycle. That equates to a delay of 1024 microseconds.

To test this I used a special(ish) camera that seemed to show that the delay made no difference and both strips had the same PWM cycle start/end without the desired offset between them.

My assumption here is that a PWM duty cycle starts as soon as analogWrite() is called, and it starts at the beginning of the duty cycle. But maybe the function just applies PWM to that pin at some random point in the duty cycle predefined by a timing circuit somewhere else...

First thought: use a logic inverter (7404 or transistor) to generate the second signal from the original PWM signal.

Software solutions require hacking the PWM registers. E.g. see the Fast PWM Mode timing diagram where the output signal can be inverted by COMnx1. Set one channel of the timer to normal output, the other one to inverted output.

The timers inside a microcontroller such as the ATmega328P are very versatile. They are capable to generate two opposite signals from a single timer in a PWM mode.

Teensy 3.1 is a MK20DX256VLH7 processor, Cortex-M4 at 72MHz.
Its timers seems to have even more capabilities.
However, I don't know if there are libraries for that board that can make those signals.

Since you already use a driver circuit with mosfets, I would add an inverter as DrDiettrich wrote.

With the inverter one strip will always be on however if you switch the other side of the strips and leave the PWM operate it will turn on and off and give you the phase relationship you want. You can do the inversion with a simple transistor circuit as stated by DrDiettrich. This requires two pins the same as you started with. If you use a logic device use a74HC04 or similar part, it will give you almost double the voltage swing on the gate as a TTL part will.

Indeed, it would be a very bad idea to use a completely obsolete and poorly functional IC.

Correct version is the 74HC04.

Thanks all for your quick responses - much appreciated.

One requirement that I should have shared is that the final implementation will have more than two LED strips. I am testing with two, but I will likely use six ultimately. In this case, the PWM duty cycle will be 16.67% for all strips, and each strip will have a delay of 1/6 * duty period from the previous strip starting its duty cycle. In this circumstance I don't think the proposed technique of inverting the second signal will work, unless I'm mistaken.

I may test it with two strips anyway, and I'd be happy to implement a hardware solution if there is one. If there is a simple software method, then that might ultimately be more desirable as perhaps it will give me more flexibility in terms of number of strips, ramping PWM, overlapping duty cycles, and so on in the future.

In my ignorance I don't see why my method of using analogWrite() and delayMicroseconds() wouldn't work - maybe this is obvious to everyone else?

I did consider bit-banging the offset square wave functions using digitalWrite() and delayMicroseconds() but I wasn't sure how to account for the delay of the two functions themselves and if this would be very reliable or sensible - any thoughts? I'm also aware it would consume all my processing power.

I'm also starting to research the tips you gave including Fast PWM but I'm only familiar with the more basic Arduino functions I'm afraid so any more pointers would be appreciated.

I only wanted to make clear which type of inverter is meant.

Then consider to use shift registers with each output dedicated to a particular strip and circular feedback from the last output to the serial input.

In software you can use a timer interrupt to update the output signals, best together with a state array.

This won't work with a single timer, because output changes can occur only at BOTTOM, TOP or Match of the unique timer/counter register. Only the Match value can be different for each channel.

With only delayMicroseconds() for the timing the controller may become too busy for other tasks like processing command input.

Yes, but - as always - we try not to provide advice which may be misinterpreted or misleading.