PWMOUT OFF problem

edmunds

Senior Member
Dear all,

I'm trying to invent the wheel (I guess) by building a two-button motor controller. Press FWD button to start the motor in FWD direction slowly and 4 more times for more speed. Then press RWD button to reduce the speed down to zero and to three speeds backwards. Pressing FWD again, should allow going back to stop and speeding FWD again and so forth.

My hardware is 14M2 and the code (including a commented out servo section for incompatibility with pwmout reasons - hpwm did not work out of the box for me, so left it for later) pasted below. Apart from unscientific and maybe less than elegant code (pardon), my main challenge is why PWMOUT C.0, OFF does not switch PWM OFF. The square wave crest on the scope is not going anywhere and motor keeps humming at Speed = 4. Why?

Code:
'Ship control

#picaxe 14m2
#no_data

'Flags
Symbol dirflag = bit0

'Byte variables
Symbol RudderPos = b4
Symbol Speed = w13
Symbol MainMotorDuty = w12

'Constants
Symbol SingleBtnDelay = 150
Symbol DoubleBtnDelay = 500
Symbol RudderRightMaxPos = 220
Symbol RudderLeftMaxPos = 80
Symbol ServoFullMoveDelay = 300
Symbol ServoStep = 5
Symbol MainMotorPeriod = 150
Symbol MainMotorStep = 20
Symbol MaxSpeed = 9                          '~3.0V motor voltage
Symbol MinSpeed = 1                          '0.0V motor voltage
Symbol SpeedStep = 1
Symbol DirCtrlVal = 4

init:
  input C.3             'Go reverse BTN
  input C.4             'Go forward BTN
  input B.2             'Steer left BTN
  input B.1             'Steer right BTN

  output B.4           'Steering servo
  output C.2           'Main engine PWM signal A
  output C.1           'Main engine PWM signal B

  RudderPos = 150
;  servo B.4, RudderPos         'Initialise servo, set rudder to centre position, trimmer pot solution required
  speed = DirCtrlVal   'corresponds to zero
  
main:
  if pinB.2 = 0 then                                                'If steer right button pressed ...
  	pause SingleBtnDelay                                          '... ebounce the signal ...
  	if pinB.1 = 0 then                                               '... and check if this is not a two button command
  		pause DoubleBtnDelay                                      'In case it is, debounce buttons enough and ... 
  		toggle B.3                                                         '... toggle NAV lights ...
  		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
;  	  servopos B.4, RudderPos
  	endif
  endif
  if pinB.1 = 0 then                                                 'Same as above, but for the steer left button
  	pause SingleBtnDelay
  	if pinB.2 = 0 then
  		pause DoubleBtnDelay
  		toggle B.3
  		pause DoubleBtnDelay
  	elseif RudderPos < RudderRightMaxPos then
  		RudderPos = RudderPos + ServoStep
;  	  servopos B.4, RudderPos
  	endif
  endif

  if pinC.4 = 0 then
  	pause SingleBtnDelay
  	if pinC.3 = 0 then
  		pause DoubleBtnDelay
  		toggle B.5
  		pause DoubleBtnDelay
    endif
  	if Speed < MaxSpeed then
 		  Speed = Speed + SpeedStep
    endif
    sertxd ("Speed: ",#Speed,CR,LF)
  	if Speed >= DirCtrlVal then
  		low C.0
      Select case Speed
      case 4
    sertxd ("At 1st 4!",CR,LF)
        pwmout C.0, OFF
        pwmout C.2, OFF
      case 5
        MainMotorDuty = 70
      case 6
        MainMotorDuty = 80
      case 7
        MainMotorDuty = 90
      case 8
        MainMotorDuty = 100
      case 9
        MainMotorDuty = 110
      endselect
  		pwmout pwmdiv64, C.2, MainMotorPeriod, MainMotorDuty
    else
  		low C.2
      Select case Speed
      case 1
        MainMotorDuty = 90
      case 2
        MainMotorDuty = 80
      case 3
        MainMotorDuty = 70
      case 4
    sertxd ("At 2nd 4!",CR,LF)
        pwmout C.0, OFF
        pwmout C.2, OFF
      endselect
  		pwmout pwmdiv64, C.0, MainMotorPeriod, MainMotorDuty
  	endif
  endif

  if pinC.3 = 0 then
  	pause SingleBtnDelay
  	if pinC.4 = 0 then
  		pause DoubleBtnDelay
  		toggle B.5
  		pause DoubleBtnDelay
    endif
  	if Speed > MinSpeed then
  		Speed = Speed - SpeedStep
  	endif
    sertxd ("Speed: ",#Speed,CR,LF)
  	if Speed >= DirCtrlVal then
  		low C.0
      Select case Speed
      case 4
    sertxd ("At 3rd 4!",CR,LF)
        pwmout C.0, OFF
        pwmout C.2, OFF
      case 5
        MainMotorDuty = 70
      case 6
        MainMotorDuty = 80
      case 7
        MainMotorDuty = 90
      case 8
        MainMotorDuty = 100
      case 9
        MainMotorDuty = 110
      endselect
  		pwmout pwmdiv64, C.2, MainMotorPeriod, MainMotorDuty
  	else
  		low C.2
      Select case Speed
      case 1
        MainMotorDuty = 90
      case 2
        MainMotorDuty = 80
      case 3
        MainMotorDuty = 70
      case 4
    sertxd ("At 4th 4!",CR,LF)
        pwmout C.0, OFF
        pwmout C.2, OFF
      endselect
  		pwmout pwmdiv64, C.0, MainMotorPeriod, MainMotorDuty
  	endif
  endif
goto main
Thank you for your time,

Edmunds
 

hippy

Technical Support
Staff member
Code:
       pwmout C.0, OFF
        pwmout C.2, OFF
      endselect
  		pwmout pwmdiv64, C.0, MainMotorPeriod, MainMotorDuty
  	endif
You seem to be reactivating C.0 after the OFF.
 

edmunds

Senior Member
Thank you, Hippy! Of course. Now it works as expected. I will now try to combine motor control with servo as I did get hpwm running as well and will see what can be done about motor noise, because this toy motor thing messes up everybody on the circuit at the moment :).

/Edmunds
 
Top