Restart loop after button press

I am using a Microview which is like a 328. I have 4 buttons and a stepper motor. The first 3 buttons select a speed and duration for the stepper motor to run. The 4th button is like a e-stop. It’s on Pin 2 and used as a interrupt. It stops the motor if pressed.
I am having problems figuring out how to make the other buttons work after pressing the e-stop button.
I have two functions in my loop. Read buttons and act on buttons. The problem is when I interrupt with the e-stop the loop is in the act on buttons function and I do not know how to make it go back to the read buttons function.
I could use some pointers. I am very very new to this and trying to learn the right way to do it. I think I need to break up the different motor functions so its non blocking but I cannot figure that out yet.
See code below:

#include <stdio.h>
#include <Arduino.h>
#include <SpeedyStepper.h>
#include <MicroView.h>

const int pan360s = A0; //button
const int pan360f = A1; //button
const int pan180s = A2; //button
const int KILL = 2; //button
const int MOTOR_EN_PIN = 6; //pan motor enable
const int MOTOR_STEP_PIN = 5; //pan motor step
const int MOTOR_DIRECTION_PIN = 3; //pan motor direction

bool buttonS360pressed = false;
bool buttonF360pressed = false;
bool buttonS180pressed = false;

SpeedyStepper stepper;

void setup() {
    Serial.begin(9600);
    delay(500);  // needed to be able to flash a new sketch more easily
     
  stepper.connectToPins(MOTOR_STEP_PIN, MOTOR_DIRECTION_PIN);
  
  pinMode(pan360s, INPUT); //Start Motor @ 1 degree per second for 360 degrees
  pinMode(pan360f, INPUT); //Start Motor @ 2 degree per second for 360 degrees
  pinMode(pan180s, INPUT); //Start Motor @ 1 degree per second for 180 degrees
  pinMode(KILL, INPUT); //Stop Motor
  pinMode(MOTOR_EN_PIN, OUTPUT);
  
  attachInterrupt(digitalPinToInterrupt(KILL), KILL_SCAN, RISING);
  
  digitalWrite(MOTOR_EN_PIN, HIGH); // disable motor driver

    uView.begin();              // start MicroView
    uView.clear(PAGE);          // erase the memory buffer, when next uView.display() is called, the OLED will be cleared.
    uView.display();            // display the content in the buffer memory
        

  // Display start
    uView.clear(PAGE);
//    uView.drawBitmap(logo);
    uView.display();
    delay(1000);
    uView.clear(PAGE);
    uView.setFontType(1); // set font type 0: Numbers and letters. 10 characters per line (6 lines)
    uView.setCursor(11,7);
    uView.print("START"); // display string
    uView.display();
    delay(500);
    uView.setCursor(2,28);
    uView.print("SCANNER");
    uView.display();
    delay(750);
     
    Serial.println("Startup complete");
}

void loop() {
  readButtons();
  actOnButtons();
}

void readButtons() {
    buttonS360pressed = false;
    buttonF360pressed = false;
    buttonS180pressed = false;

    if (digitalRead(pan360s) == LOW) {
        buttonS360pressed = true;        
    }
    if (digitalRead(pan360f) == LOW) {
        buttonF360pressed = true;
    }
    if (digitalRead(pan180s) == LOW) {
        buttonS180pressed = true;
    }    
}

void actOnButtons() {
    if (buttonS360pressed == true) {
        PANO360S();
    }
    if (buttonF360pressed == true) {
        PANO360F();
    }
    if (buttonS180pressed == true) {
        PANO180S();
    }
}   
 

void PANO360S() {
    digitalWrite(MOTOR_EN_PIN, LOW); // enable drive
    stepper.setStepsPerRevolution(82880);
    stepper.setSpeedInRevolutionsPerSecond(0.0027778); // 1 degree per second, 360 degrees in 6 minutes
    stepper.setAccelerationInRevolutionsPerSecondPerSecond(1.0);
    stepper.setCurrentPositionInSteps(0); 
    stepper.moveToPositionInRevolutions(1); // rotates 360 degrees
    delay(100);
    digitalWrite(MOTOR_EN_PIN, HIGH); // disable driver
    }

void PANO360F() {
    digitalWrite(MOTOR_EN_PIN, LOW); // enable drive
    stepper.setStepsPerRevolution(82880);
    stepper.setSpeedInRevolutionsPerSecond(0.0055556); // 2 degree per second, 360 degrees in 3 minutes
    stepper.setAccelerationInRevolutionsPerSecondPerSecond(1.0);
    stepper.setCurrentPositionInSteps(0); 
    stepper.moveToPositionInRevolutions(1); // rotates 360 degrees
    delay(100);
    digitalWrite(MOTOR_EN_PIN, HIGH); // disable driver
    }

void PANO180S() {
    digitalWrite(MOTOR_EN_PIN, LOW); // enable drive
    stepper.setStepsPerRevolution(82880);
    stepper.setSpeedInRevolutionsPerSecond(0.0027778); // 1 degree per second, 360 degrees in 6 minutes
    stepper.setAccelerationInRevolutionsPerSecondPerSecond(1.0);
    stepper.setCurrentPositionInSteps(0); 
    stepper.moveToPositionInRevolutions(0.5); // rotates 180 degrees
    delay(100);
    digitalWrite(MOTOR_EN_PIN, HIGH); // disable driver
    }

void KILL_SCAN() {
    digitalWrite(MOTOR_EN_PIN, HIGH); // disable drive    
    }    

    

thanks in advance

you can’t if you mean you want to get there the next nanosecond

once the interrupt is dealt with (unless you reset the Arduino in the interrupt function), you go back to where you were.

what you could do is set a a flag in the ISR to say you’ve been interrupted, in which case you abort the actOnButtons() function but this can only be checked when you are not in one of your blocking functions such as delay() or (I assume) stepper.moveToPositionInRevolutions()

if you want to be able to handle such urgent stop, you need to re-architect your code so that there is no blocking code and come back to the loop often to take the next step (I’m not familiar with SpeedyStepper but accelStepper library might help)

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.