Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of MotorLib by
motor.h
- Committer:
- sepp_nepp
- Date:
- 2018-11-01
- Revision:
- 15:88fecbdd191c
- Parent:
- 14:f0667bfc2e98
- Child:
- 16:d818c1a4dafb
File content as of revision 15:88fecbdd191c:
/**
* @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
#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
/** \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
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;
/** \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 {
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 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 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.
* 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.
* 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.
* 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:
/** 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)());
/** 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
@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);
}
/** 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);
/** 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();
/** 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();
/** 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.
* 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.
* Old Name was: setCalibration, but not good explicit name. */
void setStepsFullTurn(uint32_t StepsFullTurn);
/** 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°.
* e.g. setRotationPeriodSec( 20.0 ); then motor will do 360° in 20 seconds.
* was previously called setSpeed(). */
void setRotationPeriodSec(float Seconds_Per_Turn) ;
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;
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;
*/
};
#endif
