I'm trying to make an oscillator where I can adjust the frequency and the duty cycle independently, but I'm not having much luck. What I want is a frequency range from 1Hz to 1MHz; and the ability to adjust the duty cycle in 10% increments from 0% to 100%, give or take. Ideally, I'd also like to be able to specify a 25% or 75% duty cycle.

My question basically boils down to: What is the simplest (i.e cheapest and smallest) way to achieve an adjustable square wave oscillator with adjustable duty cycle, with the specifications above, and where adjusting either the frequency or the duty cycle does not cause the other to change?

Here follows a detailed explanation of how I got here:

My first thought was a 555 timer, but that was very problematic. Adjusting the duty cycle also had an impact on the frequency, and achieving a duty cycle of less than 50% was pretty much impossible.

555 timer PWM

My second attempt involved a schmitt inverter. Sadly, the schmitt zone wasn't centred evenly between VCC and GND, so I had to offset the input voltage using a voltage divider. This then limited the current to the point that the (TTL) schmitt did not function. I later swapped it out for a CMOS variant and removed the resistors, but still couldn't get anywhere near reliable operation.

schmitt inverter PWM

My third idea was to get a microcontroller - specifically, a PIC12F675 - to use its ADC to read two potentiometers, and from these values generate a square wave programmatically. However, when I crunched the numbers, it turned out to be impractical.

A PIC12F675 has a maximum clock speed of 4MHz. If we assume that it will occasionally have to perform up to 10 instructions between changing output states, and bearing in mind that a full wave requires 2 state changes, we end up with a maximum output frequency of 200KHz. This is somewhat lower than I was looking for.

In addition, at this maximum frequency of 200KHz, the MCU will (by definition) be unable to change state any more quickly; and therefore the duty cycle will be fixed at 50%, defeating the purpose. We we assume that we require at least an adjustable range of 10% - 90%, we will be unable to generate an output frequency of more than approximately 20KHz. Or maybe 10KHz.

Using a faster MCU wouldn't help much. The ATmega328 has a maximum clock frequency of 16MHz, which would give us up to 80KHz output. Still not very useful.

My fourth idea involved two 555 timers - one generating an adjustable square wave with a fixed duty cycle, the other acting as a one-shot to generate the duty cycle. Unfortunately, the duty cycle would be measured in time, rather than percentage, and therefore adjusting the frequency would affect the duty cycle. In addition, at the extreme low or high end of the frequency range, the duty cycle adjustment knob would be totally ineffectual for the majority of its travel.

My fifth idea involved a 555 timer for generating the square wave (as above), with a 4017 decade counter to split the output into chunks. Connecting the first output, for example, would give me a 10% duty cycle. I could change the frequency without affecting the duty cycle. There are some problems with this approach, though.

Firstly, unless I wanted to be flipping jumpers by hand, I would need some way to control the output with a knob. So a microcontroller, then. The microcontroller would need some sort of programmable multi-channel switch, such as the PCA9548A. Unfortunately this is an 8-channel switch, and I'm using a decade counter. I could connect the 4017 reset to the 8th position, and make it an 8-way counter, but then I wouldn't be able to get 10% or 90% duty cycle. So I'd need quite a lot of parts: 1 capacitor, 1 pot, 1 555 timer, 1 MCU, 1 4017 and 2 8-channel switches.

If I wanted a 25% or 75% duty cycle, I would need to add to this list another 4017, another switch IC, another capacitor and some way to switch the capacitors programmatically.


