// https://wokwi.com/projects/399355387445360641
// for https://forum.arduino.cc/t/limit-switch-issue-for-stepper-motor-application/1265784/12
// Add a stepper.stepAsNeeded() function that works like step() but returns
// a boolena about whether a step happened or not.
//
// based on sim https://wokwi.com/projects/388661915235241985
// and https://github.com/waspinator/AccelStepper/tree/master/examples/Bounce
// adding a state machine to have an un-balanced CW-CCW movement
// and a limited number of cycle counts
//
//
// Bounce.pde -- adapted for state machine
// -*- mode: C++ -*-
//
// Make a single stepper bounce from one limit to another
//
// Copyright (C) 2012 Mike McCauley
// $Id: Random.pde,v 1.1 2011/01/05 01:51:01 mikem Exp mikem $
#include <AccelStepper.h> // https://www.airspayce.com/mikem/arduino/AccelStepper/index.html
class myAccelStepper : public AccelStepper
{
public:
boolean myAccelStepper::stepAsNeeded()
{
// step as needed and return whether or not it stepped
bool stepped = false;
if (stepped = runSpeed())
computeNewSpeed();
return stepped;
}
using AccelStepper::AccelStepper;
using AccelStepper::setMaxSpeed;
using AccelStepper::moveTo;
};
// Define a stepper and the pins it will use
myAccelStepper stepper(1, 10, 7); // Defaults to AccelStepper::FULL4WIRE (4 pins) on 2, 3, 4, 5
const byte limitSwitchPin = A1;
int stateSwitch = 0; // CCW, CW, IDLE
long positionAbs = 200;
long bigPos = 1000;
int cycleCount = 2; // CCW counts
int currentCycle = 0;
const byte s2Dir = 8, s2Step = 9;
void setup()
{
Serial.begin(115200);
pinMode(limitSwitchPin, INPUT_PULLUP);
// Change these to suit your stepper if you want
stepper.setMaxSpeed(100);
stepper.setAcceleration(100);
stepper.moveTo(-500);
stepper.run();
Serial.print("s-");
pinMode(s2Dir, OUTPUT);
pinMode(s2Step, OUTPUT);
digitalWrite(s2Dir, LOW);
}
void loop()
{
bool limitSwitchActive = digitalRead(limitSwitchPin) == LOW
|| stepper.currentPosition() < -500;
// If at the end of travel go to the other end
switch (stateSwitch) {
case 0: // moving CCW
if (stepper.distanceToGo() == 0 // finished motion?
|| limitSwitchActive // active limit switch
)
{
currentCycle += 1;
digitalWrite(s2Dir, HIGH);
if (currentCycle <= cycleCount) {
stepper.moveTo(bigPos - positionAbs);
stateSwitch = 1; // move CW
Serial.print("0+");
} else {
stateSwitch = 2; // go idle
}
}
break;
case 1: // moving CW
if (stepper.distanceToGo() == 0) {
stepper.moveTo(-positionAbs);
stateSwitch = 0;
digitalWrite(s2Dir, LOW);
Serial.print("1-");
}
break;
case 2: // IDLE
; // do nothing
break;
}
//stepper.run(); // move stepper as needed
//if (stepper.runSpeed()) {
// stepper.computeNewSpeed();
//}
if (stepper.stepAsNeeded() == true) {
pulse2();
// Serial.print('.');
}
}
void pulse2(void) {
static byte state = 0;
const byte stepPin = s2Step;
state = !state; // flip-flop divide by 2
if (state) {
digitalWrite(stepPin, HIGH);
digitalWrite(stepPin, LOW);
}
}