Off-Board PWM

This forum is for posts that might be considered off-topic but that may be useful or interesting to members. Examples include posts about electronics or programming in general, other microcontrollers or interesting devices, useful websites, etc.
Post Reply
Don_Kirby
Posts: 341
Joined: 15 October 2006, 3:48 AM
Location: Long Island, New York

Off-Board PWM

Post by Don_Kirby »

Has anyone seen or used a standalone PWM generator? I'm in need of more PWM channels than I have available, and was hoping to offload some of the work to another chip. Something in an I2C or 1-Wire would be nice. I've been looking at products from Toshiba, Maxxim, and others, but have no personal experience with any of them.

Alternatively, is it possible to create more than two channels of PWM on a Mega32 or Mega644 based ZX (in software)?

-Don
mwf
Posts: 27
Joined: 06 October 2006, 9:26 AM
Location: Boulder, CO

Post by mwf »

I've used Al Williams' stuff for low volume projects. A bit pricey if you need a lot and can justify developing your own program.

http://www.awce.com/pak5.htm will get you to his PWM chip. There are other IO expanders there too.
mwf
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Re: Off-Board PWM

Post by dkinzer »

Don_Kirby wrote:Alternatively, is it possible to create more than two channels of PWM on a Mega32 or Mega644 based ZX (in software)?
Each PWM channel requires a hardware timer and the PWM functions in the System Library are designed to work only with the 16-bit timers. The mega32 and mega644 both have only one 16-bit timer. The other two timers are only 8-bits wide - Timer0 is used for the RTC and Timer2 is used for the SW UART channels (Com3-Com6). If you aren't using Com3-Com6 and 8-bit resolution is sufficient, you can get one additional PWM channel on the mega32 and two additional channels on the mega644 by manipulating Timer2 directly. See Tony's PWM Application Note for details.

If you need additional 16-bit PWM channels, you might consider using the ZX-1281. It provides six 16-bit PWM channels via two different timers (Timer1 and Timer3).
- Don Kinzer
mikep
Posts: 796
Joined: 24 September 2005, 15:54 PM

Post by mikep »

If you are comfortable programming AVRs as some of the board members are then you could produce your own AVR-based multi-channel PWM generator. Here is an example http://cappels.org/dproj/8ch%20pwm/8chasm.htm that could be ported to a TinyAVR. I don't know how well it works but the source is quite well-known so it should be ok.

Don't forget the Oak Micros' socket friendly ZX-1281e and ZX-128e if you choose to go to a more powerful and capable ZX device.
Last edited by mikep on 21 May 2007, 18:12 PM, edited 1 time in total.
Mike Perks
Don_Kirby
Posts: 341
Joined: 15 October 2006, 3:48 AM
Location: Long Island, New York

Post by Don_Kirby »

I looked at the Al Williams' device, and it's perfect for my application. If I can get it in an MLF or TQFP package I'd be all set.

I had considered going with the 1281, but I'm partial to the small size of the Mega32 devices (MLF44). It would make thingsa a bit easier.

Mike, If size weren't an issue, I would be using the Oak Micros device. The extra features would be very handy.

Don, I did read Tony's appnote, but after realizing that the features had been incorporated into the VM, I didn't pursue it any further. Although 2 more would be great, I can do what I need to do with only one more channel. I'll read the appnote more thoroughly tonight.

-Don
sturgessb
Posts: 287
Joined: 25 April 2008, 6:34 AM
Location: Norwich, UK

Post by sturgessb »

Im trying to get the PAK-VII and PAK-VIII chips working with the zx-24, but having no joy, can't establish communication.

Does anyone have any sample code I can use as reference?

Cheers

Ben
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Post by dkinzer »

sturgessb wrote:Does anyone have any sample code I can use as reference?
What frequency is the resonator you're using on the PAK-VIII? According to the documentation, at 50MHz, the clock signal can be up to 100KHz. However, the default clock rate for ShiftOut() on a ZX is about 200KHz. You can specify a slower clock using ShiftOutEx(). The value 150 for the sixth parameter will yield a clock frequency of about 98KHz.

Also, the documentation for the PAK-VIII indicates that the clock should have a rising edge to clock the data in. Consequently, you should initialize the clock output pin to the low state before calling ShiftOutEx().
- Don Kinzer
sturgessb
Posts: 287
Joined: 25 April 2008, 6:34 AM
Location: Norwich, UK

Post by sturgessb »

Yeah I'm using the standard 50 mhz resonator, so maybe that could be the problem.

wiring it all up again now, and ill see if that makes any difference.

Thanks

