Tarek Lule / MotorLib

Fork of MotorLib by CreaLab

Revision:
13:4563244c4071
Parent:
11:25d26c72a2f7
Child:
14:f0667bfc2e98
--- a/motor.h	Mon Oct 15 12:06:50 2018 +0000
+++ b/motor.h	Wed Oct 31 14:24:17 2018 +0000
@@ -1,102 +1,228 @@
 // -------------------- Motor ---------------------------
-#ifdef MOTOR_H
-#else
+#ifndef MOTOR_H
 #define MOTOR_H
 
 #include "mbed.h"
 
-#define MOTOR_STEP_TIME_MIN 700
-#define MOTOR_STEP_TIME_DEFAULT 5000
-#define MOTOR_TICKS_FOR_A_TURN 4096
+#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
 
-typedef enum MotorStateList {   // Define Motor States for the State Machine
-    Motor_IDLE = 0,
-    Motor_RUN,
-    Motor_PAUSE,
+/** Possible Motor States that the motor state machine can be in;
+    Motor_CALIB is deprecated, was removed from the states
+    Motor_OFF   replaces Motor_STOP, a state where all current is off
+    Motor_ON    replaces Motor_PAUSE, a state where phases are engaged but motor is not running
+    Motor_ZERO  is the motor at phase position 0, only reached at init and call of Zero command 
+    Motor_RUN   is deprecated, the motor running is simply represented 
+                by being in ON state, and the motor-command == MOTOR_run */
+typedef enum {  
+    Motor_OFF = 0,
+    Motor_ON,
     Motor_ZERO,
-    Motor_CALIB
-    } MotorState;
+    Motor_RUN
+    } motorStates;
     
-typedef enum MotorCommandList { // Define Motor State Machine Commands
+/** Possible Motor Commands that the state machine handles:
+    MOTOR_nop   is no active command to execute
+    MOTOR_run   run for requested direction, speed, duration
+    MOTOR_stop  stops immediately all, turns off motor
+    MOTOR_pause is the motor is paused from the state run
+    MOTOR_restart was replaced by MOTOR_run  
+    OFF and STOP commands do not go through the ticker command handler.
+        */
+typedef enum { // Define Motor State Machine Commands
     MOTOR_nop = 0,
-    MOTOR_start,
-    MOTOR_pause,
-    MOTOR_restart,
+    MOTOR_run,
     MOTOR_stop,
-    MOTOR_zero
-    } MotorCommand;
+    MOTOR_pause
+    } motorCommands;
 
-typedef enum MotorDirectionList { // Define Motor Clockwise or Anticlockwise
+typedef enum motorDir { // Define Motor Clockwise or Anticlockwise
     CLOCKWISE = 0,
     COUNTERCLOCKWISE
-    } MotorDir;
+    } motorDir;
     
