| Author | Richard Zengerink, Copyright © 2009..2010, all rights reserved. |
| Adapted-by | Rob Hamerling (2016) |
| Compiler | 2.4q5 |
Library for a single stepper motor.
Includes configurable startup- en slowdown-curves
and optionally user-defined control patterns.
Designed and tested with a unipolar motor,
but can be used with a bipolar motor as well.
Supports inverting and non-inverting buffer-ICs
.
Required declarations before including the library:
This library uses 4 control pins to control a stepper motor.
When all pins are in the same nibble (most efficient) declare an alias
for this nibble, for example when pins pin_B0 through pin_B3 are used:
alias stepper_coils is portB_low
and set all the pins if this nibble to output:
portB_low_direction = ALL_OUTPUT
Alternatively with individual pins (not necessarily on the same nibble)
alias stepper_coil1a is pin_B0
alias stepper_coil2a is pin_B1
alias stepper_coil1b is pin_C0
alias stepper_coil2b is pin_C1
and set these pins to output:
pin_B0 = OUTPUT
pin_B1 = OUTPUT
pin_C0 = OUTPUT
pin_C1 = OUTPUT
The wiring of the 4 pins to the coils must of course match
the bit patterns in the arrays below!
.
A constant array of bit patterns is required to
specify the signal state for each half-step:
const byte STEPPER_ARRAY[8] =
{
0b_0001, -- coil 1a
0b_0011, -- coil 1a + 2a
0b_0010, -- coil 2a
0b_0110, -- coil 2a + 1b
0b_0100, -- coil 1b
0b_1100, -- coil 1b + 2b
0b_1000, -- coil 2b
0b_1001 -- coil 2b + 1a
}
These bit patterns are examples for a unipolar stepper motor and
are the defaults when the array is absent in the user program.
The entries specify the bit pattern for every half step in
clock-wise rotation.
In full-step mode only the even entries of the array are used.
With bipolar stepper motors or with special buffer-ICs
the appropriate patterns need be defined by the user program.
In any case the bit pattern should match the actual wiring and
your definition of clockwise!
.
Specify a bit constant to indicate when you use an inverting
buffer-IC to control the stepper motor:
const bit STEPPER_INVERTING_BUFFER = TRUE
When not specified the default behaviour is non-inverting.
.
A word constant must be declared which specifies the number of steps
for a complete rotation of the stepper motor axis in full-step mode,
for example:
const word STEPPER_STEPS_PER_ROTATION = 200
.
A bit variable 'stepper_cw' must be declared to specify the direction of
rotation. Value TRUE means 'clockwise' and FALSE 'counter-clockwise'.
var bit stepper_cw = TRUE
Make sure your wiring matches this setting and the way the stepper moves.
The value may be changed dynamically by the user program.
.
A bit variable 'stepper_fullstep' must be declared to indicate
that the stepper must run at full-steps (TRUE) or half-steps (FALSE).
var bit stepper_fullstep = TRUE
The value may be changed dynamically by the user program.
.
This library was initially designed for PICs with 16-bits wide Timer0.
This excluded the use of midrange PICs, which have only 8-bits Timer0.
A 16-bits timer is required to support a wide enough speedrange
of stepper motors. When using a PIC without a 16-bits wide Timer0
this revised version of the library automatically selects Timer3 or
the PWM3 modules when present.
.
Available public procedures:
stepper_run() -- set motor speed (accellerate/decellerate smoothly)
stepper_stop() -- stop motor (decellerate smoothly)
stepper_hold() -- stop motor immediately and lock it (keep powered)
stepper_accel() -- set acceleration ratio (smooth accelleration)
stepper_decel() -- set decellaration ratio (smooth decelleration)
stepper_detach() -- stop motor immediately and release it (power off)
stepper_attach() -- lock motor in position (power on, no stepping)
stepper_actual_rpm() -- return actual rpm
- Log of changes 2016/02
* loading of 16-bits timers by a procedure for proper sequence
* changed global non-static variables which are used only in
one procedure into local variables
* added support for other Fosc values than 48 MHz
* introduced a constant 'STEPPER_INVERTING_BUFFER' to support
positive and negative logic for motor control (depending of buffer IC)
* stepper_attach() uses current entry in stepper array in stead of all zero
* added use of Timer3 for PICs with an 8-bit Timer0 (midrange)
* fixed 'flippering' effect which occurred randomly when switching
from half-step ccw to full-step cw rotation.
* fixed very long first step when accellerating from zero speed.
* added, improved, aligned comments
* renamed several variables/constants/procedures
* enforced Jallib standards, i.c. global names prefixed by 'stepper_'
- Log of changes 2016/03
* Added support for control pins not in the same nibble.
* Stepper motor stops always on full-step position
* Added support for use of 16-bits timer of PWM3 module when
no 16-bits Timer0 or Timer3 is available (12/16f15xx).
* Added function returning actual RPM (pos:cw, neg:ccw)
* Added support for 16-bits timer0 of 16f183xx/188xx
* All timers temporary disabled for (re-)loading.
No dependency found
var word stepper_set_speed = 0
var byte stepper_step_index = 0
var word stepper_steptimer_interval = 0
var word stepper_actual_speed = 0
var byte stepper_steptimer_byte[2] at stepper_steptimer_interval
var bit stepper_to_stop = FALSE
var word stepper_accel_ratio = 0
var bit stepper_decel_active = FALSE
var word stepper_decel_ratio = 0
const word STEPPER_TIMER1_RELOAD = 65535 - word(target_clock / 4 / STEPPER_TIMER1_PRESCALE / 100)
var bit stepper_slope_speedset = FALSE
var bit stepper_accel_active = FALSE
var bit stepper_running = FALSE
stepper_accel(word in sec, word in rpm)
stepper_hold()
stepper_timer1_off()
stepper_attach()
stepper_slope_timer_isr()
stepper_timer_load(word in t)
stepper_steptimer_isr()
stepper_decel(word in sec, word in rpm)
stepper_run(word in rpm)
stepper_timer1_on()
stepper_detach()
stepper_stop()
stepper_control(byte in p)
var word stepper_set_speed = 0
desired speed in 1/10 rpm
var byte stepper_step_index = 0
index in step pattern array
var word stepper_steptimer_interval = 0
holds actual interval for stepper timer
var word stepper_actual_speed = 0
actual speed in 1/10 rpm
var byte stepper_steptimer_byte[2] at stepper_steptimer_interval
THMxH/TMRxL
var bit stepper_to_stop = FALSE
is set during stop slope and reset after stop
var word stepper_accel_ratio = 0
accelleration ratio in rpm/sec
var bit stepper_decel_active = FALSE
is set during decelleration
var word stepper_decel_ratio = 0
decelleration ratio in rpm/sec
const word STEPPER_TIMER1_RELOAD = 65535 - word(target_clock / 4 / STEPPER_TIMER1_PRESCALE / 100)
No documentation found
var bit stepper_slope_speedset = FALSE
TRUE while accellerating/decellerating
var bit stepper_accel_active = FALSE
is set during accelleration
var bit stepper_running = FALSE
is set during run and reset after stop
stepper_accel(word in sec, word in rpm)
Descr: Determine accelleration ratio Input: - sec (word) number of 0.1 seconds rpm (word) number of 0.1 RPM Notes: - The stepper speed will increase with # RPMs per 10 ms For example: with stepper_accel(100,3000) the stepper accellerates with 300 RPM in 10 seconds (30 RPM/sec) or accellerate in 2 seconds from 0 to 60 RPM or from 50 to 110 RPM, etc. Accelleration (and decelleration) settings are only taken into account when stepper speed is changed, e.g. with stepper_run() or stepper_stop() and may be changed any time.
stepper_hold()
Descr: Immediately stop and lock stepper Notes: Stepper locked on full-step boundary. This prevents a (half) step in the wrong direction when switching from half to full-step mode at restart.
stepper_timer1_off()
Deactivate timer1
stepper_attach()
Descr: (re-)power one coil
stepper_slope_timer_isr()
Accelleration/Decelleration Timer interrupt handler ------- When Timer1 active this handler is called every 0.01 seconds When accelerating or decellerating the steptime is adjusted.
stepper_timer_load(word in t)
Load stepper timer Timer is temporarily stopped (PWM3 module has double buffering, no need to stop)
stepper_steptimer_isr()
Step timer interrupt handler ------
stepper_decel(word in sec, word in rpm)
Descr: Determine decelleration ratio Input: - sec (word) number of 0.1 seconds rpm (word) number of 0.1 RPM Notes: The stepper speed will decrease with # RPMs per 10 ms See also the notes with stepper_accel()
stepper_run(word in rpm)
Descr: Set stepper speed to desired RPM Input: data (word) in 0.1 RPM (50 means 5 RPM) Notes: - Power to one (or two with halfstep) coils is applied automatically Depending on current speed and the specified accelleration and decelleration settings the stepper speed may change gradually. Use stepper_detach() to remove power (automatic with rpm zero)
stepper_timer1_on()
Activate timer1 interrupts (100 per second)
stepper_detach()
Descr: Immediately stop stepper and release the stepper (all coils power off)
stepper_stop()
Descr: Stop the stepper gradually according to decelleration ratio Notes: One coil (maybe 2 with half-step) will remain powered, locks the stepper Use stepper_detach() to remove power and unlock the stepper
stepper_control(byte in p)
Control the stepper motor Activate the coils with pattern 'p' (low nibble) Control by nibble or individual pins Take care of inverting steppermotor buffer
stepper_actual_rpm() return sword
Descr: Obtain current stepper speed RPM Returns: The actual RPM in units of 0.1 RPM A negative value means counter-clockwise rotation
stepper_stepticks(word in rpm) return word
Descr: Calculate pulse width for specified RPM Returns: Steptime in timer ticks Notes: - Prescaler value may be changed depending on RPM Timer0: 1:2 for high RPM, 1:256 for low RPM Timer3: 1:1 1:8 PWM3: 1:1 1:8 (PWM3 allows 1:128, but is not needed with LFINTOSC at 31 KHz)
| 16f1618 | 16f1618_steppermotor.jal |
| 18f25k50 | 18f25k50_steppermotor.jal |