Asynchronous PWM for Pumps, Glow Plug
Any turbojet ECU will
require as a minimum a controllable fuel pump, and sometimes an
adjustable glow plug driver. The traditional technique for
varying a DC motor is by using PWM (Pulse Width Modulation),
whereby a pulsed signal's duty cycle is varied, causing the
device (in this case an advanced MOSFET) to switch on and off
very rapidly. This in turn effectively varies the voltage which
the target device sees. A benefit, especially for a motor, is
that torque at low speeds is improved over a resistive setup, and
the efficiency is much greater.
A microcontroller can
produce PWM in 2 ways... it can be dedicated to PWM output, which
means that it will have essentially no additional time to process
other parameters. Or, it can have contained within it a Timer
module which allows continuous PWM output while the processor
clock can effectively perform other functions without causing
gross interruptions in the PWM output.
conveniently has two PWM output modules, one of which can control
a pump, the other controlling a glow plug driver. The PWM output
is fed through a diode and resistor and delivered to the gate of
an N-MOSFET capable of "turning on" at logic voltage
levels. The MOSFET must additionally have a resistor from gate to
source (ground), or the MOSFET will latch "on" with the
first pulse from the uController.
This code, when compiled
and loaded into the PIC, generates a PWM output suitable for both
a Speed280/300 style pump or a glow plug.
'This program is designed to explore the PWM characteristics
'of the 16F876 for motor or Glow excitation. Buttons one
'and 2 are Active Low and are wired to PortB 3 and 4 using
'2 10K pullup resistors. The LCD is a Scott Adams Serial LCD
'module. Compiled with PicBasic Pro and MPASM.
'For MOSFETs, I highly recommend the compact and efficient International
'Rectifier IRLU3103. For gate drive for a Speed 300/280 type pump, use
'a 10K resistor, with a 12K resistor gate to ground. Higher gate to ground
'resistance reduces resolution of the byte Duty Cycle variable.
'Clamp the Motor with a 10 or 12V 1/2W Zener.
'Experimentation is always in order.
PumpDC var CCPR1L
PumpOut var PORTC.2
PumpOn con %1111110 '16 Pre/Post scale
PumpOff con %1111010
PumpEnable var T2CON 'Timer2 ControlRegister
'See Scott Adams Serial LCD sheets for these commands
LCDOutPin VAR PORTB.2 '23 --> LCD
LCDCmd CON 254 'LCD Command prefix
LCDHome CON 2 'Move cursor home, Pause
LCDClr CON 1 'Clear LCD screen, Pause
LCDLine1 CON 128 'First cell line 1
LCDLine2 CON 192 'First cell line 2
'Buttons, select any convenient I/O port. Buttons will change
'(and scroll) the Duty Cycle of the PWM from 0 to 255.
Btn1 var PORTB.3
Btn2 var PORTB.4
Gosub EnablePump 'Set required PWM/Timer2 registers
Gosub DisplayDC 'Initialize LCD
'Buttons, set for pull up, active low
TRISB.3 = 1: TRISB.4 = 1
'The buttons will increment or decrement the duty cycle
'by one within a range of 0 to 255.
if Btn1 = 0 then
if PumpDC < 255 then PumpDC = PumpDC + 1
Gosub DisplayDC 'Update LCD
Pause 150 'Button debounce/scroll rate
if Btn2 = 0 then
if PumpDC then PumpDC = PumpDC - 1
Goto SetDC 'Loop endlessly polling for button presses
'Pump subroutines --------------------------------------------------
PumpEmergencyOff: 'Sets throttle to zero, Kills timer2, and sets
PumpDC = 0 'Pump Drive pin to Low
PumpEnable = PumpOff
DisplayDC: 'Display the current Duty Cycle of PWM on LCD
SerOut LCDOutPin, N9600, [LCDCmd, LCDClr] 'Clear LCD
SerOut LCDOutPin, N9600, [LCDCmd, LCDLine1, "DC: ", #PumpDC]
EnablePump: 'Call once to enable PWM
PR2 = $FF 'PWM Period
PumpDC = 0 'Set DC to 0
TRISC.2 = 0 'Set pin to output
CCP1CON = %001100 'Set CCP Register for PWM
PumpEnable = PumpOn 'Turn On timer