Go Down

Topic: Microstep Stepper Controller Interface Class (Read 6666 times) previous topic - next topic

Syn42ME

Jan 26, 2011, 07:14 pm Last Edit: Jan 26, 2011, 09:52 pm by Syn42ME Reason: 1
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) [Select]

/*
  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) [Select]

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


PaulS

In the absence of specific directives, numeric values are treated as ints.
Code: [Select]
  _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..


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'

Syn42ME

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

sbright33

#5
Dec 05, 2012, 03:14 am Last Edit: Dec 05, 2012, 03:42 am by sbright33 Reason: 1
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...
If you fall... I'll be there for you!
-Floor

Skype Brighteyes3333
(262) 696-9619

Go Up