My Version of the Crealab MotorLib.

Fork of MotorLib by CreaLab

Files at this revision

API Documentation at this revision

Comitter:
sepp_nepp
Date:
Thu Apr 18 12:12:48 2019 +0000
Parent:
23:6060422cd6eb
Commit message:
Compiles

Changed in this revision

CreaMot.cpp Show annotated file Show diff for this revision Revisions of this file
CreaMot.h Show annotated file Show diff for this revision Revisions of this file
motor.cpp Show diff for this revision Revisions of this file
motor.h Show diff for this revision Revisions of this file
diff -r 6060422cd6eb -r 932ea7bdc850 CreaMot.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CreaMot.cpp	Thu Apr 18 12:12:48 2019 +0000
@@ -0,0 +1,249 @@
+#include "CreaMot.h"
+
+  // -------------------- CreaMot Class ---------------------------
+
+CreaMot::CreaMot(PinName _MPh[4]) {
+    initialization( _MPh , MOTOR_STEP_TIME_DEFAULT_US);
+}
+
+CreaMot::CreaMot(PinName _MPh0, PinName _MPh1, PinName _MPh2, PinName _MPh3) {
+    PinName _MPh[4] = {_MPh0, _MPh1, _MPh2, _MPh3};
+    initialization( _MPh , MOTOR_STEP_TIME_DEFAULT_US);
+}
+
+CreaMot::CreaMot(PinName _MPh0, PinName _MPh1, PinName _MPh2, PinName _MPh3, uint32_t AStepTime_us) {
+    PinName _MPh[4] = {_MPh0, _MPh1, _MPh2, _MPh3};
+    initialization( _MPh, AStepTime_us);
+}
+
+void CreaMot::initialization(PinName _MPh[4], uint32_t AStepTime_us) {
+
+    for (int ph=0; ph<4; ph++) { MPh[ph] = new DigitalOut(_MPh[ph]); } 
+    
+    MotorOFF();    // Default state is all phases are OFF
+    StepPhase = 0; // initial phase is Zero
+    
+    setCommand(MOTOR_nop, CLOCKWISE, 0);// Default command is NOP, clockwise direction, 0 steps
+    
+    TickIsAttached = false;
+    StepTime_us = AStepTime_us;// duration in micro second for one step
+
+    Steps_FullTurn = MOTOR_STEPS_FOR_A_TURN;  // Default Calibration value
+    _callback = NULL; // No default Callback
+    
+    // All geometric information defaults to 0:
+    diam_cm          = 0; // wheel diameter in centimeter
+    perim_cm         = 0; // wheel perimeter in centimeter
+    degree_per_cm    = 0; // rotation angle in degrees per cm circumference
+    defaultDirection = CLOCKWISE;
+}
+
+// *****************************************************************
+//   all following functions are based on centimeter information
+// *****************************************************************
+
+/* High Level: Run CreaMot for a given number of Dist_cm, Dist_cm<0 are run in opposite direction. */
+void CreaMot::RunDist_cm(bool AClockWise, float Dist_cm)
+{  RunDegrees(AClockWise,Dist_cm * degree_per_cm); }
+
+/* High Level: Run CreaMot for a given number of Dist_cm in default direction. */
+void CreaMot::RunDist_cm(float Dist_cm)
+{  RunDegrees(defaultDirection, Dist_cm * degree_per_cm); }
+
+/** Additional geometric information: set the wheel diameter, also sets perimeter and degrees per cm.*/
+void CreaMot::setDiamCM( float Adiam_cm) 
+{   diam_cm = Adiam_cm;
+    perim_cm = PI*diam_cm;
+    degree_per_cm=360.0f/perim_cm;
+} 
+
+/** Calculate the needed wheel angle from a turn angle and a turn_radius_cm  */
+void CreaMot::RunTurnAngle(float turn_angle_deg, float turn_radius_cm) 
+{   // a turn radius smaller than 0 make no sense is not executed
+    if( turn_radius_cm>= 0 ) 
+        RunDegrees(  turn_angle_deg * PI_OVER_180 * turn_radius_cm * degree_per_cm);
+} 
+
+void CreaMot::setSpeed_cm_sec(float speed_cm_sec)
+{   if (speed_cm_sec < MIN_SPEED_CM_SEC) // catch too small or negative speeds
+          setRotationPeriodSec( perim_cm / MIN_SPEED_CM_SEC); 
+    else  setRotationPeriodSec( perim_cm / speed_cm_sec );
+}
+
+// *****************************************************************
+//  all following functions are agnostic of centimeter-information
+// *****************************************************************
+
+void CreaMot::RunInfinite(bool AClockWise) 
+{   setCommand(MOTOR_run, AClockWise, -1);
+    StartTick();
+}
+
+/* High Level: Run CreaMot for a given angle, angles<0 are run in opposite direction. */
+void CreaMot::RunDegrees(bool AClockWise, float angle_deg) {
+ RunSteps( AClockWise, (int32_t)(angle_deg * (float)Steps_FullTurn / 360.0f) );   
+}
+
+/* High Level: Run CreaMot for a given angle in default direction, angles<0 are run in opposite direction. */
+void CreaMot::RunDegrees(float angle_deg) {
+ RunSteps( defaultDirection, (int32_t)(angle_deg * (float)Steps_FullTurn / 360.0f) );   
+}
+
+/* High Level: Run CreaMot for a given number of steps, steps<0 are run in opposite direction. */
+void CreaMot::RunSteps(bool AClockWise, int32_t steps) 
+{   if (steps<0) { AClockWise = !AClockWise; steps=-steps; }
+    if (steps>0) 
+        { setCommand( MOTOR_run, AClockWise, steps );
+          StartTick(); }
+}
+
+void CreaMot::PauseRun() 
+{   if (CurrCmd==MOTOR_run) CurrCmd = MOTOR_pause;  }
+
+void CreaMot::RestartRun() 
+{   if (CurrCmd==MOTOR_pause) CurrCmd = MOTOR_run;  }
+
+// not only halt the state machine but also set NSteps to 0
+void CreaMot::StopRun() 
+{   setCommand(MOTOR_stop,ClockWise,0);  } 
+
+void CreaMot::setCommand(motCmands aCmd, bool aClockWise, int32_t  aNSteps) {
+    CurrCmd    = aCmd;
+    ClockWise  = aClockWise;
+    NStepsToDo = aNSteps;
+};
+
+
+/*******************************************************
+ **   Ticker / Timing procedures
+ *******************************************************/
+//Get, set the scaling
+uint32_t CreaMot::getStepsFullTurn()
+{    return Steps_FullTurn;  }
+
+void CreaMot::setStepsFullTurn(uint32_t StepsFullTurn) 
+{   Steps_FullTurn = StepsFullTurn; }
+
+void CreaMot::setRotationPeriodSec(float Seconds_Per_Turn) {
+    // rescale to usec and pass on to the next handler. 
+    setStepTime_us( uint32_t(Seconds_Per_Turn / Steps_FullTurn * 1000000) ) ;
+}
+void CreaMot::setStepTime_us(uint32_t AStepTime_us) {
+    if(StepTime_us == AStepTime_us) return; // avoid futile activity
+    if (StepTime_us < MOTOR_STEP_TIME_MIN_US) // filter too small values
+       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(); }
+ }
+
+void CreaMot::StartTick() {
+    if(!TickIsAttached)   {
+        // Connect Interrupt routine in which the CreaMot and all the state machine is performed
+        MotorSysTick.attach_us(callback(this, &CreaMot::ProcessMotorStateMachine), StepTime_us);
+        // last=tuneTimings.read_us();
+        TickIsAttached=true;
+        }
+}
+
+void CreaMot::ProcessMotorStateMachine()
+{
+    switch(CurrCmd) {
+        case MOTOR_run: {
+            switch(CurrState) {
+                case Motor_OFF:
+                    MotorON(); // First only turn on the CreaMot ..
+                    break;
+                case Motor_ZERO:
+                case Motor_ON:
+                        CurrState = Motor_RUN;
+                case Motor_RUN:
+                    if (NStepsToDo==0)  // No more steps to go
+                        { CurrCmd = MOTOR_stop; 
+                          if (_callback) _callback.call(); } 
+                      else // More steps to go
+                        { StepOnce(); 
+                        NStepsToDo--;}
+                    break;
+                } // switch(CurrState)
+            } // case MOTOR_run
+        case MOTOR_stop:
+            StopTick();
+            CurrCmd = MOTOR_nop; 
+            MotorOFF(); 
+            break;       
+        case MOTOR_nop:
+        case MOTOR_pause:
+        default: break;
+    } // switch(CurrCmd)
+}
+
+void CreaMot::StopTick() {
+    if(TickIsAttached)   
+      { MotorSysTick.detach(); TickIsAttached=false; }
+}
+
+/*******************************************************
+ **   all the low level direct CreaMot HW access
+ *******************************************************/
+ 
+
+ void CreaMot::MotorTest()    // Just to check that it make a full turn back and forth
+{
+    int i;
+    MotorON();
+    for (i=0; i<Steps_FullTurn; i++) {
+        wait(0.005);
+        StepClkW();
+        }   
+    wait(0.5);
+    for (i=0; i<Steps_FullTurn; i++) {
+        wait(0.005);
+        StepCCW();
+        }   
+    MotorOFF();
+}
+
+ /** Turn off all CreaMot Phases, no more current flowing */
+void CreaMot::MotorOFF() 
+{   for (int ph=0; ph<4; ph++) *MPh[ph] = 0;  
+    CurrState=Motor_OFF;
+}
+
+/** Turn on the CreaMot Phase, In the last used phase, memorized in StepPhases 
+*  Equivalent to what previously the function "void Start();" did */
+void CreaMot::MotorON()
+{   SetPhases(); // attention, does not change StepPhase!
+    if (StepPhase==0)  CurrState=Motor_ZERO;  
+        else CurrState=Motor_ON;
+} 
+
+/** CreaMot phases turned on and put to Zero Position*/    
+void CreaMot::MotorZero() {
+    StepPhase = 0;  // sets the phases to 0
+    SetPhases(); 
+    CurrState=Motor_ZERO;
+}
+
+void    CreaMot::StepOnce()     // Move the CreaMot in the requested 'direction'
+{   if (ClockWise) StepClkW(); else StepCCW();
+}
+
+void    CreaMot::StepClkW()    // Move the CreaMot one step Clockwise
+{   if (StepPhase<7) StepPhase++;  else  StepPhase = 0;
+    SetPhases();
+}
+void    CreaMot::StepCCW()    // Move the CreaMot one step Clockwise
+{   if (StepPhase>0) StepPhase--;  else  StepPhase = 7;
+    SetPhases();
+}
+
+static const int MotPh[4][8] = 
+    { {1, 1, 0, 0, 0, 0, 0, 1}, 
+      {0, 1, 1, 1, 0, 0, 0, 0}, 
+      {0, 0, 0, 1, 1, 1, 0, 0}, 
+      {0, 0, 0, 0, 0, 1, 1, 1}};
+      
+void    CreaMot::SetPhases()    // Engage CreaMot Phases according to StepPhase
+{ for (int ph=0; ph<4; ph++) { *MPh[ph] = MotPh[ph][StepPhase]; }   }
+
diff -r 6060422cd6eb -r 932ea7bdc850 CreaMot.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CreaMot.h	Thu Apr 18 12:12:48 2019 +0000
@@ -0,0 +1,447 @@
+/**
+ * @file CreaMot.h
+ * \brief File contains Crealab CreaMot Library.
+ 
+ * CreaMot.h contains the class CreaMot, and related enums and structs.
+ * Includes only "mbed.h".
+ *
+ * MotStatus structure is dissolved into the CreaMot Class
+ *
+ * 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/  */
+ 
+ // -------------------- CreaMot ---------------------------
+ 
+#ifndef CREAMOT_H
+#define CREAMOT_H
+
+#include "mbed.h"
+
+#define MOTOR_STEP_TIME_MIN_US 700      /**< Shortest Time between two CreaMot steps = 0.7ms, was MOTOR_STEP_TIME_MIN*/
+#define MOTOR_STEP_TIME_DEFAULT_US 5000 /**< Default Time between two CreaMot steps = 5ms, was MOTOR_STEP_TIME_DEFAULT*/
+#define MOTOR_STEPS_FOR_A_TURN 4096     /**< Default number of CreaMot steps to complete a turn = 4096 steps  */
+#define CLOCKWISE true                  /**< Constant for Clockwise direction */
+#define COUNTERCLOCKWISE false          /**< Constant for Counter-Clockwise direction */
+#define MAX_SPEED_CM_SEC 30.0f    /**< Clamp maximum advancement speed = 30cm/sec, was MAX_SPEED */
+#define MIN_SPEED_CM_SEC 0.001f   /**< Clamp minimum advancement speed = 10um/sec */
+#define PI 3.141592f    /** PI needed to calcuate from angle to distances */
+#define PI_OVER_180 (PI/180.0f)  /** needed to translate from angle to circumference */
+
+/** \enum motStates 
+* \brief Possible States of CreaMot 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,     /**< CreaMot at phase position 0 and ON, only reached by call of Zero() procedure. */  
+    Motor_ON,       /**< Phases are engaged, but CreaMot state machine stopped, replaces Motor_PAUSE. */  
+    Motor_RUN       /**< Phases are engaged, and CreaMot state machine runs*/  
+} motStates;
+
+/** \enum motCmands 
+* \brief Commands that are handled by the CreaMot state machine
+*
+* These Commands are issued asynchonously by calling CreaMot 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 {
+    MOTOR_nop = 0,  /**< No active command to execute. */
+    MOTOR_run,      /**< Run CreaMot until Nsteps are achieved. */
+    MOTOR_stop,     /**< Stop immediately all activity, turn off CreaMot. */
+    MOTOR_pause     /**< CreaMot is temporarily paused from the state run. */
+} motCmands;
+
+/** ATTENTION UNDER CONSTRUCTION, DO NOT YET USE.
+*
+* Class of a Four Phase Stepper CreaMot.
+*
+* 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 the one ongoing command versus the CreaMot state at every tick.
+* When End of Run is detected tickers stop, and CreaMot turns off. 
+*
+* To define the speed of the CreaMot set the variable StepTime_us, either by
+*    a) Using the createor CreaMot(...., uint32_t AStepTime_us);
+*    b) Calling function setStepTime_us(uint32_t AStepTime_us); any time
+*    c) or leave it to the default value MOTOR_STEP_TIME_DEFAULT_US = 5000
+*
+* To be able to run the CreaMot for a given angle, set the number of steps per full turn
+*    with the function "setStepsFullTurn"
+*    That value defaults to MOTOR_STEPS_FOR_A_TURN = 4096
+*
+* To be able to run the CreaMot for a given perimeter distance in centimeters, 
+*    set the wheel diameter with the function setDiamCM( float Adiam_cm); 
+*
+* 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 CreaMot 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.
+*
+*Low-Level functions directly talk to the hardware without ticker. 
+*   Use of Low-Level functions while tickers still run may lead to unexpected behavior. 
+*
+* NB: all times are uint32_t, step numbers are int32_t
+*/
+class CreaMot
+{
+public:
+    /** CreaMot Class Creator
+    *
+    * Creates the class, initiallizes all fields, creates Phase Pins.  
+    * Time between two steps defaults here to MOTOR_STEP_TIME_DEFAULT_US = 5000usec.
+    * Pin names are used to create digital outputs: Pin0 = new DigitalOut(_MPh0)
+    *
+    @code
+       PinName MotPhases[] = {PB_1, PB_15, PB_14, PB_13};
+       CreaMot MotorName(MotPhases); // Call this creator for example like this:  
+    @endcode 
+    * 
+    * @param _MPh Array of Names of the 4 Digital Pins of type PinNames 
+    */
+    CreaMot(PinName _MPh[4] );
+    
+    /** CreaMot Class Creator
+    *
+    * Creates the class, initiallizes all fields, creates Phase Pins.  
+    * Time between two steps defaults here to MOTOR_STEP_TIME_DEFAULT_US=5000usec.
+    * Pin names are used to create digital outputs: Pin0 = new DigitalOut(_MPh0)
+    *
+    @code
+      // Call this creator for example like this:
+       CreaMot MotorName(PB_1, PB_15, PB_14, PB_13);
+    @endcode 
+    * 
+    * @param <_MPh0, _MPh1, _MPh2, _MPh3> List of Names of the 4 Digital Pins of type PinNames    
+    */
+    CreaMot(PinName _MPh0, PinName _MPh1, PinName _MPh2, PinName _MPh3);
+    
+    /** CreaMot Class Creator
+    *
+    * Creates the class, initiallizes all fields, creates Phase Pins.  
+    * Time between two steps is passed as parameter.
+    * Pin names are used to create digital outputs: Pin0 = new DigitalOut(_MPh0)
+    *
+    @code
+      // Call this creator for example like this:
+       CreaMot MotorName(PB_1, PB_15, PB_14, PB_13, 6000);
+    @endcode 
+    *
+    * @param <_MPh0, _MPh1, _MPh2, _MPh3> List of Names of the 4 Digital Pins of type PinNames    
+    * @param <AStepTime_us> the time in usec between two steps, thats used initially.   
+    */
+    CreaMot(PinName _MPh0, PinName _MPh1, PinName _MPh2, PinName _MPh3, uint32_t AStepTime_us);
+
+private:
+    // 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.
+    *
+    * A callback is called when the current Command reaches it's requested end.
+    * Not called when the CreaMot 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; }
+
+    // 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)(void)) {_callback = CBfunction;};
+
+
+    /** Attach a Callback function, member of a class.
+    * Only called when a Run Command reaches it's requested end.
+    * Not called when the CreaMot is stopped by a call of Stop Function, or any other events.
+    * For use see precautions at Class description above. 
+    * @param <*object> Class pointer which possesses callback member.
+    * @param <*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, state variable endMove can be polled by main thread
+    void AClass::CallBackMemberFunction()
+    {  endMove=true;  }
+    @endcode
+    */
+    template<typename T>
+    void callbackSet(T *object, void (T::*CBmember)(void)) {
+        _callback = callback(object,CBmember);
+    }
+
+    /** Remove the Callback function that may have been attached previously. */
+    void callbackRemove() { _callback = NULL; };
+
+public: 
+    // *********************************************************************
+    //  all following functions use wheel diameter to achieve cm distance
+    // *********************************************************************
+
+    /** High Level: Run CreaMot for a given number of centimeters.
+    *
+    * Runs CreaMot for a given wheel circumference in cimeters in given direction. 
+    * You must setup the perimeter and diameter with setDiam(Adiam_cm) in advance, otherwise no reaction.
+    * Call Pause() or Stop() to pause or end the CreaMot 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] <AClockWise> Given Direction, true for CLOCKWISE, false for COUNTERCLOCKWISE.
+    * @param[in] <Dist_cm> Circumference to rotate for, in cm, Dist_cm<0 are run in opposite direction.
+    */
+    void RunDist_cm  (bool AClockWise, float Dist_cm);
+   
+    /** High Level: Run CreaMot for a given number of centimeters in default direction.
+    * Same as RunDist_cm(AClockWise,Dist_cm) but uses Default diretion.*/
+    void RunDist_cm  (float Dist_cm);
+    
+    /** High Level: Run CreaMot for a turn angle around a turn_radius_cm  in default direction
+    *
+    * Runs CreaMot for a given turn angle in degrees with a given turn radius.
+    *   in default direction. Negative angles are rotated in opposite direction. 
+    *   turn-radius must be positive. Zero or negative radius are not executed. 
+    * You must setup the perimeter and diameter with setDiam(Adiam_cm) in advance, otherwise no reaction.
+    * Call Pause() or Stop() to pause or end the CreaMot 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] <turn_angle_deg> Given turn angle in degrees that should be run
+    * @param[in] <turn_radius_cm> Given Trun radius that should be run */
+    void RunTurnAngle(float turn_angle_deg, float turn_radius_cm); 
+
+    /** Additional geometric information: set the wheel diameter, also sets perimeter and degrees per cm.*/
+    void setDiamCM( float Adiam_cm); 
+
+    /** Set CreaMot speed in centimeter/sec, based on perimeter in cm */
+    void setSpeed_cm_sec(float speed_cm_sec);
+
+    /** Default rotation direction that serves as local storage, but not as actual direction */
+    bool defaultDirection;
+    
+    /** State value that is used and managed by the class owner.
+    * Used for example by Creabot library to indicate if this is the left or right CreaMot. */
+    char StateValue;
+private:
+
+    /** Additional geometric information: wheel diameter in centimeter */
+    float diam_cm;
+
+    /** Additional geometric information: wheel perimeter in centimeter */
+    float perim_cm;
+
+    /** Additional geometric information: rotation angle in degrees per cm circumference */
+    float degree_per_cm;
+
+public: 
+    // *****************************************************************
+    //  following functions are agnostic of wheel dimensions in centimeters
+    // *****************************************************************
+
+   /** High Level: Run CreaMot for a given angle.
+    *
+    * Runs CreaMot for a given angle in given direction. 
+    * Angles<0 are run in opposite direction.
+    * Call Pause() or Stop() to pause or end the CreaMot run prematurely.
+    * While running: 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] <AClockWise> Given Direction, true for CLOCKWISE, false for COUNTERCLOCKWISE.
+    * @param[in] <angle_deg> Angle>0 to rotate for, in degrees, Angles<0 are run in opposite direction.     
+    */
+   void RunDegrees  (bool AClockWise, float angle_deg);
+   
+   /** High Level: Run CreaMot for a given angle in default direction
+   * for details see RunDegrees  (bool AClockWise, float angle_deg);
+   */
+   void RunDegrees  (float angle_deg);
+
+    /** High Level: Run CreaMot 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] <AClockWise> Given Direction, true for CLOCKWISE, false for COUNTERCLOCKWISE.
+    * @param[in] <Nsteps> Number of steps to run for; Nsteps<0 are run in opposite direction!    
+    */
+   void RunSteps (bool AClockWise, int32_t Nsteps);
+
+    /** High Level: Run CreaMot "unlimited"
+    *
+    * Runs CreaMot 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 CreaMot run.
+    * @param[in] <AClockWise> Given Direction, true for CLOCKWISE, false for COUNTERCLOCKWISE.
+    */
+    void RunInfinite (bool AClockWise);
+
+    /** High Level: Pause a CreaMot Run.
+     * Put CreaMot 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();
+
+    /** 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 RestartRun();
+
+    /** 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 StopRun();
+    
+public: // All the ticker timing related parameters
+
+    /** 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  uint32_t The number of motor steps needed for a full turn. */
+    uint32_t getStepsFullTurn();
+
+    /** 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 CreaMot turn
+    */
+    void setStepsFullTurn(uint32_t StepsFullTurn);
+
+    /** Mid Level: Get the CreaMot step time. 
+    
+    * Step time is time between two CreaMot steps, and is given in microseconds
+    * and is passed to the ticker as delay time. 
+    * So the larger the value the slower the CreaMot speed.  
+    * Defaults to MOTOR_STEP_TIME_DEFAULT_US = 5000.
+    * @return  uint32_t The structure of CreaMot status registers.
+    */
+    uint32_t getStepTime_us();
+    
+    /** Set the time in microseconds between two CreaMot 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 CreaMot steps
+    */
+    void setStepTime_us(uint32_t AStepTime_us);
+
+    /** Set the time in seconds to get one full turn, rotation of 360°.
+    * was previously called setSpeed().  
+    * @param <Seconds_Per_Turn> Period of Rotation, e.g. if =20.0 then CreaMot will do 360° in 20 seconds.
+    */
+    void setRotationPeriodSec(float Seconds_Per_Turn) ;
+
+
+    motStates   CurrState;  /**< General state that the CreaMot state machine is in.*/
+    motCmands   CurrCmd;    /**< Command asked to be executed currently by the state machine.*/
+
+private:
+    void setCommand(motCmands aCmd, bool aClockWise, int32_t  aNSteps); 
+                        /**< Helper; set Command, Direction and NSteps in one call. */
+
+    // all the  Ticker and Timing procedures, used to run the CreaMot 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();
+    timestamp_t StepTime_us;    // Time in µs for one CreaMot step
+    Ticker      MotorSysTick;   // System Timer for CreaMot
+    uint32_t    Steps_FullTurn; // Number of step for a complete turn
+    bool        ClockWise;  /**< Direction that the CreaMot is asked to run. True if Clockwise */
+    int32_t     NStepsToDo; /**< Number of steps remain for the CreaMot to run. 
+                                NSteps=0: all steps finished; NSteps<0: indicates to run "forever" */
+    bool        TickIsAttached; /**< Indicates if Ticker is attached.
+                            Ticker is automatically attached while CreaMot runs, or paused; 
+                            detaches when finished a run, or stopped.  */
+    
+public: // all the low level direct CreaMot 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();
+
+    /** Low Level: turn off all CreaMot 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();
+    
+    /** Low Level: turn on the CreaMot 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();
+    
+    /** Low Level: Advance CreaMot one step, rotates in direction of variable AClockWise. */
+    void StepOnce();
+    
+    /** Low Level: Advance CreaMot one step, rotates CounterClockwise. */
+    void StepCCW();
+    
+    /** Low Level: Advance CreaMot one step, rotates Clockwise. */
+    void StepClkW();
+    
+    /** Low Level: turn on the CreaMot Phases in Zero Position. 
+     * After: State: Motor_ZERO, StepPhases==0
+     */
+    void MotorZero();
+    
+private:
+
+    /** Low Level: Engage CreaMot Phases according to MotorIndex. */
+    void SetPhases(); 
+
+    DigitalOut *MPh[4];       // Digital outputs, one per phase
+    int        StepPhase;     // CreaMot Phase Variable, counts up and down with every step
+};
+
+#endif
diff -r 6060422cd6eb -r 932ea7bdc850 motor.cpp
--- a/motor.cpp	Wed Apr 17 21:48:14 2019 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,252 +0,0 @@
-#include "motor.h"
-
-
-  // -------------------- CreaMot Class ---------------------------
-
-CreaMot::CreaMot(PinName _MPh[4]) {
-    initialization( _MPh , MOTOR_STEP_TIME_DEFAULT_US);
-}
-
-CreaMot::CreaMot(PinName _MPh0, PinName _MPh1, PinName _MPh2, PinName _MPh3) {
-    PinName _MPh[4] = {_MPh0, _MPh1, _MPh2, _MPh3};
-    initialization( _MPh , MOTOR_STEP_TIME_DEFAULT_US);
-}
-
-CreaMot::CreaMot(PinName _MPh0, PinName _MPh1, PinName _MPh2, PinName _MPh3, uint32_t AStepTime_us) {
-    PinName _MPh[4] = {_MPh0, _MPh1, _MPh2, _MPh3};
-    initialization( _MPh, AStepTime_us);
-}
-
-void CreaMot::initialization(PinName _MPh[4], uint32_t AStepTime_us) {
-
-    for (int ph=0; ph<4; ph++) { MPh[ph] = new DigitalOut(_MPh[ph]); } 
-    
-    MotorOFF();    // Default state is all phases are OFF
-    StepPhase = 0; // initial phase is Zero
-    
-    setStatus(MOTOR_nop, CLOCKWISE, 0);// Default command is NOP, clockwise direction, 0 steps
-    
-    TickIsAttached = false;
-    StepTime_us = AStepTime_us;// duration in micro second for one step
-
-    Steps_FullTurn = MOTOR_STEPS_FOR_A_TURN;  // Default Calibration value
-    _callback = NULL; // No default Callback
-    
-    // All geometric information defaults to 0:
-    rotate_angle_deg = 0; // calculated wheel rotation angle 
-    diam_cm          = 0; // wheel diameter in centimeter
-    perim_cm         = 0; // wheel perimeter in centimeter
-    degree_per_cm    = 0; // rotation angle in degrees per cm circumference
-    defaultDirection = CLOCKWISE;
-}
-
-// *****************************************************************
-//   all following functions are based on centimeter information
-// *****************************************************************
-
-/* High Level: Run CreaMot for a given number of Dist_cm, Dist_cm<0 are run in opposite direction. */
-void CreaMot::RunDist_cm  (bool AClockWise, float Dist_cm);
-{  RunDegrees(AClockWise, Dist_cm * degree_per_cm; ) }
-
-/* High Level: Run CreaMot for a given number of Dist_cm in default direction. */
-void CreaMot::RunDist_cm  (float Dist_cm);
-{  RunDegrees(defaultDirection, Dist_cm * degree_per_cm; ) }
-
-/** Additional geometric information: set the wheel diameter, also sets perimeter and degrees per cm.*/
-void CreaMot:setDiamCM( float Adiam_cm) /**< Helper; set diameter and perim to values  */
-{   diam_cm = Adiam_cm;
-    perim_cm = PI*diam_cm;
-    degree_per_cm=360.0f/perim_cm;
-} 
-
-/** Helper: calculate the needed wheel angle from a turn angle and a turn_radius_cm  */
-float CreaMot:RunTurnAngle(float turn_angle_deg, float turn_radius_cm) 
-{   // a turn radius smaller than 0 make no sense
-    if( turn_radius_cm>= 0 ) 
-        rotate_angle_deg = turn_angle_deg * PI_OVER_180 * turn_radius_cm * degree_per_cm;
-        else rotate_angle_deg = 0;
-    return rotate_angle_deg;
-} 
-
-void CreaMot::setSpeed_cm_sec(float speed_cm_sec)
-{   if (speed_cm_sec < MIN_SPEED_CM_SEC) // catch too small or negative speeds
-          setRotationPeriodSec( perim_cm / MIN_SPEED_CM_SEC); 
-    else  setRotationPeriodSec( perim_cm / speed_cm_sec );
-}
-
-// *****************************************************************
-//  all following functions are agnostic of centimeter-information
-// *****************************************************************
-
-void CreaMot::RunInfinite(bool AClockWise) {
-    setStatus(MOTOR_run, AClockWise, -1);
-    StartTick();
-}
-
-/* High Level: Run CreaMot for a given angle, angles<0 are run in opposite direction. */
-void CreaMot::RunDegrees(bool AClockWise, float angle_deg) {
- RunSteps( AClockWise, (int32_t)(angle_deg * (float)Steps_FullTurn / 360.0f) );   
-}
-
-/* High Level: Run CreaMot for a given angle in default direction, angles<0 are run in opposite direction. */
-void CreaMot::RunDegrees(float angle_deg) {
- RunSteps( defaultDirection, (int32_t)(angle_deg * (float)Steps_FullTurn / 360.0f) );   
-}
-
-/* High Level: Run CreaMot for a given number of steps, steps<0 are run in opposite direction. */
-void CreaMot::RunSteps(bool AClockWise, int32_t steps) {
-    if (steps!=0) 
-        { setStatus(MOTOR_run, AClockWise ^^ (steps<0), abs(steps));
-          StartTick(); }
-}
-
-void CreaMot::PauseRun() 
-{   if (CurrCmd==MOTOR_run) CurrCmd = MOTOR_pause;  }
-
-void CreaMot::RestartRun() 
-{   if (CurrCmd==MOTOR_pause) CurrCmd = MOTOR_run;  }
-
-void CreaMot::StopRun() 
-{   CurrCmd = MOTOR_stop;  } 
-
-MotStatus CreaMot::getStatus() { return Status; }
-
-/*******************************************************
- **   Ticker / Timing procedures
- *******************************************************/
-//Get, set the scaling
-uint32_t CreaMot::getStepsFullTurn()
-{    return Steps_FullTurn;  }
-
-void CreaMot::setStepsFullTurn(uint32_t StepsFullTurn) 
-{   Steps_FullTurn = StepsFullTurn; }
-
-void CreaMot::setRotationPeriodSec(float Seconds_Per_Turn) {
-    // rescale to usec and pass on to the next handler. 
-    setStepTime_us( uint32_t(Seconds_Per_Turn / Steps_FullTurn * 1000000) ) ;
-}
-void CreaMot::setStepTime_us(uint32_t AStepTime_us) {
-    if(StepTime_us == AStepTime_us) return; // avoid futile activity
-    if (StepTime_us < MOTOR_STEP_TIME_MIN_US) // filter too small values
-       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(); }
- }
-
-void CreaMot::StartTick() {
-    if(!TickIsAttached)   {
-        // Connect Interrupt routine in which the CreaMot and all the state machine is performed
-        MotorSysTick.attach_us(callback(this, &CreaMot::ProcessMotorStateMachine), StepTime_us);
-        // last=tuneTimings.read_us();
-        TickIsAttached=true;
-        }
-}
-
-void CreaMot::ProcessMotorStateMachine()
-{
-    switch(CurrCmd) {
-        case MOTOR_run: {
-            switch(CurrState) {
-                case Motor_OFF:
-                    MotorON(); // First only turn on the CreaMot ..
-                    break;
-                case Motor_ZERO:
-                case Motor_ON:
-                        CurrState = Motor_RUN;
-                case Motor_RUN:
-                    if (NStepsToDo==0)  // No more steps to go
-                        { CurrCmd = MOTOR_stop; 
-                          if (_callback) _callback.call(); } 
-                      else // More steps to go
-                        { StepOnce(); 
-                        NStepsToDo--;}
-                    break;
-                } // switch(CurrState)
-            } // case MOTOR_run
-        case MOTOR_stop:
-            StopTick();
-            CurrCmd = MOTOR_nop; 
-            MotorOFF(); 
-            break;       
-        case MOTOR_nop:
-        case MOTOR_pause:
-        default: break;
-    } // switch(CurrCmd)
-}
-
-void CreaMot::StopTick() {
-    if(TickIsAttached)   
-      { MotorSysTick.detach(); TickIsAttached=false; }
-}
-
-/*******************************************************
- **   all the low level direct CreaMot HW access
- *******************************************************/
- 
-void CreaMot::setStatus(motCmands aCmd, bool AClockWise, int32_t  aNSteps) {
-    cmd = aCmd;
-    AClockWise = AClockWise;
-    NSteps  = aNSteps;
-};
-
-
- void CreaMot::MotorTest()    // Just to check that it make a full turn back and forth
-{
-    int i;
-    MotorON();
-    for (i=0; i<Steps_FullTurn; i++) {
-        wait(0.005);
-        StepClkW();
-        }   
-    wait(0.5);
-    for (i=0; i<Steps_FullTurn; i++) {
-        wait(0.005);
-        StepCCW();
-        }   
-    MotorOFF();
-}
-
- /** Turn off all CreaMot Phases, no more current flowing */
-void CreaMot::MotorOFF() 
-{   for (int ph=0; ph<4; ph++) *MPh[ph] = 0;  
-    CurrState=Motor_OFF;
-}
-
-/** Turn on the CreaMot Phase, In the last used phase, memorized in StepPhases 
-*  Equivalent to what previously the function "void Start();" did */
-void CreaMot::MotorON()
-{   SetPhases(); // attention, does not change StepPhase!
-    if (StepPhase==0)  CurrState=Motor_ZERO;  
-        else CurrState=Motor_ON;
-} 
-
-/** CreaMot phases turned on and put to Zero Position*/    
-void CreaMot::MotorZero() {
-    StepPhase = 0;  // sets the phases to 0
-    SetPhases(); 
-    CurrState=Motor_ZERO;
-}
-
-void    CreaMot::StepOnce()     // Move the CreaMot in the Status 'direction'
-{   if (Status.AClockWise) StepClkW(); else StepCCW();
-}
-
-void    CreaMot::StepClkW()    // Move the CreaMot one step Clockwise
-{   if (StepPhase<7) StepPhase++;  else  StepPhase = 0;
-    SetPhases();
-}
-void    CreaMot::StepCCW()    // Move the CreaMot one step Clockwise
-{   if (StepPhase>0) StepPhase--;  else  StepPhase = 7;
-    SetPhases();
-}
-
-static const int MotPh[4][8] = 
-    { {1, 1, 0, 0, 0, 0, 0, 1}, 
-      {0, 1, 1, 1, 0, 0, 0, 0}, 
-      {0, 0, 0, 1, 1, 1, 0, 0}, 
-      {0, 0, 0, 0, 0, 1, 1, 1}};
-      
-void    CreaMot::SetPhases()    // Engage CreaMot Phases according to StepPhase
-{ for (int ph=0; ph<4; ph++) { *MPh[ph] = MotPh[ph][StepPhase]; }   }
-
diff -r 6060422cd6eb -r 932ea7bdc850 motor.h
--- a/motor.h	Wed Apr 17 21:48:14 2019 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,447 +0,0 @@
-/**
- * @file CreaMot.h
- * \brief File contains Crealab CreaMot Library.
- 
- * CreaMot.h contains the class CreaMot, and related enums and structs.
- * Includes only "mbed.h".
- *
- * MotStatus structure is dissolved into the CreaMot Class
- *
- * 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/  */
- 
- // -------------------- CreaMot ---------------------------
- 
-#ifndef MOTOR_H
-#define MOTOR_H
-
-#include "mbed.h"
-
-#define MOTOR_STEP_TIME_MIN_US 700      /**< Shortest Time between two CreaMot steps = 0.7ms, was MOTOR_STEP_TIME_MIN*/
-#define MOTOR_STEP_TIME_DEFAULT_US 5000 /**< Default Time between two CreaMot steps = 5ms, was MOTOR_STEP_TIME_DEFAULT*/
-#define MOTOR_STEPS_FOR_A_TURN 4096     /**< Default number of CreaMot steps to complete a turn = 4096 steps  */
-#define CLOCKWISE true                  /**< Constant for Clockwise direction */
-#define COUNTERCLOCKWISE false          /**< Constant for Counter-Clockwise direction */
-#define MAX_SPEED_CM_SEC 30.0f    /**< Clamp maximum advancement speed = 30cm/sec, was MAX_SPEED */
-#define MIN_SPEED_CM_SEC 0.001f   /**< Clamp minimum advancement speed = 10um/sec */
-#define PI 3.141592f    /** PI needed to calcuate from angle to distances */
-#define PI_OVER_180 (PI/180.0f)  /** needed to translate from angle to circumference */
-
-/** \enum motStates 
-* \brief Possible States of CreaMot 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,     /**< CreaMot at phase position 0 and ON, only reached by call of Zero() procedure. */  
-    Motor_ON,       /**< Phases are engaged, but CreaMot state machine stopped, replaces Motor_PAUSE. */  
-    Motor_RUN       /**< Phases are engaged, and CreaMot state machine runs*/  
-} motStates;
-
-/** \enum motCmands 
-* \brief Commands that are handled by the CreaMot state machine
-*
-* These Commands are issued asynchonously by calling CreaMot 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 {
-    MOTOR_nop = 0,  /**< No active command to execute. */
-    MOTOR_run,      /**< Run CreaMot until Nsteps are achieved. */
-    MOTOR_stop,     /**< Stop immediately all activity, turn off CreaMot. */
-    MOTOR_pause     /**< CreaMot is temporarily paused from the state run. */
-} motCmands;
-
-/** ATTENTION UNDER CONSTRUCTION, DO NOT YET USE.
-*
-* Class of a Four Phase Stepper CreaMot.
-*
-* 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 the one ongoing command versus the CreaMot state at every tick.
-* When End of Run is detected tickers stop, and CreaMot turns off. 
-*
-* To define the speed of the CreaMot set the variable StepTime_us, either by
-*    a) Using the createor CreaMot(...., uint32_t AStepTime_us);
-*    b) Calling function setStepTime_us(uint32_t AStepTime_us); any time
-*    c) or leave it to the default value MOTOR_STEP_TIME_DEFAULT_US = 5000
-*
-* To be able to run the CreaMot for a given angle, set the number of steps per full turn
-*    with the function "setStepsFullTurn"
-*    That value defaults to MOTOR_STEPS_FOR_A_TURN = 4096
-*
-* To be able to run the CreaMot for a given perimeter distance in centimeters, 
-*    set the wheel diameter with the function setDiamCM( float Adiam_cm); 
-*
-* 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 CreaMot 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.
-*
-*Low-Level functions directly talk to the hardware without ticker. 
-*   Use of Low-Level functions while tickers still run may lead to unexpected behavior. 
-*
-* NB: all times are uint32_t, step numbers are int32_t
-*/
-class CreaMot
-{
-public:
-    /** CreaMot Class Creator
-    *
-    * Creates the class, initiallizes all fields, creates Phase Pins.  
-    * Time between two steps defaults here to MOTOR_STEP_TIME_DEFAULT_US = 5000usec.
-    * Pin names are used to create digital outputs: Pin0 = new DigitalOut(_MPh0)
-    *
-    @code
-       PinName MotPhases[] = {PB_1, PB_15, PB_14, PB_13};
-       CreaMot MotorName(MotPhases); // Call this creator for example like this:  
-    @endcode 
-    * 
-    * @param _MPh Array of Names of the 4 Digital Pins of type PinNames 
-    */
-    CreaMot(PinName _MPh[4] );
-    
-    /** CreaMot Class Creator
-    *
-    * Creates the class, initiallizes all fields, creates Phase Pins.  
-    * Time between two steps defaults here to MOTOR_STEP_TIME_DEFAULT_US=5000usec.
-    * Pin names are used to create digital outputs: Pin0 = new DigitalOut(_MPh0)
-    *
-    @code
-      // Call this creator for example like this:
-       CreaMot MotorName(PB_1, PB_15, PB_14, PB_13);
-    @endcode 
-    * 
-    * @param <_MPh0, _MPh1, _MPh2, _MPh3> List of Names of the 4 Digital Pins of type PinNames    
-    */
-    CreaMot(PinName _MPh0, PinName _MPh1, PinName _MPh2, PinName _MPh3);
-    
-    /** CreaMot Class Creator
-    *
-    * Creates the class, initiallizes all fields, creates Phase Pins.  
-    * Time between two steps is passed as parameter.
-    * Pin names are used to create digital outputs: Pin0 = new DigitalOut(_MPh0)
-    *
-    @code
-      // Call this creator for example like this:
-       CreaMot MotorName(PB_1, PB_15, PB_14, PB_13, 6000);
-    @endcode 
-    *
-    * @param <_MPh0, _MPh1, _MPh2, _MPh3> List of Names of the 4 Digital Pins of type PinNames    
-    * @param <AStepTime_us> the time in usec between two steps, thats used initially.   
-    */
-    CreaMot(PinName _MPh0, PinName _MPh1, PinName _MPh2, PinName _MPh3, uint32_t AStepTime_us);
-
-private:
-    // 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.
-    *
-    * A callback is called when the current Command reaches it's requested end.
-    * Not called when the CreaMot 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; }
-
-    // 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)(void)) {_callback = CBfunction;};
-
-
-    /** Attach a Callback function, member of a class.
-    * Only called when a Run Command reaches it's requested end.
-    * Not called when the CreaMot is stopped by a call of Stop Function, or any other events.
-    * For use see precautions at Class description above. 
-    * @param <*object> Class pointer which possesses callback member.
-    * @param <*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, state variable endMove can be polled by main thread
-    void AClass::CallBackMemberFunction()
-    {  endMove=true;  }
-    @endcode
-    */
-    template<typename T>
-    void callbackSet(T *object, void (T::*CBmember)(void)) {
-        _callback = callback(object,CBmember);
-    }
-
-    /** Remove the Callback function that may have been attached previously. */
-    void callbackRemove() { _callback = NULL; };
-
-public: 
-    // *********************************************************************
-    //  all following functions use wheel diameter to achieve cm distance
-    // *********************************************************************
-
-    /** High Level: Run CreaMot for a given number of centimeters.
-    *
-    * Runs CreaMot for a given wheel circumference in cimeters in given direction. 
-    * You must setup the perimeter and diameter with setDiam(Adiam_cm) in advance, otherwise no reaction.
-    * Call Pause() or Stop() to pause or end the CreaMot 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] <AClockWise> Given Direction, true for CLOCKWISE, false for COUNTERCLOCKWISE.
-    * @param[in] <Dist_cm> Circumference to rotate for, in cm, Dist_cm<0 are run in opposite direction.
-    */
-    void RunDist_cm  (bool AClockWise, float Dist_cm);
-   
-    /** High Level: Run CreaMot for a given number of centimeters in default direction.
-    * Same as RunDist_cm(AClockWise,Dist_cm) but uses Default diretion.*/
-    void RunDist_cm  (float Dist_cm);
-    
-    /** High Level: Run CreaMot for a turn angle around a turn_radius_cm  in default direction
-    *
-    * Runs CreaMot for a given wheel circumference in cimeters in given direction. 
-    * You must setup the perimeter and diameter with setDiam(Adiam_cm) in advance, otherwise no reaction.
-    * Call Pause() or Stop() to pause or end the CreaMot 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] <turn_angle_deg> Given turn angle in degrees that should be run
-    * @param[in] <turn_radius_cm> Given Trun radius that should be run */
-    float RunTurnAngle(float turn_angle_deg, float turn_radius_cm); 
-
-    /** Additional geometric information: set the wheel diameter, also sets perimeter and degrees per cm.*/
-    void setDiamCM( float Adiam_cm); 
-
-    /** Set CreaMot speed in centimeter/sec, based on perimeter in cm */
-    void setSpeed_cm_sec(float speed_cm_sec);
-
-
-    /** Calculated wheel Angle from calcAngle() Helper function */
-    float rotate_angle_deg;
-
-    /** Additional geometric information: wheel diameter in centimeter */
-    float diam_cm;
-
-    /** Additional geometric information: wheel perimeter in centimeter */
-    float perim_cm;
-
-    /** Additional geometric information: rotation angle in degrees per cm circumference */
-    float degree_per_cm;
-
-    /** Default rotation direction that serves as local storage, but not as actual direction */
-    bool defaultDirection;
-    
-    /** State value that is used and managed by the class owner.
-    * Used for example by Creabot library to indicate if this is the left or right CreaMot. 
-    */
-    char StateValue;
-
-public: 
-    // *****************************************************************
-    //  following functions are agnostic of wheel dimensions in centimeters
-    // *****************************************************************
-
-   /** High Level: Run CreaMot for a given angle.
-    *
-    * Runs CreaMot for a given angle in given direction. 
-    * Angles<0 are run in opposite direction.
-    * Call Pause() or Stop() to pause or end the CreaMot run prematurely.
-    * While running: 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] <AClockWise> Given Direction, true for CLOCKWISE, false for COUNTERCLOCKWISE.
-    * @param[in] <angle_deg> Angle>0 to rotate for, in degrees, Angles<0 are run in opposite direction.     
-    */
-   void RunDegrees  (bool AClockWise, float angle_deg);
-   
-   /** High Level: Run CreaMot for a given angle in default direction
-   * for details see RunDegrees  (bool AClockWise, float angle_deg);
-   */
-   void RunDegrees  (float angle_deg);
-
-    /** High Level: Run CreaMot 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] <AClockWise> Given Direction, true for CLOCKWISE, false for COUNTERCLOCKWISE.
-    * @param[in] <Nsteps> Number of steps to run for; Nsteps<0 are run in opposite direction!    
-    */
-   void RunSteps (bool AClockWise, int32_t Nsteps);
-
-    /** High Level: Run CreaMot "unlimited"
-    *
-    * Runs CreaMot 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 CreaMot run.
-    * @param[in] <AClockWise> Given Direction, true for CLOCKWISE, false for COUNTERCLOCKWISE.
-    */
-    void RunInfinite (bool AClockWise);
-
-    /** High Level: Pause a CreaMot Run.
-     * Put CreaMot 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();
-
-    /** 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 RestartRun();
-
-    /** 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 StopRun();
-    
-public: // All the ticker timing related parameters
-
-    /** 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  int32_t The structure of CreaMot status registers. */
-    int32_t getStepsFullTurn();
-
-    /** 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 CreaMot turn
-    */
-    void setStepsFullTurn(int32_t StepsFullTurn);
-
-    /** Mid Level: Get the CreaMot step time. 
-    
-    * Step time is time between two CreaMot steps, and is given in microseconds
-    * and is passed to the ticker as delay time. 
-    * So the larger the value the slower the CreaMot speed.  
-    * Defaults to MOTOR_STEP_TIME_DEFAULT_US = 5000.
-    * @return  uint32_t The structure of CreaMot status registers.
-    */
-    uint32_t getStepTime_us();
-    
-    /** Set the time in microseconds between two CreaMot 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 CreaMot steps
-    */
-    void setStepTime_us(uint32_t AStepTime_us);
-
-    /** Set the time in seconds to get one full turn, rotation of 360°.
-    * was previously called setSpeed().  
-    * @param <Seconds_Per_Turn> Period of Rotation, e.g. if =20.0 then CreaMot will do 360° in 20 seconds.
-    */
-    void setRotationPeriodSec(float Seconds_Per_Turn) ;
-
-private:
-    // all the  Ticker and Timing procedures, used to run the CreaMot 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();
-    timestamp_t StepTime_us;    // Time in µs for one CreaMot step
-    Ticker      MotorSysTick;   // System Timer for CreaMot
-    int32_t     Steps_FullTurn; // Number of step for a complete turn
-    bool        ClockWise;  /**< Direction that the CreaMot is asked to run. True if Clockwise */
-    int32_t     NStepsToDo; /**< Number of steps remain for the CreaMot to run. 
-                                NSteps=0: all steps finished; NSteps<0: indicates to run "forever" */
-    bool        TickIsAttached; /**< Indicates if Ticker is attached.
-                            Ticker is automatically attached while CreaMot runs, or paused; 
-                            detaches when finished a run, or stopped.  */
-    
-public: // all the low level direct CreaMot HW access, States are immediately reached
-    motStates   CurrState;  /**< General state that the CreaMot state machine is in.*/
-    motCmands   CurrCmd;    /**< Command asked to be executed currently by the state machine.*/
-    void setStatus(motCmands aCmd, bool AClockWise, int32_t  aNSteps); 
-                        /**< Helper; set Command, Direction and NSteps in one call. */
-    
-
-    /** 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();
-
-    /** Low Level: turn off all CreaMot 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();
-    
-    /** Low Level: turn on the CreaMot 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();
-    
-    /** Low Level: Advance CreaMot one step, rotates in direction of variable AClockWise. */
-    void StepOnce();
-    
-    /** Low Level: Advance CreaMot one step, rotates CounterClockwise. */
-    void StepCCW();
-    
-    /** Low Level: Advance CreaMot one step, rotates Clockwise. */
-    void StepClkW();
-    
-    /** Low Level: turn on the CreaMot Phases in Zero Position. 
-     * After: State: Motor_ZERO, StepPhases==0
-     */
-    void MotorZero();
-    
-private:
-
-    /** Low Level: Engage CreaMot Phases according to MotorIndex. */
-    void SetPhases(); 
-
-    DigitalOut *MPh[4];       // Digital outputs, one per phase
-    int        StepPhase;     // CreaMot Phase Variable, counts up and down with every step
-};
-
-#endif