Bugs na saido do tempo e leitura travada

Olá, estou montando um projeto de spin-coater usando um HD como motor, pra isso tenho um código um pouco complexo, pois envolver muitas coisas, porém meu programa apresentar alguns bugs, e não consigo reconhecer. Ao iniciar a ciclagem ele demora certo tempo pra mostrar o tempo e também quando vou fazer a interrupção também.

#include <Arduino.h>
#include <Servo.h>
#include "config.h"
#include "display.h"
#include "Encoder.h"

Servo esc;

int pinomotor = PINESC;

#define TROTTLEMIN   750   // 75
#define TROTTLEMAX  2000   //  170

void varia(int vel2);
void pisca(int n);
void testaRPM(int vel, int vel2, long tempo);


void setupBrushless()
{
    esc.attach(pinomotor);
    esc.writeMicroseconds(TROTTLEMAX);
    delay(4000);
    esc.writeMicroseconds(TROTTLEMIN);
    delay(4000);

}


void loopBrushless()
{

    varia(150);
    delay(10000); // espera o ESC apitar
    pisca(2);
    varia(80);
    delay(10000); // espera o ESC apitar
}



int vel = 0;

boolean onRPM(int vel2, long tempo)
{
      int deltaT = 15;//30;
      for(; vel<vel2;vel++){
          esc.write(vel);
          delay(deltaT); // 
      }
      for(; vel>vel2;vel--){
          esc.write(vel);
          delay(deltaT); // 
      }
      //lcd.print("..."); 
      long t0 = millis();
      long corrido = 0;
      while( corrido < UNIDADE_TEMPO_MS*tempo){
            if (onClick(PINENC_SW))
                return false;
            else{
              sprintf(buffer,"%02d:%02d", corrido/60000,1);
              lcd.setCursor(11,1);
              sprintf(buffer,"%02d", corrido/60000);
              lcd.print(buffer);
              lcd.print(":");
              sprintf(buffer,"%02d", (corrido/1000)%60);
              lcd.print(buffer);
            }
            corrido = millis() - t0;
      }
       lcd.setCursor(16-2,1);
       lcd.print("   ");
      return true;
}

void startGiro(int pvel)
{
          //vel = pvel;
          for(; vel<pvel;vel++){
              esc.write(vel);
              delay(100); // 
          }
          delay(1000);
}

void varia(int vel2)
{

      for(; vel<vel2;vel++){
          esc.write(vel);
          delay(100); // espera o ESC apitar
      }
      for(; vel>vel2;vel--){
          esc.write(vel);
          delay(50); // espera o ESC apitar
      }
}     


void pisca(int n)
{
      for(int i=0; i<n;i++){
              digitalWrite(LED_BUILTIN,HIGH);
              delay(140); 
              digitalWrite(LED_BUILTIN,LOW);
              delay(140); 
              }
}
  
// PARAMETROS DE CICLO DEFAULT
#define NCICLOS 5;
#define TEMP_CI 10;
#define TEMP_CII 10;
#define VEL_CI 3000;
#define VEL_CII 100;
#define UNIDADE_TEMPO_MS 60000


//  Pinos I2C
#define I2C_SDA  A4
#define I2C_SCL  A5
// Pino do ESC para o MOTOR
#define PINESC 9
// Pinos do Rotary Encoder
#define PINENC_SW 3
// Comente linha abaixo se desejar utlizar digital Pins 12 e 13 INT 0  ( Default A2 A3 INT1)
#define ANALOGPINS
#ifdef ANALOGPINS    // funçao da configuração do hardware
#define PINENC_CLOCK  A2
#define PINENC_DATA A3
#else
#define PINENC_CLOCK  12
#define PINENC_DATA 13
#endif

  

#include <Wire.h> 
#include "LiquidCrystal_I2C.h" // Biblioteca para operar o LCD
#include "Arduino.h"
#include <math.h>   // Biblioteca para funções matemáticas avançadas
#include "config.h"
#include "Encoder.h"

// Definições de tempo
#define SECS_PER_MIN  (60UL)
#define SECS_PER_HOUR (3600UL)
#define SECS_PER_DAY  (SECS_PER_HOUR * 24L)
 
