Duplicate External PWM Signal's Frequency, Phase, but not Duty Cycle

Hi everyone, I am working on a project with a 5V Arduino Pro Mini.

There is an external 12V PWM signal, whose frequency and duty cycle are unknown, although the frequency will certainly be <1kHz. Let’s say the signal is 100 Hz and 60% duty cycle. I am trying to find a way to create a 5V PWM signal that is also 100 Hz, in-phase with the external signal, and whose duty cycle is <= 60% (will be adjusted based on other signals/calculations from Arduino).

If an application will help you help me, think of LED’s being driven by a PWM signal from an external source, and I want to reduce their brightness (duty cycle) to my preference. I cannot alter the LED’s original power signal, but I can put a switch between the signal and LED’s. I want to create a 5V PWM signal to turn off and on the switch to either allow the power signal to pass through, or reduce the duty cycle without causing the lights to flicker.

My plan so far was to use a voltage divider to bring the external PWM down to a level that the Arduino can work with and potentially measure. I know I’ll need to brush up on how I can use registers to create variable PWM signals, but I wanted to make sure I was on a good/clear path first.

Thank you!

Look for the rising edge of the input signal and switch the chosen output pin high and start a timer. After a preset period, and before the start of the next rising edge of the input signal, switch the output pin low.

In doing this, you will have duplicated the frequency and phase of the input signal. You adjust the duty cycle by changing the period for which the output pin is high.

For low frequencies (e.g. your 100 Hz) you can simple poll the input pin in the loop to find the low to high transition.

For sure this screams for using interrupts, especially for measuring the input signal. How fast does the input signal change? Is it enough to determine the frequency and send out a PWM signal at that freq, or do you really need to match every transition? In the second case, I would do the following:

  • use an interrupt to start your cycle. Push your pin HIGH, and start a timer based on your set duty cycle.
  • at the end of the timer, set the pin LOW again.
  • wait for the next transition in the input signal to start again.

I don't understand why you can't simply create another PWM signal and switch between both. Or fix the switch to Arduino only and vary the duty cycle as you like. Or use the external PWM signal to reset the PWM timer...

Also explain what means "in phase" - starting at the same time?

Thank you for the ideas; this gives me plenty to get started with.

6v6gt, wouldn't I need to know/measure the frequency of the external signal in order to set an appropriate duty cycle/period? Would you just suggest using interrupts to do that?

TimMJN, the input signal's frequency should not be changing, although its duty cycle might based on an external bright/dim switch. And similar to above, how would I know the max timer length? I may have been misleading in my question; I was using 100 Hz as an example but I do not exactly know that beforehand and would like the capability of determining the frequency.

DrDiettrich, I didn't provide that reasoning in my original question, but there are current monitors on the external signal, and a fault/error would occur if that PWM was on but no current was flowing. You have me now rethinking whether it will work to just burn the external PWM through an appropriate resistor and create a separate PWM... I have some testing to do.

. . .
6v6gt, wouldn't I need to know/measure the frequency of the external signal in order to set an appropriate duty cycle/period? Would you just suggest using interrupts to do that?
. . .

  1. If you want a specific duty cycle, the mark part of the wave form (the ON period) has to a function of the full period of the input waveform. You gave an example of 100Hz. The period period is 10mS. Therefore, if you require a 40% duty cycle at the output, the ON period has to be 4mS.
    You measure the full period of the input waveform by determining the interval between two adjacent rising edges (or transitions from LOW to HIGH). Frequency is a function of the period of a wave form so the short answer to that part of your question is yes.
  2. For 100Hz, which is very slow compared with the clock cycle of the Arduino's microcontroller, it is not necessary to use interrupts. But the decision also depends on what else you are doing in the loop() and how much jitter you can tolerate.

Also think about a monoflop emulation. At each rising edge of the external signal create a pulse of the new duty cycle length.