Take the 2-minute tour ×
Electrical Engineering Stack Exchange is a question and answer site for electronics and electrical engineering professionals, students, and enthusiasts. It's 100% free, no registration required.

So I've been playing with an ATtiny45, and it occurs to me that I could probably brute force PWM by prescaling a timer to sysclock/64, then running ISR code that manually switches the outputs on or off depending on global variables set elsewhere in code or via IO. At max sysclock speed of 20MHz I oughta get decent resolution, and I'll get to use all my IO pins as PWMs instead of the two the chip provides, so the big question is...why not? Other than using up a lot of sysclock cycles, I don't really see disadvantages...could someone give me some?

share|improve this question
I tried doing this once (but with a different controller). In practice you dont get a clean pulse. Instead it varies depending on your clock cycle time, and slows down if your controller is busy with something else. –  scordova88 Apr 28 at 4:22
it also feels ugly - it takes very little hardware for a single pwm channel - it can literally be a resettable binary counter xored and nored to a register, plus some clock dividing logic and possibly a similar setup for the off pulse too. bit banging suffers from inconsistent and difficult to precisely predict timing, as well as (relatively) intense resource use - code execution, interrupt channels, system clocks (which may have more features than PWM clocks) - all for such a simple feature. why do you need more channels? there may be a cheaper way. –  user3125280 Apr 28 at 7:50
Doesn't the ATtinyX5 provide 3 output comparitors, OC0A, OC0B/OC1A (shared on PB1), OC1B? –  Nick T Apr 28 at 19:06

6 Answers 6

up vote 6 down vote accepted

The three disadvantages are Power Consumption, tying up a Timer, and interrupting other code. If you don't care about low power modes, and have no need for the timer, and have no critical code that can't withstand a few clock cycles to service the interrupt, there is no disadvantage. Some projects are fairly simple, and don't take up a tenth of the power of the microcontroller, so don't let anyone tell you you are doing it wrong by taking advantage of the timers like that. Software PWM is fine if it fits your needs.

share|improve this answer
By power consumption you mean a timer with ISR uses more energy than a purely software solution, right? A timer with ISR should have about the same power consumption as using the dedicated PWM hardware. –  SomeEE Apr 28 at 4:34
@MathEE When the CPU is not executing instructions, you can instruct it to enter a low power sleep mode. This means that the device will consume much less power for a given time. For some sleep modes timer controlled PWM will keep running, but of course bit banged PWM won't. Interrupts are a common method to exit sleep mode. –  jippie Apr 28 at 5:06
@jippie Yes, I understand that one can use interrupts to pop out of sleep mode to save power - an advantage. I was trying to understand Passerby's comment that power consumption is a disadvantage. I'm sure Passerby had something in mind but it is not clear to me that PWM hardware would consume less power than a counter combined with ISR. After all, the PWM module is just a counter with extra hardware. –  SomeEE Apr 28 at 5:16
@MathEE When using hardware/timer PWM, you don't need the CPU and you can turn it into sleep. That would save a fair amount of power. He assumes that the CPU is idling when using timer controlled PWM (and thus can be put to sleep), rather than counting instruction cycles when doing bit banged PWM. –  jippie Apr 28 at 5:23
Bear in mind that all this talk about "saving power" is irrelevant if you are so much as dimly lighting a single LED. –  Nick T Apr 28 at 19:07

I've just recently been playing with a lot of PWM switching power supply stuff, and you're right, there are perfectly valid reasons to "bit bang" pulse width modulated signals. But one of the chief failings of this method is when you need immediate feedback control of the generated duty cycle.

Even with a 20 MHz onboard clock, the cycle time is 50 nanoseconds. Computationally, you would have to acquire the signal being monitored, subtract it from the reference level, and then resume generation of the duty cycle. This will create "jitter" where the duty cycle is inconsistent. Using an onboard DAC isn't out of the question, but it eats up cycles. To trim down on this, you could add an external DAC, but then you have committed maybe 8 or 12 pins from the microcontroller to the external DAC for a quick reading (depending on how much resolution you want). Then you have to worry about additional signal propagation delay through switching components.

