PWM on Arbitrary Ports?

I noticed that orangutan-lib’s pwm code only supports pwm on the motor ports. How hard would it be to get arbitrary pwm on portb/portc of an orangutan? I tried rewriting counter.c to flip the LED in relation to a duty cycle. The hope was to make the LED dim, but instead it just flashes wildly.

Actually, it’ll use any ports. They’re defined in device.h but it’s a software PWM so you can make the outputs happen on any ports.

Lemme ask you a related question: Right now the PWM software ties up one of the 8-bit timers (TIMER0 or TIMER2, your choice, also defined in device.h) and can only drive two motors. It was meant to be used with the on-board H-bridge, but it doesn’t have to be used that way. In fact, the ports/pins used for the onboard H-bridge means you can drive them very effectively using the AVR TIMER’s PWM mode. There’s just this asymmetry problem when driving them forward and reverse using that scheme, which is why the software PWM routines wound up being written.

But it’d also be possible to use hardware PWM to drive the onboard H-bridge, and use software PWM to drive off-board H-bridges.

So if things were re-done this way… Would it be useful to be able to drive multiple off-board H-bridges? A similar trick to the one used for the servo code could be used to drive multiple motors off a single timer. It would generate more interrupts, of course, and eat up more system resources, but there’s nothing saying it can’t be done.


I knew the pins for motor PWMs could be changed, but unfortunately they’re still designed around motor “channels” composed using two pins each. What I meant was it would be useful to have something like pwm(pin, duty_cycle).

As for the timer question, I haven’t studied the problem very closely, so I’m not sure what you mean by hardware vs. software PWM. I thought all of the Orangutan’s PWM was software/interrupt driven. However, if some of that responsibility could be given to hardware, allowing a more flexible software solution, I think that would be immensely useful.

Aha! Okey doke, now I get you. Yeah, that’s entirely doable. I’d want to do some name shuffling, though.

The AVR timers have a whole slew of modes they can be run in. One generates interrupts on timer compares and overflows (which is how the motor PWM code is done right now), but in other modes it’ll do all the PWM waveform generation in hardware. Jim Remington has a good comparison of some of the various PWM modes on his web site:

The catch with the hardware PWMs is that each timer is tied to particular I/O pins. So it’s not a completely flexible approach. But it sure takes a load off the CPU to use one of the hardware modes because no interrupts are generated. It just spits out the waveform.

For what it’s worth the same is true for inputs. Some of the AVRs timers can be clocked from an external source. This is great for stuff like tachometers, encoders, etc. The pin change interrupt code in the library is more generic, and isn’t tied to any timer, but it’s also slower.

So a related question: How many PWM outputs would you want to be able to generate? Depending on the answer I can think of a couple of ways to do it. For a lot of them, it winds up being a little expensive in terms of resources, not just the I/O pins it’d tie up.


Currently, I’m just using 3 or 4 at most, but don’t let that stop you :wink:

Heh! Fair 'nuff. I’ll poke around at it and see what I come up with.