Stepper motor control class library

Dependents:   StepperMotor_HelloWorld

Components pages

Components pages are available for bipolar and unipolar motor libraries

A bipolar stepper motor driving pulse generator

A unipolar stepper motor driving pulse generator

Files at this revision

API Documentation at this revision

Comitter:
okano
Date:
Thu Nov 25 11:11:51 2010 +0000
Child:
1:dc6cf8f8bcb7
Commit message:

Changed in this revision

StepperMotor.cpp Show annotated file Show diff for this revision Revisions of this file
StepperMotor.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/StepperMotor.cpp	Thu Nov 25 11:11:51 2010 +0000
@@ -0,0 +1,193 @@
+#include "mbed.h"
+#include "StepperMotor.h"
+
+StepperMotor::StepperMotor(
+    PinName out_A,
+    PinName out_B,
+    PinName out_PWR,
+    PinName position_detect
+) :
+        motor_out( out_A, out_B ),
+        pwr_out( out_PWR ),
+        position_detect_pin( position_detect ),
+        rot_mode( SHORTEST ),
+        sync_mode( ASYNCHRONOUS ),
+        max_pos( 480 ),
+        current_pos( 0 ),
+        pos_offset( 0 ),
+        target_pos( 0 ),
+        max_pps( MAX_PPS ),
+        init_done( false ),
+        pause( false ),
+        power_ctrl( false ) {
+
+    pps     = max_pps;
+    t.attach( this, &StepperMotor::motor_maintain, 1.0 / (float)pps );
+}
+
+int StepperMotor::set_pps( int v ) {
+    int     p;
+
+    p   = pps;
+    pps = v;
+    t.detach();
+    t.attach( this, &StepperMotor::motor_maintain, 1.0 / (float)pps );
+    return ( p );
+}
+
+void StepperMotor::set_max_pps( int v ) {
+    max_pps     = v;
+}
+
+int StepperMotor::find_home_position( PositionDetectPorarity edge ) {
+    RotMode     prev_rot;
+    SyncMode    prev_sync;
+    int         prev_pps;
+    int         prev_det_pin;
+    int         direction;
+
+    prev_pps    = set_pps( max_pps );
+    prev_rot    = rot_mode;
+    prev_sync   = sync_mode;
+    set_sync_mode( SYNCHRONOUS );
+    set_rot_mode( SHORTEST );
+
+    prev_det_pin    = position_detect_pin;
+
+    if ( prev_rot == COUNTER_CLOCKWISE_ONLY )
+        direction   = -1;
+    else
+        direction   = 1;
+
+    if ( prev_rot == NO_WRAPAROUND ) {
+
+        for ( int i = 0; i < (max_pos >> 1); i++ ) {
+            move_steps( -1 );
+            if ( ((edge == RISING_EDGE) && !prev_det_pin && position_detect_pin)
+                    || ((edge == FALLING_EDGE) && prev_det_pin && !position_detect_pin) ) {
+                set_home_position();
+                init_done   = true;
+                break;
+            }
+            prev_det_pin    = position_detect_pin;
+        }
+    }
+
+    for ( int i = 0; i < ((prev_rot == NO_WRAPAROUND) ? (max_pos - 1) : (max_pos + 10)); i++ ) {
+        move_steps( direction );
+        if ( ((edge == RISING_EDGE) && !prev_det_pin && position_detect_pin)
+                || ((edge == FALLING_EDGE) && prev_det_pin && !position_detect_pin) ) {
+            set_home_position();
+            init_done   = true;
+            break;
+        }
+        prev_det_pin    = position_detect_pin;
+    }
+
+    go_position( 0 );
+    set_pps( prev_pps );
+    set_rot_mode( prev_rot );
+    set_sync_mode( prev_sync );
+
+    return ( init_done );
+}
+
+void StepperMotor::set_home_position( void ) {
+    set_pause( true );
+    pos_offset  = current_pos & 0x3;
+    current_pos = 0;
+    set_target_pos( 0 );
+    set_pause( false );
+}
+
+int StepperMotor::go_position( int v ) {
+    set_target_pos( v );
+    return ( current_pos );
+}
+
+void StepperMotor::go_angle( float angle ) {
+    go_position( (int)((angle / 360.0) * (float)max_pos) );
+}
+
+int StepperMotor::move_steps( int s ) {
+    set_target_pos( current_pos + s );
+    return ( current_pos );
+}
+
+void StepperMotor::set_rot_mode( RotMode m ) {
+    rot_mode    = m;
+}
+
+void StepperMotor::set_sync_mode( SyncMode m ) {
+    sync_mode    = m;
+}
+
+int StepperMotor::distance( void ) {
+    return( target_pos - current_pos );
+}
+
+void StepperMotor::set_pause( int sw ) {
+    pause   = sw;
+}
+
+void StepperMotor::set_target_pos( int p ) {
+    target_pos  = (p + max_pos) % max_pos;
+
+    if (sync_mode == SYNCHRONOUS)
+        while ( distance() )
+            wait( 0 );
+}
+
+void StepperMotor::set_power_ctrl( int sw ) {
+    power_ctrl  = sw;
+}
+
+void StepperMotor::set_steps_per_rotate( int steps ) {
+    max_pos = steps;
+}
+
+void StepperMotor::motor_maintain( void ) {
+
+    int     diff;
+    int     direction;
+
+    if ( pause )
+        return;
+
+    diff    = target_pos - current_pos;
+
+    if ( !diff ) {
+        pwr_out = power_ctrl ? 0 : 1;
+        return;
+    }
+
+    pwr_out = 1;
+
+    diff = (diff + max_pos) % max_pos;
+
+    if ( diff > (max_pos >> 1) )
+        diff -= max_pos;
+
+    switch ( rot_mode ) {
+        case NO_WRAPAROUND :
+            direction   = ( (target_pos - current_pos) < 0 ) ? -1 : 1;
+            break;
+        case CLOCKWISE_ONLY :
+            direction   = 1;
+            break;
+        case COUNTER_CLOCKWISE_ONLY :
+            direction   = -1;
+            break;
+        default : // SHORTEST :
+            direction   = ( diff < 0 ) ? -1 : 1;
+            break;
+    }
+
+
+    current_pos = ((current_pos + max_pos) + direction) % max_pos;
+
+//    printf( "pos=%d  ofst=%d  puls=%d\r\n", current_pos, pos_offset, (current_pos + pos_offset) );
+    motor_out   = pat[ (current_pos + pos_offset) & 0x3 ];
+};
+
+const unsigned char StepperMotor::pat[ 4 ]  = { 0, 1, 3, 2 };
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/StepperMotor.h	Thu Nov 25 11:11:51 2010 +0000
@@ -0,0 +1,228 @@
+/** Stepper Motor control library
+ *  
+ *  Copyright: 2010 Tedd OKANO, Tsukimidai Communications Syndicate - Crawl Design
+ *  The library that controls stepper motor via motor driver chip: TA7774
+ *  The TA7774 is a driver for a bipolar stepper motor. 
+ *  With this library, mbed will generate 2 phase pulses to operate the motor. 
+ */
+ 
+#ifndef    MBED_STEPPERMOTOR
+#define    MBED_STEPPERMOTOR
+
+#include "mbed.h"
+
+#define MAX_PPS   50   //  pulse per second
+
+/** Stepper Motor control class
+ *
+ *  Example:
+ *  @code
+ *  #include "mbed.h"
+ *  #include "StepperMotor.h"
+ *
+ *  StepperMotor m( p21, p22, p23, p24 );
+ *
+ *  int main() {
+ *      m.set_sync_mode( StepperMotor::SYNCHRONOUS );
+ *      m.set_power_ctrl( true );
+ *
+ *      while( 1 ) {
+ *          m.go_angle( 120 );
+ *          wait( 0.5 );
+ *     
+ *          m.go_angle( 240 );
+ *          wait( 0.5 );
+ *   
+ *          m.go_angle( 0 );
+ *          wait( 0.5 ); 
+ *
+ *          m.go_angle( 240 );
+ *          wait( 0.5 );
+ *     
+ *          m.go_angle( 120 );
+ *          wait( 0.5 );
+ *   
+ *          m.go_angle( 0 );
+ *          wait( 0.5 ); 
+ *      }
+ *  }
+ *  @endcode
+ */
+
+class StepperMotor {
+public:
+
+    /** Constants for motor rotate mode */     
+    typedef enum  {
+        SHORTEST,                   /**< turn by shortest direction      */
+        NO_WRAPAROUND,              /**< do not accross home position    */
+        CLOCKWISE_ONLY,             /**< one-way: clockwise turn         */
+        COUNTER_CLOCKWISE_ONLY      /**< one-way: counter clockwise turn */
+    } RotMode;
+
+    /** Constants for syncronization mode */     
+    typedef enum  {
+        ASYNCHRONOUS,               /**< program does wait motor turn completion     */
+        SYNCHRONOUS                 /**< program doesn't wait motor turn completion  */
+    } SyncMode;
+
+    /** Constants for position detection edge polarity */     
+    typedef enum  {
+        RISING_EDGE,                /**< position detection done by rising  edge */
+        FALLING_EDGE                /**< position detection done by falling edge */
+    } PositionDetectPorarity;
+
+    /** Create a stepper motor object connected to specified DigitalOut pins and a DigitalIn pin
+     *
+     *  @param out_A DigitalOut pin for motor pulse signal-A
+     *  @param out_B DigitalOut pin for motor pulse signal-B
+     *  @param out_PWR DigitalOut pin for TA7774's power control (option)
+     *  @param position_detect DigitalIn pin for home position detection (option)
+     */
+    StepperMotor(
+        PinName out_A   = p21,
+        PinName out_B   = p22,
+        PinName out_PWR = p23,
+        PinName position_detect = p24
+    ) ;
+
+    /** Set the pulse width (i.e. motor turning speed)
+     *
+     *  @param v pulse per second : default is 100. lower number makes the turn slower
+     */
+    int set_pps( int v );
+
+    /** Set maximum PPS (= minimum pulse width) which will be used in finding home position
+     *
+     *  @param v maximum pulse per second : default is 100. lower number makes the turn slower
+     */
+    void set_max_pps( int v );
+
+    /** Find home position: rotate the motor until the detection edge comes.
+     *
+     *  Turns the motor until the home position detected. 
+     *  The "home position" is a reference point for the step and angle. It will be step=0 and angle=0. 
+     *  The detection signal edge can be defined by an argument. 
+     *  It follows the rotate mode. 
+     *  When the edge is detected, the motor will be stopped and it will be the new home position. 
+     *  If no detection signal detected, no home position update done. 
+     * 
+     *  @param edge defines detection edge rise or fall
+     */
+    int find_home_position( PositionDetectPorarity edge );
+    
+    /** Update home position
+     *
+     *  Set the home position as current motor position.
+     */     
+    void set_home_position( void );
+    
+    /** Turn the motor to defined position (by steps from home position)
+     *
+     *  Make motor move to absolute position
+     *
+     *  @param v the position defined by steps from home position
+     */     
+    int go_position( int v );
+
+    /** Turn the motor to defined position (by angle (0.0..360 degree) from home position)
+     *
+     *  Make motor move to absolute position
+     *
+     *  @param v the position defined by steps from home position
+     */     
+    void go_angle( float angle );
+
+    /** Turn the motor to defined position (by steps from current position)
+     *
+     *  Make motor move to defined position
+     *
+     *  @param v the position defined by steps from home position
+     */     
+    int move_steps( int s );
+    
+    /** Interface for motor rotate mode setting
+     *
+     *  Example:
+     *  @code
+     *  StepperMotor    m( p21, p22, p23, p24 );
+     *  int main() {
+     *      m.set_rot_mode( StepperMotor::NO_WRAPAROUND );
+     *      ...
+     *  @endcode
+     *
+     *  @param m motor rotate mode : SHORTEST, NO_WRAPAROUND, CLOCKWISE_ONLY or COUNTER_CLOCKWISE_ONLY
+     */
+    void set_rot_mode( RotMode m );
+
+    /** Interface for syncronization mode setting
+     *
+     *  Example:
+     *  @code
+     *  StepperMotor    m( p21, p22, p23, p24 );
+     *  int main() {
+     *      m.set_sync_mode( StepperMotor::NO_WRAPAROUND );
+     *      ...
+     *  @endcode
+     *
+     *  @param m motor rotate mode : ASYNCHRONOUS or SYNCHRONOUS
+     */
+    void set_sync_mode( SyncMode m );
+
+    /** Check remaining distance that motor need to move
+     *
+     *  software can check if the motor action completed in asynchronous mode
+     *  
+     *  @return remaining steps that motor need to go
+     */
+    int distance( void );
+
+    /** Pause/Resume the motor action
+     *
+     *  @param sw use "true" for pause, "false" for resume
+     */
+    void set_pause( int sw );
+
+    /** Auto power control enable
+     *
+     *  If the auto power control is enabled, the motor power will be turned-off when it stays same place
+     *  
+     *  @param sw use "true" for pause, "false" for resume
+     */
+    void set_power_ctrl( int sw );
+
+    /** Setting for steps/rotate
+     *
+     *  This parameter is required if program want to use the "go_angle()" interface. 
+     *  The angle will be calculated from this parameter.
+     *  
+     *  @param steps per rotate
+     */
+    void set_steps_per_rotate( int steps );
+    
+private:
+
+    Ticker      t;
+    BusOut      motor_out;
+    DigitalOut  pwr_out;
+    DigitalIn   position_detect_pin;
+
+    static const unsigned char  pat[ 4 ];  //  2 phase pulse pattern for motor control
+    RotMode     rot_mode;
+    SyncMode    sync_mode;
+    int         max_pos;
+    int         current_pos;
+    int         pos_offset;
+    int         target_pos;
+    int         pps;
+    int         max_pps;
+    int         init_done;
+    int         pause;
+    int         power_ctrl;
+
+    void set_target_pos( int p );  //  target position setting interface
+    void motor_maintain( void );   //  this function is called periodically by Ticker
+};
+
+
+#endif
\ No newline at end of file