I'm working on a combined motor/CVT controller and datalogger. The unit works very well but with one exception, the PWM is unintentionally turned off at regular intervals which seem to coincide with part of the program that manipulates data then sends it to an LCD and datalogger. I realise some commands do interfere with PWM but as far as I can tell I'm not using any of those. I'd be grateful for any suggestions as to what could be causing it.
Code:
'THSYE Picaxe based speed controller, G C-S 13/02/10
'40x2 processor, current limit set by pot, button to initiate.
'Serial output to LCD, serial output to Openlog datalogger
setfreq em16 'processor speed
settimer t1s_16 'sets increment of timestamp recorded to datalogger
low c.2
serout B.7,N2400_16,(254,1) 'clear LCD display
pause 2000
w9=0 'variable for pwm duty set to zero at startup
w27=0 'logging loop counter set to zero
input d.0 'pin for "go" button set as input
input d.1 'pin for pit button
do
high b.3 'loop to ensure lowest gear
pause 5000
low b.3
pause 500
if pind.1=1 then exit 'switching pit button to "off" will exit loop
loop
goto startup
startup:
w27=w27+1 'periodical logging loop
if w27=500 then
goto serial1
else endif
if pind.1=0 then
goto pit
else endif
if b30>60 then 'check motor temp is OK
goto limphome 'if motor hot goes to low power setting
else endif
if pind.0=1 then 'check if "go" button is pressed
goto minpow 'if not pressed go to power off routine
else
goto currcontrol 'if pressed will go to control loop
endif
limphome: 'allows car to return to pits at low power setting
if pind.0=1 then 'check if "go" button is pressed
goto minpow
else
goto limpcontrol
endif
limpcontrol:
readadc10 0,w0 'toroidal current sensor
readadc10 1,w1 'current limiting rotary pot
w4=w1/18+520 'scale pot reading to match current sensor range
if w0>w4 then powdown 'decide which way to adjust motor power to reach target current
if w0<w4 then powup
pit:
readadc 6,b6 'this subroutine will force the CVT to its lowest
if b6>140 then 'setting and limit pwm to 25%
high b3
pause 400
low b3
pause 400
else endif
w9=250
pwmout c.2 , 249 , w9
goto startup
currcontrol:
readadc10 0,w0 'toroidal current sensor
readadc10 1,w1 'current limiting rotary pot
w4=w1/13+580 'scale pot reading to match current sensor range
if w0>w4 then powdown 'decide which way to adjust motor power to reach target current
if w0<w4 then powup
if w0=w4 then startup
powdown:
readadc 6, b6
if b6>140 then geardown
if w9<25 then minpow 'prevents w9 overflowing back
w9=w9-5 'increments w9 downwards to match target current
pwmout C.2 , 249, w9 'sets pwm duty
goto startup
powup:
if w9>975 then maxpow 'prevents w9 overflowing above 1000
w9=w9+5 'increments w9 upwards to match target current
pwmout C.2 , 249, w9 'sets pwm duty
goto startup
cvtcont:
readadc10 0,w0 'toroidal current sensor
readadc10 1,w1 'current limiting rotary pot
w4=w1/13+580 'scale pot reading to match current sensor range
if w0>w4 then geardown 'decide which way to adjust motor power to reach target current
if w0<w4 then gearup
if w0=w4 then startup
geardown:
high b.3 'blip CVT actuator to give a small change of ratio
pause 400
low b.3
pause 400
goto startup
gearup:
high b.4
pause 400 'blip CVT actuator to give a small change of ratio
low b.4
pause 400
goto startup
maxpow:
if w9=1000 then 'If PWM is at 100% the current will be below the target
goto gearup 'setting so gear ratio will be increased to put more
else endif 'load on the motor
w9=1000 'puts pwm to maximum setting
pwmout C.2 , 249, w9
goto startup
minpow:
w9=0 'puts pwm to minimum setting
pwmout C.2 , 249, w9
goto startup
serial1:
readadc10 0,w0 'toroidal current sensor, re-reads this sensor otherwise will display last reading when "go" button released
readadc10 2,w2 'Battery A potential divider
readadc10 5,w5 'Motor temperature thermistor
readadc 6,b6 'CVT slider pot
if w0<512 then 'Small fudge to prevent current reading overflowing
w0=507 else 'downwards at very low values
w0=w0
endif
b20=w0-507*10/51 'calc current digits
b21=w0-507*10//51*10/51 'calc current decimal
b22=w2*2/69 'calc Battery voltage digits
b23=w2*2//69*10/69 'calc Battery voltage decimal
b30=w5-280/8 'calc motor temp
b28=w9/10 'calc % pwm setting
' the following block of code converts byte variables to ascii characters, these
' are then sent by serial output to the lcd. This process overcomes the garbled
' character problem that arises if the lcd receives characters too quickly from
' the picaxe. By converting to ascii the characters are sent individually and
' slight gap between them gives the lcd firmware chip time to process.
' Note that each byte variable must be split into three ascii variables each
' of a single character, where only one or two of these are required for the
' display the remainder may be reused in a later conversion.
bintoascii b20,b42,b41,b40 'current digits to b40 & 41
bintoascii b21,b44,b43,b42 'current decimals to b42
bintoascii b22,b45,b44,b43 'battery volt digits to b43 & 44
bintoascii b23,b47,b46,b45 'battery volt decimal to b45
bintoascii b30,b51,b50,b49 'motor temp to b49 & 50
bintoascii b28,b53,b52,b51 'pwm % to b51, b52 & b53
'battery voltages and current for top line of lcd
pause 10
serout B.7,N2400_16,(254,128,b44,b43,".",b45,"V ")
pause 10
serout B.7,N2400_16,(254,134,b41,b40,".",b42,"A ")
'temp and power settings for bottom line of lcd
pause 10
Serout B.7,N2400_16,(254,192,b53,b52,b51,"%")
pause 10
serout B.7,N2400_16,(254,198,b50,b49,"C ")
pause 10
high d.4 'set pin high prior to sending raw data to openlog
pause 10
serout d.4,t9600_16,(b41,b40,".",b42,",",b44,b43,".",b45,",",b53,b52,b51,",",b50,b49,",",#w1,",",#b6,",",#timer,cr)
'serout d.4,t9600_16,(#w0,",",#w1,",",#w2,",",#w3,",",#w4,",",#w5,",",#w6,",",#w9,",",#timer,cr)
w27=0
goto startup