Provides an API software interface to TIMER2 to control upto four stepper motors.

Dependents:   Steppermotor

Files at this revision

API Documentation at this revision

Comitter:
AjK
Date:
Fri May 20 09:13:31 2011 +0000
Parent:
3:71ab7209adb3
Commit message:
1.1 See ChangeLog.h

Changed in this revision

inc/ChangeLog.h Show annotated file Show diff for this revision Revisions of this file
inc/SimpleStepperProfiler.h Show annotated file Show diff for this revision Revisions of this file
inc/SimpleSteppers.h Show annotated file Show diff for this revision Revisions of this file
inc/example1.h Show annotated file Show diff for this revision Revisions of this file
inc/example2.h Show annotated file Show diff for this revision Revisions of this file
src/SimpleSteppers.cpp Show annotated file Show diff for this revision Revisions of this file
diff -r 71ab7209adb3 -r 7b7940df7865 inc/ChangeLog.h
--- a/inc/ChangeLog.h	Mon May 02 10:17:33 2011 +0000
+++ b/inc/ChangeLog.h	Fri May 20 09:13:31 2011 +0000
@@ -3,7 +3,13 @@
 SimpleSteppers change log history.
 ==================================
 
+1.1    20/May/2011
+
+    * Added the SimpleStepperProfiler class to control start/stop accel profiles.
+    * Added example2.h to show how to use the profiler.
+    
 1.0     2/May/2011
+
     * Initial release.
 
 */
\ No newline at end of file
diff -r 71ab7209adb3 -r 7b7940df7865 inc/SimpleStepperProfiler.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/inc/SimpleStepperProfiler.h	Fri May 20 09:13:31 2011 +0000
@@ -0,0 +1,104 @@
+/*
+    Copyright (c) 2011 Andy Kirkham
+ 
+    Permission is hereby granted, free of charge, to any person obtaining a copy
+    of this software and associated documentation files (the "Software"), to deal
+    in the Software without restriction, including without limitation the rights
+    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+    copies of the Software, and to permit persons to whom the Software is
+    furnished to do so, subject to the following conditions:
+ 
+    The above copyright notice and this permission notice shall be included in
+    all copies or substantial portions of the Software.
+ 
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+    THE SOFTWARE.
+*/
+
+
+#ifndef AJK_SIMPLESTEPERPROFILER_H
+#define AJK_SIMPLESTEPERPROFILER_H
+
+#include "mbed.h"
+#include "SimpleSteppers.h"
+
+namespace AjK {
+
+class SimpleStepperProfiler : public SimpleStepper {
+
+protected:
+    Ticker  _poll;
+    int     _desired_speed;
+    int     _step_pos;
+    int     _step_neg;
+    int     _poll_interval;
+
+    void poll(void) 
+    {
+        if (_steps_per_second < _desired_speed) {
+            _steps_per_second += _step_pos;
+            if (_steps_per_second > _desired_speed) {
+                _steps_per_second = _desired_speed;
+            }
+            SimpleStepper::setSpeed(_steps_per_second);
+        }
+        if (_steps_per_second > _desired_speed) {
+            _steps_per_second -= _step_neg;
+            if (_steps_per_second < _desired_speed) {
+                _steps_per_second = _desired_speed;
+            }
+            SimpleStepper::setSpeed(_steps_per_second);
+        }
+    }
+    
+public:
+
+    friend class Ticker;
+    
+    SimpleStepperProfiler(PinName pulse, SimpleStepperOutput *direction = 0) : 
+        SimpleStepper(pulse, direction) 
+    {
+        _desired_speed = 0;
+        _step_pos      = 10;
+        _step_neg      = 10;
+        _poll_interval = 10000; // 10ms
+        _poll.attach_us(this, &SimpleStepperProfiler::poll, _poll_interval);   
+    }
+    
+    int  getStepPos(void)  { return _step_pos; }
+    void setStepPos(int i) { _step_pos = i; }
+    
+    int  getStepNeg(void)  { return _step_neg; }
+    void setStepNeg(int i) { _step_neg = i; }
+    
+    int  getPollInterval(void)  { return _poll_interval; }
+    void setPollInterval(int i) 
+    { 
+        _poll_interval = i;
+        _poll.detach();
+        _poll.attach_us(this, &SimpleStepperProfiler::poll, _poll_interval);
+    }
+    
+    void setSpeed(int steps_per_second = 0, uint32_t raw = 0)
+    {
+        _desired_speed = steps_per_second;
+    }
+    
+    void eStop(void) 
+    {
+        _desired_speed = _steps_per_second = 0;
+        SimpleStepper::setSpeed(_steps_per_second);
+    }
+    
+   
+};
+
+}; // namespace AjK ends.
+
+
+#endif
diff -r 71ab7209adb3 -r 7b7940df7865 inc/SimpleSteppers.h
--- a/inc/SimpleSteppers.h	Mon May 02 10:17:33 2011 +0000
+++ b/inc/SimpleSteppers.h	Fri May 20 09:13:31 2011 +0000
@@ -134,6 +134,8 @@
     int64_t     _pulseWrapNeg;    
     uint32_t    _currentMatch;
     
