Pages: [1]   Go Down
Author Topic: Microstep Stepper Controller Interface Class  (Read 6172 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So, as I received help on an issue when writing this, I figured I'd at least post the working code that I have. I'm still adding some control characteristics, so it';s not finished. However, what is implemented does work.

P.S. - I hope this is what I'm supposed to do, being new to the open-source thing.

-Syn


Code: (StepperMicro.h)
/*
   StepperMicro.h - Microstepper Controller Interface for Arduino - v0.1
  
   Defines a modular interface for commercial microstep stepper motors controllers. The motor run task
   is designed to run real time while letting other processes run simultaneously. The only process delay
   used is when pulsing to the controller, but this delay is in microseconds.

*/

#ifndef StepperMicro_h
#define StepperMicro_h

#define MICROSTEP LOW
#define FULL_STEP HIGH

#define CW        LOW
#define CCW       HIGH

class StepperMicro
{
  public:
    bool          blnInMotion;              // Used to show that a step command is in process
    
    // Constructors
    StepperMicro(int intPinPulse, int intPinToggleMicrostep, int intPinToggleDirection);

    // Public function calls
    bool MoveMotor(int intGoToPosition, int intSpeed, bool blnConstSpeed, bool blnEnableMicrostep);
    void SetMicrostepResolution(int resolution);
    void SetPulseLength(unsigned long pulseLength);
  private:
    // private function calls
    bool step();
    void stepMotor();
    
    // Toggle flags
    bool          _blnInMotion;             // Used to show that a step command is in process
    
    // Physical values
    int           _intMotorSpeed;           // (cycles/sec) Run speed of motor
    int           _intMotorPosition;        // Current step count location of stepper motor
    int           _intStepsRemaining;       // Count of the steps remaining until the step task is complete
    int           _intPulseType;            // Toggles between microstepping and full-step: LOW = microstep, HIGH = full-step
    int           _intDirection;            // Toggles direction: LOW = CW, HIGH = CCW
    int           _intMicrostepResolution;  // The number of microsteps per step that the controller is set to
    
    // Pin location definitions
    int           _intPinToggleDirection;
    int           _intPinToggleMicrostep;
    int           _intPinPulse;
                  
    unsigned long _ulongPulseLength;        // (microseconds) The length of the pulse signal sent to the controller
    unsigned long _ulongLastStepTime;       // (microseconds) The last time a pulse was sent to the controller
    unsigned long _ulongStepInterval;       // (microseconds) The time between pulses; set from the desired motor speed
    
    long          _longPosition;
};

#endif

Code: (StepperMicro.pde)
/*
   StepperMicro.pde - Microstepper Controller Interface for Arduino - v0.1
  
   Defines a modular interface for commercial microstep stepper motors controllers. The motor run task
   is designed to run real time while letting other processes run simultaneously. The only process delay
   used is when pulsing to the controller, but this delay is in microseconds.

*/

#include "StepperMicro.h"

// Initializes the stepper motor controller
StepperMicro::StepperMicro(int intPinPulse, int intPinToggleMicrostep, int intPinToggleDirection)
{
  // Set the output pin locations
  _intPinToggleDirection = intPinToggleDirection;
  _intPinToggleMicrostep = intPinToggleMicrostep;
  _intPinPulse           = intPinPulse;
    
  // Stepper initialization
  _intMotorPosition = 0;      // Reset motor position to 0
  _ulongPulseLength = 2;      // Set the default pulse lenght default to 2 microseconds
  _intPulseType = FULL_STEP;       // Set the default pulse state to full pulse
  _intDirection = CCW;       // Set the default direction to CCW
  
  // A step task is not running
  _blnInMotion = false;
  
  // Set the starting state of the pulse pin to low
  digitalWrite(intPinPulse, LOW);
}

// Set a custom microstep resolution
void StepperMicro::SetMicrostepResolution(int resolution) { _intMicrostepResolution = resolution; }

// Set a custom step interval
void StepperMicro::SetPulseLength(unsigned long pulseLength) { _ulongPulseLength = pulseLength; }

// Starts and handles a move action
// RETURNS: Returns true while the motor is still in a move state.
bool StepperMicro::MoveMotor(int intGoToPosition, int intSpeed, bool blnConstSpeed, bool blnEnableMicrostep)
{
  // If currently processing a move task, call the step function and return.
  if ( _blnInMotion ) { _blnInMotion = step(); return _blnInMotion; }
  
  // --------The setup for the move action.------------------------------------------
  //
  // flag that a move task is in motion
  _blnInMotion = true;
  
  // set the remaining number of steps for the move task
  _intStepsRemaining = intGoToPosition - _intMotorPosition;
  
  // set the direction of the move task
  if(_intStepsRemaining > 0) _intDirection = CCW;
  if(_intStepsRemaining < 0) _intDirection = CW;
  
  // remove the sign from the remaining step count
  _intStepsRemaining = abs(_intStepsRemaining);
  
  // set the speed of the movement and step interval
  // NOTE: This will later be variable if blnConstSpeed is false. This will
  //       make the motor ramp up and ramp down speed to move faster and smoother.
  //       For now, constant speed works.
  _intMotorSpeed = intSpeed;
  _ulongStepInterval = 1000000ul / _intMotorSpeed ;
  
  // set the first step to run on the next pass
  _ulongLastStepTime = micros() - _ulongStepInterval;
  
  // enable or disable microstepping
  if(blnEnableMicrostep) _intPulseType = FULL_STEP; else _intPulseType = MICROSTEP;
  digitalWrite(_intPinToggleMicrostep,_intPulseType);
  
  // return that the move action is not ready. The stepping will begin next cycle.
  return _blnInMotion;
}

// handles the stepping
// RETURNS: If the steps remaining is > 0, return true.
bool StepperMicro::step()
{  
  // Call the step function
  if ((micros() - _ulongLastStepTime) >= _ulongStepInterval)
  {
    // Set the last pulse time as now
    _ulongLastStepTime = micros();

    // Step the motor one pulse
    stepMotor();

    // decriment the remaining steps
    _intStepsRemaining--;
  }

  // Return true until the remaining steps has reached 0.
  return ( _intStepsRemaining > 0 );
}

// Generates a single pulse to the controller to make the motor perform a step
void StepperMicro::stepMotor()
{
  digitalWrite( _intPinPulse, HIGH );
  delayMicroseconds(_ulongPulseLength);
  digitalWrite( _intPinPulse, LOW );
  
}
« Last Edit: January 26, 2011, 03:52:34 pm by Syn42ME » Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

In the absence of specific directives, numeric values are treated as ints.
Code:
  _ulongStepInterval = 1000000 / _intMotorSpeed ;
1000000 is not an int, so it needs to have UL appended, to tell the compiler that the value is an unsigned long, and should be treated as such..
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Updated. Thanks for pointing that out!
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,
Newbie here, Imported the library and when I run the code here`s what I get...

core.a(main.cpp.o): In function `main':
I:\arduino-1.0.2\hardware\arduino\cores\arduino/main.cpp:5: undefined reference to `setup'
I:\arduino-1.0.2\hardware\arduino\cores\arduino/main.cpp:15: undefined reference to `loop'
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Please note that this was a library, not a full program. From the error, it looks like you don't have either of the two required "main" functions, setup or loop.

http://arduino.cc/en/Tutorial/BareMinimum
Logged

Offline Offline
Edison Member
*
Karma: 8
Posts: 1341
If you're not living on the Edge, you're taking up too much space!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have created something similar, see other post in this category.  But we came at the problem from 2 very different perspectives!  I wish we could combine the best of mine with the best of yours...  Take a look at my code?

Ah but yours uses a complex more expensive controller, instead of just 4 MOSFETs or a $1 ULN2003.
There's room for the 2 of us in this town...
« Last Edit: December 04, 2012, 09:42:00 pm by sbright33 » Logged

If you fall... I'll be there for you!
-Floor

Skype Brighteyes3333
(262) 696-9619

Pages: [1]   Go Up
Jump to: