Converting PWM duty cycle to variable frequency

Thread Starter

spale

Joined Apr 8, 2017
10
Dear AAC fellows,

I am designing a circuit where my input is PWM and the output is a rotation of 8 outputs (on/off). So far I have a 3 bits DEMUX for the outputs (74xx138), a 4 bits counter (74xx193) and a LM555 astable oscillator (typical configuration see http://www.ti.com/lit/ds/symlink/lm555.pdf page 10, figure 14).

But now I'm stuck and can't figure out how to "link" my PWM with the changing the value of RL. I thought about adding a PNP transistor in series with RL to vary the frequency, but for that I would still need a variable voltage.

PWM: This is a 3V3 output of a CPU Atmel AT91SAM9G25 SoC, I can change the frequency, but not during operations. Only the duty cycle can be changed "on-the-fly".

Let's not focus on the LM555, what I need is to convert my 3V3 fixed frequency (but settable) PWM to a specific frequency by varying the duty cycle. The expect output frequency (from duty cycle 1% to 99%) should be in the range of 1Hz to 300Hz.

I don't need full schematics of the solution, but some help / guidance in which direction to go / what to look for.

PS: I could use a GPIO but I would need to generate the frequency in software. This solution would however not be accurate enough for my needs. (CPU load might alter the frequency, etc..)

Thank you
 

Dodgydave

Joined Jun 22, 2012
11,395
You can use a "Ladder Resistor Network" from your counter output and feed this into pin 5 of the 555 to alter the sweep frequency.
I'm not familiar with Atmel microcontrollers, only pic.

Ideally we would like to see your circuit diagram..
 

Thread Starter

spale

Joined Apr 8, 2017
10
Sorry, I think my explanation was not clear. Probably because I started to describe it from the output to the input.

1) My input is PWM (3V3) fixed frequency (but settable), variable duty cycle.
2) black magic happens here, converting the PWM duty cycle to a variable frequency (1 to 300Hz).
3) The square signal frequency then goes into a counter that outputs 4 bits (74xx193). A GPIO is used here to modify the behaviour of the counter so I can count up or down.
4) The three LSB bits go then to a DEMUX (74xx138) with 8 outputs, thus creating a rotational output.

The step 2 is where I need the help.
 

Alec_t

Joined Sep 17, 2013
15,104
I would need to generate the frequency in software. This solution would however not be accurate enough for my needs.
I think it would be much more accurate, and faster, than any analogue approach. To do this by an analogue method you would need to convert the duty cycle to a voltage (the longer the integration time involved the greater the accuracy) then convert the voltage to a frequency.
The PWM generator must already have a stored value controlling the duty cycle, so why not just use that value to set the period of a square-wave output?
 

Thread Starter

spale

Joined Apr 8, 2017
10
@Alec_t, using the GPIO requires me to control the timing (usleep()) in software. Going above about 50-60Hz is not really possible without tweaking the kernel internal clock (defaults to 100Hz). I'd like to avoid having a custom kernel. (maybe I'm missing something here, let me know if you think I do).

Doing it with an analogue approach would be to smooth out the PWM to a voltage linearly proportional to the duty cycle using simple resistors and capacitors ? Once I have that, I could vary the top RL (http://www.ti.com/lit/ds/symlink/lm555.pdf page 10, figure 14) using a PNP transistor? Is that what you think ?
 

LesJones

Joined Jan 8, 2017
4,511
Is there no way to insert a small interrupt routine (Written in assembler.) using one of the 32 bit counters into your C program (I am assuming you are using C rather than assembler as you mention usleep) You could just load a preset value that counted down the period of half a cycle of the required frequency. The interrupt handler routine woulld just need to do an XOR of a bit with the bit of the I/O port that you used and reload the value in the counter. I do not program in in C so I don't know if this is possible.

Les.
 

Thread Starter

spale

Joined Apr 8, 2017
10
@LesJones Your problem remains the same, timing. There are ugly tricks, such as using complex math function to make the CPU busy and use this as a time interval. However, this is not a realtime OS so you would always suffer from delays introduced by other programs using CPU time. If you don't have programmable hardware to configure a frequency, you have to do the frequency yourself in software and so you're dependent on the fine grain offered by the kernel, which defaults to 100Hz (you can't sleep for shorter than 10ms). Customizing the kernel allows you to be more precise with the drawback that these will be fixed interrupts that will interrupt the kernel more often. 1kHz should be doable, above that you might slowly slide into side effects.
 
The rote approach is to low pass your PWM then uses the resulting DC to drive a voltage-to-frequency converter.
The low pass can be made by some RC stages, a voltage to frequency converter can be made using a 555. Alternatively you can use a small micro (PIC or Tiny) with a build in AD-converter to measure the DC and produce the frequency you need. Once you made that step, you can go all the way using the small micro to also measure the pulse width.
 

Alec_t

Joined Sep 17, 2013
15,104
The expected output frequency (from duty cycle 1% to 99%) should be in the range of 1Hz to 300Hz.
Those figures suggest to me you are looking for a linearity tolerance of ~1% or less in output frequency as a function of duty-cycle. If so, I think that will call for some fairly sophisticated analogue circuitry to provide the necessary stability/accuracy.
 

GopherT

Joined Nov 23, 2012
8,009

Thread Starter

spale

Joined Apr 8, 2017
10
UPDATE: Found LM331, ranges from 1Hz to 10kHz, Vcc can be 5V and is much cheaper than the VFC32. Thanks again @GopherT for pointing the voltage out. I would have ruined it ;)
 
Top