#include <AccelStepper.h>
typedef enum
{
ST_INIT=0,
ST_RIGHT,
ST_LEFT,
ST_PAUSE,
ST_WAIT
}eStepperStates_t;
//can play with these constants to best suit your system
#define K_STEPSPERREV 1024u //steps per revolution of the motor
#define K_DESIREDMPH 5.0 //desired clothesline miles per hour
#define K_WHEELDIAMETER 6.0 //pulley diameter in inches
#define K_CORRECTION 1.0 //correction (e.g. for gearhead); could leave as '1.0' and correct K_STEPSPERREV
#define K_MOTORACCEL 250.0 //larger == faster acceleration from a stop
#define K_BRAKEACCEL 2500.0 //larger == faster braking to a stop
const uint32_t T_PAUSE = 1000ul;
const uint32_t T_SWQUAL = 100ul;
//not moving to a # of steps as we have limit switches so just have something big here
const long lDistance = (long)10000000;
const uint8_t pinRightLimSw = 5; // pin for right side sensor
const uint8_t pinLeftLimSw = 1; // pin for left side sensor
long motorTarget;
AccelStepper stepper( AccelStepper::FULL4WIRE, 6, 7, 8, 9, true );
void setup()
{
stepper.setMaxSpeed( ComputeMaxSpeed( K_STEPSPERREV, K_DESIREDMPH, K_WHEELDIAMETER, K_CORRECTION ) );
stepper.setAcceleration(K_MOTORACCEL);
motorTarget = lDistance; //change to -lDistance if start-up direction is wrong
pinMode( pinRightLimSw, INPUT_PULLUP );
pinMode( pinLeftLimSw, INPUT_PULLUP );
}//setup
void loop()
{
static uint32_t
tSw,
tPause = 0ul;
static eStepperStates_t
stateNext,
stateStepper = ST_INIT;
uint8_t
swState;
uint32_t
tNow = millis();
switch( stateStepper )
{
case ST_INIT:
stepper.moveTo( motorTarget );
stateStepper = ST_RIGHT;
break;
case ST_PAUSE:
//wait for the motor to stop
stepper.run();
if( stepper.isRunning() == false )
{
tPause = tNow;
stateStepper = ST_WAIT;
}
break;
case ST_WAIT:
if( (tNow - tPause) >= T_PAUSE )
{
stepper.setAcceleration(K_MOTORACCEL);
motorTarget = -motorTarget;
stepper.moveTo( motorTarget );
stateStepper = stateNext;
}//if
break;
case ST_RIGHT:
stepper.run();
swState = digitalRead(pinRightLimSw);
if( swState == HIGH )
{
tSw = tNow;
}//if
if( digitalRead(pinRightLimSw) == LOW )
{
if( (tNow - tSw) >= T_SWQUAL )
{
stepper.setAcceleration(K_BRAKEACCEL);
stepper.stop();
stepper.runToPosition();
stateNext = ST_LEFT;
stateStepper = ST_PAUSE;
}//if
}//if
break;
case ST_LEFT:
stepper.run();
swState = digitalRead(pinLeftLimSw);
if( swState == HIGH )
{
tSw = tNow;
}//if
if( digitalRead(pinLeftLimSw) == LOW )
{
if( (tNow - tSw) >= T_SWQUAL )
{
stepper.setAcceleration(K_BRAKEACCEL);
stepper.stop();
stepper.runToPosition();
stateNext = ST_RIGHT;
stateStepper = ST_PAUSE;
}//if
}//if
break;
}//switch
}//loop
float ComputeMaxSpeed( uint16_t stepsperrev, float fMPH, float fWheelDiameter, float fCorrection )
{
//some intermediate calcs for clarity
//sample calc for 6" diameter wheel, 1024 steps/rev and 5mph
float inchespersec = (fMPH * 5280.0 * 12.0) / 3600.0; //(5.0 * 5280.0 * 12.0) / 3600.0 = 88in/sec
float circumference = (float)PI * fWheelDiameter; //3.14159 * 6.0 = 18.8496in
float revspersec = inchespersec / circumference; //88.0 / 18.8496 = 4.6685 revs/sec
float stepspersec = revspersec * (float)stepsperrev; //4.6685 * (float)1024 = 4780.6 steps/sec
float correctedsps = stepspersec * fCorrection;
return( stepspersec );
}//ComputeMaxSpeed