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.
Dependents: VAM_reliability VAM_REV2 VAM_DAX VAM_DAX_RELIABILITY ... more
Fork of Stepper by
Diff: Stepper.cpp
- Revision:
- 0:f2a3b0be279d
- Child:
- 1:a456aa3935ca
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Stepper.cpp Mon Apr 15 11:29:15 2013 +0000
@@ -0,0 +1,169 @@
+#include "Stepper.h"
+
+//***********************************/************************************
+// Constructors //
+//***********************************/************************************
+Stepper::Stepper(PinName clk, PinName dir): _clk(clk) , _dir(dir)
+{
+ _state = STOP;
+ _pos = 0;
+ _steps = 0;
+ _spd = 400;
+}
+
+//***********************************/************************************
+// Get Set //
+//***********************************/************************************
+void Stepper::setSpeed(float speed)
+{
+ _spd = (speed<0) ? -speed : speed; //speed must be unsigned
+ if(_spd)_dtmin = 1000000/_spd; //fin min delay (max spd)
+}
+
+float Stepper::getSpeed(void)
+{
+ return _spd;
+}
+
+void Stepper::setAcceleration(float acc)
+{
+ _acc = (acc<0) ? -acc : acc; //acceleration must be unsigned
+ if(_acc)_dt0 = 676000 * sqrt(2.0/_acc); //Equation 15 [µs] instead Equation 7
+}
+
+float Stepper::getAcceleration(void)
+{
+ return _acc;
+}
+
+void Stepper::setDeceleration(float dec)
+{
+ _dec = (dec<0) ? -dec : dec; //deceleration must be unsigned
+}
+
+float Stepper::getDeceleration(void)
+{
+ return _dec;
+}
+
+void Stepper::setPositionZero(void)
+{
+ _pos = 0;
+}
+
+int Stepper::getPosition(void)
+{
+ return _pos;
+}
+
+bool Stepper::stopped(void)
+{
+ return (_state == STOP) ? true : false;
+}
+
+//***********************************/************************************
+// Public Methods //
+//***********************************/************************************
+void Stepper::stop(void)
+{
+ _timer.detach(); //detach step generator thread
+ _state = STOP; //update state machine
+ _steps = 0; //reset total steps per move
+}
+
+void Stepper::rotate(bool direction)
+{
+ if(!_spd)return; //spd must > 0
+ _dir = direction; //set output pin direction value
+ _steps = 0; //rotate until stop() by user
+ run(); //start thread
+}
+
+void Stepper::move(int steps)
+{
+ if(!steps || !_spd) return;
+ if(steps<0) //fin direction
+ {
+ _dir = CCW; //set output pin direction value
+ _steps = -steps; //total steps per move must be unsigned
+ }
+ else
+ {
+ _dir = CW; //set output pin direction value
+ _steps = steps; //total steps per move
+ }
+ run();
+}
+
+void Stepper::goesTo(int position)
+{
+ move(position-_pos); //absolute to relative transformation
+}
+
+//***********************************/************************************
+// Protected Methods //
+//***********************************/************************************
+void Stepper::run(void)
+{
+ static float dtn; //delay for next step
+ static unsigned int nStartDec; //steps to start decelerate
+ static unsigned int n; //steps counter
+
+ switch(_state)
+ {
+ case STOP:
+ n = 0; //reset setp counter (motor stopped)
+
+ if(_dt0 <= _dtmin || !_acc) //if first step faster than max speed step
+ {
+ dtn = _dtmin; //delay = delaymin
+ _state = CRUISE; //no acceleration needed
+ }
+ else
+ {
+ dtn = _dt0; //set first delay
+ _state = ACCEL; //acceleration phase
+ }
+
+ if(_steps) //if finite mov required
+ {
+ unsigned int nToSpeed = nTo(_spd,_acc); //Equation 16 How many steps to reach max speed
+ nStartDec = (_steps * _dec) / (_dec + _acc); //Equation 19 after how many step we must start decelerate
+ if(nStartDec > nToSpeed)nStartDec = _steps - ((nToSpeed*_acc)/_dec); //if speed can be reach Equation 17
+ }
+ break;
+
+ case ACCEL:
+ dtn -= (dtn*2) / ((n<<2)+1); //Equation 20 find next delay
+ if((unsigned int)dtn <= _dtmin) //if max speed reached
+ {
+ dtn = _dtmin;
+ _state = CRUISE; //constant phase
+ }
+ if(_steps && _dec && n >= nStartDec)_state = DECEL; //chech when must start decelerate
+
+ break;
+
+ case CRUISE:
+ if(_steps && _dec && n >= nStartDec)_state = DECEL; //chech when must start decelerate
+ break;
+
+ case DECEL:
+ dtn += (dtn*2) / (((_steps-n)<<2)+1); //Equation 20 find next delay
+ break;
+ }
+
+ n++; //increment step counter
+ _pos += (_dir<<1)-1; //set new position +1 if cw; -1 if ccw
+ _clk = !_clk; //toggle step out pin
+ _timer.attach_us(this,&Stepper::run,(unsigned int)dtn); //set next delay
+ if(_steps && n >= _steps)stop(); //check for motor stop
+}
+
+unsigned int Stepper::nTo(float speed,float acc)
+{
+ if(speed<0)speed = -speed;
+ if(acc<0)acc = -acc;
+
+ return (!acc || !speed) ? 0 : (speed * speed) / (2 * acc); //Equation 16 step number n as a function of speed & acceleration
+}