// Macros úteis para obter o tempo decorrido
#define numberOfSeconds(_time_) (_time_ % SECS_PER_MIN)  
#define numberOfMinutes(_time_) ((_time_ / SECS_PER_MIN) % SECS_PER_MIN)
#define numberOfHours(_time_) (( _time_% SECS_PER_DAY) / SECS_PER_HOUR)
#define elapsedDays(_time_) ( _time_ / SECS_PER_DAY)  

// Alterar o construtor para 16x2 (substitua 0x27 pelo endereço I2C correto se necessário)
LiquidCrystal_I2C lcd(0x27, 16, 2);
char buffer[17];

String printDigits2(int digits) {
  // Função utilitária para exibição de tempo digital
  String returnval = "";
  if (digits < 10)
    returnval += "0";
  returnval += digits; 
  return returnval; 
}

String time2(int val) {  
  // Calcula o número de dias, horas, minutos e segundos
  int days = elapsedDays(val);
  int hours = numberOfHours(val);
  int minutes = numberOfMinutes(val);
  int seconds = numberOfSeconds(val);
  
  // Exibição digital do tempo atual 
  return printDigits2(minutes) + ":" + printDigits2(seconds) + "   ";
}

void displayInit(char *title1, char *title2) {
  lcd.init();
  lcd.backlight();
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(title1);
  lcd.setCursor(0, 1);
  lcd.print(title2);
  delay(4000);
  lcd.clear();
}

void displayInt(int linha, char *label, int valor) {
  lcd.setCursor(0, linha); // Exibe as configurações no LCD
  lcd.print(label);
  lcd.setCursor(strlen(label) + 2, linha);
  lcd.print(valor);
  lcd.print("  ");
}

void displayTime(int linha, char *label, int valor) {
  lcd.setCursor(0, linha); // Exibe as configurações no LCD
  lcd.print(label);
  lcd.setCursor(strlen(label) + 2, linha);
  lcd.print(time2(valor));
  lcd.print("  ");
}

void menu(char *title, char *itens[], int n) {
  if (posEncoder == encoder.getPosition()) 
    return;
  
  posEncoder = positivando(encoder.getPosition(), n);
  encoder.setPosition(posEncoder);
  int selected = posEncoder % n;
  
  Serial.println(title);
  lcd.setCursor(0, 0);
  lcd.print(title);
  lcd.print("     ");
  lcd.setCursor(0, 1);
  
  for (int i = 0; i < n; i++) {
    if (i == 0) {
      lcd.print("[");
      lcd.print(itens[(selected + i) % n]);
      lcd.print("]");
    } else {
      lcd.print(" ");
      lcd.print(itens[(selected + i) % n]);
      lcd.print(" ");
    }
  }  
  lcd.print("  ");   
}

int positivando(int valor, int n) {
  while (valor < 0)
    valor += n;
  return valor;
}

#include <Wire.h> 
#include "LiquidCrystal_I2C.h" // Biblioteca para operar o LCD
#include "Arduino.h"
#include <math.h>   // Biblioteca para funções matemáticas avançadas
#include "config.h"
#include "Encoder.h"

// Definições de tempo
#define SECS_PER_MIN  (60UL)
#define SECS_PER_HOUR (3600UL)
#define SECS_PER_DAY  (SECS_PER_HOUR * 24L)
 
// Macros úteis para obter o tempo decorrido
#define numberOfSeconds(_time_) (_time_ % SECS_PER_MIN)  
#define numberOfMinutes(_time_) ((_time_ / SECS_PER_MIN) % SECS_PER_MIN)
#define numberOfHours(_time_) (( _time_% SECS_PER_DAY) / SECS_PER_HOUR)
#define elapsedDays(_time_) ( _time_ / SECS_PER_DAY)  

// Alterar o construtor para 16x2 (substitua 0x27 pelo endereço I2C correto se necessário)
LiquidCrystal_I2C lcd(0x27, 16, 2);
char buffer[17];

String printDigits2(int digits) {
  // Função utilitária para exibição de tempo digital
  String returnval = "";
  if (digits < 10)
    returnval += "0";
  returnval += digits; 
  return returnval; 
}

