My motor spinning stuck at the first speed

I need to make a spin coater machine. It spins in 3 stages and each stage have different speed(servo value) and time ( how long for it to spin). A lot of people recommended that I use FSM. I have decided to do the programming in FSM. I manage to build FSM for this machine, however, the motor spin only at the first speed but not according to the time allocated and rpm measurement code does not seem to be getting any reading . Also, the program does not seem to be changing state. I was wondering if you guys can help me and pinpoint my mistakes and offer some solution.I’m relatively new to FSM. This is my first try… it compiles of course, but the output using hardware is not what I wanted it to be. Here is the code, a bit long, but should be able to understand easily. My hardware is Arduino Uno, 20x4LCD Screen I2C, Brushless motor, Electronic Speed Control( ESC). While the motor spins, I need the rpm sensor to detect the rpm of the motor, hence I’m using FSM so that the Rpm measurement function and motor spin function work together. I hope you guys can steer me in the right direction. Thanks.

A brief explanation of coding: This coding consist of many functions that perform a different task. In the main loop that runs the FSM, The state will change after the function in each state has completed their task. The flow of this FSM is like this: In state (enter value), function for entering values from the keypad is called. Once all the speed and time have been key in and stored, move to state spin. Here, function for rpm calculation and motorspin is called. The motor will spin and the rpm of motor spinning is measured. After the motor completed the spinning according to the time set, the state goes to state finish. Here the motor stops and move to state enter value for the next motor spin session with news speed and time.