Ben
sturgessb
Posts: 287
Joined: 25 April 2008, 6:34 AM
Location: Norwich, UK

Post by sturgessb »

Well, I've tried what I thought would be the correct code to center servo (please don't laugh)

Code: Select all

'RESET PAK
Call putPin(8,zxOutputLow)
Call putPin(7,zxOutputHigh)
Call putPin(8,zxOutputHigh)
'reset options
Call ShiftOutEx(8, 7, 8, &HFF, &H00, 150)
Call Delay(1.0)

'MOVE SERVO TO CENTER

'High time to 1.5ms
Call putPin(7,zxOutputLow)
Call ShiftOutEx(8, 7, 8, &H8, &H00, 150)
Call putPin(7,zxOutputLow)
Call ShiftOutEx(8, 7, 8, LoByte(150), &H00, 150)
Call putPin(7,zxOutputLow)
Call ShiftOutEx(8, 7, 8, HiByte(150), &H00, 150)

'Low time to 20ms
Call putPin(7,zxOutputLow)
Call ShiftOutEx(8, 7, 8, &H10, &H00, 150) 'low time 20ms
Call putPin(7,zxOutputLow)
Call ShiftOutEx(8, 7, 8, LoByte(2000), &H00, 150)
Call putPin(7,zxOutputLow)
Call ShiftOutEx(8, 7, 8, HiByte(2000), &H00, 150)
But still no sensible movement from the servo.

This is the manual for the PAK, http://www.awce.com/pak8a.pdf

Any ideas what I'm doing wrong?

Ben
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Post by dkinzer »

sturgessb wrote:Any ideas what I'm doing wrong?
Debugging remotely is inherently difficult, but I see a couple of things that probably contribute to the difficulty.

Firstly, I mentioned earlier that the PAK-VIII expects to receive a rising clock edge when the data is available and, therefore, you must set the clock pin low initially so that you'll get a positive-going pulse for each data bit. Therefore, you need the following instruction before the call to ShiftOutEx().

Code: Select all

Call putPin(7,zxOutputLow)
Secondly, the fifth parameter to ShiftOutEx() does not have the correct bits asserted to tell it to use the (sixth) timing parameter. Try this, for example:

Code: Select all

Call ShiftOutEx(8, 7, 8, &HFF, &H04, 150) 
As an aside, it is highly recommended to use defined constants for the I/O pins instead of using numeric constants. Doing so makes the code less prone to error and also makes it easier to modify and maintain.

Code: Select all

Const clkPin as Byte = 7
Const dataPin as Byte = 8
Const PAK8_SHIFT_FLAGS as Byte = &H04
Const PAK8_SHIFT_PERIOD as UnsignedInteger = 150
...
Call ShiftOutEx(dataPin, clkPin, 8, &HFF, PAK8_SHIFT_FLAGS, PAK8_SHIFT_PERIOD) 
- Don Kinzer
spamiam
Posts: 739
Joined: 13 November 2005, 6:39 AM

Re: Off-Board PWM

Post by spamiam »

Don_Kirby wrote:Alternatively, is it possible to create more than two channels of PWM on a Mega32 or Mega644 based ZX (in software)?

-Don
Well, yes it is possible. It jut depends on how "soft" you mean. You could do it purely in software especially if the time base of the PWM in all the channels is the same.

You had mentioned servo control in one of the messages in this thread, so I am assuming that you have this application in mind.

The solution that comes to me off the top of my head applies mostly to a native mode device.

Assuming that you need a 50Hz servo signal with a 1 to 2mS pulse width and 256 different widths available, then you would need a timer set to give a 256000 Hz interrupt (1ms/256 I think, correct me if I am wrong).

The interrupt goes like this:

At time 0, load all the PWM counters with their respective pulse width (1-255), and turn on all the non-zero counter's pins. Set another interrupt counter to 1.

At each subsequent interrupt decrement all the counters. When a counter reaches zero turn off its respective pin. Increment the interrupt counter. When the interrupt counter reaches 5120, start it all over again.

I am not aware of a methd to get such a high frequency interrupt from within a non-native mode device, but if Don said there was, I would not be surprised considering how good the VM software is.

To get the 256000Hz interrupt, you could run an 8-bit timer at a prescaler of 1 and count to 57 or 58 (ideally 57.6) to trigger the timer interrupt. Hmmm, this is not a lot of clock cycles to service the interrupt and still do anything useful otherwise. This is probably not a reasonable solution. I wonder if there are any other good ideas out there on how to do this on the Zbasic platform? I hope I am wrong about the interrupt frequency required to do the job?

-Tony
Post Reply