Timer interrupts not working correctly

Hi,
I am working my CNC Machine project for a while.I will briefly explain.I am setting step value, Compare value, precalar value in C# and I’m sending Arduino but sometimes the timer is not working correctly(10 to 20 millisecond faults) I found these mistakes using millis(). At the beginning the value of the prescale was constantly at 8 when this error occurred.When I used this code, most of the problem was solved.

TCCR4B &= ~(1 << CS40 | 1 << CS41 | 1 << CS42);

but there are still time errors sometimes.Here millis() results.

here my arduino Code

#include <avr/interrupt.h>
//--------------------------------------------
#define TIMER3_ON TIMSK3 |= (1 << OCIE3A)
#define TIMER3_OFF TIMSK3 &= ~(1 << OCIE3A)
//--------------------------------------------
#define TIMER4_ON TIMSK4 |= (1 << OCIE4A)
#define TIMER4_OFF TIMSK4 &= ~(1 << OCIE4A)
//--------------------------------------------
#define TIMER5_ON TIMSK5 |= (1 << OCIE5A)
#define TIMER5_OFF TIMSK5 &= ~(1 << OCIE5A)
//--------------------------------------------
#define MotorXstep 48
#define MotorXdirection 49
//--------------------------------------------
#define MotorYstep 50
#define MotorYdirection 51
//--------------------------------------------
#define MotorZstep 51
#define MotorZdirection 52
//--------------------------------------------
volatile long sayacX = 0, sayacY = 0, sayacZ = 0;
volatile byte VeriAl = 0;
//--------------------------------------------
volatile unsigned long cury, prey = 0, curx, prex = 0, curz, prez = 0;
volatile unsigned int Fx[200];
volatile unsigned int Fy[200];
volatile unsigned int Fz[200];
byte prescalarX[200];
byte prescalarY[200];
byte prescalarZ[200];
volatile long xStep[200];
volatile long yStep[200];
volatile long zStep[200];
//------------------
volatile bool PrescalarX = false;
volatile bool PrescalarY = false;
volatile bool PrescalarZ = false;
bool Calistir = false;

void setup()
{
  Serial.begin(115200);
  //-----------------
  TCCR3A = 0;
  TCCR3B = 0;
  TCNT3 = 0;
  TIMSK3 = 0;
  //---------
  TCCR4A = 0;
  TCCR4B = 0;
  TCNT4 = 0;
  TIMSK4 = 0;
  //---------
  TCCR5A = 0;
  TCCR5B = 0;
  TCNT5 = 0;
  TIMSK5 = 0;
  //---------
  pinMode(32, OUTPUT); // X - Yeşil Lamba
  pinMode(33, OUTPUT); // Y - Kırmızı Lamba
  pinMode(34, OUTPUT); // Z - Sarı Lamba
  pinMode(35, OUTPUT); // VeriAlınıyor LED
  pinMode(MotorXstep, OUTPUT);
  pinMode(MotorXdirection, OUTPUT);
  pinMode(MotorYstep, OUTPUT);
  pinMode(MotorYdirection, OUTPUT);
  pinMode(MotorZstep, OUTPUT);
  pinMode(MotorZdirection, OUTPUT);
  //--------------------------------------------
  TCCR3B |= (0 << CS30 | 1 << CS31 | 0 << CS32);
  TCCR4B |= (0 << CS40 | 1 << CS41 | 0 << CS42);
  TCCR5B |= (0 << CS50 | 1 << CS51 | 0 << CS52);
  TCCR3B &= ~(1 << CS30 | 1 << CS31 | 1 << CS32);
  TCCR4B &= ~(1 << CS40 | 1 << CS41 | 1 << CS42);
  TCCR5B &= ~(1 << CS50 | 1 << CS51 | 1 << CS52);
}

void loop()
{
  if (Calistir == true)
    Ayarla();
}