String time2(int val) {  
  // Calcula o número de dias, horas, minutos e segundos
  int days = elapsedDays(val);
  int hours = numberOfHours(val);
  int minutes = numberOfMinutes(val);
  int seconds = numberOfSeconds(val);
  
  // Exibição digital do tempo atual 
  return printDigits2(minutes) + ":" + printDigits2(seconds) + "   ";
}

void displayInit(char *title1, char *title2) {
  lcd.init();
  lcd.backlight();
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(title1);
  lcd.setCursor(0, 1);
  lcd.print(title2);
  delay(4000);
  lcd.clear();
}

void displayInt(int linha, char *label, int valor) {
  lcd.setCursor(0, linha); // Exibe as configurações no LCD
  lcd.print(label);
  lcd.setCursor(strlen(label) + 2, linha);
  lcd.print(valor);
  lcd.print("  ");
}

void displayTime(int linha, char *label, int valor) {
  lcd.setCursor(0, linha); // Exibe as configurações no LCD
  lcd.print(label);
  lcd.setCursor(strlen(label) + 2, linha);
  lcd.print(time2(valor));
  lcd.print("  ");
}

void menu(char *title, char *itens[], int n) {
  if (posEncoder == encoder.getPosition()) 
    return;
  
  posEncoder = positivando(encoder.getPosition(), n);
  encoder.setPosition(posEncoder);
  int selected = posEncoder % n;
  
  Serial.println(title);
  lcd.setCursor(0, 0);
  lcd.print(title);
  lcd.print("     ");
  lcd.setCursor(0, 1);
  
  for (int i = 0; i < n; i++) {
    if (i == 0) {
      lcd.print("[");
      lcd.print(itens[(selected + i) % n]);
      lcd.print("]");
    } else {
      lcd.print(" ");
      lcd.print(itens[(selected + i) % n]);
      lcd.print(" ");
    }
  }  
  lcd.print("  ");   
}

int positivando(int valor, int n) {
  while (valor < 0)
    valor += n;
  return valor;
}

#include <Wire.h> 
#include "LiquidCrystal_I2C.h" // Biblioteca para operar o LCD
#include "Arduino.h"
#include <math.h>   // Biblioteca para funções matemáticas avançadas
#include "config.h"
#include "Encoder.h"

// Definições de tempo
#define SECS_PER_MIN  (60UL)
#define SECS_PER_HOUR (3600UL)
#define SECS_PER_DAY  (SECS_PER_HOUR * 24L)
 
// Macros úteis para obter o tempo decorrido
#define numberOfSeconds(_time_) (_time_ % SECS_PER_MIN)  
#define numberOfMinutes(_time_) ((_time_ / SECS_PER_MIN) % SECS_PER_MIN)
#define numberOfHours(_time_) (( _time_% SECS_PER_DAY) / SECS_PER_HOUR)
#define elapsedDays(_time_) ( _time_ / SECS_PER_DAY)  

// Alterar o construtor para 16x2 (substitua 0x27 pelo endereço I2C correto se necessário)
LiquidCrystal_I2C lcd(0x27, 16, 2);
char buffer[17];

String printDigits2(int digits) {
  // Função utilitária para exibição de tempo digital
  String returnval = "";
  if (digits < 10)
    returnval += "0";
  returnval += digits; 
  return returnval; 
}

String time2(int val) {  
  // Calcula o número de dias, horas, minutos e segundos
  int days = elapsedDays(val);
  int hours = numberOfHours(val);
  int minutes = numberOfMinutes(val);
  int seconds = numberOfSeconds(val);
  
  // Exibição digital do tempo atual 
  return printDigits2(minutes) + ":" + printDigits2(seconds) + "   ";
}

void displayInit(char *title1, char *title2) {
  lcd.init();
  lcd.backlight();
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(title1);
  lcd.setCursor(0, 1);
  lcd.print(title2);
  delay(4000);
  lcd.clear();
}

void displayInt(int linha, char *label, int valor) {
  lcd.setCursor(0, linha); // Exibe as configurações no LCD
  lcd.print(label);
  lcd.setCursor(strlen(label) + 2, linha);
  lcd.print(valor);
  lcd.print("  ");
}

