Tarek Lule / MotorLib

Fork of MotorLib by CreaLab

Revision:
16:d818c1a4dafb
Parent:
15:88fecbdd191c
Child:
17:86e5af6f7628
--- a/motor.h	Thu Nov 01 15:29:33 2018 +0000
+++ b/motor.h	Wed Nov 28 09:44:34 2018 +0000
@@ -1,40 +1,44 @@
 /**
  * @file motor.h
- * @brief File containing Crealab Motor Library.
+ * @brief File contains Crealab Motor Library.
  
  * motor.h contains the class Motor, and related enums and structs.
- * Includes only "mbed.h"
- * Doxygens Tags are words preceeded by either a backslash @\ or by an at symbol @@.
+ * Includes only "mbed.h".
+ 
+ * Rotation directions are now consistently called Clockwise, and Counterclockwise (CCW), 
+ * instead of mix them with Left and Right. 
+ * Doxygens Tags are preceeded by either a backslash @\ or by an at symbol @@.
 
  * @author Tarek Lule, Francois Druilhe, et al.
  * @date 01. Nov. 2018.
  * @see https://os.mbed.com/users/sepp_nepp/code/MotorLib/  */
  
  // -------------------- Motor ---------------------------
+ 
 #ifndef MOTOR_H
 #define MOTOR_H
 
 #include "mbed.h"
 
-#define MOTOR_STEP_TIME_MIN_US 700      // was MOTOR_STEP_TIME_MIN
-#define MOTOR_STEP_TIME_DEFAULT_US 5000 // was MOTOR_STEP_TIME_DEFAULT
-#define MOTOR_STEPS_FOR_A_TURN 4096
+#define MOTOR_STEP_TIME_MIN_US 700      /**< Shortest Time between two motor steps = 0.7ms, was MOTOR_STEP_TIME_MIN*/
+#define MOTOR_STEP_TIME_DEFAULT_US 5000 /**< Default Time between two motor steps = 5ms, was MOTOR_STEP_TIME_DEFAULT*/
+#define MOTOR_STEPS_FOR_A_TURN 4096     /**< Default number of motor steps to complete a turn = 4096 steps  */
 
 /** \enum motorStates 
-* \brief Motor States of motor state machine
+* \brief Motor States of Motor state machine
 * 
 * Motor_CALIB is deprecated, was removed from the enum structure */
 typedef enum {
     Motor_OFF = 0,  /**< All phase currents is off, replaces Motor_STOP. */  
     Motor_ZERO,     /**< Motor at phase position 0 and ON, only reached by call of Zero() command. */  
-    Motor_ON,       /**< Phases are engaged, but motor is not running, replaces Motor_PAUSE. */  
-    Motor_RUN       /**< Phases are engaged, and motor state machine is running*/  
+    Motor_ON,       /**< Phases are engaged, but Motor does not run, replaces Motor_PAUSE. */  
+    Motor_RUN       /**< Phases are engaged, and Motor state machine runs*/  
 } motorStates;
 
 /** \enum motorCommands 
 * \brief Commands that are handled by the Motor state machine
-* 
-* These Commands are issued asynchonously by calling Motor class methods.
+
+* These Commands are issued asynchonously by call Motor class methods.
 * They are executed in the state machine called by the ticker handler.
 
 * OFF and STOP commands do not go through the state machine.
@@ -57,174 +61,254 @@
 } motorDir;
 
 /** \struct MotStatus
-* \brief Structure of Motor Status registers
-* Is used by Motor Class to hold all Status 'Registers'. 
+* \brief Structure of Motor Status registers.
+
+* Used by Motor Class to hold all Status 'Registers'. 
 * The structure can be requested to get by Motor.getStatus(). */
 typedef struct {
     motorStates  state; /**< General state that the moter state machine is in.*/
     motorCommands cmd;  /**< Command asked to be executed currently by the state machine.*/
-    motorDir      dir;  /**< Direction that the motor is asked to run.*/
-    int32_t       NSteps;/**< Number of steps left for the motor to run. 
+    motorDir      dir;  /**< Direction that the Motor is asked to run.*/
+    int32_t       NSteps;/**< Number of steps remain for the Motor to run. 
     NSteps=0: all steps finsihed; NSteps<0: indicates to run "forever" */
     bool         TickIsAttached; /**< Indicates if Ticker is attached.
-    Ticker is automatically attached while Motor is running, or paused; 
+    Ticker is automatically attached while Motor runs, or paused; 
     detaches when finished a run, or stopped.  */
-    /** Helper to set Command, Direction and NSteps in one call. */
-    void set(motorCommands aCmd, motorDir aDir, int32_t  aNSteps);
+    void set(motorCommands aCmd, motorDir aDir, int32_t  aNSteps); /**< Helper; set Command, Direction and NSteps in one call. */
 } MotStatus;
 