closed as unclear what you're asking by Dave Tweed Aug 13 '17 at 21:22

Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • \$\begingroup\$ Since you're already down the learning curve with PIC12F675, consider using Microchip's Numerically-controlled-oscillator (NCO) versions (example: 16F1507). These are fairly versatile. \$\endgroup\$ – glen_geek Aug 13 '17 at 16:27
  • \$\begingroup\$ @glen_geek Thank you, I will look into that chip. I notice, however, that it comes in a 20-pin DIP. Do you know of anything similar in a DIP8 form factor? Size is an issue, here. And sadly, SMD is difficult for me at present. \$\endgroup\$ – Sod Almighty Aug 13 '17 at 16:34
  • \$\begingroup\$ So, that's a really bad situation. If size matters, don't use DIP. SOIC and the like really aren't hard to solder at all. \$\endgroup\$ – Marcus Müller Aug 13 '17 at 16:50
  • \$\begingroup\$ @MarcusMüller They are when you're using matrix board. I'm not convinced I'd have much luck etching my own PCBs precisely enough to mount SMD chips. \$\endgroup\$ – Sod Almighty Aug 13 '17 at 16:54
  • \$\begingroup\$ @SodAlmighty I used to do that, it's not that hard, but I've stopped, since making my own boards was harder, less exact and also more expensive in tools and waste then just ordering very small boards from oshpark.com or medium-sized boards from elecrow.com. It really is a time-saver, compared to designing circuits for matrix board, cutting unwanted traces, soldering things in place. \$\endgroup\$ – Marcus Müller Aug 13 '17 at 16:58

Very clearly, this is a case for the PWM unit of a sufficiently fast MCU, as you noted.

Now, your whole counting of instructions is superfluous – MCUs come with PWM timers that do that job for you, and the CPU core is not involved in that. Thus, in some CPUs, PWMs can run at a much higher rate than the CPU core without problem.

So, yes, this is absolutely doable with the MCUs you mention. And also with MCUs that are a lot cheaper.

Personally, I like the PWM units on ST Micro STM32 arms. But that's really just because they're so easy to use; not because they are cheap. At the time of writing this, Silabs ARMs are cheap, so if you've got 75ct per piece to spare and would like to write C for a 24 MHz 32 bit platform, why not?

If you need to go cheaper, really simply look into the cheapest microcontrollers that you can buy that come with a sufficiently flexible PWM unit. Really, PWM is such a common requirement that most microcontrollers have hardware for that, and you really don't need to have the CPU execute code to toggle an output with the right duty cycle and frequency.

  • \$\begingroup\$ It's a while since I've looked into this. How low can you adjust the PWM cycle time on one of those? 1 Hz? \$\endgroup\$ – Transistor Aug 13 '17 at 16:24
  • 1
    \$\begingroup\$ @Transistor that really depends. Now, the MCU I linked to has a 16 bit PWM unit, so sysclk*2^-16, I guess? Others come with 32 bit counters. Now, you can often adjust sysclk in wide ranges, but I think the minimum for the linked IC generated from an internal clock generator (you can of course use a 555 to drive the MCU with a 42 Hz clock, if you really desire) is 1.2 MHz. Now, 1.2e6 / 2**16 would be something like 18 Hz? But really, if you need the lowest PWM frequencies, having 32 bit PWMs would sound wiser. \$\endgroup\$ – Marcus Müller Aug 13 '17 at 16:28
  • \$\begingroup\$ @MarcusMüller Thank you. That kind of price would be quite acceptable. However, I notice this is an SMD chip. At present, I would prefer to stick to DIP, ideally DIP8. Can you suggest any DIP8 chip with a sufficiently configurable PWM capability? \$\endgroup\$ – Sod Almighty Aug 13 '17 at 16:37
  • 1
    \$\begingroup\$ @SodAlmighty If you want to stay ARM: DIP is always pretty expensive. If you don't care: Maybe a MSP430? Or, really: just go ahead and buy an ARM dev board for <10€ for prototyping, and use SMD as soon as you go into series. Assembly cost of Through Hole is much higher than that of SMD, so if cost of your system is a relevant factor, DIP is usually out of question. \$\endgroup\$ – Marcus Müller Aug 13 '17 at 16:46
  • 2
    \$\begingroup\$ @SodAlmighty You wrote, "I'm still no closer to solving the problem than I was to begin with." You would be, if you were willing to work for your own solutions, rather than expect others to do so. You wrote, "That all sounds WAY too complicated. I barely understand the concept of PWM.." As Marcus said, you know the details of your problems better than anyone else. If you are too ignorant to be able to bridge the gap between where you are and where you need to be, that is no one else's fault but your own. And no one else but you has any responsibility to fix your ignorance problems. \$\endgroup\$ – jonk Aug 13 '17 at 18:44

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