void displayTime(int linha, char *label, int valor) {
  lcd.setCursor(0, linha); // Exibe as configurações no LCD
  lcd.print(label);
  lcd.setCursor(strlen(label) + 2, linha);
  lcd.print(time2(valor));
  lcd.print("  ");
}

void menu(char *title, char *itens[], int n) {
  if (posEncoder == encoder.getPosition()) 
    return;
  
  posEncoder = positivando(encoder.getPosition(), n);
  encoder.setPosition(posEncoder);
  int selected = posEncoder % n;
  
  Serial.println(title);
  lcd.setCursor(0, 0);
  lcd.print(title);
  lcd.print("     ");
  lcd.setCursor(0, 1);
  
  for (int i = 0; i < n; i++) {
    if (i == 0) {
      lcd.print("[");
      lcd.print(itens[(selected + i) % n]);
      lcd.print("]");
    } else {
      lcd.print(" ");
      lcd.print(itens[(selected + i) % n]);
      lcd.print(" ");
    }
  }  
  lcd.print("  ");   
}

int positivando(int valor, int n) {
  while (valor < 0)
    valor += n;
  return valor;
}

#define ENCODER_MAIN
#include "config.h"
#include "Encoder.h"
#include <Arduino.h>


#ifdef ANALOGPINS
void setupRotaryEncoder()
{
  // You may have to modify the next 2 lines if using other pins than A2 and A3
      PCICR |= (1 << PCIE1);    // This enables Pin Change Interrupt 1 that covers the Analog input pins or Port C.
      PCMSK1 |= (1 << PCINT10) | (1 << PCINT11);  // This enables the interrupt for pin 2 and 3 of Port C.   a2 Clock A3 data
      encoder.setPosition(0); // nao esquecer de parametrizar em RotaryEncoder encoder(A2,A3 ) 
      pinMode(pinClick,INPUT_PULLUP);
} 


// The Interrupt Service Routine for Pin Change Interrupt 1
ISR(PCINT1_vect) 
{
      encoder.tick(); // just call tick() to check the state.
}

#else
void setupRotaryEncoder()
{
  // You may have to modify the next 2 lines if using other pins than D12 and D13
      PCICR |= (1 << PCIE0);    // This enables Pin Change Interrupt 0 that covers D8 a D13
      PCMSK0 |= (1 << PCINT4) | (1 << PCINT5);  // This enables the interrupt for pin D12 and D13 of Port  ....   12 Clock 13 data
      encoder.setPosition(0); // nao esquecer de parametrizar em RotaryEncoder encoder(A2,A3 ) // 12, 13);
      pinMode(pinClick,INPUT_PULLUP);
} 

// The Interrupt Service Routine for Pin Change Interrupt 0
ISR(PCINT0_vect) 
{
      encoder.tick(); // just call tick() to check the state.
}
#endif


int debounce(int pin)
{
  int i;
  if(digitalRead(pin)==HIGH) 
      return 0;
  long timestart = millis();
  for(i=0;digitalRead(pin) == LOW ;i++)delay(1);
  if (i<3) 
      return 0;  // menor que 3 e um ruido no canal errado
  long timeend = millis();
  if(timeend - timestart > 500)
        return 10;
  else
        return 1;
}

boolean onClick(int pin)
{
  if(digitalRead(pin)==HIGH) 
      return false;
  return true;
}

#include "config.h"

void setToDefaults();
void programaEstagios();
void setHalted();
void setEnded();
void setAbortConfirmed();
boolean ciclando();
int choice(char * msg, int position0);
int choice(char * msg, int position0, int delta, int minimo, int maximo);
void testaRPM(int vel, int vel2, long tempo);
void startGiro(int pvel);
boolean onRPM(int vel2, long tempo);
float g2Rpm(float ng);

#ifdef PROCESSOS_MASTER

extern int vel;

int nciclos = NCICLOS;
int tempoH = TEMP_CI;
int velH = VEL_CI;
int velL = VEL_CII;
int tempoL = TEMP_CII;



void setToDefaults(){ 
  nciclos = NCICLOS;
  tempoH = TEMP_CI;
  tempoL = TEMP_CII;  
  velH = VEL_CI;
  velL = VEL_CII;      
  }

