#include <ezButton.h>
#include <AccelStepper.h>

#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
 
#define SCREEN_WIDTH 128  // OLED display width, in pixels
#define SCREEN_HEIGHT 64  // OLED display height, in pixels
#define OLED_RESET    4  // Reset pin # (or -1 if sharing reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

ezButton limit_switch_1(6);   // create ezButton object for pin D6
ezButton limit_switch_2(12);  // create ezButton object for pin D12

AccelStepper stepper(1, 2, 5);  // (Type of driver: with 2 pins, STEP, DIR)

#define POT_PIN A0

#define DIRECTION_CCW -1
#define DIRECTION_CW 1

#define STATE_CHANGE_DIR 1
#define STATE_MOVE 2
#define STATE_MOVING 3

#define MAX_POSITION 0x7FFFFFFF  // maximum of position we can set (long type)

int stepper_state = STATE_MOVE;
int direction = DIRECTION_CW;
long target_pos = 0;


void setup() {
  Serial.begin(192000);
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C))
  {
    Serial.println("SSD1306 allocation failed");
    while(1); //Don't proceed, loop forever
  }
  
  display.clearDisplay();
  display.setTextColor(WHITE);  
  display.setTextSize(4);
  display.setCursor(0, 10);
  display.print("OLED");
  display.display();
  delay(1000);
  
  limit_switch_1.setDebounceTime(50);  // set debounce time to 50 milliseconds
  limit_switch_2.setDebounceTime(50);  // set debounce time to 50 milliseconds

  // Set maximum speed value for the stepper
  stepper.setMaxSpeed(1000.0);     // set the maximum speed
  stepper.setAcceleration(100.0);  // set acceleration
  stepper.setSpeed(50.0);
  stepper.setCurrentPosition(0);  // set position
}

void loop() {
  
  limit_switch_1.loop();  // MUST call the loop() function first
  limit_switch_2.loop();  // MUST call the loop() function first
  int pot_val = (analogRead(A0));
  float speed_val = float (pot_val / 10.23);
  display.clearDisplay(); 
  display.setTextSize(3);
  display.setCursor(10, 0);
  display.print("SPEED:");
  display.setTextSize(4);
  display.setCursor(10,30);
  display.print(speed_val,1);
  display.display();

  if (limit_switch_1.isPressed()) {
    stepper_state = STATE_CHANGE_DIR;
    Serial.println(F("The limit switch 1: TOUCHED"));
  }
  if (limit_switch_2.isPressed()) {
    stepper_state = STATE_CHANGE_DIR;
    Serial.println(F("The limit switch 2: TOUCHED"));
  }
  switch (stepper_state) {
    case STATE_CHANGE_DIR:
    delay(1000);
      direction *= -1;  // change direction
      Serial.print(F("The direction -> "));
      if (direction == DIRECTION_CW)
        Serial.println(F("CLOCKWISE"));
      else
        Serial.println(F("ANTI-CLOCKWISE"));
      stepper_state = STATE_MOVE;  // after changing direction, go to the next state to move the motor

      break;
    case STATE_MOVE:
      target_pos = direction * MAX_POSITION;
      stepper.setCurrentPosition(0);  // set position
      stepper.moveTo(target_pos);     // move the motor to maximum position 
      stepper.setMaxSpeed(pot_val);  //sets speed to A0 POT_PIN
      
      stepper_state = STATE_MOVING;  // after moving, go to the next state to keep the motor moving infinity
      
      break;
    case STATE_MOVING:                    // without this state, the move will stop after reaching maximum position
      if (stepper.distanceToGo() == 0)   // if motor moved to the maximum position
        stepper.setCurrentPosition(0);    // reset position to 0
        stepper.moveTo(target_pos);       // move the motor to maximum position again
        stepper.setMaxSpeed(pot_val); //sets speed to A0 POT_PIN 
                
      break;
    }
     //display.clearDisplay(); 
     //display.setTextSize(4);
     //display.setCursor(10,30);
     //display.print(val);
     //display.display();

      stepper.run();
  }
A4988