Stepper Motor Angle and Speed Control

Well, it is a bit complicated to distinguish between so much modes with only one button. But 3 is possible: The MoToButtons class can distinguish between click ( a 'short shortpress' ) double click and long press. So your mode selection could be ( set zero with long press, select compass withh single click, return to reference point with double click):

#include <MobaTools.h>

// hardware related definitiona
// Set pins according to your hardware
const int stepPin = 6; //3;
const int dirPin = 5; //4;
const int enPin = 7; //2;
const byte buttonPins[] = {2};
const byte joyLRPin = A1;
const int ledPin =  LED_BUILTIN;
//----------------------------

const long maxAngle = 400;          // this is the max angle in every direction.
const int maxSpeed = 2500;          // max Speed is 2500 steps/sec ( depends what the motor can do )
const int minSpeed = 10;            // lowest Speed
const int stepsPerRev = 200 * 50;   // steps per revolution with gear box
//-----------------------------

// limits for joystick
//const int joyLimits[] = { 245, 500, 524, 774 };
const int joyLimits[] = { 0, 500, 524, 1024 };
//------------------------------------------------------------------------------

int joyLR;
byte function = 1;                            // default is joystick
int motorSpeed = 500;                         // Steps/sec

// create MobaTools objects
MoToStepper stepper1( stepsPerRev, STEPDIR );       // create a stepper instance
MoToButtons myButtons( buttonPins, 1, 20, 3000 );   // manage buttons(s), longpress is 3 seconds
MoToTimebase printTimer;                            // Timer to print in regular intervals without blocking sketch
MoToTimebase joyTimer;                              // Timer to read joystick in regular intervals without blocking sketch

void setup() {
    Serial.begin (115200);
    printTimer.setBasetime( 1000 );           // print values every second
    joyTimer.setBasetime( 100 );              // read joystick 10 times a second

    pinMode(ledPin, OUTPUT);

    // initiate stepper
    stepper1.attach( stepPin, dirPin );
    stepper1.setSpeed(motorSpeed );              // rev/min (if stepsPerRev is set correctly)
    stepper1.setRampLen( 100 );                  // set ramp length to what the motor needs to not loose steps
    stepper1.attachEnable( enPin, 100, LOW );  // disable motor current in standstill

}

void loop() {

    myButtons.processButtons();

    // select function mode by button presses
    if ( myButtons.longPress(0) ) {
        // button pressed long -> set referencepoint
        Serial.println( "Set referencepoint" );
        stepper1.setZero();
        function = 1;
    }

    switch ( myButtons.clicked(0) ) {
        case NOCLICK:
            ; // do nothing
            break;
        case DOUBLECLICK:
            Serial.println( "Return to refrencepoint" );
            stepper1.setSpeedSteps( 2000 );   // Speed when moving home
            stepper1.write(0);
            function = 3;
            break;
        case SINGLECLICK:
            Serial.println( "Set function 2" );
            function = 2;
            break;
    }

    switch ( function ) {
        case 1:  // mode 1 - joystick control
            if (joyTimer.tick() ) {
                // read joystick and set stepper speed accordingly

                joyLR = analogRead(joyLRPin);
                // if the joystic is in the middle ===> sti
                if ( joyLR > joyLimits[1] && joyLR < joyLimits[2] ) // neutral area
                {
                    digitalWrite(ledPin, HIGH);
                    stepper1.rotate(0 );      // stop stepper if joystick in the middle
                }
                else
                {   // move the motor in desired direction
                    digitalWrite(ledPin, LOW);
                    if ( joyLR >= joyLimits[2] ) {
                        // move towards max angle
                        motorSpeed = map ( joyLR , joyLimits[2], joyLimits[3] , minSpeed, maxSpeed ); // Values may be adjusted to the joystick
                        stepper1.setSpeedSteps( motorSpeed * 10 );
                        stepper1.write( maxAngle );
                    } else {
                        // move towards min angle
                        motorSpeed = map ( joyLR , joyLimits[1], joyLimits[0] , minSpeed, maxSpeed ); // Values may be adjusted to the joystick
                        stepper1.setSpeedSteps( motorSpeed * 10 );
                        stepper1.write( -maxAngle );

                    }
                }
            }
            break;
        case 2: // mode 2 compass control
                // to be implemented
            break;
        case 3: // return to reference point, switch back to joystick control if reached
            if ( !stepper1.moving() ) function = 1;
            break;
    }
    if ( myButtons.longPress(0) ) {
        // button pressed long -> set referencepoint
        Serial.println( "Set referencepoint" );
        stepper1.setZero();
    }

    if ( printTimer.tick() ) {
        // debug printing every second
        Serial.print( "CurrentAngle "); Serial.print(stepper1.read() );
        Serial.print ( " step ");       Serial.print (stepper1.readSteps() );

        Serial.print ( " DIR ");
        if (joyLR >= joyLimits[2]) Serial.print ( "right") ;
        else if (joyLR <= joyLimits[1]) Serial.print( "left");
        else Serial.print( "stop");

        Serial.print ( " SpeedCC ");    Serial.print (motorSpeed);

        Serial.print(" joyLR = ");      Serial.print (joyLR);

        Serial.print(" Button= ");      Serial.println (myButtons.state(0));
    }
}