My Version of the Crealab MotorLib.

Fork of MotorLib by CreaLab

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers CreaMot.h Source File

CreaMot.h

Go to the documentation of this file.
00001 /**
00002  * @file CreaMot.h
00003  * \brief File contains Crealab CreaMot Library.
00004  
00005  * CreaMot.h contains the class CreaMot, and related enums and structs.
00006  * Includes only "mbed.h".
00007  *
00008  * MotStatus structure is dissolved into the CreaMot Class
00009  *
00010  * Rotation directions are now consistently called Clockwise, and Counterclockwise (CCW), 
00011  * instead of mix them with Left and Right. 
00012  * Doxygens Tags are preceeded by either a backslash @\ or by an at symbol @@.
00013 
00014  * @author Tarek Lule, Francois Druilhe, et al.
00015  * @date 01. Nov. 2018.
00016  * @see https://os.mbed.com/users/sepp_nepp/code/MotorLib/  */
00017  
00018  // -------------------- CreaMot ---------------------------
00019  
00020 #ifndef CREAMOT_H
00021 #define CREAMOT_H
00022 
00023 #include "mbed.h"
00024 
00025 #define MOTOR_STEP_TIME_MIN_US 700      /**< Shortest Time between two CreaMot steps = 0.7ms, was MOTOR_STEP_TIME_MIN*/
00026 #define MOTOR_STEP_TIME_DEFAULT_US 5000 /**< Default Time between two CreaMot steps = 5ms, was MOTOR_STEP_TIME_DEFAULT*/
00027 #define MOTOR_STEPS_FOR_A_TURN 4096     /**< Default number of CreaMot steps to complete a turn = 4096 steps  */
00028 #define CLOCKWISE true                  /**< Constant for Clockwise direction */
00029 #define COUNTERCLOCKWISE false          /**< Constant for Counter-Clockwise direction */
00030 #define MAX_SPEED_CM_SEC 30.0f    /**< Clamp maximum advancement speed = 30cm/sec, was MAX_SPEED */
00031 #define MIN_SPEED_CM_SEC 0.001f   /**< Clamp minimum advancement speed = 10um/sec */
00032 #define PI 3.141592f    /** PI needed to calcuate from angle to distances */
00033 #define PI_OVER_180 (PI/180.0f)  /** needed to translate from angle to circumference */
00034 
00035 /** \enum motStates 
00036 * \brief Possible States of CreaMot state machine
00037 * 
00038 * Motor_CALIB is deprecated, was removed from the enum structure */
00039 typedef enum {
00040     Motor_OFF = 0,  /**< All phase currents is off, replaces Motor_STOP. */  
00041     Motor_ZERO,     /**< CreaMot at phase position 0 and ON, only reached by call of Zero() procedure. */  
00042     Motor_ON,       /**< Phases are engaged, but CreaMot state machine stopped, replaces Motor_PAUSE. */  
00043     Motor_RUN       /**< Phases are engaged, and CreaMot state machine runs*/  
00044 } motStates;
00045 
00046 /** \enum motCmands 
00047 * \brief Commands that are handled by the CreaMot state machine
00048 *
00049 * These Commands are issued asynchonously by calling CreaMot class methods.
00050 * They are executed in the state machine called by the ticker handler.
00051 *
00052 * OFF and STOP commands do not go through the state machine.
00053 *
00054 * MOTOR_restart is equivalent to and replaced by MOTOR_run.
00055 */
00056 typedef enum {
00057     MOTOR_nop = 0,  /**< No active command to execute. */
00058     MOTOR_run,      /**< Run CreaMot until Nsteps are achieved. */
00059     MOTOR_stop,     /**< Stop immediately all activity, turn off CreaMot. */
00060     MOTOR_pause     /**< CreaMot is temporarily paused from the state run. */
00061 } motCmands;
00062 
00063 /** ATTENTION UNDER CONSTRUCTION, DO NOT YET USE.
00064 *
00065 * Class of a Four Phase Stepper CreaMot.
00066 *
00067 * Perform Runs for number of steps, or given amount angle, but also Low-Level steps. 
00068 *
00069 * High-Level Run functions have 'Run' in their name.
00070 * They rely on tickers and return immediately after ticker is set up. 
00071 * A state-machine evaluates the one ongoing command versus the CreaMot state at every tick.
00072 * When End of Run is detected tickers stop, and CreaMot turns off. 
00073 *
00074 * To define the speed of the CreaMot set the variable StepTime_us, either by
00075 *    a) Using the createor CreaMot(...., uint32_t AStepTime_us);
00076 *    b) Calling function setStepTime_us(uint32_t AStepTime_us); any time
00077 *    c) or leave it to the default value MOTOR_STEP_TIME_DEFAULT_US = 5000
00078 *
00079 * To be able to run the CreaMot for a given angle, set the number of steps per full turn
00080 *    with the function "setStepsFullTurn"
00081 *    That value defaults to MOTOR_STEPS_FOR_A_TURN = 4096
00082 *
00083 * To be able to run the CreaMot for a given perimeter distance in centimeters, 
00084 *    set the wheel diameter with the function setDiamCM( float Adiam_cm); 
00085 *
00086 * Callbacks can be attached to react to 'end of run' events. 
00087 *
00088 *Attention: the attached Callback is called within a Ticker Callback.
00089 *    Your code you execute in the Callback should be short, must not use waits, or any long routines.
00090 *    Do not call any CreaMot run commands in the callback, as it creates conflict situations.
00091 *    Long Callback code may impair this and any other Ticker functions that run in your application.
00092 *
00093 *Low-Level functions directly talk to the hardware without ticker. 
00094 *   Use of Low-Level functions while tickers still run may lead to unexpected behavior. 
00095 *
00096 * NB: all times are uint32_t, step numbers are int32_t
00097 */
00098 class CreaMot
00099 {
00100 public:
00101     /** CreaMot Class Creator
00102     *
00103     * Creates the class, initiallizes all fields, creates Phase Pins.  
00104     * Time between two steps defaults here to MOTOR_STEP_TIME_DEFAULT_US = 5000usec.
00105     * Pin names are used to create digital outputs: Pin0 = new DigitalOut(_MPh0)
00106     *
00107     @code
00108        PinName MotPhases[] = {PB_1, PB_15, PB_14, PB_13};
00109        CreaMot MotorName(MotPhases); // Call this creator for example like this:  
00110     @endcode 
00111     * 
00112     * @param _MPh Array of Names of the 4 Digital Pins of type PinNames 
00113     */
00114     CreaMot(PinName _MPh[4] );
00115     
00116     /** CreaMot Class Creator
00117     *
00118     * Creates the class, initiallizes all fields, creates Phase Pins.  
00119     * Time between two steps defaults here to MOTOR_STEP_TIME_DEFAULT_US=5000usec.
00120     * Pin names are used to create digital outputs: Pin0 = new DigitalOut(_MPh0)
00121     *
00122     @code
00123       // Call this creator for example like this:
00124        CreaMot MotorName(PB_1, PB_15, PB_14, PB_13);
00125     @endcode 
00126     * 
00127     * @param <_MPh0, _MPh1, _MPh2, _MPh3> List of Names of the 4 Digital Pins of type PinNames    
00128     */
00129     CreaMot(PinName _MPh0, PinName _MPh1, PinName _MPh2, PinName _MPh3);
00130     
00131     /** CreaMot Class Creator
00132     *
00133     * Creates the class, initiallizes all fields, creates Phase Pins.  
00134     * Time between two steps is passed as parameter.
00135     * Pin names are used to create digital outputs: Pin0 = new DigitalOut(_MPh0)
00136     *
00137     @code
00138       // Call this creator for example like this:
00139        CreaMot MotorName(PB_1, PB_15, PB_14, PB_13, 6000);
00140     @endcode 
00141     *
00142     * @param <_MPh0, _MPh1, _MPh2, _MPh3> List of Names of the 4 Digital Pins of type PinNames    
00143     * @param <AStepTime_us> the time in usec between two steps, thats used initially.   
00144     */
00145     CreaMot(PinName _MPh0, PinName _MPh1, PinName _MPh2, PinName _MPh3, uint32_t AStepTime_us);
00146 
00147 private:
00148     // deprecated: void initialization(PinName _MPh0, PinName _MPh1, PinName _MPh2, PinName _MPh3, uint32_t AStepTime_us);
00149     void initialization(PinName _MPh[4], uint32_t AStepTime_us);
00150 
00151 public:
00152     /** Attach a basic Callback function.
00153     *
00154     * A callback is called when the current Command reaches it's requested end.
00155     * Not called when the CreaMot is stopped by a call of Stop Function, or any other events.
00156     * For use see precautions at Class description above. 
00157     * Formerly called setMotorCallback()
00158     *
00159     @code
00160     // Simple callback function, state variable endMove can be polled elsewhere
00161     void CallBackFunction()
00162     { endMove=true; }
00163 
00164     // main routine
00165     void main()
00166     {   ...
00167         // Attach callback function:
00168         MotorInstance->callbackSet(CallBackFunction);
00169         ...
00170         while (true) {
00171             ....
00172         if (endMove) // poll the endMove flag
00173                { ... } // react to Movement End
00174                
00175             ....
00176         }
00177     }
00178     @endcode
00179     * @param <*CBfunction> Callback function, must not be member of a class.
00180 
00181     */
00182     void callbackSet(void (*CBfunction)(void)) {_callback = CBfunction;};
00183 
00184 
00185     /** Attach a Callback function, member of a class.
00186     * Only called when a Run Command reaches it's requested end.
00187     * Not called when the CreaMot is stopped by a call of Stop Function, or any other events.
00188     * For use see precautions at Class description above. 
00189     * @param <*object> Class pointer which possesses callback member.
00190     * @param <*CBmember> Pointer to callback function, member of Class.
00191     * 
00192     @code
00193     // Class Creator:
00194      AClass::AClass(Class Creation Parameters)
00195     {   ...
00196         // Attach callback function:
00197         MotorInstance->setMotorCallback(this, &AClass::CallBackMemberFunction);
00198         ...  
00199     }
00200 
00201     // Simple callback function, state variable endMove can be polled by main thread
00202     void AClass::CallBackMemberFunction()
00203     {  endMove=true;  }
00204     @endcode
00205     */
00206     template<typename T>
00207     void callbackSet(T *object, void (T::*CBmember)(void)) {
00208         _callback = callback(object,CBmember);
00209     }
00210 
00211     /** Remove the Callback function that may have been attached previously. */
00212     void callbackRemove() { _callback = NULL; };
00213 
00214 public: 
00215     // *********************************************************************
00216     //  all following functions use wheel diameter to achieve cm distance
00217     // *********************************************************************
00218 
00219     /** High Level: Run CreaMot for a given number of centimeters.
00220     *
00221     * Runs CreaMot for a given wheel circumference in cimeters in given direction. 
00222     * You must setup the perimeter and diameter with setDiam(Adiam_cm) in advance, otherwise no reaction.
00223     * Call Pause() or Stop() to pause or end the CreaMot run prematurely.
00224     * While run: Uses ticker; State: first Motor_ON then Motor_RUN; cmd=MOTOR_run.
00225     * At end: calls attached Callback, stops ticker; State: Motor_OFF; cmd=MOTOR_stop then MOTOR_nop.
00226     * @param[in] <AClockWise> Given Direction, true for CLOCKWISE, false for COUNTERCLOCKWISE.
00227     * @param[in] <Dist_cm> Circumference to rotate for, in cm, Dist_cm<0 are run in opposite direction.
00228     */
00229     void RunDist_cm  (bool AClockWise, float Dist_cm);
00230    
00231     /** High Level: Run CreaMot for a given number of centimeters in default direction.
00232     * Same as RunDist_cm(AClockWise,Dist_cm) but uses Default diretion.*/
00233     void RunDist_cm  (float Dist_cm);
00234     
00235     /** High Level: Run CreaMot for a turn angle around a turn_radius_cm  in default direction
00236     *
00237     * Runs CreaMot for a given turn angle in degrees with a given turn radius.
00238     *   in default direction. Negative angles are rotated in opposite direction. 
00239     *   turn-radius must be positive. Zero or negative radius are not executed. 
00240     * You must setup the perimeter and diameter with setDiam(Adiam_cm) in advance, otherwise no reaction.
00241     * Call Pause() or Stop() to pause or end the CreaMot run prematurely.
00242     * While run: Uses ticker; State: first Motor_ON then Motor_RUN; cmd=MOTOR_run.
00243     * At end: calls attached Callback, stops ticker; State: Motor_OFF; cmd=MOTOR_stop then MOTOR_nop.
00244     * @param[in] <turn_angle_deg> Given turn angle in degrees that should be run
00245     * @param[in] <turn_radius_cm> Given Trun radius that should be run */
00246     void RunTurnAngle(float turn_angle_deg, float turn_radius_cm); 
00247 
00248     /** Additional geometric information: set the wheel diameter, also sets perimeter and degrees per cm.*/
00249     void setDiamCM( float Adiam_cm); 
00250 
00251     /** Set CreaMot speed in centimeter/sec, based on perimeter in cm */
00252     void setSpeed_cm_sec(float speed_cm_sec);
00253 
00254     /** Default rotation direction that serves as local storage, but not as actual direction */
00255     bool defaultDirection;
00256     
00257     /** State value that is used and managed by the class owner.
00258     * Used for example by Creabot library to indicate if this is the left or right CreaMot. */
00259     char StateValue;
00260 private:
00261 
00262     /** Additional geometric information: wheel diameter in centimeter */
00263     float diam_cm;
00264 
00265     /** Additional geometric information: wheel perimeter in centimeter */
00266     float perim_cm;
00267 
00268     /** Additional geometric information: rotation angle in degrees per cm circumference */
00269     float degree_per_cm;
00270 
00271 public: 
00272     // *****************************************************************
00273     //  following functions are agnostic of wheel dimensions in centimeters
00274     // *****************************************************************
00275 
00276    /** High Level: Run CreaMot for a given angle.
00277     *
00278     * Runs CreaMot for a given angle in given direction. 
00279     * Angles<0 are run in opposite direction.
00280     * Call Pause() or Stop() to pause or end the CreaMot run prematurely.
00281     * While running: Uses ticker; 
00282     * State: first Motor_ON then Motor_RUN; cmd=MOTOR_run.
00283     * At end: calls attached Callback, stops ticker; State: Motor_OFF; cmd=MOTOR_stop then MOTOR_nop.
00284     * @param[in] <AClockWise> Given Direction, true for CLOCKWISE, false for COUNTERCLOCKWISE.
00285     * @param[in] <angle_deg> Angle>0 to rotate for, in degrees, Angles<0 are run in opposite direction.     
00286     */
00287    void RunDegrees  (bool AClockWise, float angle_deg);
00288    
00289    /** High Level: Run CreaMot for a given angle in default direction
00290    * for details see RunDegrees  (bool AClockWise, float angle_deg);
00291    */
00292    void RunDegrees  (float angle_deg);
00293 
00294     /** High Level: Run CreaMot for a number of Steps.
00295     * 
00296     * During Run: Uses ticker; State: first Motor_ON then Motor_RUN; cmd=MOTOR_run.
00297     * Call Pause() or Stop() to pause or end the run prematurely.
00298     * At the end: calls the Callback, stops ticker; State: Motor_OFF.
00299     * @param[in] <AClockWise> Given Direction, true for CLOCKWISE, false for COUNTERCLOCKWISE.
00300     * @param[in] <Nsteps> Number of steps to run for; Nsteps<0 are run in opposite direction!    
00301     */
00302    void RunSteps (bool AClockWise, int32_t Nsteps);
00303 
00304     /** High Level: Run CreaMot "unlimited"
00305     *
00306     * Runs CreaMot with out limit in given direction, precisely runs 4Billion Steps.
00307     * While run: Uses ticker; State: first Motor_ON then Motor_RUN; cmd=MOTOR_run.
00308     * Call Pause() or Stop() to pause or end the CreaMot run.
00309     * @param[in] <AClockWise> Given Direction, true for CLOCKWISE, false for COUNTERCLOCKWISE.
00310     */
00311     void RunInfinite (bool AClockWise);
00312 
00313     /** High Level: Pause a CreaMot Run.
00314      * Put CreaMot into Pause state, Run is suspended, but only effective if Status.cmd=MOTOR_run.
00315      * Retains the number of steps that remain to be run if restarting run.
00316      * While paused: still uses ticker; State: Motor_RUN; cmd=MOTOR_pause.
00317      * Use RestartRun(); to continue. */
00318     void PauseRun();
00319 
00320     /** High Level: Restart a Paused Run.
00321      * Restart the Run that was launched before calling PuaseRun. 
00322      * Only effective if Status.cmd=MOTOR_pause, otherwise no re/action.
00323      * Status afterwards is same as afterRun commands. */
00324     void RestartRun();
00325 
00326     /** High Level: End any Run.
00327     * Force stop of any ongoing run, but does not call the Callback function.
00328     * Only effective if Status.cmd=MOTOR_run, otherwise no re/action.
00329     * Emits first cmd=MOTOR_stop then cmd=MOTOR_nop.
00330     * Aftewards: ticker is detached; State: Motor_OFF; */
00331     void StopRun();
00332     
00333 public: // All the ticker timing related parameters
00334 
00335     /** MidLevel: Get number of Steps per Full turn
00336     
00337     * Defaults to MOTOR_STEPS_FOR_A_TURN = 4096.
00338     * Used by RunDegrees() to translate from angle in degrees to number of steps.
00339     * Old Name was: getCalibration, but that was not a good explicit name. 
00340     * @return  uint32_t The number of motor steps needed for a full turn. */
00341     uint32_t getStepsFullTurn();
00342 
00343     /** MidLevel: Set number of Steps per Full turn.
00344     
00345     * Defaults is MOTOR_STEPS_FOR_A_TURN = 4096.
00346     * Used by RunDegrees() to translate from degrees to number of steps.
00347     * Old Name was: setCalibration, but not good explicit name.
00348     * @param <StepsFullTurn> Number of steps needed to complete a full CreaMot turn
00349     */
00350     void setStepsFullTurn(uint32_t StepsFullTurn);
00351 
00352     /** Mid Level: Get the CreaMot step time. 
00353     
00354     * Step time is time between two CreaMot steps, and is given in microseconds
00355     * and is passed to the ticker as delay time. 
00356     * So the larger the value the slower the CreaMot speed.  
00357     * Defaults to MOTOR_STEP_TIME_DEFAULT_US = 5000.
00358     * @return  uint32_t The structure of CreaMot status registers.
00359     */
00360     uint32_t getStepTime_us();
00361     
00362     /** Set the time in microseconds between two CreaMot steps.
00363     *  Defaults to MOTOR_STEP_TIME_DEFAULT_US = 5000usec.
00364     *  Filters values below Minimum Value = 700.
00365     *  Passed to the ticker as delay time.
00366     *  Can be called while ticker is running, and takes immediate effect. 
00367     *  Was previously called setStepTime(), but was not clear which units.  
00368     * @param <AStepTime_us> the time in microseconds between two CreaMot steps
00369     */
00370     void setStepTime_us(uint32_t AStepTime_us);
00371 
00372     /** Set the time in seconds to get one full turn, rotation of 360°.
00373     * was previously called setSpeed().  
00374     * @param <Seconds_Per_Turn> Period of Rotation, e.g. if =20.0 then CreaMot will do 360° in 20 seconds.
00375     */
00376     void setRotationPeriodSec(float Seconds_Per_Turn) ;
00377 
00378 
00379     motStates   CurrState;  /**< General state that the CreaMot state machine is in.*/
00380     motCmands   CurrCmd;    /**< Command asked to be executed currently by the state machine.*/
00381 
00382 private:
00383     void setCommand(motCmands aCmd, bool aClockWise, int32_t  aNSteps); 
00384                         /**< Helper; set Command, Direction and NSteps in one call. */
00385 
00386     // all the  Ticker and Timing procedures, used to run the CreaMot for a duration
00387     void StartTick();
00388     void ProcessMotorStateMachine();
00389     // The call back function pointer that is called when the Processor
00390     // State Machine reaches its end.
00391     Callback<void()> _callback;
00392     void StopTick();
00393     timestamp_t StepTime_us;    // Time in µs for one CreaMot step
00394     Ticker      MotorSysTick;   // System Timer for CreaMot
00395     uint32_t    Steps_FullTurn; // Number of step for a complete turn
00396     bool        ClockWise;  /**< Direction that the CreaMot is asked to run. True if Clockwise */
00397     int32_t     NStepsToDo; /**< Number of steps remain for the CreaMot to run. 
00398                                 NSteps=0: all steps finished; NSteps<0: indicates to run "forever" */
00399     bool        TickIsAttached; /**< Indicates if Ticker is attached.
00400                             Ticker is automatically attached while CreaMot runs, or paused; 
00401                             detaches when finished a run, or stopped.  */
00402     
00403 public: // all the low level direct CreaMot HW access, States are immediately reached    
00404 
00405     /** Low Level: Run one full turn clockwise then anticlockwise. 
00406     * After: State: Motor_OFF.
00407     * Blocking function, returns back only after end of full movement. 
00408     */
00409     void MotorTest();
00410 
00411     /** Low Level: turn off all CreaMot Phases
00412     * No more current flows, reduces holding force.
00413     * After: State: Motor_OFF.
00414     * StepPhases memorizes the last used phase.
00415     * Equivalent what previously the function "void Stop();" did .  */
00416     void MotorOFF();
00417     
00418     /** Low Level: turn on the CreaMot Phases in the last used phase.
00419     * The last used phase is held in StepPhases.
00420     * After: State: Motor_ON, or Motor_ZERO if StepPhases==0
00421     * Equivalent to what previously the function "void Start();" did.  */
00422     void MotorON();
00423     
00424     /** Low Level: Advance CreaMot one step, rotates in direction of variable AClockWise. */
00425     void StepOnce();
00426     
00427     /** Low Level: Advance CreaMot one step, rotates CounterClockwise. */
00428     void StepCCW();
00429     
00430     /** Low Level: Advance CreaMot one step, rotates Clockwise. */
00431     void StepClkW();
00432     
00433     /** Low Level: turn on the CreaMot Phases in Zero Position. 
00434      * After: State: Motor_ZERO, StepPhases==0
00435      */
00436     void MotorZero();
00437     
00438 private:
00439 
00440     /** Low Level: Engage CreaMot Phases according to MotorIndex. */
00441     void SetPhases(); 
00442 
00443     DigitalOut *MPh[4];       // Digital outputs, one per phase
00444     int        StepPhase;     // CreaMot Phase Variable, counts up and down with every step
00445 };
00446 
00447 #endif