Tarek Lule / MotorLib

Fork of MotorLib by CreaLab

Committer:
sepp_nepp
Date:
Wed Oct 31 14:24:17 2018 +0000
Revision:
13:4563244c4071
Parent:
11:25d26c72a2f7
Child:
14:f0667bfc2e98
First publishing of my version of Motor Lib

Who changed what in which revision?

UserRevisionLine numberNew contents of line
garphil 0:bd05fd602a6e 1 // -------------------- Motor ---------------------------
sepp_nepp 13:4563244c4071 2 #ifndef MOTOR_H
garphil 5:9886fd337a4b 3 #define MOTOR_H
garphil 5:9886fd337a4b 4
garphil 0:bd05fd602a6e 5 #include "mbed.h"
garphil 0:bd05fd602a6e 6
sepp_nepp 13:4563244c4071 7 #define MOTOR_STEP_TIME_MIN_US 700 // was MOTOR_STEP_TIME_MIN
sepp_nepp 13:4563244c4071 8 #define MOTOR_STEP_TIME_DEFAULT_US 5000 // was MOTOR_STEP_TIME_DEFAULT
sepp_nepp 13:4563244c4071 9 #define MOTOR_STEPS_FOR_A_TURN 4096
garphil 9:5983c10d5f8e 10
sepp_nepp 13:4563244c4071 11 /** Possible Motor States that the motor state machine can be in;
sepp_nepp 13:4563244c4071 12 Motor_CALIB is deprecated, was removed from the states
sepp_nepp 13:4563244c4071 13 Motor_OFF replaces Motor_STOP, a state where all current is off
sepp_nepp 13:4563244c4071 14 Motor_ON replaces Motor_PAUSE, a state where phases are engaged but motor is not running
sepp_nepp 13:4563244c4071 15 Motor_ZERO is the motor at phase position 0, only reached at init and call of Zero command
sepp_nepp 13:4563244c4071 16 Motor_RUN is deprecated, the motor running is simply represented
sepp_nepp 13:4563244c4071 17 by being in ON state, and the motor-command == MOTOR_run */
sepp_nepp 13:4563244c4071 18 typedef enum {
sepp_nepp 13:4563244c4071 19 Motor_OFF = 0,
sepp_nepp 13:4563244c4071 20 Motor_ON,
garphil 0:bd05fd602a6e 21 Motor_ZERO,
sepp_nepp 13:4563244c4071 22 Motor_RUN
sepp_nepp 13:4563244c4071 23 } motorStates;
garphil 2:c91c5ef00d25 24
sepp_nepp 13:4563244c4071 25 /** Possible Motor Commands that the state machine handles:
sepp_nepp 13:4563244c4071 26 MOTOR_nop is no active command to execute
sepp_nepp 13:4563244c4071 27 MOTOR_run run for requested direction, speed, duration
sepp_nepp 13:4563244c4071 28 MOTOR_stop stops immediately all, turns off motor
sepp_nepp 13:4563244c4071 29 MOTOR_pause is the motor is paused from the state run
sepp_nepp 13:4563244c4071 30 MOTOR_restart was replaced by MOTOR_run
sepp_nepp 13:4563244c4071 31 OFF and STOP commands do not go through the ticker command handler.
sepp_nepp 13:4563244c4071 32 */
sepp_nepp 13:4563244c4071 33 typedef enum { // Define Motor State Machine Commands
garphil 2:c91c5ef00d25 34 MOTOR_nop = 0,
sepp_nepp 13:4563244c4071 35 MOTOR_run,
garphil 2:c91c5ef00d25 36 MOTOR_stop,
sepp_nepp 13:4563244c4071 37 MOTOR_pause
sepp_nepp 13:4563244c4071 38 } motorCommands;
garphil 0:bd05fd602a6e 39
sepp_nepp 13:4563244c4071 40 typedef enum motorDir { // Define Motor Clockwise or Anticlockwise
garphil 4:c009bcd5518c 41 CLOCKWISE = 0,
garphil 4:c009bcd5518c 42 COUNTERCLOCKWISE
sepp_nepp 13:4563244c4071 43 } motorDir;
garphil 0:bd05fd602a6e 44
sepp_nepp 13:4563244c4071 45
sepp_nepp 13:4563244c4071 46 typedef struct {
sepp_nepp 13:4563244c4071 47 /** Structure of Motor Status registers
sepp_nepp 13:4563244c4071 48 Used inside Motor Class. Can be passed back by Motor.getStatus() */
sepp_nepp 13:4563244c4071 49 /** state = the general state that the moter state machine is in:
sepp_nepp 13:4563244c4071 50 * can be either of: Motor_OFF = 0, Motor_ON, Motor_ZERO, or Motor_RUN */
sepp_nepp 13:4563244c4071 51 motorStates state;
sepp_nepp 13:4563244c4071 52 /** cmd = the current command being executed */
sepp_nepp 13:4563244c4071 53 motorCommands cmd;
sepp_nepp 13:4563244c4071 54 /** dir = the direction that the motor is asked to run*/
sepp_nepp 13:4563244c4071 55 motorDir dir;
sepp_nepp 13:4563244c4071 56 /** NSteps = the number of steps left for the motor to run
sepp_nepp 13:4563244c4071 57 NSteps=0 indicates all steps finsihed; NSteps<0 indicates to run "forever" */
sepp_nepp 13:4563244c4071 58 int32_t NSteps;
sepp_nepp 13:4563244c4071 59 /** TickIsAttached = True while the Ticker is attached */
sepp_nepp 13:4563244c4071 60 bool TickIsAttached;
sepp_nepp 13:4563244c4071 61 void set(motorCommands Acmd, motorDir Adir, int32_t ANSteps);
sepp_nepp 13:4563244c4071 62 } MotStatus;
sepp_nepp 13:4563244c4071 63
sepp_nepp 13:4563244c4071 64 /** Class of a Four Phase Stepper Motor
sepp_nepp 13:4563244c4071 65 Handles single steps but also running a number of steps, or given amount angle.
sepp_nepp 13:4563244c4071 66
sepp_nepp 13:4563244c4071 67 Higher level function rely on ticker and a state-machine evaluating now incoming commands versus the motor state at every tick.
sepp_nepp 13:4563244c4071 68
sepp_nepp 13:4563244c4071 69 Lower level functions directly talk to the hard ware without ticker.
sepp_nepp 13:4563244c4071 70 */
garphil 0:bd05fd602a6e 71 class Motor {
garphil 0:bd05fd602a6e 72
sepp_nepp 13:4563244c4071 73 public:
sepp_nepp 13:4563244c4071 74 /** Class Creator: receives the names of the 4 Digital Pins in an array of PinNames
sepp_nepp 13:4563244c4071 75 * the time in between two steps defaults here to MOTOR_STEP_TIME_DEFAULT_US=5000usec
sepp_nepp 13:4563244c4071 76 * Uses Ticker callback to handle step times.
sepp_nepp 13:4563244c4071 77 * Call it for example like this:
sepp_nepp 13:4563244c4071 78 * @code
sepp_nepp 13:4563244c4071 79 * PinName MotPhases[] = {PB_1, PB_15, PB_14, PB_13};
sepp_nepp 13:4563244c4071 80 * Motor MotorName(MotPhases);
sepp_nepp 13:4563244c4071 81 * @endcode
sepp_nepp 13:4563244c4071 82 */
sepp_nepp 13:4563244c4071 83 Motor(PinName _MPh[4] );
sepp_nepp 13:4563244c4071 84 /** Class Creator: receives the names of the 4 Digital Pins,
sepp_nepp 13:4563244c4071 85 * Uses Ticker callback to handle step times.
sepp_nepp 13:4563244c4071 86 * the time between two steps defaults here to MOTOR_STEP_TIME_DEFAULT_US=5000usec */
garphil 9:5983c10d5f8e 87 Motor(PinName _MPh0, PinName _MPh1, PinName _MPh2, PinName _MPh3);
sepp_nepp 13:4563244c4071 88 /** Class Creator: receives the names of the 4 Digital Pins,
sepp_nepp 13:4563244c4071 89 * Uses Ticker callback to handle step times.
sepp_nepp 13:4563244c4071 90 * aStepTime_us is the time in usec between two steps, thats used initially. */
sepp_nepp 13:4563244c4071 91 Motor(PinName _MPh0, PinName _MPh1, PinName _MPh2, PinName _MPh3, uint32_t aStepTime_us);
sepp_nepp 13:4563244c4071 92 private:
sepp_nepp 13:4563244c4071 93 // void initialization(PinName _MPh0, PinName _MPh1, PinName _MPh2, PinName _MPh3, uint32_t aStepTime_us);
sepp_nepp 13:4563244c4071 94 void initialization(PinName _MPh[4], uint32_t aStepTime_us);
sepp_nepp 13:4563244c4071 95 public:
sepp_nepp 13:4563244c4071 96 /** Attaching a basic Callback function, not member of a class
sepp_nepp 13:4563244c4071 97 * It is only called when a Run Command reaches it's target
sepp_nepp 13:4563244c4071 98 * It is not called when the Motor is stopped by calling Stop Function, or any other events.
sepp_nepp 13:4563244c4071 99 * Attention: the attached Callback is called within a Ticker Callback.
sepp_nepp 13:4563244c4071 100 * Your code you execute in the Callback should be short, must not use waits, or any long routines.
sepp_nepp 13:4563244c4071 101 * Do not call any motor run commands in the callback, as it creates conflicting situations.
sepp_nepp 13:4563244c4071 102 * Long Callback code may impair this and any other Ticker functions that are running in your application.
sepp_nepp 13:4563244c4071 103 */
garphil 9:5983c10d5f8e 104 void setMotorCallback(void (*mIT)());
sepp_nepp 13:4563244c4071 105 /** Attaching a Callback function, member of a class
sepp_nepp 13:4563244c4071 106 * It is only called when a Run Command reaches it's target
sepp_nepp 13:4563244c4071 107 * It is not called when the Motor is stopped by calling Stop Function
sepp_nepp 13:4563244c4071 108 * Attention: the attached Callback is called within a Ticker Callback.
sepp_nepp 13:4563244c4071 109 * Your code you execute in the Callback should be short, must not use waits, or any long routines.
sepp_nepp 13:4563244c4071 110 * Do not call any motor run commands in the callback, as it creates conflicting situations.
sepp_nepp 13:4563244c4071 111 * Long Callback code may impair this and any other Ticker functions that are running in your application.
sepp_nepp 13:4563244c4071 112 */
sepp_nepp 13:4563244c4071 113 template<typename T>
sepp_nepp 13:4563244c4071 114 void setMotorCallback(T *object, void (T::*member)(void))
sepp_nepp 13:4563244c4071 115 { _callback = callback(object,member); }
sepp_nepp 13:4563244c4071 116
sepp_nepp 13:4563244c4071 117 /** Removing the Callback function that may have been attached previously. */
garphil 9:5983c10d5f8e 118 void removeMotorCallback();
sepp_nepp 13:4563244c4071 119
sepp_nepp 13:4563244c4071 120 /** RunSteps Main Motor Running Function:
sepp_nepp 13:4563244c4071 121 * Runs motor for a number Nsteps>0 of steps; Nsteps<=0 will not be executed
sepp_nepp 13:4563244c4071 122 * Given Direction can be: CLOCKWISE, or COUNTERCLOCKWISE
sepp_nepp 13:4563244c4071 123 * Call Pause() or Stop() to pause or end the motor running prematurely
sepp_nepp 13:4563244c4071 124 * While running: Uses ticker; State = first Motor_ON then Motor_RUN; cmd=MOTOR_run
sepp_nepp 13:4563244c4071 125 * At the end: calls the Callback, stops ticker; State = Motor_OFF */
sepp_nepp 13:4563244c4071 126 void RunSteps (motorDir direction, uint32_t Nsteps);
sepp_nepp 13:4563244c4071 127
sepp_nepp 13:4563244c4071 128 /** RunDegrees = Main Motor Running Function:
sepp_nepp 13:4563244c4071 129 * Runs motor for a given angle>0 in degrees; Angles<=0 will not be executed
sepp_nepp 13:4563244c4071 130 * Given Dicection can be: CLOCKWISE, or COUNTERCLOCKWISE
sepp_nepp 13:4563244c4071 131 * Call Pause() or Stop() to pause or end the motor running prematurely
sepp_nepp 13:4563244c4071 132 * While running: Uses ticker; State = first Motor_ON then Motor_RUN; cmd=MOTOR_run
sepp_nepp 13:4563244c4071 133 * At the end: calls the Callback, stops ticker; State = Motor_OFF; cmd=MOTOR_stop then MOTOR_nop */
sepp_nepp 13:4563244c4071 134 void RunDegrees (motorDir direction, float angle);
garphil 9:5983c10d5f8e 135
sepp_nepp 13:4563244c4071 136 /** RunInfinite = Main Motor Running Function:
sepp_nepp 13:4563244c4071 137 * Runs motor "unlimited", more precisely it runs 4Billion Steps.
sepp_nepp 13:4563244c4071 138 * Dicection can be: CLOCKWISE, or COUNTERCLOCKWISE
sepp_nepp 13:4563244c4071 139 * While running: Uses ticker; State = first Motor_ON then Motor_RUN; cmd=MOTOR_run
sepp_nepp 13:4563244c4071 140 * Call Pause() or Stop() to pause or end the motor running*/
sepp_nepp 13:4563244c4071 141 void RunInfinite (motorDir direction);
sepp_nepp 13:4563244c4071 142
sepp_nepp 13:4563244c4071 143 /** Pause puts Motor into Pause state, stepping is suspended
sepp_nepp 13:4563244c4071 144 * Only effective if Status.cmd=MOTOR_run
sepp_nepp 13:4563244c4071 145 * Retains the number of steps that remain to be run.
sepp_nepp 13:4563244c4071 146 * While pausing: still uses ticker; State = Motor_RUN; cmd=MOTOR_pause
sepp_nepp 13:4563244c4071 147 * Use Restart(); to continue */
sepp_nepp 13:4563244c4071 148 void Pause();
sepp_nepp 13:4563244c4071 149
sepp_nepp 13:4563244c4071 150 /** Restart continues with the paused stepping activity,
sepp_nepp 13:4563244c4071 151 * Only effective if Status.cmd=MOTOR_pause, otherwise no action
sepp_nepp 13:4563244c4071 152 * Status afterwards is same as afterRun commands.*/
sepp_nepp 13:4563244c4071 153 void Restart();
garphil 4:c009bcd5518c 154
sepp_nepp 13:4563244c4071 155 /** Stop completely ends any running/stepping activity,
sepp_nepp 13:4563244c4071 156 * Does not call the Callback function. Emits first cmd=MOTOR_stop then cmd=MOTOR_nop
sepp_nepp 13:4563244c4071 157 * Aftewards: ticker is detached; State = Motor_OFF; */
garphil 4:c009bcd5518c 158 void Stop();
sepp_nepp 13:4563244c4071 159 /** getSTatus allows direct access to all motor status registers:
arnophilippe 7:439458133bba 160
sepp_nepp 13:4563244c4071 161 MotStatus getStatus();
sepp_nepp 13:4563244c4071 162 public: // All the timing related parameters
sepp_nepp 13:4563244c4071 163 /** Get number of Steps per Full turn,
sepp_nepp 13:4563244c4071 164 * Defaults to MOTOR_STEPS_FOR_A_TURN = 4096
sepp_nepp 13:4563244c4071 165 * Needed to translate from degrees to number of steps
sepp_nepp 13:4563244c4071 166 * Old Name was: getCalibration, but not good explicit name */
sepp_nepp 13:4563244c4071 167 uint32_t getStepsFullTurn();
sepp_nepp 13:4563244c4071 168 /** Set number of Steps per Full turn,
sepp_nepp 13:4563244c4071 169 * Defaults to MOTOR_STEPS_FOR_A_TURN = 4096
sepp_nepp 13:4563244c4071 170 * Needed to translate from degrees to number of steps */
sepp_nepp 13:4563244c4071 171 void setStepsFullTurn(uint32_t StepsFullTurn);
sepp_nepp 13:4563244c4071 172 /** Set the time in microseconds between two motor steps
sepp_nepp 13:4563244c4071 173 * was previously called setStepTime() */
sepp_nepp 13:4563244c4071 174 void setStepTime_us(uint32_t aStepTime_us); // in ms
sepp_nepp 13:4563244c4071 175 /** Set the time in seconds to get one full turn, rotation of 360°
sepp_nepp 13:4563244c4071 176 * e.g. setRotationPeriodSec( 20.0 ); then motor will do 360° in 20 seconds;
sepp_nepp 13:4563244c4071 177 * was previously called setSpeed() */
sepp_nepp 13:4563244c4071 178 void setRotationPeriodSec(float Seconds_Per_Turn) ;
garphil 10:1df5a7a265e8 179
sepp_nepp 13:4563244c4071 180 private:
sepp_nepp 13:4563244c4071 181 // all the Ticker and Timing procedures, used to run the motor for a duration
sepp_nepp 13:4563244c4071 182 void StartTick();
garphil 1:9519ac966b79 183 void ProcessMotorStateMachine();
sepp_nepp 13:4563244c4071 184 // The call back function pointer that is called when the Processor
sepp_nepp 13:4563244c4071 185 // State Machine reaches its end.
sepp_nepp 13:4563244c4071 186 Callback<void()> _callback;
sepp_nepp 13:4563244c4071 187 void StopTick();
sepp_nepp 13:4563244c4071 188 MotStatus Status;
sepp_nepp 13:4563244c4071 189 //now part of Status: motorCommands command;
sepp_nepp 13:4563244c4071 190 //now part of Status: motorDir direction;
sepp_nepp 13:4563244c4071 191 //now part of Status: int32_t NumSteps;
sepp_nepp 13:4563244c4071 192 //now part of Status: bool TickIsAttached;
sepp_nepp 13:4563244c4071 193 //now part of Status: motorStates state;
sepp_nepp 13:4563244c4071 194 timestamp_t StepTime_us; // Time in µs for one motor step
sepp_nepp 13:4563244c4071 195 Ticker MotorSysTick; // System Timer for Motor
sepp_nepp 13:4563244c4071 196
sepp_nepp 13:4563244c4071 197 public: // all the low level direct motor HW access, States are immediately reached
sepp_nepp 13:4563244c4071 198 /** Turn off all motor Phases, no more current flowing
sepp_nepp 13:4563244c4071 199 * Equivalent to what previously the function "void Stop();" did */
sepp_nepp 13:4563244c4071 200 void MotorOFF();
sepp_nepp 13:4563244c4071 201 /** Turn on the motor Phase, In the last used phase, memorized in StepPhases
sepp_nepp 13:4563244c4071 202 * Equivalent to what previously the function "void Start();" did */
sepp_nepp 13:4563244c4071 203 void MotorON();
sepp_nepp 13:4563244c4071 204 /** Motor phases turned on and put to Zero Position*/
sepp_nepp 13:4563244c4071 205 void MotorZero();
sepp_nepp 13:4563244c4071 206 void TestMotor();
sepp_nepp 13:4563244c4071 207 private:
sepp_nepp 13:4563244c4071 208 /** Motor advances one step rotating in direction of variable direction */
sepp_nepp 13:4563244c4071 209 void StepOnce();
sepp_nepp 13:4563244c4071 210 /** Motor advances one step rotating left */
sepp_nepp 13:4563244c4071 211 void StepLeft();
sepp_nepp 13:4563244c4071 212 /** Motor advances one step rotating right */
sepp_nepp 13:4563244c4071 213 void StepRight();
sepp_nepp 13:4563244c4071 214 /** Engage Motor Phases according to MotorIndex */
sepp_nepp 13:4563244c4071 215 void SetPhases(); // Engage Motor Phases according to StepPhase
sepp_nepp 13:4563244c4071 216
sepp_nepp 13:4563244c4071 217 DigitalOut *MPh[4]; // Digital outputs, one per phase
sepp_nepp 13:4563244c4071 218 int StepPhase; // Motor Phase Variable, counts up and down with every step
sepp_nepp 13:4563244c4071 219 uint32_t Steps_FullTurn;// Number of step for a complete turn
sepp_nepp 13:4563244c4071 220
sepp_nepp 13:4563244c4071 221 private: /* Deprecated, unused members of the class
sepp_nepp 13:4563244c4071 222 void SetDirection(motorDir direction); // direction is set anyway by all the other commands
garphil 10:1df5a7a265e8 223 Timer tuneTimings;
sepp_nepp 13:4563244c4071 224 uint32_t last;
sepp_nepp 13:4563244c4071 225 */
garphil 5:9886fd337a4b 226 };
garphil 5:9886fd337a4b 227
garphil 5:9886fd337a4b 228 #endif