/* Example for MobaTools
Moving a stepper back and forth with limit switches
Based on https://github.com/MicroBahner/MobaTools/tree/master/examples/_Stepper/back_ForthStepperPause
Modified to add simulated limit switches, with sim outputs on 10 & 11
feeding limit switches on 3 & 4
Wokwi simulation at https://wokwi.com/projects/362218133861312513
Wokwi wiring based on https://wokwi.com/projects/327823888123691604 sin
For https://forum.arduino.cc/t/how-to-read-temperature-values-while-the-stepper-motor-is-moving-non-blocking/1115846/11
*/
#include <MobaTools.h> // https://github.com/MicroBahner/MobaTools
// Adjust pins, steps and time as needed
const byte stepPin = 9;
const byte dirPin = 8;
const byte lowLimitPin = 3; // low limit switch Normally closed,
const byte highLimitPin = 4; // low limit switch
const byte LED_LOW = 10; // low limit switch triggered by Sim
const byte LED_HIGH = 11; // high limit switch triggered by Sim
const int stepsPerRev = 200; // Steps per Revolution ( example with 1/4 microsteps )
long targetPos = 200; // stepper moves between 0 and targetpos
long targetPosLow = 0; // stepper moves between 0 and targetpos
long nextPos;
MoToStepper myStepper ( stepsPerRev, STEPDIR );
MoToTimer pause; // Pause between stepper moves
bool stepperRunning;
int limitHigh = HIGH ; // Normally closed, pullup
int limitLow = HIGH ; // Normally closed, pullup
void setup() {
myStepper.attach( stepPin, dirPin );
myStepper.setSpeed( 60 ); // 60 Rev/Min
myStepper.setRampLen( 5 );
stepperRunning = true;
pinMode(LED_LOW,OUTPUT);
pinMode(LED_HIGH,OUTPUT);
pinMode(lowLimitPin,INPUT);
pinMode(highLimitPin,INPUT);
Serial.begin(115200);
}
void loop() {
if ( stepperRunning ) {
// Wait till stepper has reached target, then set pause time
if ( !myStepper.moving() ) {
// stepper has reached target, start pause
pause.setTime( 1 );
stepperRunning = false;
} else { // stepper moving
if (digitalRead(highLimitPin) == HIGH && digitalRead(dirPin)==HIGH ){
targetPos = min(targetPos,myStepper.currentPosition()); // update high target
myStepper.writeSteps(targetPosLow);
} else if (digitalRead(lowLimitPin) == HIGH && digitalRead(dirPin)==LOW ) {
targetPosLow = max(targetPosLow,myStepper.currentPosition()); // update high target
myStepper.writeSteps(targetPos);
}
}
} else {
// stepper doesn't move, wait till pause time expires
if ( pause.expired() ) {
// pause time expired. Start stepper in opposite direction
if ( nextPos == 0 ) {
nextPos = targetPos;
} else {
nextPos = 0;
}
myStepper.moveTo( nextPos );
stepperRunning = true;
}
}
simLimitSwitches();
report();
// The sketch is not blocked while the stepper is moving nor while it is stopped.
// Other nonblocking tasks can be added here
}
void simLimitSwitches(void){
limitHigh = myStepper.currentPosition() > 150 ? LOW : HIGH ;
limitLow = myStepper.currentPosition() < 50 ? LOW : HIGH ;
digitalWrite(LED_LOW,limitLow == LOW);
digitalWrite(LED_HIGH,limitHigh == LOW);
}
void report(void){
uint32_t interval = 250;
static uint32_t last = - interval;
if(millis() - last < interval) return;
last += interval;
Serial.print("Speed:");
Serial.print(myStepper.getSpeedSteps());
Serial.print(" Pos:");
Serial.print(myStepper.currentPosition());
Serial.print(" stepsToGo:");
Serial.print(myStepper.stepsToDo());
Serial.print(" dirPin:");
Serial.print(digitalRead(dirPin));
Serial.print(" Speed:");
Serial.print(((long)myStepper.getSpeedSteps())*(digitalRead(dirPin)?1:-1));
Serial.println();
}