void programaEstagios()
{ 
      nciclos = choice("Quantos Ciclos", nciclos);
      velH = choice("Fase I (RPM)", velH, 100, 1000, 7200);  // Seleção direta de RPM
      tempoH = choice("Tempo I (em min)", tempoH);
      velL = choice("Fase II (RPM)", velL, 100, 1000, 7200); // Seleção direta de RPM
      tempoL = choice("Tempo II (em min)", tempoL);
      lcd.setCursor(0, 1);
      lcd.print("Programado, OK!");    
      lcd.print("       ");  
      delay(750);    
}

void testaMotor()
{ 
      testaRPM(117, 118, 10);
 
}

void setHalted(){
    Serial.println("Halted");      
      lcd.setCursor(0,1);
      lcd.print("Halted!");    
      lcd.print("         ");      
}

void setEnded()
{
      lcd.clear();
      lcd.print("Terminado");    
      lcd.print("         ");       
      lcd.setCursor(0,1);
      lcd.print("Clique para sair");    
      lcd.print(" ");       
      lcd.print("         ");       
}

int iCiclo = 0;

void setAbortConfirmed()
{
      lcd.setCursor(0,0);
      lcd.print("Interrompido");    
      lcd.print("         ");       
      lcd.setCursor(0,1);
      lcd.print("Clique para sair");    
      lcd.print(" ");       
      Serial.println("Interrompido");
      onRPM(0,0);
      iCiclo = 0;
}


int choice(char * msg, int position0)
{
      encoder.setPosition(position0);
      int val = encoder.getPosition();
      lcd.clear(); lcd.print(msg);
      lcd.setCursor(0,1); lcd.print(val);
      
      while(!debounce(pinClick)) 
            if(val != encoder.getPosition()){
                  val = encoder.getPosition();
                  if (val <= 0 ){
                      val = 1;
                      encoder.setPosition(val);
                  }
                  lcd.setCursor(0,1); lcd.print(val);lcd.print("         ");
            }
      return encoder.getPosition();
}

int choice(char * msg, int position0, int delta, int minimo, int maximo)
{
      encoder.setPosition(position0/delta);
      int val = encoder.getPosition();
      lcd.clear(); lcd.print(msg);
      lcd.setCursor(0,1); lcd.print(val*delta);   
      while(!debounce(pinClick)) 
            if(val != encoder.getPosition()){
                  val = encoder.getPosition();
                  if (val < minimo ){
                      val = minimo;
                      encoder.setPosition(val);
                  }
                 if (val > maximo ){
                      val = maximo;
                      encoder.setPosition(val);
                  }
                  lcd.setCursor(0,1); lcd.print(val*delta);lcd.print("         ");
            }
      return encoder.getPosition()*delta;
}

boolean ciclando()
{
     if(iCiclo == 0 && false){
         lcd.clear();  lcd.print("Partindo ");  
         startGiro(150);
     }        
     if(iCiclo++ < nciclos ){
        lcd.clear();  lcd.print("Ciclo ");  
        lcd.print(iCiclo);  
        lcd.print("/");  
        lcd.print(nciclos);  
        lcd.setCursor(0, 1);   
        lcd.print("1 ");  
        lcd.print(velH);  // Exibe o valor de RPM
        lcd.print("x");  
        lcd.print(tempoH);  
        lcd.print(" ");  
        if(!onRPM(velH, tempoH))  // Usa o RPM diretamente
            return false;
        lcd.setCursor(0, 1);   
        lcd.print("2 ");  
        lcd.print(velL);  // Exibe o valor de RPM
        lcd.print("x");  
        lcd.print(tempoL);  
        lcd.print(" ");  
        onRPM(velL, tempoL);  // Usa o RPM diretamente
        return false;
    }
    onRPM(0, 0);  // Para o motor
    iCiclo = 0;
    return true;
}

float g2Rpm(float ng)
{
#define R 50.
      float a = (120.-30.)/(7143. - 1188.);
      float b = 30 - a*1188;
      float f = sqrt(ng/(1.1178620909604E-06*R));
      return a*f + b;

}



#endif