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));
}
}