Here is the code:

  #include <Keypad.h>
    #include <Wire.h>  // Comes with Arduino IDE
    #include <LiquidCrystal_I2C.h>
    #include <Servo.h>
    Servo myservo;
    LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address

    const byte ROWS = 4; //four rows
    const byte COLS = 3; //three columns
    char keys[ROWS][COLS] =
    {
    {'1', '2', '3'},
    {'4', '5', '6'},
    {'7', '8', '9'},
    {'*', '0', '#'}
    };

    byte rowPins[ROWS] = {9,8,7,6}; //row pinouts of the keypad (L1, L2, L3, L4)
    byte colPins[COLS] = {5,4,3}; //column pinouts of the keypad (R1, R2, R3)
    Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );


    // STATE CONDITION FOR MAIN LOOP
    enum  { enter_values, spin , finish } state;
    
    unsigned long previousMillis = 0;
    

   // RPM MEASUREMENT
   const int dataIN = 2; //IR sensor INPUT
   unsigned long prevmillis; // To store time
   unsigned long duration; // To store time difference
   unsigned long lcdrefresh; // To store time for lcd to refresh
   int rpm; // RPM value
   boolean currentstate; // Current state of IR input scan
   boolean prevstate; // State of IR sensor in previous scan

    // DECLARE
   int stage1speed , stage1time ,stage2speed , stage2time ,stage3speed , stage3time ;



    void setup()
    { 
    Serial.begin(9600);
    lcd.begin(20,4);
    myservo.attach(11);
  
    systemstate = enter_values;  // set up the starting state

    pinMode(dataIN,INPUT);   
    prevmillis = 0;
    prevstate = LOW;  
   
    lcd.setCursor(4,1);
    lcd.print("SPIN COATER");
    lcd.setCursor(6,2);
    lcd.print("MACHINE");
    delay(5000);
    lcd.clear();

    lcd.setCursor(3,1);
    lcd.print("S = speed(sv)");
    lcd.setCursor(3,2);
    lcd.print("T = time(sec)");
    delay(5000);
    lcd.clear();


    lcd.setCursor(0,0);
    lcd.print("S=");
    lcd.setCursor(0,1);
    lcd.print("T=");
    lcd.setCursor(0,2);
    lcd.print("S=");
    lcd.setCursor(0,3);
    lcd.print("T=");
    lcd.setCursor(10,0);
    lcd.print("S=");
    lcd.setCursor(10,1);
    lcd.print("T=");
    }

    //FUNCTION FOR KEY IN SPEED AND TIME
    void enter_speed_time()
    {
  
     stage1speed = getTheNumber();
     lcd.setCursor(2,0);
     lcd.print(stage1speed);
     lcd.print("sv");
     stage1time = getTheNumber();
     lcd.setCursor(2,1);
     lcd.print(stage1time);
     lcd.print("sec");
  
     stage2speed = getTheNumber();
     lcd.setCursor(2,2);
     lcd.print(stage2speed);
     lcd.print("sv");
     stage2time = getTheNumber();
     lcd.setCursor(2,3);
     lcd.print(stage2time);
     lcd.print("sec");
  

     stage3speed = getTheNumber();
     lcd.setCursor(12,0);
     lcd.print(stage3speed);
     lcd.print("sv");
     stage3time = getTheNumber();
     lcd.setCursor(12,1);
     lcd.print(stage3time);
     lcd.print("sec");
    }


   // FUNCTION TO GET NUMBERS FROM 4X3 MATRIC KEYPAD
   int getTheNumber()
   {
    char buffer[4];
    int i=0;
    while (1)
    {
        char key = keypad.getKey();

        // If it's a number AND we have space left, add to our string
        if ('0' <= key && key <= '9' && i < 3)
        {
            buffer[i] = key;
            i++;        
        }
        // If it's a * or #, end
        else if ('#' == key && i > 0)
        {
            // Null terminate
            buffer[i] =0; 
            int value = atoi(buffer);  // Convert to an integer
            break;
        }    
    }
    return atoi(buffer);
    }

    // FUNCTION FOR RPM MEASUREMENT
     void rpmMeasure()
     {
     // RPM Measurement
     currentstate = digitalRead(dataIN); // Read IR sensor state
     if( prevstate != currentstate) // If there is change in input
     {
     if( currentstate == HIGH ) // If input only changes from LOW to HIGH
       {
         duration = ( micros() - prevmillis ); // Time difference between revolution in microsecond
         rpm = (60000000/duration); // rpm = (1/ time millis)*1000*1000*60;
         prevmillis = micros(); // store time for next revolution calculation
       }
      }
     prevstate = currentstate; // store this scan (prev scan) data for next scan
      lcd.setCursor(10,3);
      lcd.print(rpm);
      lcd.print("rpm");         
      }
  

     // FUNCTION FOR MOTOR SPINNING ACCORDING TO TIME AND SPEED   
    void motorspin()
    {  
   
     unsigned long currentMillis = millis();
     int idleValue = 0;

     static enum { IDLE, STAGE1, STAGE2, STAGE3 } spinningstate;
     switch (spinningstate) {
      case IDLE:
            myservo.write(stage1speed);
            previousMillis =currentMillis; 
            spinningstate = STAGE1;
            
        break;
    case STAGE1:
        if (currentMillis - previousMillis >= stage1time*1000) {
            myservo.write(stage2speed);
            previousMillis = currentMillis;
            spinningstate = STAGE2;
        }
        break;
    case STAGE2:
        if (currentMillis - previousMillis >= stage2time*1000) {
            myservo.write(stage3speed);
            previousMillis = currentMillis;
            spinningstate = STAGE3;
            
        }
        break;
    case STAGE3:
        if (currentMillis - previousMillis >= stage3time*1000) {
            myservo.write(idleValue);
            spinningstate = IDLE;
        }
        break;
      }
      }


      // MAIN LOOP
      void loop()
      { 
       switch(systemstate)
      {  
    case enter_values:
    
        enter_speed_time();
        systemstate = spin;
        break;
        
    case spin: 
    
       rpmMeasure();
       motorspin();
       if (if enough time have passed ) // haven't figure out yet
       {
        systemstate = finish;
       }
       break;
       
    case finish:
    
       systemstate = enter_values;
       break;        
    }
    }