Need to run 3 PWM's on different duty cycles w/ same start point on rising edge

I am trying to prove a project for industrial use using an UNO with the 328 chip. I need 3 PWM's running the same period but at different duty cycles and the rising edges must be synced. A couple other notes: the period is determined by the main duty cycle (dutyCycle*100/60) so that the on pulse duration is the same throughout the duty cycle range. I can get this to somewhat work with pins 5 & 6 although I don't seem to have the period range I'm looking for. I can get the period range I need from pins 3 & 11 but the duty cycles seem to vary from the center of the pulse not a common rising edge, i.e. if you have pin 3 running 50% duty cycle and pin 11 running 25% duty cycle the leading edge for pin 11 is shifted right and the falling edge is shifted left.

Thanks for taking the time to post on the forum. Did you have any questions?

I have some questions, I can't quite understand your explanation.

the same period but at different duty cycles

Different duty cycles, ok.

the period is determined by the main duty cycle (dutyCycle*100/60)

The same duty cycle for all 3, which is 100/60?

So i need all three pins to run at 58 hz for arguments sake. One pin will run at 10% duty cycle, one pin will run at 35% duty cycle, and the last pin will run at 40% duty cycle. (Duty cycles could change, these are legitimate examples though)

The frequency will be determined by the middle duty cycle above so (35*100/60)=frequency.

I need all three signals rising edges to start together then use the duty cycle to "cascade" the devices turning off.

Making a little more sense now. Before you said "main duty cycle".

What level of accuracy is needed? How close is "together"? How accurate must you be to 58Hz? How close to the 10% or 35% must you be? Please be quantitative.

jt082576:
So i need all three pins to run at 58 hz for arguments sake.

The standard Arduino frequency is 490Hz

The frequency will be determined by the middle duty cycle above so (35*100/60)=frequency.

The frequency is independent of the duty cycle

IIRC the GTCCR register (Atmega 328 datasheet) can be used to ensure that the Timers (which produce PWM) start at the same time. I'm pretty sure that is how I arranged to synchronize the PWM cycles on two different Arduinos.

...R

The ideal target here is that the middle duty cycle in previous post is always on for 6mS. The device we are controlling is 24V but a requires a short spike of 48VDC to turn on quick enough for the process. Hence the 10% duty cycle. It also requires being driven to -24VDC to turn off fast enough. Hence the longer duty cycle at the end. These will work with some gates to control the device.

As for how accurate this needs to be the answer is +/- 1% on the frequency. The device is a spray nozzle and the frequency and duty cycle directly affect volume used.

As for together I mean all three signals rising edges need to start at the same moment in time.

So all three signals need to start at 0 seconds. The first duty cycle will go off at 2ms. The second duty cycle will go off at 6ms. The final duty cycle will go off at 8 ms. Then all 3 will turn back on at 15 ms. (Times are for example only. I didn't do the math on all 3 to verify.)

I agree if I were running two different boards but that doesn't appear to sink the 3 timers that the 6 pins on the UNO run off of. Pins 3/11 on clock 0. Pins 5/6 on clock 1. Pins 9/10 on clock 2. I will try again though to make sure I did that correctly. Pins 5/6 seem to be limited on frequency as well.

I need all three signals rising edges to start together then use the duty cycle to “cascade” the devices turning off.

With millisecond timing I would suggest that you use a software timer, perhaps configured in microseconds. What is the range of cycle frequencies?

You can turn all the pins on simultaneously at the cycle start with a direct port command instead of digitalWrite().

A timed sequential state machine with all on>two on> one on>all off would fit well.

jt082576:
So i need all three pins to run at 58 hz for arguments sake.

As @cattledog has said at a low frequency like that there is no need to use the Hardware Timers.

If you really do need to use Hardware Timers then get an Arduino Mega which has more of them so you don't need to use the one that is dedicated to millis()

...R

all three signals rising edges need to start at the same moment in time.

All 3 edges with zero time difference is impossible. Even with the finest, most expensive equipment in the world and most careful engineering, there will always be a small time difference. That’s why I asked “how close is together”. So what time difference is acceptable to you? You seem to say 1% of 15ms = 150us is acceptable accuracy for timing the falling edges, so is that not also acceptable for the difference between the rising edges? If so, using ordinary digitalWtite() is all you need. Making all 3 outputs high should be <10us with digitalWrite(), so direct port manipulation should not be needed, I think.

I would start by just writing some basic code with digitalWrite() and micros() functions. Don’t worry about hardware timers until you are certain you need them.

I appreciate all of the feedback. The software solution was my next option. I just wanted to make sure I understood correctly the hardware timers and functionality.

If you really do need to use Hardware Timers then get an Arduino Mega which has more of them so you don't need to use the one that is dedicated to millis()

On both the Mega and the Leonardo, some of the timers have three output pins so there is no synchronization across timers required. Your common start and sequential turn off would be easier with one of those Arduinos than with a Uno if you really need to use a hardware timer for your application.

If it is just for proof of concept with the Arduino doing nothing else, go for software PWM. Easy and flexible to implement.

If the Arduino has to do many other things, and timing is important, use hardware timers. The 3-output timers from the Mega sound very good for this purpose; otherwise the Uno can do a lot with the help of timer interrupts (each timer has two compare and one overflow interrupt - some smart programming and that can give you the three you need, with all starting within the same clock cycle using a single PORT write).

otherwise the Uno can do a lot with the help of timer interrupts (each timer has two compare and one overflow interrupt - some smart programming and that can give you the three you need, with all starting within the same clock cycle using a single PORT write).

I'm not so certain about this, because he wants a dead band with no pins active. Before I recommended the software solution I tried to come up with timer compare match and overflow interrupt solution, but couldn't get the three pins and the complete cycle frequency longer than the longest output.

Write your own PWM... (softwarePWM)
Luckily ~58Hz is pretty slow...
Turn all outs on with one PINx write, then using separate millis/micros timers, turn off the individual pins as needed on the timeline.
This approach should be largely independent of other tasks on the core, but if precision becomes an issue, you may shift to a timer interrupt to derive your pulse width events.

You'd have to reset the overflow timer for the remainder of the time, something like that. Or use a compare match in one of the other timers, that gets reset at the same time.
Not straightforward for sure, but should be doable.

Use the right PWM mode (Fast PWM) for synchronized pulse starts. A Mega can generate 3 PWM signals from a single timer, a Uno can generate only 2 signals so that two timers have to be used and synchronized.

I've been pondering this and arrived at - a lookup table. May be a bit offbeat but give it a look.

1ms  0b0111
2ms  0b0111
3ms  0b0110
4ms  0b0110
5ms  0b0110
6ms  0b0110
7ms  0b0100
8ms  0b0100
9ms  0x0000
10ms 0x0000
and so on

Put the values in an unsigned array and at one millisecond intervals iterate through the array and put the low three bits of the indexed value out to the port. Two-second signal is in bit zero. A port write will get all three signals to the port at the same instant.

.02