+
+typedef struct {
+    /** Structure of Motor Status registers 
+    Used inside Motor Class. Can be passed back by Motor.getStatus() */
+    /** state = the general state that the moter state machine is in: 
+    * can be either of:     Motor_OFF = 0, Motor_ON, Motor_ZERO, or Motor_RUN  */
+    motorStates  state;
+    /** cmd = the current command being executed */
+    motorCommands cmd; 
+    /** dir = the direction that the motor is asked to run*/
+    motorDir      dir;
+    /** NSteps = the number of steps left for the motor to run 
+    NSteps=0 indicates all steps finsihed; NSteps<0 indicates to run "forever" */
+    int32_t       NSteps;
+    /** TickIsAttached = True while the Ticker is attached */
+    bool         TickIsAttached;
+    void set(motorCommands Acmd, motorDir Adir, int32_t  ANSteps);
+    } MotStatus;
+    
+/** Class of a Four Phase Stepper Motor 
+Handles single steps but also running a number of steps, or given amount angle. 
+
+Higher level function rely on ticker and a state-machine evaluating now incoming commands versus the motor state at every tick. 
+
+Lower level functions directly talk to the hard ware without ticker. 
+ */
 class Motor {
     
-    MotorState state;
-    MotorCommand command;
-    MotorDir direction;
-
-    
-    public:
- 
-    
-    Motor(PinName _MPh0, PinName _MPh1, PinName _MPh2, PinName _MPh3, uint32_t TickTime);
+  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 it for example like this:
+    * @code
+    *    PinName MotPhases[] = {PB_1, PB_15, PB_14, PB_13};
+    *    Motor MotorName(MotPhases);
+    * @endcode
+    */ 
+    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 */
     Motor(PinName _MPh0, PinName _MPh1, PinName _MPh2, PinName _MPh3);
-    void RunSteps(MotorDir direction, uint32_t steps);
-    void RunDegrees(MotorDir direction, float steps);
-    void RunInfinite(MotorDir direction);
-    void SetDirection(MotorDir dir);
-    void TestMotor();
-    void RunMotor();
+    /** 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(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);
+    void initialization(PinName _MPh[4], uint32_t aStepTime_us);
+  public:
+    /** Attaching a basic 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)());
-     void setMotorCallback(void (*mIT)(), bool itOnStop);
- 
-template<typename T>
-void setMotorCallback(T *object, void (T::*member)(void))
-{
-    _callback = callback(object,member);
-    itOnStop = 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 
+     * 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.
+     */
+    template<typename T>
+        void setMotorCallback(T *object, void (T::*member)(void))
+            {  _callback = callback(object,member);  }
+        
+    /** Removing the Callback function that may have been attached previously. */
     void removeMotorCallback();
+    
+    /** 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);
+    
+    /** 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);
 
-    uint32_t getCalibration();    
-    void setCalibration(uint32_t nbTicksforFullTurn);
-    void setDelayBtwTicks(uint32_t tickTime); // in ms
-    void setSpeed(float sForOneTurn) ;// nb of s to get rotation of 360° (if 20s, the motor will do 360° in 20 s). 
+    /** 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*/
+    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();
+    
+    /** Restart continues with the paused stepping activity, 
+     * Only effective if Status.cmd=MOTOR_pause, otherwise no action 
+     * Status afterwards is same as afterRun commands.*/
+    void Restart();
     
-    void Start();
+    /** Stop completely ends any running/stepping activity, 
+    * Does not call the Callback function. Emits first cmd=MOTOR_stop then cmd=MOTOR_nop
+    * Aftewards: ticker is detached; State = Motor_OFF; */
     void Stop();
-    void Pause();
-    void Restart();
-    void SetZero();
+    /** getSTatus allows direct access to all motor status registers:
     
-    MotorStateList getState();
+    MotStatus getStatus();
+  public: // All the 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 */
+    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 */
+    void setStepsFullTurn(uint32_t StepsFullTurn);
+    /** Set the time in microseconds between two motor steps 
+     *  was previously called setStepTime()  */
+    void setStepTime_us(uint32_t aStepTime_us); // in ms
+    /** 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()  */
+    void setRotationPeriodSec(float Seconds_Per_Turn) ;
     
-    private:
-    void initialization(PinName _MPh0, PinName _MPh1, PinName _MPh2, PinName _MPh3, uint32_t TickTime);
- 
-    void StopMotor();
-    void StartMotor();
-    void SetCommand(MotorCommand cmd);
-    void LeftMotor();
-    void RightMotor();
+  private: 
+    // 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
+    // State Machine reaches its end. 
+    Callback<void()> _callback;
+    void StopTick();
+    MotStatus Status;       
+    //now part of Status: motorCommands command;
+    //now part of Status: motorDir direction;
+    //now part of Status: int32_t    NumSteps;    
+    //now part of Status: bool        TickIsAttached;
+    //now part of Status: motorStates state;
+    timestamp_t StepTime_us;  // Time in µs for one motor step
+    Ticker      MotorSysTick;    // System Timer for Motor
+    
+  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 */
+    void MotorOFF();
+    /** Turn on the motor Phase, In the last used phase, memorized in StepPhases 
+     *  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 */
+    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
+
+    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;
-    DigitalOut *MPh0, *MPh1, *MPh2, *MPh3;
-    
-    int MotorIndex;    // --- Motor Variable
-   
-    bool init;
-    Ticker  MotorSystemTick;    // System Callback for Motor
-    timestamp_t MotorStepTime;  // Time in µs for one motor step
-    uint32_t    MotorFullTurn;  // Number of step for a complete turn
-    int32_t    NumSteps;       // Number of Steps = NumWire * MotorFullTurn
-    Callback<void()> _callback;
-
-    bool itOnStop;
+    uint32_t last;
+    */ 
 };
 
 #endif
\ No newline at end of file