ISRStepper
SwordfishUser.ISRStepper History
Hide minor edits - Show changes to output
Changed lines 1-3 from:
Interrupt driven stepper motor module. Uses Timer1 to generate interrupt at correct interval for motor speed. Each interrupt advances motor to next step.[[<<]]Public flag "MovementComplete" indicates when commanded position / number of steps have been reached.
to:
Interrupt driven stepper motor module. Uses Timer1 to generate interrupt at correct interval for motor speed. Each interrupt advances motor to next step.[[<<]]Public flag "MovementComplete" indicates when commanded position or number of steps have been reached.
Changed lines 1-3 from:
Interrupt driven stepper motor module. Uses Timer1 to generate interrupt at correct interval for motor speed. Each interrupt advances motor to next step.
to:
Interrupt driven stepper motor module. Uses Timer1 to generate interrupt at correct interval for motor speed. Each interrupt advances motor to next step.[[<<]]Public flag "MovementComplete" indicates when commanded position / number of steps have been reached.
Changed lines 13-20 from:
'''Move''' - moves motor specified number of steps with given direction and speed.
'''MoveToPosition''' - moves motor as close as possible to specified degree position (0 - 359.99) with given direction and speed.
'''ShortestMoveToPosition''' - moves motor in the shortest direction as close as possible to specified degree position (0 - 359.99) with given speed.
'''MoveToLimit''' - moves motor in specified direction until agiven PIC pin goes high. Can be used with a limit switch for calibrating the system to a known position. Optional StepTimeout sets number of steps after which movement stops regardless of limit switch state.
'''ShortestMoveToPosition''' - moves motor in the shortest direction as close as possible to specified degree position (0 - 359.99) with given speed.
'''MoveToLimit''' - moves motor in specified direction until a
to:
'''Move''' - moves motor specified number of steps with given direction and speed.[[<<]]''MovementComplete = True when finished''
'''MoveToPosition''' - moves motor as close as possible to specified degree position (0 - 359.99) with given direction and speed.[[<<]]''MovementComplete = True when finished''
'''ShortestMoveToPosition''' - moves motor in the shortest direction as close as possible to specified degree position (0 - 359.99) with given speed.[[<<]]''MovementComplete = True when finished''
'''MoveToLimit''' - moves motor in specified direction until a given PIC pin goes high. Can be used with a limit switch for calibrating the system to a known position. Optional StepTimeout sets number of steps after which movement stops regardless of limit switch state.[[<<]]''MovementComplete = True when finished. LimitSwitchReached = True if movement stopped because limit switch was triggered, False if StepTimeout reached.''
'''MoveToPosition''' - moves motor as close as possible to specified degree position (0 - 359.99) with given direction and speed.[[<<]]''MovementComplete = True when finished''
'''ShortestMoveToPosition''' - moves motor in the shortest direction as close as possible to specified degree position (0 - 359.99) with given speed.[[<<]]''MovementComplete = True when finished''
'''MoveToLimit''' - moves motor in specified direction until a given PIC pin goes high. Can be used with a limit switch for calibrating the system to a known position. Optional StepTimeout sets number of steps after which movement stops regardless of limit switch state.[[<<]]''MovementComplete = True when finished. LimitSwitchReached = True if movement stopped because limit switch was triggered, False if StepTimeout reached.''
Changed lines 23-24 from:
'''Rotate''' - turns motor through a given number of complete revolutions plus a number of degrees (0 - 359.99).
to:
'''Rotate''' - turns motor through a given number of complete revolutions plus a number of degrees (0 - 359.99).[[<<]]''MovementComplete = True when finished''
Changed lines 1-3 from:
Interrupt driven stepper motor module. Uses Timer1 to generate interrupt at correct interval for motor speed. Interrupt advances motor to next step.
to:
Interrupt driven stepper motor module. Uses Timer1 to generate interrupt at correct interval for motor speed. Each interrupt advances motor to next step.
Added lines 3-5:
!!ISRStepper Motor Module
Deleted lines 7-9:
Added lines 1-844:
Interrupt driven stepper motor module. Uses Timer1 to generate interrupt at correct interval for motor speed. Interrupt advances motor to next step.
Motor may be connected to any four pins on one port.
!!ISRStepper Motor Module
!!!Subs and Functions
(see code for parameters and other information)
''Note: All angles are * 100 (i.e. 90 degrees in reality = 9000 in module)''
'''Move''' - moves motor specified number of steps with given direction and speed.
'''MoveToPosition''' - moves motor as close as possible to specified degree position (0 - 359.99) with given direction and speed.
'''ShortestMoveToPosition''' - moves motor in the shortest direction as close as possible to specified degree position (0 - 359.99) with given speed.
'''MoveToLimit''' - moves motor in specified direction until a given PIC pin goes high. Can be used with a limit switch for calibrating the system to a known position. Optional StepTimeout sets number of steps after which movement stops regardless of limit switch state.
'''ResetPosition''' - sets module's Position variable to specified value. Useful for setting zero point after MoveToLimit or other calibration.
'''Rotate''' - turns motor through a given number of complete revolutions plus a number of degrees (0 - 359.99).
'''PowerOff''' / '''PowerOn''' - stops / resumes output on stepper motor pins. PowerOff cancels any movement in progress.
'''Pause''' / '''Resume''' - Pauses / resumes current movement.
'''GetPosition''' - returns current degree position of motor (0 - 359.99)
'''GetStep''' - returns current step number (1 - 8)
!!!Options
=code [=
#option ISRStepper_Port = PORTB 'Which PORT stepper is connected to
#option ISRStepper_Pin1 = %00000001 '}
#option ISRStepper_Pin2 = %00000010 '}Which 4 pins the stepper motor is
#option ISRStepper_Pin3 = %00000100 '}connected to. (Pins 0-3 shown here)
#option ISRStepper_Pin4 = %00001000 '}
#option ISRStepper_FullStepSize = 750 'Degrees motor moves in one full step
#option ISRStepper_HalfStepMode = True 'Drive motor in half step mode?
#option ISRStepper_DefaultSpeed = 4 'Default delay in mS between steps
#option ISRStepper_Priority = ipHigh 'Stepper interrupt priority
#option ISRStepper_LimitSwitch = PORTB.4 'Pin which limit switch is connected
'to. Note: Active HIGH
=]
!!!Usage Example
=code [=
#option ISRStepper_Port = PORTB '}
#option ISRStepper_Pin1 = %00000001 '}Stepper connected to pins 0,2,3 & 5
#option ISRStepper_Pin2 = %00000100 '}of PORTB
#option ISRStepper_Pin3 = %00001000 '}
#option ISRStepper_Pin4 = %00100000 '}
#option ISRStepper_FullStepSize = 500 'Full step is 5 degrees
#option ISRStepper_HalfStepMode = True 'Drive stepper in half-step mode
#option ISRStepper_DefaultSpeed = 4 'Default 4mS between steps
#option ISRStepper_Priority = ipHigh 'Stepper interrupt has high priority
#option ISRStepper_LimitSwitch = PORTA.0 'Pin for limit switch
Include "ISRStepper.bas"
Const Clockwise = True
Const AntiClockwise = False
'Set PortA.0 to input (limit switch)
TRISA = %00000001
'Move motor 10 steps clockwise at default speed
ISRStepper.Move(Clockwise, 10)
Repeat
'do useful things...
Until ISRStepper.MovementComplete = True
'Move motor to 120 degrees in shortest direction
ISRStepper.ShortestMoveToPosition(12000)
Repeat
'do useful things...
Until ISRStepper.MovementComplete = True
'Move motor anti-clockwise at 8mS between steps until it reaches limit switch.
'If limit switch not reached after 100 steps then stop driving motor:
ISRStepper.MoveToLimit(AntiClockwise, 8, 100)
Repeat
Until ISRStepper.MovementComplete = True
If ISRStepper.LimitSwitchReached = True Then
'Limit switch reached succesfully, set zero point
ISRStepper.ResetPosition(0)
Else
'Limit switch not reached, must be a mechanical problem, turn off motor
ISRStepper.PowerOff()
EndIf
'Rotate 3 1/4 times clockwise. If PORTB.6 goes High then pause movement, resume
'movement when PORTB.6 goes low again:
ISRStepper.Rotate(3, 9000, Clockwise)
Repeat
If PORTB.6 = 1 Then
ISRStepper.Pause()
Repeat
Until PORTB.6 = 0
ISRStepper.Resume()
EndIf
Until ISRStepper.MovementComplete = True
=]
!!!Module Code
=code [=
{
********************************************************************************
* Name : Interrupt Driven Stepper Motor Module *
* Author : AndyO *
* Notice : Copyright (c) 2008 AndyO *
* : All Rights Reserved *
* Date : 20/03/2008 *
* Version : 1.0 *
* Notes : Uses Timer1 and Compare module to trigger interrupt at correct *
* : interval for motor move speed *
* : *
* : For use with 4 phase unipolar stepper motor *
* : *
* : All angles * 100 (i.e. 7.5deg in reality = 750 in module) *
********************************************************************************
}
Module ISRStepper
'===============================================================================
'User definable options
'-------------------------------------------------------------------------------
#option ISRStepper_Port = PORTB 'Which PORT stepper is connected to
#option ISRStepper_Pin1 = %00000001 '}
#option ISRStepper_Pin2 = %00000010 '}Which 4 pins the stepper motor is
#option ISRStepper_Pin3 = %00000100 '}connected to. (Pins 0-3 shown here)
#option ISRStepper_Pin4 = %00001000 '}
#option ISRStepper_FullStepSize = 750 'Degrees motor moves in one full step
#option ISRStepper_HalfStepMode = True 'Drive motor in half step mode?
#option ISRStepper_DefaultSpeed = 4 'Default delay in mS between steps
#option ISRStepper_Priority = ipHigh 'Stepper interrupt priority
#option ISRStepper_LimitSwitch = PORTB.4 'Pin which limit switch is connected
'to. Note: Active HIGH
#option ISRStepper_TRIS = getTRIS(ISRStepper_Port)
'===============================================================================
'Variable and Const Declarations
'-------------------------------------------------------------------------------
'---Bring options into module
Private Const
#if ISRStepper_HalfStepMode Then
StepJump = 1,
StepSize = ISRStepper_FullStepSize / 2,
#else
StepJump = 2,
StepSize = ISRStepper_FullStepSize,
#endif
Pin1 As Byte = ISRStepper_Pin1,
Pin2 As Byte = ISRStepper_Pin2,
Pin3 As Byte = ISRStepper_Pin3,
Pin4 As Byte = ISRStepper_Pin4,
'PortMask used to turn on/off only the pins the stepper is connnected to
PortMask As Byte = Not(Pin1 Or Pin2 Or Pin3 Or Pin4),
'Step masks used to turn on the correct pins for the current step.
'Constant array loaded with half-step sequence
StepMask(8) As Byte = (Pin1, 'Step 1: 0001
Pin1 Or Pin2, 'Step 2: 0011
Pin2, 'Step 3: 0010
Pin2 Or Pin3, 'Step 4: 0110
Pin3, 'Step 5: 0100
Pin3 Or Pin4, 'Step 6: 1100
Pin4, 'Step 7: 1000
Pin4 Or Pin1), 'Step 8: 1001
DefaultSpeed = ISRStepper_DefaultSpeed,
StepperPriority = ISRStepper_Priority,
Timer1mSCount = _clock * 250 'No. of ticks Timer1 makes in 1mS
Private Dim
StepperPort As ISRStepper_Port,
LimitSwitch As ISRStepper_LimitSwitch.ISRStepper_LimitSwitch@,
StepperTRIS As ISRStepper_TRIS
'---Timer1 & CCP Module Registers
Private Dim
Timer1Value As TMR1L.AsWord,
Timer1On As T1CON.Booleans(0),
CompareValue As CCPR1L.AsWord,
CompareInterruptFlag As PIR1.Booleans(2),
CompareInterruptEnable As PIE1.Booleans(2),
CompareInterruptHighPriority As IPR1.Booleans(2),
CompareUsingTimer3 As T3CON.Booleans(3)
'---Private Variables
Private Dim CurrentStep As Byte
Private Dim Position As Word
Private Dim RotateClockwise As Boolean
Private Dim StepCount As Word
Private Dim MoveToLimitMode As Boolean
Private Dim UseLimitTimeout As Boolean
Private Dim Distance As Word
Private Dim DistanceAntiClockwise As Word
'---Public Variables
Public Dim MovementComplete As Boolean
Public Dim LimitSwitchReached As Boolean
'===============================================================================
'Helper Subs and Functions (Private - can't be called from main program)
'-------------------------------------------------------------------------------
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'Name: SingleStep (Inline)
'Purpose: Updates StepCount and Position Variables, set relevant pins high for
' current step.
'
'Note: Inline sub - doesn't save codespace but used to improve readability
' of interrupt routine.
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Private Inline Sub SingleStep()
'Adjust CurrentStep according to direction and update Position variable
If RotateClockwise Then
CurrentStep = CurrentStep + StepJump
Position = Position + StepSize
If Position > 35999 Then
Position = Position - 36000
EndIf
Else
CurrentStep = CurrentStep - StepJump
'Going anti-clockwise so need to check for zero-cross
If Position >= StepSize Then
Position = Position - StepSize
Else
Position = (36000 + Position) - StepSize
EndIf
EndIf
Select CurrentStep
Case >8
CurrentStep = StepJump
Case 0
CurrentStep = 8
EndSelect
'AND'ing Port with PortMask sets only stepper pins to '0' ignores others
'OR'ing Port with StepMask for current step sets the relevant pins high
StepperPort = (StepperPort And PortMask) Or StepMask(CurrentStep - 1)
End Sub
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'Name: BeginMove
'Purpose: Enables interrupt, allowing motor movement to begin.
'
' Loads necessary values into Compare register and Timer1, starts
' Timer1 and enables interrupt
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Private Sub BeginMove(pSpeed As Byte)
'Load compare module with appropriate value depending on speed
CompareValue = pSpeed * Timer1mSCount - 1
'Set Timer1 to just before compare value and turn it on
Timer1Value = CompareValue - 1
Timer1On = True
'Turn on interrupt - interrupt triggered when Timer1 = compare value
CompareInterruptEnable = True
End Sub
'===============================================================================
'Interrupts
'-------------------------------------------------------------------------------
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'Name: OnTimer
'Purpose: Interrupt triggered when Timer1 reaches CCPR1 register value
' (CompareValue).
'
' Occurs every x mS where x is the speed setting for the movement.
'
' Movement finishes when number of steps have been taken or limit
' switch reached (depending on what mode we're in). Once movement is
' complete, interrupt is un-enabled and MovementComplete flag = True.
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Interrupt OnTimer(StepperPriority)
'Context save
Save(0)
If MoveToLimitMode = True Then
If UseLimitTimeout = True Then
'Timeout specified (StepCount holds StepTimeout)
If LimitSwitch = 0 And StepCount > 0 Then
SingleStep()
Dec(StepCount)
ElseIf LimitSwitch = 1 And StepCount > 0 Then
'Limit switch was reached in time
MovementComplete = True
LimitSwitchReached = True
Timer1On = False
CompareInterruptEnable = False
Else
'Ran out of steps before the limit switch was reached
MovementComplete = True
LimitSwitchReached = False
Timer1On = False
CompareInterruptEnable = False
EndIf
Else
'No timeout specified - just keep moving until the limit switch triggers
If LimitSwitch = 0 Then
SingleStep()
Else
'Limit switch reached
MovementComplete = True
LimitSwitchReached = True
Timer1On = False
CompareInterruptEnable = False
EndIf
EndIf
Else
'Not moving to the limit switch - instead move until StepCount = 0
If StepCount > 0 Then
SingleStep()
Dec(StepCount)
Else
MovementComplete = True
Timer1On = False
CompareInterruptEnable = False
EndIf
EndIf
'Context restore
Restore
CompareInterruptFlag = False
End Interrupt
'===============================================================================
'Public Subs and Functions
'-------------------------------------------------------------------------------
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'Name: Move
'Purpose: Moves stepper with specified direction, number of steps and speed.
'
' MovementComplete flag = True when move is finished.
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Public Sub Move(pRotateClockwise As Boolean = True, pNumberOfSteps As Word = 1, pSpeed As Byte = DefaultSpeed)
MovementComplete = False
MoveToLimitMode = False
RotateClockwise = pRotateClockwise
StepCount = pNumberOfSteps
BeginMove(pSpeed)
End Sub
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'Name: MoveToLimit
'Purpose: Moves stepper with specified direction and speed until limit switch
' is triggered. Optional pStepTimeout sets number of steps after
' which movement stops regardless of limit switch state.
'
' Once movement complete (indicated by MovementComplete flag = True),
' LimitSwitchReached flag = True if movement stopped because the limit
' switch was triggered; flag = False if movement stopped because
' StepTimeout was reached.
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Public Sub MoveToLimit(pRotateClockwise As Boolean = True, pSpeed As Byte = DefaultSpeed, pStepTimeout As Word = 0)
MovementComplete = False
LimitSwitchReached = False
MoveToLimitMode = True
If pStepTimeout > 0 Then
'Timeout has been specified
UseLimitTimeout = True
StepCount = pStepTimeout
Else
'No timeout specified
UseLimitTimeout = False
EndIf
RotateClockwise = pRotateClockwise
BeginMove(pSpeed)
End Sub
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'Name: ResetPosition
'Purpose: Sets Position variable to specified value. Useful for setting zero
' point after move to limit switch or other calibration.
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Public Sub ResetPosition(pPosition As Word = 0)
Position = pPosition
End Sub
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'Name: MoveToPosition
'Purpose: Moves stepper as close as possible to desired position with
' specified direction and speed.
'
' MovementComplete flag = True when move is finished.
'
'Note: All positions * 100 i.e. 90 deg = 9000
'
' Final position of stepper may vary from desired position due to
' resolution of step size.
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Public Sub MoveToPosition(pDesiredPosition As Word, pRotateClockwise As Boolean = True, pSpeed As Byte = DefaultSpeed)
MovementComplete = False
MoveToLimitMode = False
RotateClockwise = pRotateClockwise
'If desired position is 360deg or over then bring it into 0 - 35999 range
If pDesiredPosition > 35999 Then
pDesiredPosition = pDesiredPosition - 36000
EndIf
'Calculate distance (in degrees) motor needs to travel
If pDesiredPosition > Position Then
If pRotateClockwise Then
Distance = pDesiredPosition - Position
Else
Distance = (36000 - pDesiredPosition) + Position
EndIf
Else
If pRotateClockwise Then
Distance = (36000 - Position) + pDesiredPosition
Else
Distance = Position - pDesiredPosition
EndIf
EndIf
If Distance > StepSize / 2 And Distance < 36000 - (StepSize / 2) Then
'Only move if desired position is more than 1/2 a step from current position
'Convert degree distance to number of steps
StepCount = Distance / StepSize
'If motor will stop more than 1/2 a step before desired position then
'better to overshoot by a step
If Distance Mod StepSize > StepSize / 2 Then
StepCount = StepCount + 1
EndIf
BeginMove(pSpeed)
Else
MovementComplete = true
EndIf
End Sub
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'Name: ShortestMoveToPosition
'Purpose: Moves stepper as close as possible to desired position with
' specified speed in the shortest direction.
'
' MovementComplete flag = True when move is finished.
'
'Note: All positions * 100 i.e. 90 deg = 9000
'
' Final position of stepper may vary from desired position due to
' resolution of step size.
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Public Sub ShortestMoveToPosition(pDesiredPosition As Word, pSpeed As Byte = DefaultSpeed)
MovementComplete = False
MoveToLimitMode = False
'If desired position is 360deg or over then bring it into 0 - 35999 range
If pDesiredPosition > 35999 Then
pDesiredPosition = pDesiredPosition - 36000
EndIf
'Calculate distance between desired and actual position in each direction
If pDesiredPosition > Position Then
Distance = pDesiredPosition - Position
DistanceAntiClockwise = (36000 - pDesiredPosition) + Position
Else
Distance = (36000 - Position) + pDesiredPosition
DistanceAntiClockwise = Position - pDesiredPosition
EndIf
'Choose the shortest distance
If Distance > DistanceAntiClockwise Then
Distance = DistanceAntiClockwise
RotateClockwise = False
Else
RotateClockwise = True
EndIf
'Convert degree distance to number of steps
StepCount = Distance / StepSize
'If motor will stop more than 1/2 a step before desired position then better
'to overshoot by a step
If Distance Mod StepSize > StepSize / 2 Then
StepCount = StepCount + 1
EndIf
BeginMove(pSpeed)
End Sub
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'Name: Rotate
'Purpose: Rotates stepper the specified number of complete revolutions plus
' 0-35999 additional degrees with specified direction and speed.
'
' MovementComplete flag = True when move is finished.
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Public Sub Rotate(pNumberOfRotations As Byte = 1, pAdditionalDegrees As Word = 0, pRotateClockwise As Boolean = True, pSpeed As Byte = DefaultSpeed)
MovementComplete = False
MoveToLimitMode = False
RotateClockwise = pRotateClockwise
'If additional degrees is 360deg or over then bring it into 0 - 35999 range
If pAdditionalDegrees > 35999 Then
pAdditionalDegrees = pAdditionalDegrees - 36000
EndIf
'Convert additional degree distance to number of steps
StepCount = pAdditionalDegrees / StepSize
'If motor will stop more than 1/2 a step before desired position then better
'to overshoot by a step
If pAdditionalDegrees Mod StepSize > StepSize / 2 Then
StepCount = StepCount + 1
EndIf
'Add correct number of steps for complete rotations
StepCount = StepCount + (pNumberOfRotations * (36000 / StepSize))
BeginMove(pSpeed)
End Sub
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'Name: PowerOff
'Purpose: Stops output on stepper pins and cancels any movement in progress
'
'Note: Stepper won't hold position
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Public Sub PowerOff()
StepCount = 0
StepperPort = StepperPort And PortMask
End Sub
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'Name: PowerOn
'Purpose: Resumes output on stepper pins
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Public Sub PowerOn()
StepperPort = (StepperPort And PortMask) Or StepMask(CurrentStep - 1)
End Sub
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'Name: Pause
'Purpose: Pauses any motor movement in progress
'
'Note: Continues to output current step on output pins
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Public Sub Pause()
Timer1On = False
End Sub
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'Name: Resume
'Purpose: Resumes movment after pause
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Public Sub Resume()
Timer1On = True
End Sub
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'Name: GetStep
'Returns: Number of current step (1 - 8)
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Public Function GetStep() As Byte
result = CurrentStep
End Function
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'Name: GetPosition
'Returns: Current stepper position (0 - 35,999)
'
'Note: All positions * 100 i.e. 90 deg = 9000
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Public Function GetPosition() As Word
result = Position
End Function
'===============================================================================
'Module Initialisation
'-------------------------------------------------------------------------------
'Initialise vars
CurrentStep = StepJump
Position = 0
StepCount = 0
MovementComplete = True
MoveToLimitMode = False
LimitSwitchReached = False
'Set TRIS without changing non-stepper pins
StepperTRIS = StepperTRIS And PortMask
'Initialise CCP and Timer1 modules:
CompareUsingTimer3 = False 'Compare module use timer1
#if ISRStepper_Priority = ipHigh Then '}
CompareInterruptHighPriority = True '}
#else '}Set interrupt priority
CompareInterruptHighPriority = False '}
#endif '}
T1CON = %00000000 'No pre-scaler, timer 1 off
CCP1CON = %00001011 'Set special event trigger
'(Resets Timer1 and triggers
'interrupt when Timer1 value
'reaches CCPR1 register value)
Enable(OnTimer)
=]
Motor may be connected to any four pins on one port.
!!ISRStepper Motor Module
!!!Subs and Functions
(see code for parameters and other information)
''Note: All angles are * 100 (i.e. 90 degrees in reality = 9000 in module)''
'''Move''' - moves motor specified number of steps with given direction and speed.
'''MoveToPosition''' - moves motor as close as possible to specified degree position (0 - 359.99) with given direction and speed.
'''ShortestMoveToPosition''' - moves motor in the shortest direction as close as possible to specified degree position (0 - 359.99) with given speed.
'''MoveToLimit''' - moves motor in specified direction until a given PIC pin goes high. Can be used with a limit switch for calibrating the system to a known position. Optional StepTimeout sets number of steps after which movement stops regardless of limit switch state.
'''ResetPosition''' - sets module's Position variable to specified value. Useful for setting zero point after MoveToLimit or other calibration.
'''Rotate''' - turns motor through a given number of complete revolutions plus a number of degrees (0 - 359.99).
'''PowerOff''' / '''PowerOn''' - stops / resumes output on stepper motor pins. PowerOff cancels any movement in progress.
'''Pause''' / '''Resume''' - Pauses / resumes current movement.
'''GetPosition''' - returns current degree position of motor (0 - 359.99)
'''GetStep''' - returns current step number (1 - 8)
!!!Options
=code [=
#option ISRStepper_Port = PORTB 'Which PORT stepper is connected to
#option ISRStepper_Pin1 = %00000001 '}
#option ISRStepper_Pin2 = %00000010 '}Which 4 pins the stepper motor is
#option ISRStepper_Pin3 = %00000100 '}connected to. (Pins 0-3 shown here)
#option ISRStepper_Pin4 = %00001000 '}
#option ISRStepper_FullStepSize = 750 'Degrees motor moves in one full step
#option ISRStepper_HalfStepMode = True 'Drive motor in half step mode?
#option ISRStepper_DefaultSpeed = 4 'Default delay in mS between steps
#option ISRStepper_Priority = ipHigh 'Stepper interrupt priority
#option ISRStepper_LimitSwitch = PORTB.4 'Pin which limit switch is connected
'to. Note: Active HIGH
=]
!!!Usage Example
=code [=
#option ISRStepper_Port = PORTB '}
#option ISRStepper_Pin1 = %00000001 '}Stepper connected to pins 0,2,3 & 5
#option ISRStepper_Pin2 = %00000100 '}of PORTB
#option ISRStepper_Pin3 = %00001000 '}
#option ISRStepper_Pin4 = %00100000 '}
#option ISRStepper_FullStepSize = 500 'Full step is 5 degrees
#option ISRStepper_HalfStepMode = True 'Drive stepper in half-step mode
#option ISRStepper_DefaultSpeed = 4 'Default 4mS between steps
#option ISRStepper_Priority = ipHigh 'Stepper interrupt has high priority
#option ISRStepper_LimitSwitch = PORTA.0 'Pin for limit switch
Include "ISRStepper.bas"
Const Clockwise = True
Const AntiClockwise = False
'Set PortA.0 to input (limit switch)
TRISA = %00000001
'Move motor 10 steps clockwise at default speed
ISRStepper.Move(Clockwise, 10)
Repeat
'do useful things...
Until ISRStepper.MovementComplete = True
'Move motor to 120 degrees in shortest direction
ISRStepper.ShortestMoveToPosition(12000)
Repeat
'do useful things...
Until ISRStepper.MovementComplete = True
'Move motor anti-clockwise at 8mS between steps until it reaches limit switch.
'If limit switch not reached after 100 steps then stop driving motor:
ISRStepper.MoveToLimit(AntiClockwise, 8, 100)
Repeat
Until ISRStepper.MovementComplete = True
If ISRStepper.LimitSwitchReached = True Then
'Limit switch reached succesfully, set zero point
ISRStepper.ResetPosition(0)
Else
'Limit switch not reached, must be a mechanical problem, turn off motor
ISRStepper.PowerOff()
EndIf
'Rotate 3 1/4 times clockwise. If PORTB.6 goes High then pause movement, resume
'movement when PORTB.6 goes low again:
ISRStepper.Rotate(3, 9000, Clockwise)
Repeat
If PORTB.6 = 1 Then
ISRStepper.Pause()
Repeat
Until PORTB.6 = 0
ISRStepper.Resume()
EndIf
Until ISRStepper.MovementComplete = True
=]
!!!Module Code
=code [=
{
********************************************************************************
* Name : Interrupt Driven Stepper Motor Module *
* Author : AndyO *
* Notice : Copyright (c) 2008 AndyO *
* : All Rights Reserved *
* Date : 20/03/2008 *
* Version : 1.0 *
* Notes : Uses Timer1 and Compare module to trigger interrupt at correct *
* : interval for motor move speed *
* : *
* : For use with 4 phase unipolar stepper motor *
* : *
* : All angles * 100 (i.e. 7.5deg in reality = 750 in module) *
********************************************************************************
}
Module ISRStepper
'===============================================================================
'User definable options
'-------------------------------------------------------------------------------
#option ISRStepper_Port = PORTB 'Which PORT stepper is connected to
#option ISRStepper_Pin1 = %00000001 '}
#option ISRStepper_Pin2 = %00000010 '}Which 4 pins the stepper motor is
#option ISRStepper_Pin3 = %00000100 '}connected to. (Pins 0-3 shown here)
#option ISRStepper_Pin4 = %00001000 '}
#option ISRStepper_FullStepSize = 750 'Degrees motor moves in one full step
#option ISRStepper_HalfStepMode = True 'Drive motor in half step mode?
#option ISRStepper_DefaultSpeed = 4 'Default delay in mS between steps
#option ISRStepper_Priority = ipHigh 'Stepper interrupt priority
#option ISRStepper_LimitSwitch = PORTB.4 'Pin which limit switch is connected
'to. Note: Active HIGH
#option ISRStepper_TRIS = getTRIS(ISRStepper_Port)
'===============================================================================
'Variable and Const Declarations
'-------------------------------------------------------------------------------
'---Bring options into module
Private Const
#if ISRStepper_HalfStepMode Then
StepJump = 1,
StepSize = ISRStepper_FullStepSize / 2,
#else
StepJump = 2,
StepSize = ISRStepper_FullStepSize,
#endif
Pin1 As Byte = ISRStepper_Pin1,
Pin2 As Byte = ISRStepper_Pin2,
Pin3 As Byte = ISRStepper_Pin3,
Pin4 As Byte = ISRStepper_Pin4,
'PortMask used to turn on/off only the pins the stepper is connnected to
PortMask As Byte = Not(Pin1 Or Pin2 Or Pin3 Or Pin4),
'Step masks used to turn on the correct pins for the current step.
'Constant array loaded with half-step sequence
StepMask(8) As Byte = (Pin1, 'Step 1: 0001
Pin1 Or Pin2, 'Step 2: 0011
Pin2, 'Step 3: 0010
Pin2 Or Pin3, 'Step 4: 0110
Pin3, 'Step 5: 0100
Pin3 Or Pin4, 'Step 6: 1100
Pin4, 'Step 7: 1000
Pin4 Or Pin1), 'Step 8: 1001
DefaultSpeed = ISRStepper_DefaultSpeed,
StepperPriority = ISRStepper_Priority,
Timer1mSCount = _clock * 250 'No. of ticks Timer1 makes in 1mS
Private Dim
StepperPort As ISRStepper_Port,
LimitSwitch As ISRStepper_LimitSwitch.ISRStepper_LimitSwitch@,
StepperTRIS As ISRStepper_TRIS
'---Timer1 & CCP Module Registers
Private Dim
Timer1Value As TMR1L.AsWord,
Timer1On As T1CON.Booleans(0),
CompareValue As CCPR1L.AsWord,
CompareInterruptFlag As PIR1.Booleans(2),
CompareInterruptEnable As PIE1.Booleans(2),
CompareInterruptHighPriority As IPR1.Booleans(2),
CompareUsingTimer3 As T3CON.Booleans(3)
'---Private Variables
Private Dim CurrentStep As Byte
Private Dim Position As Word
Private Dim RotateClockwise As Boolean
Private Dim StepCount As Word
Private Dim MoveToLimitMode As Boolean
Private Dim UseLimitTimeout As Boolean
Private Dim Distance As Word
Private Dim DistanceAntiClockwise As Word
'---Public Variables
Public Dim MovementComplete As Boolean
Public Dim LimitSwitchReached As Boolean
'===============================================================================
'Helper Subs and Functions (Private - can't be called from main program)
'-------------------------------------------------------------------------------
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'Name: SingleStep (Inline)
'Purpose: Updates StepCount and Position Variables, set relevant pins high for
' current step.
'
'Note: Inline sub - doesn't save codespace but used to improve readability
' of interrupt routine.
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Private Inline Sub SingleStep()
'Adjust CurrentStep according to direction and update Position variable
If RotateClockwise Then
CurrentStep = CurrentStep + StepJump
Position = Position + StepSize
If Position > 35999 Then
Position = Position - 36000
EndIf
Else
CurrentStep = CurrentStep - StepJump
'Going anti-clockwise so need to check for zero-cross
If Position >= StepSize Then
Position = Position - StepSize
Else
Position = (36000 + Position) - StepSize
EndIf
EndIf
Select CurrentStep
Case >8
CurrentStep = StepJump
Case 0
CurrentStep = 8
EndSelect
'AND'ing Port with PortMask sets only stepper pins to '0' ignores others
'OR'ing Port with StepMask for current step sets the relevant pins high
StepperPort = (StepperPort And PortMask) Or StepMask(CurrentStep - 1)
End Sub
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'Name: BeginMove
'Purpose: Enables interrupt, allowing motor movement to begin.
'
' Loads necessary values into Compare register and Timer1, starts
' Timer1 and enables interrupt
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Private Sub BeginMove(pSpeed As Byte)
'Load compare module with appropriate value depending on speed
CompareValue = pSpeed * Timer1mSCount - 1
'Set Timer1 to just before compare value and turn it on
Timer1Value = CompareValue - 1
Timer1On = True
'Turn on interrupt - interrupt triggered when Timer1 = compare value
CompareInterruptEnable = True
End Sub
'===============================================================================
'Interrupts
'-------------------------------------------------------------------------------
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'Name: OnTimer
'Purpose: Interrupt triggered when Timer1 reaches CCPR1 register value
' (CompareValue).
'
' Occurs every x mS where x is the speed setting for the movement.
'
' Movement finishes when number of steps have been taken or limit
' switch reached (depending on what mode we're in). Once movement is
' complete, interrupt is un-enabled and MovementComplete flag = True.
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Interrupt OnTimer(StepperPriority)
'Context save
Save(0)
If MoveToLimitMode = True Then
If UseLimitTimeout = True Then
'Timeout specified (StepCount holds StepTimeout)
If LimitSwitch = 0 And StepCount > 0 Then
SingleStep()
Dec(StepCount)
ElseIf LimitSwitch = 1 And StepCount > 0 Then
'Limit switch was reached in time
MovementComplete = True
LimitSwitchReached = True
Timer1On = False
CompareInterruptEnable = False
Else
'Ran out of steps before the limit switch was reached
MovementComplete = True
LimitSwitchReached = False
Timer1On = False
CompareInterruptEnable = False
EndIf
Else
'No timeout specified - just keep moving until the limit switch triggers
If LimitSwitch = 0 Then
SingleStep()
Else
'Limit switch reached
MovementComplete = True
LimitSwitchReached = True
Timer1On = False
CompareInterruptEnable = False
EndIf
EndIf
Else
'Not moving to the limit switch - instead move until StepCount = 0
If StepCount > 0 Then
SingleStep()
Dec(StepCount)
Else
MovementComplete = True
Timer1On = False
CompareInterruptEnable = False
EndIf
EndIf
'Context restore
Restore
CompareInterruptFlag = False
End Interrupt
'===============================================================================
'Public Subs and Functions
'-------------------------------------------------------------------------------
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'Name: Move
'Purpose: Moves stepper with specified direction, number of steps and speed.
'
' MovementComplete flag = True when move is finished.
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Public Sub Move(pRotateClockwise As Boolean = True, pNumberOfSteps As Word = 1, pSpeed As Byte = DefaultSpeed)
MovementComplete = False
MoveToLimitMode = False
RotateClockwise = pRotateClockwise
StepCount = pNumberOfSteps
BeginMove(pSpeed)
End Sub
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'Name: MoveToLimit
'Purpose: Moves stepper with specified direction and speed until limit switch
' is triggered. Optional pStepTimeout sets number of steps after
' which movement stops regardless of limit switch state.
'
' Once movement complete (indicated by MovementComplete flag = True),
' LimitSwitchReached flag = True if movement stopped because the limit
' switch was triggered; flag = False if movement stopped because
' StepTimeout was reached.
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Public Sub MoveToLimit(pRotateClockwise As Boolean = True, pSpeed As Byte = DefaultSpeed, pStepTimeout As Word = 0)
MovementComplete = False
LimitSwitchReached = False
MoveToLimitMode = True
If pStepTimeout > 0 Then
'Timeout has been specified
UseLimitTimeout = True
StepCount = pStepTimeout
Else
'No timeout specified
UseLimitTimeout = False
EndIf
RotateClockwise = pRotateClockwise
BeginMove(pSpeed)
End Sub
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'Name: ResetPosition
'Purpose: Sets Position variable to specified value. Useful for setting zero
' point after move to limit switch or other calibration.
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Public Sub ResetPosition(pPosition As Word = 0)
Position = pPosition
End Sub
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'Name: MoveToPosition
'Purpose: Moves stepper as close as possible to desired position with
' specified direction and speed.
'
' MovementComplete flag = True when move is finished.
'
'Note: All positions * 100 i.e. 90 deg = 9000
'
' Final position of stepper may vary from desired position due to
' resolution of step size.
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Public Sub MoveToPosition(pDesiredPosition As Word, pRotateClockwise As Boolean = True, pSpeed As Byte = DefaultSpeed)
MovementComplete = False
MoveToLimitMode = False
RotateClockwise = pRotateClockwise
'If desired position is 360deg or over then bring it into 0 - 35999 range
If pDesiredPosition > 35999 Then
pDesiredPosition = pDesiredPosition - 36000
EndIf
'Calculate distance (in degrees) motor needs to travel
If pDesiredPosition > Position Then
If pRotateClockwise Then
Distance = pDesiredPosition - Position
Else
Distance = (36000 - pDesiredPosition) + Position
EndIf
Else
If pRotateClockwise Then
Distance = (36000 - Position) + pDesiredPosition
Else
Distance = Position - pDesiredPosition
EndIf
EndIf
If Distance > StepSize / 2 And Distance < 36000 - (StepSize / 2) Then
'Only move if desired position is more than 1/2 a step from current position
'Convert degree distance to number of steps
StepCount = Distance / StepSize
'If motor will stop more than 1/2 a step before desired position then
'better to overshoot by a step
If Distance Mod StepSize > StepSize / 2 Then
StepCount = StepCount + 1
EndIf
BeginMove(pSpeed)
Else
MovementComplete = true
EndIf
End Sub
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'Name: ShortestMoveToPosition
'Purpose: Moves stepper as close as possible to desired position with
' specified speed in the shortest direction.
'
' MovementComplete flag = True when move is finished.
'
'Note: All positions * 100 i.e. 90 deg = 9000
'
' Final position of stepper may vary from desired position due to
' resolution of step size.
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Public Sub ShortestMoveToPosition(pDesiredPosition As Word, pSpeed As Byte = DefaultSpeed)
MovementComplete = False
MoveToLimitMode = False
'If desired position is 360deg or over then bring it into 0 - 35999 range
If pDesiredPosition > 35999 Then
pDesiredPosition = pDesiredPosition - 36000
EndIf
'Calculate distance between desired and actual position in each direction
If pDesiredPosition > Position Then
Distance = pDesiredPosition - Position
DistanceAntiClockwise = (36000 - pDesiredPosition) + Position
Else
Distance = (36000 - Position) + pDesiredPosition
DistanceAntiClockwise = Position - pDesiredPosition
EndIf
'Choose the shortest distance
If Distance > DistanceAntiClockwise Then
Distance = DistanceAntiClockwise
RotateClockwise = False
Else
RotateClockwise = True
EndIf
'Convert degree distance to number of steps
StepCount = Distance / StepSize
'If motor will stop more than 1/2 a step before desired position then better
'to overshoot by a step
If Distance Mod StepSize > StepSize / 2 Then
StepCount = StepCount + 1
EndIf
BeginMove(pSpeed)
End Sub
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'Name: Rotate
'Purpose: Rotates stepper the specified number of complete revolutions plus
' 0-35999 additional degrees with specified direction and speed.
'
' MovementComplete flag = True when move is finished.
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Public Sub Rotate(pNumberOfRotations As Byte = 1, pAdditionalDegrees As Word = 0, pRotateClockwise As Boolean = True, pSpeed As Byte = DefaultSpeed)
MovementComplete = False
MoveToLimitMode = False
RotateClockwise = pRotateClockwise
'If additional degrees is 360deg or over then bring it into 0 - 35999 range
If pAdditionalDegrees > 35999 Then
pAdditionalDegrees = pAdditionalDegrees - 36000
EndIf
'Convert additional degree distance to number of steps
StepCount = pAdditionalDegrees / StepSize
'If motor will stop more than 1/2 a step before desired position then better
'to overshoot by a step
If pAdditionalDegrees Mod StepSize > StepSize / 2 Then
StepCount = StepCount + 1
EndIf
'Add correct number of steps for complete rotations
StepCount = StepCount + (pNumberOfRotations * (36000 / StepSize))
BeginMove(pSpeed)
End Sub
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'Name: PowerOff
'Purpose: Stops output on stepper pins and cancels any movement in progress
'
'Note: Stepper won't hold position
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Public Sub PowerOff()
StepCount = 0
StepperPort = StepperPort And PortMask
End Sub
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'Name: PowerOn
'Purpose: Resumes output on stepper pins
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Public Sub PowerOn()
StepperPort = (StepperPort And PortMask) Or StepMask(CurrentStep - 1)
End Sub
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'Name: Pause
'Purpose: Pauses any motor movement in progress
'
'Note: Continues to output current step on output pins
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Public Sub Pause()
Timer1On = False
End Sub
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'Name: Resume
'Purpose: Resumes movment after pause
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Public Sub Resume()
Timer1On = True
End Sub
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'Name: GetStep
'Returns: Number of current step (1 - 8)
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Public Function GetStep() As Byte
result = CurrentStep
End Function
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
'Name: GetPosition
'Returns: Current stepper position (0 - 35,999)
'
'Note: All positions * 100 i.e. 90 deg = 9000
'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Public Function GetPosition() As Word
result = Position
End Function
'===============================================================================
'Module Initialisation
'-------------------------------------------------------------------------------
'Initialise vars
CurrentStep = StepJump
Position = 0
StepCount = 0
MovementComplete = True
MoveToLimitMode = False
LimitSwitchReached = False
'Set TRIS without changing non-stepper pins
StepperTRIS = StepperTRIS And PortMask
'Initialise CCP and Timer1 modules:
CompareUsingTimer3 = False 'Compare module use timer1
#if ISRStepper_Priority = ipHigh Then '}
CompareInterruptHighPriority = True '}
#else '}Set interrupt priority
CompareInterruptHighPriority = False '}
#endif '}
T1CON = %00000000 'No pre-scaler, timer 1 off
CCP1CON = %00001011 'Set special event trigger
'(Resets Timer1 and triggers
'interrupt when Timer1 value
'reaches CCPR1 register value)
Enable(OnTimer)
=]