+    volatile int _steps_per_second;
+    
     bool        _maintainPositionData;
     
     PULSE_STATE _pulseState;
@@ -253,6 +255,13 @@
      */
     void setSpeed(double steps_per_second = 0, uint32_t raw = 0); 
     
+    /** getSpeed
+     * 
+     * Get the demanded motor speed in pulses per second. Zero stops all motor pulses.
+     * @return int steps_per_second Number of pulses per second demanded.     
+     */
+    int getSpeed(void) { return _steps_per_second; }
+    
     /** setInterval
      * 
      * Set the motor speed pulse interval. Zero stops all motor pulses.
diff -r 71ab7209adb3 -r 7b7940df7865 inc/example1.h
--- a/inc/example1.h	Mon May 02 10:17:33 2011 +0000
+++ b/inc/example1.h	Fri May 20 09:13:31 2011 +0000
@@ -1,46 +1,46 @@
-
-#include "mbed.h"
-#include "SimpleSteppers.h"
-
-SimpleStepperOutput led1(LED1);
-
-// SimpleStepperOutput is basically the same as
-// Mbed's DigitalOut class. However, it's more
-// portable to other platforms without having
-// to also port the entire Mbed library.
-SimpleStepperOutput sdir0(p17);
-SimpleStepperOutput sdir1(p18);
-SimpleStepperOutput sdir2(p19);
-SimpleStepperOutput sdir3(p20);
-
-// Create four steppers.
-// Stepper0 has the pulse output on p8 and dir on p17
-SimpleStepper stepper0(p8, &sdir0);
-// Stepper1 has the pulse output on p7 and dir on p18
-SimpleStepper stepper1(p7, &sdir1);
-// Stepper2 has the pulse output on p7 and dir on p19
-SimpleStepper stepper2(p6, &sdir2);
-// Stepper3 has the pulse output on p7 and dir on p20
-SimpleStepper stepper3(p5, &sdir3);
-
-int main() {
-
-    // We do not need to maintain the stepper position
-    // for this simple example. This reduces the amount
-    // of work the ISR has to do.
-    stepper0.setMaintainPositionData(false);
-    stepper1.setMaintainPositionData(false);
-    stepper2.setMaintainPositionData(false);
-    stepper3.setMaintainPositionData(false);
-    
-    // Set all steppers to top speed of 5000 pulses/second.
-    stepper0.setSpeed(5000);
-    stepper1.setSpeed(5000);
-    stepper2.setSpeed(5000);
-    stepper3.setSpeed(5000);
-
-    while(1) {
-        led1 = !led1;
-        wait(0.2);        
-    }
-}
+
+#include "mbed.h"
+#include "SimpleSteppers.h"
+
+SimpleStepperOutput led1(LED1);
+
+// SimpleStepperOutput is basically the same as
+// Mbed's DigitalOut class. However, it's more
+// portable to other platforms without having
+// to also port the entire Mbed library.
+SimpleStepperOutput sdir0(p17);
+SimpleStepperOutput sdir1(p18);
+SimpleStepperOutput sdir2(p19);
+SimpleStepperOutput sdir3(p20);
+
+// Create four steppers.
+// Stepper0 has the pulse output on p8 and dir on p17
+SimpleStepper stepper0(p8, &sdir0);
+// Stepper1 has the pulse output on p7 and dir on p18
+SimpleStepper stepper1(p7, &sdir1);
+// Stepper2 has the pulse output on p7 and dir on p19
+SimpleStepper stepper2(p6, &sdir2);
+// Stepper3 has the pulse output on p7 and dir on p20
+SimpleStepper stepper3(p5, &sdir3);
+
+int main() {
+
+    // We do not need to maintain the stepper position
+    // for this simple example. This reduces the amount
+    // of work the ISR has to do.
+    stepper0.setMaintainPositionData(false);
+    stepper1.setMaintainPositionData(false);
+    stepper2.setMaintainPositionData(false);
+    stepper3.setMaintainPositionData(false);
+    
+    // Set all steppers to top speed of 5000 pulses/second.
+    stepper0.setSpeed(5000);
+    stepper1.setSpeed(5000);
+    stepper2.setSpeed(5000);
+    stepper3.setSpeed(5000);
+
+    while(1) {
+        led1 = !led1;
+        wait(0.2);        
+    }
+}
diff -r 71ab7209adb3 -r 7b7940df7865 inc/example2.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/inc/example2.h	Fri May 20 09:13:31 2011 +0000
@@ -0,0 +1,54 @@
+
+#include "mbed.h"
+#include "SimpleStepperProfiler.h"
+
+SimpleStepperOutput led1(LED1);
+
+// SimpleStepperOutput is basically the same as
+// Mbed's DigitalOut class. However, it's more
+// portable to other platforms without having
+// to also port the entire Mbed library.
+SimpleStepperOutput sdir0(p17);
+
+// Create four stepper profilers.
+// Stepper0 has the pulse output on p8 and dir on p17
+SimpleStepperProfiler stepper0(p8, &sdir0);
+
+int main() {
+    
+    // We do not need to maintain the stepper position
+    // for this simple example. This reduces the amount
+    // of work the ISR has to do.
+    stepper0.setMaintainPositionData(false);
+    
+    // Set all steppers to top speed of 5000 pulses/second.
+    // Because we are using the SimpleStepperProfiler then
+    // the accel will be 1000pps/s, so to reach 5000pps will
+    // take 5seconds.
+    
+    // The accel profile can be adjusted by altering the profilers
+    // step value and poll interval. The default step value is 10
+    // each poll interval and the default poll interval is 10ms.
+    // This equates to 100 * 10 = 1000pps/s. Adjust as required
+    // using :-
+    //   setStepPos(int i); where i is the step value +/- each poll interval accel
+    //   setStepNeg(int i); where i is the step value +/- each poll interval decel
+    //   setPollInterval(int i) where i is the poll interval in microseconds.
+    
+    stepper0.setSpeed(5000);
+    while(stepper0.getSpeed() != 5000); // wait to reach speed.
+    
+    // Decel stepper to halt/stop.
+    stepper0.setSpeed(0);
+    while(stepper0.getSpeed() != 0); // wait to reach speed.
+    
+    // Set speed but peform async emergency stop while accelerating.
+    stepper0.setSpeed(5000);
+    wait(2.5);
+    stepper0.eStop();
+    
+    while(1) {
+        led1 = !led1;
+        wait(0.2);        
+    }
+}
diff -r 71ab7209adb3 -r 7b7940df7865 src/SimpleSteppers.cpp
--- a/src/SimpleSteppers.cpp	Mon May 02 10:17:33 2011 +0000
+++ b/src/SimpleSteppers.cpp	Fri May 20 09:13:31 2011 +0000
@@ -57,6 +57,8 @@
     
     _maintainPositionData = true; 
     
+    _steps_per_second = 0;
+    
     setPulseSense(1);
     setDirectionSense(1);
     
@@ -194,12 +196,14 @@
     if (steps_per_second == 0) {
         LPC_TIM2->EMR |=  (NothingOnMatch << _EMCshift);
         LPC_TIM2->MCR &= ~(7UL << _match_shift);
-        if (_pulseSense) LPC_TIM2->EMR &= ~_EMmask; else LPC_TIM2->EMR |= _EMmask; 
+        if (_pulseSense) LPC_TIM2->EMR |= _EMmask; else LPC_TIM2->EMR &= ~_EMmask; 
         _stepperState = Stopped;
         _pulseState = PulseIdle;
         _commandSpeed = 0;
+        _steps_per_second = 0;
     }
     else {
+        _steps_per_second = steps_per_second;
         int n = steps_per_second;
         if (n < 0) n *= -1;
         if (_direction) {