Skip to content

GarethS/Motor

Repository files navigation

Gareth Scott (c) 2011, garethjscott@gmail.com

This project describes a stepper motor controller used by a typical embedded controller.
It allows the motor to accelerate using an S-curve profile described by the equation: 1 / (1 + exp(-t))
The code is written as a C++ class and tested with Cygwin and a Luminary Micro Cortex-M3 controller (LM3S3748).

The architecture of this class adjusts a peripheral timer in the controller to match the acceleration curve.
For speed, a lookup table is used since the timer calls an interrupt service routine and time is at a premium.

There are 3 variables involved in acceleration: max-frequency or omega, time and steps.
The steps to move and frequency (min/max) can be set. The stepper class can tell you
how long the move will take, but will not allow you to set the distance based on time.
That is an easy function to turn on, but we didn't think it very useful.
You can set the time that the acceleration will last but that can be overridden if the
movement is not long enough to contain that acceleration distance.

All times are in micro-seconds unless shown otherwise.

It's hard to draw an s-shaped velocity profile using only ascii-characters.
For a better graph see: http://en.wikipedia.org/wiki/Logistic_function

velocity
|
|         ............... 
|       .                .
|     .                    .
|     .                    .
|   .                        .
|..                            .....  
__________________________________________time

Typical usage shown below:

-------------------------------------------------------------------------------	   

	stepper s;
	s.accelOmega(200, 1200);	// set min/max rotational speed (radians/s) at start and end of acceleration
	s.accelTime(2000000);		// set time to perform acceleration
	s.accelSharpness(8);		// typical smooth s-curve
	s.moveAbsolute(2000);

	s.velocity(200);			// set a continuous velocity
	s.velocity(1200);			// increase velocity using last acceleration curve
	
	s.stop();					// stop by ramping down the acceleration curve

-------------------------------------------------------------------------------	   
	   
Pending tasks (* = addressed this issue):
1. Why does OPTIMIZE_CURVE_CALC produce slightly different results depending on whether it's on and off? Suspect round-off error.
2. This class should do the following:
   a. Move motor from one point to another.
   b. Change velocity
   c. Execute any changes using an acceleration curve
3. Initialize timer code needs added to: stepper_init()
4. Connect isr() up to stepper::isr()
5. Commit to github. Need to consolidate files into one central location. Have FreeRTOS, Luminary and source files for stepper.
6.* Basic regression testing.
7. Debugging output not dependent on #preprocessor macro.
8. Add safeguard to never change motor speed by more than xx Hz.
9. Set position by radians as well as steps
10.* copy constructor and assignment for accel class
11.*Copy stepper and accel classes to motor directory and build them from there...
11a.* ...then submit to Github

12. Follow encoder feature
13. IO port header
14. Queue for motor commands that can't be executed immediately
15.* Add RPM setting. Include deg/step
16. Make KiCad project location so new versions can share the same location.
17.* Allow acceleration time to be set in steps rather than us. See: accel::stepsToTime()
18.* Need to get frequency-at-each-step curve correct. Currently it's lopsided in graph. Why?!
     Got it. See motor.ods "Cumulative time from Cygwin motor run" graph.
19.* Connect RealTerm. Bad physical connection on DB9 connector. Needs cleaning.
     Turned out to be bad solder connection. Stress had lifted the pad off the board.
20. Try serial bootloader
21.* Consolidate stepper.*, accel.* in one location. Add IAR project to scottdesign
     to keep keep git history of files. Update Makefile since files don't need
     copied any more.
22. Executive commands:
        moveAbsolute(int)     
        position(); // Get current position. To do relative move: moveAbsolute(position() + relative)
        velocity(int); // 
        clearQueue();   //
        disable();
        enable();
        getIO(int); // Read IO line
        setIO(int, int);
23.* Change RPM to RPMx10k (rev-per-minute x 10000). This avoids using floats and keeps the
     timeframe in microsecs.
24. Add asymetrical accelerations, ie. different times to accelerate and decelerate.
    Also may want velocity to change between acceleration and deceleration.
    Along same lines, allow discontinuities in acceleration to get past resonant
    frequencies.
25. Add scaling factor from steps to inch, mm.
26. Implement PID controller in user defined code.
27.* Output cumulative time vs frequency in Cygwin log file in order to plot velocity
     profile in spreadsheet.
28. Test constant velocity.
29.* Hardware motor is currently set to 2usteps rather than 8 due to bad solder joint.
    Test max speed at both settings. Update schematic to run MS1, MS2 lines to gpio.
    a. 2usteps: 1650 ustep/sec * 1.8deg/set * 1step/2ustep = 1485 deg/sec = 4 rev/sec
                That's about the fastest smooth top speed.
    b. 8usteps: Basically about the same high end speed at 6600 steps/sec                
30. Add release build to IAR
31. Investigate adding more points to acceleration lookup table.
32. Add asserts. See curveIndexToclockTicks() as prime candidate.    
        
Limitations

Notes
1. Under Cygwin, to redirect output to a file use: ./motor >motor.txt 2>motorErr.txt
2. Note that ./motor is run from a cygwin command window. It needs access to c:\cygwin\bin\cygwin1.dll to run.
    Install a minimal cygwin to get this. To run from a DOS command prompt, add cygwin to your path using the following:
	"set Path=%Path%;c:\cygwin\bin" and then type "motor". It's really best just to install cygwin in the first place.
3. Regression test issue this from the command line: make test1	

About

Low-level stepper motor controller

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published