void serialEvent()
{
  char oku = Serial.read();
  digitalWrite(35, LOW);
  if (oku == 'o')
  {
    digitalWrite(35, HIGH);
    String Degerler;
    VeriAl++;
    if (VeriAl == 200) // VeriAl 200 değerine ulaştığında Sıfırlanmalıdır!
      VeriAl = 0;
    //-------------------------------------
    Degerler = Serial.readStringUntil('.');
    prescalarX[VeriAl] = Degerler.toInt();  // X Prescalar verisi alındı.
    Degerler = Serial.readStringUntil('.');
    xStep[VeriAl] = Degerler.toInt();       // X Adım verisi alındı.
    Degerler = Serial.readStringUntil('.');
    Fx[VeriAl] = Degerler.toInt();          // X Timer verisi alındı.
    //------------------------------------
    Degerler = Serial.readStringUntil('.');
    prescalarY[VeriAl] = Degerler.toInt(); // Y Prescalar verisi alındı.
    Degerler = Serial.readStringUntil('.');
    yStep[VeriAl] = Degerler.toInt();      // Y Adım verisi alındı.
    Degerler = Serial.readStringUntil('.');
    Fy[VeriAl] = Degerler.toInt();         // Y Timer verisi alındı.
    //------------------------------------
    Degerler = Serial.readStringUntil('.');
    prescalarZ[VeriAl] = Degerler.toInt(); // Z Prescalar verisi alındı.
    Degerler = Serial.readStringUntil('.');
    zStep[VeriAl] = Degerler.toInt();      // Z Adım verisi alındı.
    Degerler = Serial.readStringUntil('.');
    Fz[VeriAl] = Degerler.toInt();         // Z Timer verisi alındı.
    //-------------------------------------
  }
  else if (oku == 's')
    Calistir = true;
}
//-------------------
void Ayarla() //Setting motors direction, prescalar, compare
{
  Calistir = false;
  //-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-X-
  if ( xStep[VeriAl] < 0)
    digitalWrite(MotorXdirection, LOW);
  else if (xStep[VeriAl] > 0)
    digitalWrite(MotorXdirection, HIGH);
  if (prescalarX[VeriAl] == 1)
    PrescalarX = false;
  else if (prescalarX[VeriAl] == 8)
    PrescalarX = true;
  //-Y-Y-Y-Y-Y-Y-Y-Y-Y-Y-Y-Y-Y-Y-Y-Y-Y-
  if ( yStep[VeriAl] < 0)
    digitalWrite(MotorYdirection, LOW);
  else if (yStep[VeriAl] > 0)
    digitalWrite(MotorYdirection, HIGH);
  if (prescalarY[VeriAl] == 1)
    PrescalarY = false;
  else if (prescalarY[VeriAl] == 8)
    PrescalarY = true;
  //-Z-Z-Z-Z-Z-Z-Z-Z-Z-Z-Z-Z-Z-Z-Z-Z-Z-
  if (zStep[VeriAl] < 0)
    digitalWrite(MotorZdirection, LOW);
  else if (zStep[VeriAl] > 0)
    digitalWrite(MotorZdirection, HIGH);
  if (prescalarZ[VeriAl] == 1)
    PrescalarZ = false;
  else if (prescalarZ[VeriAl] == 8)
    PrescalarZ = true;
  //---------------------------
  sayacX = 0;
  sayacY = 0;
  sayacZ = 0;
  cli();
  //----------------------------
  TCCR3A = 0;
  TCCR3B = 0;
  TCNT3 = 0;               // Sayac Sıfırlanır
  OCR3A = Fx[VeriAl];      // Compare Degeri
  TCCR3B |= (1 << WGM32);  // CTC Modu aktif
  if (PrescalarX == true)  
    TCCR3B |= (0 << CS30 | 1 << CS31); // Prescalar 8
  else                     
    TCCR3B |= (1 << CS30 | 0 << CS31); // Prescalar 1
  TIMSK3 = 0;
  //-------------------------------
  TCCR4A = 0;
  TCCR4B = 0;
  TCNT4 = 0;
  OCR4A = Fy[VeriAl];
  TCCR4B |= (1 << WGM42);
  if (PrescalarY == true)
    TCCR4B |= (0 << CS40 | 1 << CS41 | 0 << CS42); // Prescalar 8
  else
    TCCR4B |= (1 << CS40 | 0 << CS41 | 0 << CS42); // Prescalar 1
  TIMSK4 = 0;
  //-------------------------------
  TCCR5A = 0;
  TCCR5B = 0;
  TCNT5 = 0;
  OCR5A = Fz[VeriAl];
  TCCR5B |= (1 << WGM52);
  if (PrescalarZ == true)
    TCCR5B |= (0 << CS50 | 1 << CS51 | 0 << CS52); // Prescalar 8
  else
    TCCR5B |= (1 << CS50 | 0 << CS51 | 0 << CS52); // Prescalar 1
  TIMSK5 = 0;
  //--------------------------------
  if (xStep[VeriAl] != 0)
    TIMSK3 |= (1 << OCIE3A); // Timer3 Başlat
  if (yStep[VeriAl] != 0)
    TIMSK4 |= (1 << OCIE4A); // Timer4 Başlat
  if (zStep[VeriAl] != 0)
    TIMSK5 |= (1 << OCIE5A); // Timer5 Başlat
  sei();
  prex = millis();
  prey = millis();
  prez = millis();
}