If what you want is rapid feedback control, it's hard to beat an independent duty cycle IC. The delay of the on board error amplifier is so small that you're more worried about the gain changing at high frequencies. Signal propagation through switching is still the same risk, of course, and has to be designed around.

It is also worth pointing out that a lot of PWM IC packages have shutdown features and dead time control inputs that can do really nifty things when coupled with a microcontroller, all on an 8 or 16 pin package.

It's pretty much up to you to decide if the bit bang method can support your needs. You can actually get the frequency up pretty high if you use a lower prescaler. The duty cycle you get will show quantization error, but that may not even be a big deal depending on what you're doing and how high you take the resolution; but then again, higher resolution comes at the cost of lower frequency. If you don't require instant feedback control, and your application can handle some jitter, then bit-banging may be the way to go.

share|improve this answer

The point of having hardware devices on the chip is to free up the processor for other tasks. If you use PWM hardware then you can simultaneously do other microcontroller tasks.

Now I think you've picked up on this bit because you are asking about using an ISR instead of running a for/while loop brute force counter but again it is the same answer. If we don't change the width of the pulse why would we want to interrupt our other tasks unnecessarily?

share|improve this answer
Because we want more than 3 PWM channels without adding to the BOM. –  Ignacio Vazquez-Abrams Apr 28 at 4:05
@Ignacio Maybe I am misreading the question but I read it as the OP wanted to brute force PWM and then as a bonus gets more PWM channels. You are right if the OP wants to do it because they need more channels. –  SomeEE Apr 28 at 4:08

You can easily do what you say - I've done it a few times. It's more useful if you want to change your PWM at predictable times; you can do this by counting the number of PWM cycles, and you'd need a timer to do that anyway.

However, there is a tradeoff between the resolution of the PWM / # of outputs vs the amount of free processor time. You will reach a point where you don't have enough free CPU to make it work.

I recommend hooking a scope up to a free pin, and then setting that pin high at the beginning of the ISR and low at the end. This will let you see the proportion of the time your routine is using.

share|improve this answer

Software PWM does not have to very CPU intensive if done in a right way, like using Binary Code Modulation. With this nice and simple technique you can have a lot of SoftPWM channels without a big CPU overhead.

share|improve this answer
Minor nit: PWM refers to a few particular modulation schemes in which a constant output level will be represented by a pulse wave with a certain duty cycle, and the frequency of the wave is independent of the level represented; the schemes vary only in how changes in the output level will be represented. Binary Code Modulation is a member of a more general class of duty cycle modulation schemes. –  supercat Apr 28 at 16:46
The linked implementation of binary code modulation has the disadvantage that an output whose value changes from 127 to 128 will be low for 255 consecutive pulses, and one whose value changes from 128 to 127 will be high for 255 consecutive cycles. Further, if the device being controlled has non-uniform turn-on/turn-off behavior, PWM will behave linearly for most of its range, while BCM will not. Some variations on BCM can be useful, but its limitations will often need to be recognized and dealt with. –  supercat Apr 28 at 17:03
Although you noticed well that BCM is not a solution for everything, it will deal with most appliances quite well and with very low CPU usage. Most common will probably be dimming LEDs. If brightness linearity is needed in this case, then both PWM and BCM would need a correction table. –  avra Apr 29 at 11:33
I've used variations of BCM for LEDs, and they're okay for solid levels, but the approach given will flicker badly if the brightness level alternates between 127 and 128. An alternative approach for 256-level PWM is to have an interrupt run e.g. once every 256 cycles, and have each interrupt write the LEDs twice, 16 cycles apart. On half the cycles (alternating), write bit 3 and then bit 7. On half of the remainder, write bit 2 and then 6, etc. On 1/16, just write zero and do other processing. –  supercat Apr 29 at 13:33

Personally I've found the timer PWMs are faster and consistent (in full 256 range, if you don't need such resolution, software["brute-force"] can be faster) , and when I've needed more than 2 I tried soft PWMing alongside the hard PWMs and it wan't very smooth so I opted to do all PWM in software and it turned out great.
The only thing is when doing and intermediary calculations/processing/interrupts that take a bit of time, the soft PWM stalls and can be very noticeable.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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