-/** ATTENTION UNDER CONSTRUCTION, DO NOT YET USE
-* Class of a Four Phase Stepper Motor
-*Handles single steps but also running a number of steps, or given amount angle.
+/** ATTENTION UNDER CONSTRUCTION, DO NOT YET USE.
+*
+*Class of a Four Phase Stepper Motor.
 *
-*Higher level function rely on ticker and a state-machine evaluating new incoming commands versus the motor state at every tick.
+*Perform Runs for number of steps, or given amount angle, but also Low-Level steps. 
+*
+*High-Level Run functions have 'Run' in their name.
+*They rely on tickers and return immediately after ticker is set up. 
+*A state-machine evaluates commands versus the Motor state at every tick.
+*When End of Run is detected tickers stop, and Motor turns off. 
 *
 *Callbacks can be attached to react to 'end of run' events. 
+*Attention: the attached Callback is called within a Ticker Callback.
+*    Your code you execute in the Callback should be short, must not use waits, or any long routines.
+*    Do not call any Motor run commands in the callback, as it creates conflict situations.
+*    Long Callback code may impair this and any other Ticker functions that run in your application.
 *
-*Lower level functions directly talk to the hardware without ticker.
+*Low-Level functions directly talk to the hardware without ticker. 
+*Use of Low-Level functions while tickers still run may lead to unexpected behavior. 
 */
 class Motor
 {
 public:
-    /** Class Creator. 
-    * Receives the names of the 4 Digital Pins in an array of PinNames.
-    * the time in between two steps defaults here to MOTOR_STEP_TIME_DEFAULT_US=5000usec.
-    * Uses Ticker callback to handle step times.
-    * Call this creator for example like this:
+    /** Motor Class Creator
+    *
+    * Creates the class, initiallizes all fields, creates Phase Pins.  
+    * Time between two steps defaults here to MOTOR_STEP_TIME_DEFAULT_US=5000usec.
+    *
     * @code
     *    PinName MotPhases[] = {PB_1, PB_15, PB_14, PB_13};
-    *    Motor MotorName(MotPhases);
-    * @endcode */
+    *    Motor MotorName(MotPhases); // Call this creator for example like this:  
+    * @endcode 
+    * 
+    * @param _MPh[4] Array of Names of the 4 Digital Pins of type PinNames */
     Motor(PinName _MPh[4] );
-    /** Class Creator.
-    * receives the names of the 4 Digital Pins.
-    *  Uses Ticker callback to handle step times.
-    *  the time between two steps defaults here to MOTOR_STEP_TIME_DEFAULT_US=5000usec.
-    * Call this creator for example like this:
+    
+    /** Motor Class Creator
+    *
+    * Creates the class, initiallizes all fields, creates Phase Pins.  
+    * Time between two steps defaults here to MOTOR_STEP_TIME_DEFAULT_US=5000usec.
+    *
+    * @param <PB_1, PB_15, PB_14, PB_13> List of Names of the 4 Digital Pins of type PinNames    
+    * 
     * @code
+    *   // Call this creator for example like this:
     *    Motor MotorName(PB_1, PB_15, PB_14, PB_13);
     * @endcode */
     Motor(PinName _MPh0, PinName _MPh1, PinName _MPh2, PinName _MPh3);
-    /** Class Creator: 
-    *  receives the names of the 4 Digital Pins.
-    *  Uses Ticker callback to handle step times.
-    *  aStepTime_us is the time in usec between two steps, thats used initially. */
+    
+    /** Motor Class Creator
+    *
+    * Creates the class, initiallizes all fields, creates Phase Pins.  
+    * Time between two steps is passed as parameter.
+    *
+    * @code
+    *   // Call this creator for example like this:
+    *    Motor MotorName(PB_1, PB_15, PB_14, PB_13);
+    * @endcode 
+    *
+    * @param <PB_1, PB_15, PB_14, PB_13> List of Names of the 4 Digital Pins of type PinNames    
+    * @param <aStepTime_us> Lthe time in usec between two steps, thats used initially.   */
     Motor(PinName _MPh0, PinName _MPh1, PinName _MPh2, PinName _MPh3, uint32_t aStepTime_us);
+
 private:
-    // void initialization(PinName _MPh0, PinName _MPh1, PinName _MPh2, PinName _MPh3, uint32_t aStepTime_us);
+    // deprecated: void initialization(PinName _MPh0, PinName _MPh1, PinName _MPh2, PinName _MPh3, uint32_t aStepTime_us);
     void initialization(PinName _MPh[4], uint32_t aStepTime_us);
+
 public:
     /** Attach a basic Callback function.
-     * @param <mIT> Callback function, not member of a class.
-     *  It is only called when a Run Command reaches it's target.
-     *  It is not called when the Motor is stopped by calling Stop Function, or any other events.
-     * Attention: the attached Callback is called within a Ticker Callback.
-     *    Your code you execute in the Callback should be short, must not use waits, or any long routines.
-     *    Do not call any motor run commands in the callback, as it creates conflicting situations.
-     *    Long Callback code may impair this and any other Ticker functions that are running in your application. */
-    void setMotorCallback(void (*mIT)());
+    *
+    * Only called when a Run Command reaches it's requested end.
+    * Not called when the Motor is stopped by a call of Stop Function, or any other events.
+    * For use see precautions at Class description above. 
+    * Formerly called setMotorCallback()
+    @code
+    // Simple callback function, state variable endMove can be polled elsewhere
+    void CallBackFunction()
+    { endMove=true; }
 
-    /** Attaching a Callback function, member of a class.
-     *  It is only called when a Run Command reaches it's target.
-     *  It is not called when the Motor is stopped by calling Stop Function.
-     * at note Attention: the attached Callback is called within a Ticker Callback.
-     *    Your code you execute in the Callback should be short, must not use waits, or any long routines.
-     *    Do not call any motor run commands in the callback, as it creates conflicting situations.
-     *    Long Callback code may impair this and any other Ticker functions that are running in your application.
-    at note AText
+    // main routine
+    void main()
+    {   ...
+        // Attach callback function:
+        MotorInstance->callbackSet(CallBackFunction);
+        ...
+        while (true) {
+            ....
+        if (endMove) // poll the endMove flag
+               { ... } // react to Movement End
+               
+            ....
+        }
+    }
+    @endcode
+    * @param <*CBfunction> Callback function, must not be member of a class.
+
+    */
+    void callbackSet(void (*CBfunction)());
+
+    /** Attach a Callback function, member of a class.
+    * Only called when a Run Command reaches it's requested end.
+    * Not called when the Motor is stopped by a call of Stop Function, or any other events.
+    * For use see precautions at Class description above. 
+    * @param <T *object> Class pointer who possesses callback member.
+    * @param <T::*CBmember> Pointer to callback function, member of Class.
+    * 
     @code
     // Class Creator:
      AClass::AClass(Class Creation Parameters)
     {   ...
         // Attach callback function:
         MotorInstance->setMotorCallback(this, &AClass::CallBackMemberFunction);
-        ...
+        ...  
     }
 
-    // Simple callback function
+    // Simple callback function, state variable endMove can be polled by main thread
     void AClass::CallBackMemberFunction()
-    {
-        endMove=true;
-    }
+    {  endMove=true;  }
     @endcode
     */
     template<typename T>
-    void setMotorCallback(T *object, void (T::*member)(void)) {
-        _callback = callback(object,member);
+    void callbackSet(T *object, void (T::*CBmember)(void)) {
+        _callback = callback(object,CBmember);
     }
 
-    /** Removing the Callback function that may have been attached previously. */
-    void removeMotorCallback();
+    /** Remove the Callback function that may have been attached previously. */
+    void callbackRemove();
 
-    /** RunSteps Main Motor Running Function.
-    * Runs motor for a number Nsteps>0 of steps; Nsteps<=0 will not be executed.
-    * Given Direction can be: CLOCKWISE, or COUNTERCLOCKWISE.
-    * Call Pause() or Stop() to pause or end the motor running prematurely.
-    * While running: Uses ticker; State = first Motor_ON then Motor_RUN; cmd=MOTOR_run.
-    * At the end: calls the Callback, stops ticker; State = Motor_OFF. */
-    void RunSteps    (motorDir direction, uint32_t Nsteps);
+    /** High Level: Run Motor for a number of Steps.
+    * 
+    * During Run: Uses ticker; State: first Motor_ON then Motor_RUN; cmd=MOTOR_run.
+    * Call Pause() or Stop() to pause or end the run prematurely.
+    * At the end: calls the Callback, stops ticker; State: Motor_OFF.
+    * @param[in] <Direction> Given Direction, can be: CLOCKWISE, or COUNTERCLOCKWISE.
+    * @param[in] <Nsteps> Number of steps to run for; must be >0 ; Nsteps<=0 will not be executed.    
+    */
+   void RunSteps (motorDir direction, uint32_t Nsteps);
 
-    /** RunDegrees = Main Motor Running Function.
-    * Runs motor for a given angle>0 in degrees; Angles<=0 will not be executed.
-    * Given Dicection can be: CLOCKWISE, or COUNTERCLOCKWISE.
-    * Call Pause() or Stop() to pause or end the motor running prematurely.
-    * While running: Uses ticker; State = first Motor_ON then Motor_RUN; cmd=MOTOR_run.
-    * At the end: calls the Callback, stops ticker; State = Motor_OFF; cmd=MOTOR_stop then MOTOR_nop. */
-    void RunDegrees  (motorDir direction, float angle);
+    /** High Level: Run Motor for a given angle
+    
+    * Runs Motor for a given angle in given direction. 
+    * Call Pause() or Stop() to pause or end the Motor run prematurely.
+    * While run: Uses ticker; State: first Motor_ON then Motor_RUN; cmd=MOTOR_run.
+    * At end: calls attached Callback, stops ticker; State: Motor_OFF; cmd=MOTOR_stop then MOTOR_nop.
+    * @param[in] <Direction> Given Direction, can be: CLOCKWISE, or COUNTERCLOCKWISE.
+    * @param[in] <angle_deg> Angle>0 to rotate for, in degrees, Angles<=0 are not executed.     
+    */
+   void RunDegrees  (motorDir direction, float angle_deg);
 
-    /** RunInfinite = Main Motor Running Function:
-    * Runs motor "unlimited", more precisely it runs 4Billion Steps.
-    * Dicection can be: CLOCKWISE, or COUNTERCLOCKWISE.
-    * While running: Uses ticker; State = first Motor_ON then Motor_RUN; cmd=MOTOR_run.
-    * Call Pause() or Stop() to pause or end the motor running.*/
+    /** High Level: Run Motor "unlimited"
+    
+    * Runs Motor with out limit in given direction, precisely runs 4Billion Steps.
+    * While run: Uses ticker; State: first Motor_ON then Motor_RUN; cmd=MOTOR_run.
+    * Call Pause() or Stop() to pause or end the Motor run.
+    * @param[in] <Direction> Given Direction, can be: CLOCKWISE, or COUNTERCLOCKWISE.
+    */
     void RunInfinite (motorDir direction);
 
-    /** Pause puts Motor into Pause state, stepping is suspended.
-     * Only effective if Status.cmd=MOTOR_run.
-     * Retains the number of steps that remain to be run.
-     * While pausing: still uses ticker; State = Motor_RUN; cmd=MOTOR_pause.
-     * Use Restart(); to continue. */
-    void Pause();
+    /** High Level: Pause a motor Run.
+     * Put Motor into Pause state, Run is suspended, but only effective if Status.cmd=MOTOR_run.
+     * Retains the number of steps that remain to be run if restarting run.
+     * While paused: still uses ticker; State: Motor_RUN; cmd=MOTOR_pause.
+     * Use RestartRun(); to continue. */
+    void PauseRun();
 
-    /** Restart continues with the paused stepping activity.
-     * Only effective if Status.cmd=MOTOR_pause, otherwise no action.
+    /** High Level: Restart a Paused Run.
+     * Restart the Run that was launched before calling PuaseRun. 
+     * Only effective if Status.cmd=MOTOR_pause, otherwise no re/action.
      * Status afterwards is same as afterRun commands. */
-    void Restart();
+    void RestartRun();
 
-    /** Stop completely ends any running/stepping activity.
-    * Does not call the Callback function.
+    /** High Level: End any Run.
+    * Force stop of any ongoing run, but does not call the Callback function.
+    * Only effective if Status.cmd=MOTOR_run, otherwise no re/action.
     * Emits first cmd=MOTOR_stop then cmd=MOTOR_nop.
-    * Aftewards: ticker is detached; State = Motor_OFF; */
-    void Stop();
-    /** Access all motor status registers.
-    See documentation of MotStatus Structure.
-    @return <MotStatus> The full structure of Motor status registers. 
-    */
+    * Aftewards: ticker is detached; State: Motor_OFF; */
+    void StopRun();
+    
+public: // All the ticker timing related parameters
+
+    /** MidLevel: Get Motor status
+    
+    * Gets the Status of the different internal mechanisms. 
+    * See documentation of MotStatus Structure.
+    * @return <MotStatus> The structure of Motor status registers. */
     MotStatus getStatus();
-public: // All the ticker timing related parameters
-    /** Get number of Steps per Full turn.
-     *  Defaults to MOTOR_STEPS_FOR_A_TURN = 4096.
-     *  Needed to translate from degrees to number of steps.
-     *  Old Name was: getCalibration, but not good explicit name. */
+
+    /** MidLevel: Get number of Steps per Full turn
+    
+    * Defaults to MOTOR_STEPS_FOR_A_TURN = 4096.
+    * Used by RunDegrees() to translate from angle in degrees to number of steps.
+    * Old Name was: getCalibration, but that was not a good explicit name. 
+    * @return <MotStatus> The structure of Motor status registers. */
     uint32_t getStepsFullTurn();
 
-    /** Set number of Steps per Full turn.
-     *  Defaults to MOTOR_STEPS_FOR_A_TURN = 4096.
-     *  Needed to translate from degrees to number of steps.
-     *  Old Name was: setCalibration, but not good explicit name. */
+    /** MidLevel: Set number of Steps per Full turn.
+    
+    * Defaults is MOTOR_STEPS_FOR_A_TURN = 4096.
+    * Used by RunDegrees() to translate from degrees to number of steps.
+    * Old Name was: setCalibration, but not good explicit name.
+    * @param <StepsFullTurn> Number of steps needed to complete a full motor turn
+    */
     void setStepsFullTurn(uint32_t StepsFullTurn);
 
-    /** Set the time in microseconds between two motor steps.
-     *  Was previously called setStepTime(), but was not clear which units.   */
+    /** Mid Level: Get the Motor step time. 
+    
+     * Step time is time between two Motor steps, and is given in microseconds
+     * and is passed to the ticker as delay time. 
+     * So the larger the value the slower the motor speed.  
+     * Defaults to MOTOR_STEP_TIME_DEFAULT_US = 5000.
+    * @return <uint32_t> The structure of Motor status registers.
+     */
+    uint32_t getStepTime_us;
+    
+    /** Set the time in microseconds between two Motor steps.
+     *  Defaults to MOTOR_STEP_TIME_DEFAULT_US = 5000usec.
+     *  Filters values below Minimum Value = 700.
+     *  Passed to the ticker as delay time.
+     *  Can be called while ticker is running, and takes immediate effect. 
+     *  Was previously called setStepTime(), but was not clear which units.  
+    * @param <aStepTime_us> the time in microseconds between two Motor steps
+    */
     void setStepTime_us(uint32_t aStepTime_us);
 
     /** Set the time in seconds to get one full turn, rotation of 360°.
-     * e.g. setRotationPeriodSec( 20.0 ); then motor will do 360° in 20 seconds.
-     * was previously called setSpeed().  */
+    * was previously called setSpeed().  
+    * @param <Seconds_Per_Turn> Period of Rotation, e.g. if =20.0 then Motor will do 360° in 20 seconds.
+    */
     void setRotationPeriodSec(float Seconds_Per_Turn) ;
 
 private:
-    // all the  Ticker and Timing procedures, used to run the motor for a duration
+    // all the  Ticker and Timing procedures, used to run the Motor for a duration
     void StartTick();
     void ProcessMotorStateMachine();
     // The call back function pointer that is called when the Processor
@@ -232,38 +316,53 @@
     Callback<void()> _callback;
     void StopTick();
     MotStatus Status;
-    timestamp_t StepTime_us;  // Time in µs for one motor step
+    timestamp_t StepTime_us;  // Time in µs for one Motor step
     Ticker      MotorSysTick; // System Timer for Motor
+    uint32_t   Steps_FullTurn;// Number of step for a complete turn
+
+public: // all the low level direct Motor HW access, States are immediately reached
+
+    /** Low Level: Run one full turn clockwise then anticlockwise. 
+    * After: State: Motor_OFF.
+    * Blocking function, returns back only after end of full movement. 
+    */
+    void MotorTest();
 
-public: // all the low level direct motor HW access, States are immediately reached
-    /** Turn off all motor Phases, no more current flowing.
-     *   Equivalent to what previously the function "void Stop();" did .  */
+    /** Low Level: turn off all Motor Phases
+     * No more current flows, reduces holding force.
+     * After: State: Motor_OFF.
+     * StepPhases memorizes the last used phase.
+     * Equivalent what previously the function "void Stop();" did .  */
     void MotorOFF();
-    /** Turn on the motor Phase, In the last used phase, memorized in StepPhases
-     *  Equivalent to what previously the function "void Start();" did.  */
+    
+    /** Low Level: turn on the Motor Phases in the last used phase.
+     * The last used phase is held in StepPhases.
+     * After: State: Motor_ON, or Motor_ZERO if StepPhases==0
+     * Equivalent to what previously the function "void Start();" did.  */
     void MotorON();
-    /** Motor phases turned on and put to Zero Position. */
-    void MotorZero();
-    void TestMotor();
-private:
-    /** Motor advances one step rotating in direction of variable direction. */
+    
+    /** Low Level: Advance Motor one step, rotates in direction of variable direction. */
     void StepOnce();
-    /** Motor advances one step rotating left. */
-    void StepLeft();
-    /** Motor advances one step rotating right. */
-    void StepRight();
-    /** Engage Motor Phases according to MotorIndex. */
-    void SetPhases(); // Engage Motor Phases according to StepPhase
+    
+    /** Low Level: Advance Motor one step, rotates CounterClockwise. */
+    void StepCCW();
+    
+    /** Low Level: Advance Motor one step, rotates Clockwise. */
+    void StepClkW();
+    
+    /** Low Level: turn on the Motor Phases in Zero Position. 
+     * After: State: Motor_ZERO, StepPhases==0
+     */
+    void MotorZero();
+    
+    
+private:
+
+    /** Low Level: Engage Motor Phases according to MotorIndex. */
+    void SetPhases(); 
 
     DigitalOut *MPh[4];       // Digital outputs, one per phase
-    int        StepPhase;     //  Motor Phase Variable, counts up and down with every step
-    uint32_t   Steps_FullTurn;// Number of step for a complete turn
-
-private: /* Deprecated, unused members of the class
-    void SetDirection(motorDir direction); // direction is set anyway by all the other commands
-    Timer tuneTimings;
-    uint32_t last;
-    */
+    int        StepPhase;     // Motor Phase Variable, counts up and down with every step
 };
 
-#endif
\ No newline at end of file
+#endif