//-------------------
// X Stepper
//-------------------
ISR(TIMER3_COMPA_vect)
{
  digitalWrite(32, HIGH); // Green LED
  digitalWrite(MotorXstep, LOW);
  digitalWrite(MotorXstep, HIGH);
  sayacX++;
  if (sayacX == abs(xStep[VeriAl]))
  {
    cli();
    TIMSK3 &= ~(1 << OCIE3A);
    TCCR3B &= ~(1 << CS30 | 1 << CS31);
    digitalWrite(32, LOW);
    curx = millis();
    Serial.print("TIMER3 = ");
    Serial.print(curx - prex);
    Serial.println("ms");
  }
}

//---------------------------
// Y stepper
//---------------------------
ISR(TIMER4_COMPA_vect)
{
  digitalWrite(33, HIGH); // Red LED
  digitalWrite(MotorYstep, LOW);
  digitalWrite(MotorYstep, HIGH);
  sayacY++;
  if (sayacY == abs(yStep[VeriAl]))
  {
    cli();
    TIMSK4 &= ~(1 << OCIE4A);
    TCCR4B &= ~(1 << CS40 | 1 << CS41 | 1 << CS42);
    digitalWrite(33, LOW);
    cury = millis();
    Serial.print("TIMER4 = ");
    Serial.print(cury - prey);
    Serial.println("ms");
  }
}

//-------------------
// Z Stepper
//-------------------
ISR(TIMER5_COMPA_vect)
{
  digitalWrite(34, HIGH); // Yellow LED
  digitalWrite(MotorZstep, LOW);
  digitalWrite(MotorZstep, HIGH);
  sayacZ++;
  if (sayacZ == abs(zStep[VeriAl]))
  {
    TIMER5_OFF;
    cli();
    TCCR5B &= ~(1 << CS50 | 1 << CS51 | 1 << CS52);
    digitalWrite(34, LOW);
    curz = millis();
    Serial.print("TIMER5 = ");
    Serial.print(curz - prez);
    Serial.println("ms");
  }
}

Note:
I have test a lot of my c# code and there is no error.

I think I am not setting correctly timer value again.

Which Arduino are you running this code on?

  TCCR3B |= (0 << CS30 | 1 << CS31 | 0 << CS32);
  TCCR4B |= (0 << CS40 | 1 << CS41 | 0 << CS42);
  TCCR5B |= (0 << CS50 | 1 << CS51 | 0 << CS52);
  TCCR3B &= ~(1 << CS30 | 1 << CS31 | 1 << CS32);
  TCCR4B &= ~(1 << CS40 | 1 << CS41 | 1 << CS42);
  TCCR5B &= ~(1 << CS50 | 1 << CS51 | 1 << CS52);

Typically, people disable interrupts while messing with timer settings. Is there some reason you don’t?

  prex = millis();
  prey = millis();
  prez = millis();

You realize that you could have stored 3 different values in prex, prey, and prez, right?

ISR(TIMER3_COMPA_vect)
{
  digitalWrite(32, HIGH); // Green LED
  digitalWrite(MotorXstep, LOW);
  digitalWrite(MotorXstep, HIGH);
  sayacX++;
  if (sayacX == abs(xStep[VeriAl]))
  {
    cli();

Interrupts are already disabled when an ISR is called.

    Serial.print("TIMER3 = ");
    Serial.print(curx - prex);
    Serial.println("ms");

You should NOT be doing Serial.print() in an ISR.

I’d recommend not to try changing which interrupts are enabled inside an ISR. Leave all the ones you
are using enabled and figure out when its called what needs doing (perhaps nothing, that’s OK). Just
setup up all the interrupts you use in setup() and leave them setup.

The act of disabling or enabling individual interrupts has pitfalls - spurious/duplicate and missed events are
possible. Its easier and clearer to just have the right logic in the ISR.

Turning the global interrupt flag on and off is fine, that never loses or duplicates interrupts (assuming you
never leave if off for long periods). And every ISR automatically disables the global flag while its running
anyway.