steppermotor

Single stepper motor library (unipolar or bipolar)

Author Richard Zengerink, Copyright © 2009..2010, all rights reserved.
Adapted-by Rob Hamerling (2016)
Compiler 2.4q5

Description

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


Notes

- 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.


Dependencies

No dependency found



Summary

Global variables/contants

Procedures

Functions


API details

Global variables/contants

Procedures

  • 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)
    Thus with it will 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 
    
    

Functions

  • 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)
    
    


Related samples

Here are the list of samples which use this library:

16f161816f1618_steppermotor.jal
18f25k5018f25k50_steppermotor.jal