Hi all,
My latest picaxe challenge below .
I'm working on a class project we built with kids this year, where the outcome is a little radio controlled fishing boat. We built a number of boats and even had a competition for the school year-end in the local pond. Now, I want to sort out known problems and improve some things for the next year.
One such improvement is adding backwards 'gears' for the ship. The code below works as expected in forward 'gears' - you can select a speed and steer left and right. However, if you select backwards 'gear', as soon as you move the rudder (inputs C.3;C.4) the pwm is thrown over to forward motor output, while keeping the duty cycle.
I was suspecting some timer incompatibility, so I looked at SFRs of 14M2, but after trying them out (see the code) I can see nothing wrong. Any ideas?
Thank you for your time,
Edmunds
My latest picaxe challenge below .
I'm working on a class project we built with kids this year, where the outcome is a little radio controlled fishing boat. We built a number of boats and even had a competition for the school year-end in the local pond. Now, I want to sort out known problems and improve some things for the next year.
One such improvement is adding backwards 'gears' for the ship. The code below works as expected in forward 'gears' - you can select a speed and steer left and right. However, if you select backwards 'gear', as soon as you move the rudder (inputs C.3;C.4) the pwm is thrown over to forward motor output, while keeping the duty cycle.
I was suspecting some timer incompatibility, so I looked at SFRs of 14M2, but after trying them out (see the code) I can see nothing wrong. Any ideas?
Code:
'Ship control
#picaxe 14m2
#no_data
'Flags
Symbol dirflag = bit0
'Byte variables
Symbol RudderPos = b4
Symbol Counter = b5
'Word variables
Symbol Speed = w13
Symbol MainMotorDuty = w12
'Constants
Symbol SingleBtnDelay = 300
Symbol DoubleBtnDelay = 500
Symbol RudderRightMaxPos = 140
Symbol RudderLeftMaxPos = 80
Symbol ServoFullMoveDelay = 300
Symbol ServoStep = 10
Symbol MainMotorPeriod = 100
Symbol MainMotorStep = 20
Symbol MaxSpeed = 9 '~3.0V motor voltage
Symbol MinSpeed = 1 '0.0V motor voltage
Symbol SpeedStep = 1
Symbol DirCtrlVal = 4
Symbol SpeedSlope = 10
init:
input B.1 'Go forward BTN
input B.2 'Go reverse BTN
input C.3 'Steer left BTN
input C.4 'Steer right BTN
output B.3 'Navigation lights, red and grn
output B.4 'Steering servo
output B.5 'Front and rear mast lights, white
output C.0 'Interior light and high beam
output C.1 'Main engine PWM signal B
output C.2 'Main engine PWM signal A
low B.5 : low B.3 : low C.0 'Initialise all lights to OFF
RudderPos = 110
peeksfr %10111110, b1
b0 = b1 | %10000000
pwmout pwmdiv64, B.4, 220, RudderPos 'Initialise servo, set rudder to centre position, trimmer pot solution required
pokesfr %10111110, b0 ;Bank 5 => 101; location 01E => 11110
speed = DirCtrlVal 'corresponds to zero
main:
peeksfr %10111110, b2
sertxd ("CCPTMRS: ",#b2,CR,LF)
sertxd ("CCPTMRS: ",#bit23,#bit22,#bit21,#bit20,#bit19,#bit18,#bit17,#bit16,CR,LF)
if pinC.4 = 0 then 'If steer right button pressed ...
pause SingleBtnDelay '... ebounce the signal ...
if pinC.3 = 0 then '... and check if this is not a two button command
pause DoubleBtnDelay 'In case it is, debounce buttons enough and ...
toggle B.5 '... toggle NAV lights ...
toggle B.3
; pause DoubleBtnDelay '... debounce some more
elseif RudderPos > RudderLeftMaxPos then '... back to single button command steer right, limit max value ...
RudderPos = RudderPos - ServoStep '... and move rudder servo a little
peeksfr %10111110, b1
b0 = b1 | %10000000
pwmout pwmdiv64, B.4, 220, RudderPos
pokesfr %10111110, b0 ;Bank 5 => 101; location 01E => 11110
endif
pause SingleBtnDelay '... ebounce the signal ...
endif
if pinC.3 = 1 then 'Same as above, but for the steer left button
pause SingleBtnDelay '... ebounce the signal ...
if pinC.4 = 1 then
pause DoubleBtnDelay
toggle B.5
toggle B.3
; pause DoubleBtnDelay
elseif RudderPos < RudderRightMaxPos then
RudderPos = RudderPos + ServoStep
peeksfr %10111110, b1
b0 = b1 | %10000000
pwmout pwmdiv64, B.4, 220, RudderPos
pokesfr %10111110, b0 ;Bank 5 => 101; location 01E => 11110
endif
pause SingleBtnDelay
endif
if pinB.1 = 1 then 'forward
pause SingleBtnDelay
pause SingleBtnDelay
if pinB.2 = 1 then
pause DoubleBtnDelay
toggle C.0
pause DoubleBtnDelay
endif
if Speed < MaxSpeed then
Speed = Speed + SpeedStep
endif
sertxd ("Speed: ",#Speed,CR,LF)
if Speed >= DirCtrlVal then
Select case Speed
case 4
sertxd ("At 1st 4!",CR,LF)
hpwm OFF
case 5
MainMotorDuty = 0
for Counter = 1 to SpeedSlope
MainMotorDuty = MainMotorDuty + 10;150
hpwm pwmdiv64, pwmsingle, pwmHHHH, %0001, MainMotorPeriod, MainMotorDuty
pause 200
next Counter
case 6
MainMotorDuty = 180;180
hpwm pwmdiv64, pwmsingle, pwmHHHH, %0001, MainMotorPeriod, MainMotorDuty
case 7
MainMotorDuty = 220;220
hpwm pwmdiv64, pwmsingle, pwmHHHH, %0001, MainMotorPeriod, MainMotorDuty
case 8
MainMotorDuty = 270;270
hpwm pwmdiv64, pwmsingle, pwmHHHH, %0001, MainMotorPeriod, MainMotorDuty
case 9
MainMotorDuty = 330;330
hpwm pwmdiv64, pwmsingle, pwmHHHH, %0001, MainMotorPeriod, MainMotorDuty
endselect
else
Select case Speed
case 1
MainMotorDuty = 220;220
hpwm pwmdiv64, pwmsingle, pwmHHHH, %0010, MainMotorPeriod, MainMotorDuty
case 2
MainMotorDuty = 180;180
hpwm pwmdiv64, pwmsingle, pwmHHHH, %0010, MainMotorPeriod, MainMotorDuty
case 3
MainMotorDuty = 150;150
hpwm pwmdiv64, pwmsingle, pwmHHHH, %0010, MainMotorPeriod, MainMotorDuty
case 4
sertxd ("At 2nd 4!",CR,LF)
hpwm OFF
endselect
endif
endif
if pinB.2 = 1 then
pause SingleBtnDelay
pause SingleBtnDelay
if pinB.1 = 1 then
pause DoubleBtnDelay
toggle C.0
pause DoubleBtnDelay
endif
if Speed > MinSpeed then
Speed = Speed - SpeedStep
endif
sertxd ("Speed: ",#Speed,CR,LF)
if Speed >= DirCtrlVal then
Select case Speed
case 4
sertxd ("At 3rd 4!",CR,LF)
hpwm OFF
case 5
MainMotorDuty = 150;150
hpwm pwmdiv64, pwmsingle, pwmHHHH, %0001, MainMotorPeriod, MainMotorDuty
case 6
MainMotorDuty = 180;180
hpwm pwmdiv64, pwmsingle, pwmHHHH, %0001, MainMotorPeriod, MainMotorDuty
case 7
MainMotorDuty = 220;220
hpwm pwmdiv64, pwmsingle, pwmHHHH, %0001, MainMotorPeriod, MainMotorDuty
case 8
MainMotorDuty = 270;270
hpwm pwmdiv64, pwmsingle, pwmHHHH, %0001, MainMotorPeriod, MainMotorDuty
case 9
MainMotorDuty = 330;330
hpwm pwmdiv64, pwmsingle, pwmHHHH, %0001, MainMotorPeriod, MainMotorDuty
endselect
else
Select case Speed
case 1
MainMotorDuty = 220;220
hpwm pwmdiv64, pwmsingle, pwmHHHH, %0010, MainMotorPeriod, MainMotorDuty
case 2
MainMotorDuty = 180;180
hpwm pwmdiv64, pwmsingle, pwmHHHH, %0010, MainMotorPeriod, MainMotorDuty
case 3
MainMotorDuty = 0
for Counter = 1 to SpeedSlope
MainMotorDuty = MainMotorDuty + 10;150
hpwm pwmdiv64, pwmsingle, pwmHHHH, %0010, MainMotorPeriod, MainMotorDuty
pause 200
next Counter
case 4
sertxd ("At 4th 4!",CR,LF)
hpwm OFF
endselect
endif
endif
goto main
Thank you for your time,
Edmunds