My Version of the Crealab MotorLib.
Fork of MotorLib by
Revision 15:88fecbdd191c, committed 2018-11-01
- Comitter:
- sepp_nepp
- Date:
- Thu Nov 01 15:29:33 2018 +0000
- Parent:
- 14:f0667bfc2e98
- Child:
- 16:d818c1a4dafb
- Commit message:
- Further extended the helps. ; Functions not yet validated.
Changed in this revision
motor.cpp | Show annotated file Show diff for this revision Revisions of this file |
motor.h | Show annotated file Show diff for this revision Revisions of this file |
--- a/motor.cpp Wed Oct 31 14:38:14 2018 +0000 +++ b/motor.cpp Thu Nov 01 15:29:33 2018 +0000 @@ -1,10 +1,10 @@ #include "motor.h" -void MotStatus::set(motorCommands Acmd, motorDir Adir, int32_t ANSteps) { +void MotStatus::set(motorCommands aCmd, motorDir aDir, int32_t aNSteps) { cmd = Acmd; dir = Adir; NSteps = NSteps; -} MotStatus; +}; Motor::Motor(PinName _MPh[4]) { initialization( _MPh , MOTOR_STEP_TIME_DEFAULT_US); @@ -34,7 +34,7 @@ Status.set(MOTOR_nop, CLOCKWISE, 0);// Default command is NOP, clockwise direction, 0 steps - TickIsAttached = false; + Status.TickIsAttached = false; StepTime_us = aStepTime_us;// duration in micro second for one step Steps_FullTurn = MOTOR_STEPS_FOR_A_TURN; // Default Calibration value @@ -110,15 +110,15 @@ StepTime_us = MOTOR_STEP_TIME_MIN_US; else StepTime_us = aStepTime_us; // or if OK then assign value // if ticker already running recreate a new ticker; - if(TickIsAttached) { StopTick(); StartTick(); } + if(Status.TickIsAttached) { StopTick(); StartTick(); } } void Motor::StartTick() { - if(!TickIsAttached) { + if(!Status.TickIsAttached) { // Connect Interrupt routine in which the motor and all the state machine is performed MotorSysTick.attach_us(callback(this, &Motor::ProcessMotorStateMachine), StepTime_us); // last=tuneTimings.read_us(); - TickIsAttached=true; + Status.TickIsAttached=true; } } @@ -126,14 +126,14 @@ { switch(Status.cmd) { case MOTOR_run: { - switch(state) { + switch(Status.state) { case Motor_OFF: MotorON(); // First only turn on the motor .. break; case Motor_ZERO: case Motor_ON: - state = MOTOR_RUN; - case MOTOR_RUN: + Status.state = Motor_RUN; + case Motor_RUN: if (Status.NSteps==0) // No more steps to go { Status.cmd = MOTOR_stop; if (_callback) _callback.call(); } @@ -141,7 +141,7 @@ { StepOnce(); Status.NSteps--;} break; - } // switch(state) + } // switch(Status.state) } // case MOTOR_run case MOTOR_stop: StopTick(); @@ -155,8 +155,8 @@ } void Motor::StopTick() { - if(TickIsAttached) - { MotorSysTick.detach(); TickIsAttached=false; } + if(Status.TickIsAttached) + { MotorSysTick.detach(); Status.TickIsAttached=false; } } /******************************************************* @@ -166,22 +166,22 @@ /** Turn off all motor Phases, no more current flowing */ void Motor::MotorOFF() { for (int ph=0; ph<4; ph++) *MPh[ph] = 0; - state=Motor_OFF; + Status.state=Motor_OFF; } /** Turn on the motor Phase, In the last used phase, memorized in StepPhases * Equivalent to what previously the function "void Start();" did */ void Motor::MotorON() { SetPhases(); // attention, does not change StepPhase! - if (StepPhase==0) state=Motor_ZERO; - else state=Motor_ON; + if (StepPhase==0) Status.state=Motor_ZERO; + else Status.state=Motor_ON; } /** Motor phases turned on and put to Zero Position*/ void Motor::MotorZero() { StepPhase = 0; // sets the phases to 0 SetPhases(); - state=Motor_ZERO; + Status.state=Motor_ZERO; } void Motor::StepOnce() // Move the Motor in the used 'direction'
--- a/motor.h Wed Oct 31 14:38:14 2018 +0000 +++ b/motor.h Thu Nov 01 15:29:33 2018 +0000 @@ -1,4 +1,16 @@ -// -------------------- Motor --------------------------- +/** + * @file motor.h + * @brief File containing 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 @@. + + * @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 @@ -8,209 +20,232 @@ #define MOTOR_STEP_TIME_DEFAULT_US 5000 // was MOTOR_STEP_TIME_DEFAULT #define MOTOR_STEPS_FOR_A_TURN 4096 -typedef enum { -/** 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 */ - Motor_OFF = 0, - Motor_ON, - Motor_ZERO, - Motor_RUN - } motorStates; - +/** \enum motorStates +* \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*/ +} motorStates; + +/** \enum motorCommands +* \brief Commands that are handled by the Motor state machine +* +* These Commands are issued asynchonously by calling 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. + +* MOTOR_restart is equivalent to and replaced by MOTOR_run. +*/ typedef enum { // 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. */ - MOTOR_nop = 0, - MOTOR_run, - MOTOR_stop, - MOTOR_pause - } motorCommands; + MOTOR_nop = 0, /**< No active command to execute. */ + MOTOR_run, /**< Run Motor until Nsteps are achieved. */ + MOTOR_stop, /**< Stop immediately all activity, turn off Motor. */ + MOTOR_pause /**< Motor is temporarily paused from the state run. */ +} motorCommands; -typedef enum motorDir { -/** Define Motor direction to be Clockwise or Anticlockwise */ - CLOCKWISE = 0, - COUNTERCLOCKWISE - } motorDir; - +/** \enum motorDir +* \brief Define Motor direction to be Clockwise or Anticlockwise +*/ +typedef enum motorDir { + CLOCKWISE = 0, /**< Turn Motor in clockwise direction. */ + COUNTERCLOCKWISE /**< Turn Motor in anti-clockwise direction. */ +} motorDir; +/** \struct MotStatus +* \brief Structure of Motor Status registers +* Is used by Motor Class to hold all Status 'Registers'. +* The structure can be requested to get by Motor.getStatus(). */ 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. + 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. + 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; + 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); +} 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. * -*Higher level function rely on ticker and a state-machine evaluating now incoming commands versus the motor state at every tick. +*Higher level function rely on ticker and a state-machine evaluating new incoming commands versus the motor state at every tick. +* +*Callbacks can be attached to react to 'end of run' events. * -*Lower level functions directly talk to the hard ware without ticker. -* Call it for example like this: -* @code -* PinName MotPhases[] = {PB_1, PB_15, PB_14, PB_13}; -* Motor MotorName(MotPhases); -* @endcode +*Lower level functions directly talk to the hardware without ticker. */ -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. - */ +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: + * @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. */ + /** 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: + * @code + * 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. + /** 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: +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. +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. - */ + * 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)()); + /** 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. + * 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 + @code + // Class Creator: + AClass::AClass(Class Creation Parameters) + { ... + // Attach callback function: + MotorInstance->setMotorCallback(this, &AClass::CallBackMemberFunction); + ... + } + + // Simple callback function + void AClass::CallBackMemberFunction() + { + endMove=true; + } + @endcode + */ template<typename T> - void setMotorCallback(T *object, void (T::*member)(void)) - { _callback = callback(object,member); } - + 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. + + /** 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. + * 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. + + /** 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. + * 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); - /** RunInfinite = Main Motor Running Function: - * Runs motor "unlimited", more precisely it runs 4Billion Steps. - * Dicection can be: CLOCKWISE, or COUNTERCLOCKWISE. + /** 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. + * 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. + + /** 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(); - + /** Stop completely ends any running/stepping activity. - * Does not call the Callback function. + * Does not call the Callback function. * Emits first cmd=MOTOR_stop then cmd=MOTOR_nop. * Aftewards: ticker is detached; State = Motor_OFF; */ void Stop(); - /** getSTatus allows direct access to all motor status registers. + /** Access all motor status registers. See documentation of MotStatus Structure. + @return <MotStatus> The full 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. +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. */ - 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. + 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. */ void setStepsFullTurn(uint32_t StepsFullTurn); - - /** Set the time in microseconds between two motor steps. + + /** Set the time in microseconds between two motor steps. * Was previously called setStepTime(), but was not clear which units. */ - void setStepTime_us(uint32_t aStepTime_us); - - /** Set the time in seconds to get one full turn, rotation of 360°. + 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(). */ void setRotationPeriodSec(float Seconds_Per_Turn) ; - - private: + +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. + // 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; + MotStatus Status; 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. + 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 + /** 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. */ + /** Motor phases turned on and put to Zero Position. */ void MotorZero(); void TestMotor(); - private: +private: /** Motor advances one step rotating in direction of variable direction. */ void StepOnce(); /** Motor advances one step rotating left. */ @@ -223,12 +258,12 @@ 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 + +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; - */ + */ }; #endif \ No newline at end of file