Microstep Stepper Controller Interface Class

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

/* 
   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
/* 
   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 );
  
}

In the absence of specific directives, numeric values are treated as ints.

  _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..

Updated. Thanks for pointing that out!

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'

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.

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...