Interrupts to read from a rotary encoder with Matlab

turn off interrupts on one pin unless speed is slower you already know the direction once the speed is up.

My encoder has 400 pulses per revolution and this code works well at high speeds

#define ClockPin 3 // Must be pin 2 or 3
//#define DataPin 9 // can be any other pin

// My Encoder has 400 Clock pulses per revolution
// note that 150000.0 = (60 seonds * 1000000 microseconds)microseconds in a minute / 400 pulses in 1 revolution)
// change the math to get the proper multiplier for RPM for your encoder
// yours has 4 pulses in 1 revolution
// note that 150000.0 = (60 seonds * 1000000 microseconds)microseconds in a minute / 4 pulses in 1 revolution)
#define Multiplier 15000000.0 // don't forget a decimal place to make this number a floating point number
volatile long count = 0;
volatile long EncoderCounter = 0;
volatile int32_t dTime; // Delt in time
volatile bool DataPinVal;

void onPin2CHANGECallBackFunction() {
  static uint32_t lTime; // Saved Last Time of Last Pulse
  uint32_t cTime; // Current Time
  cTime = micros(); // Store the time for RPM Calculations

  /*
    // Encoder Code
      DataPinVal = digitalRead(DataPin);
    // We know pin 2 just went high to trigger the interrupt
    // depending on direction the data pin will either be high or low
      EncoderCounter += (DataPinVal) ? 1 : -1; // Should we step up or down?
    // End Encoder Code
  */
  // calculate the DeltaT between pulses
  dTime = cTime - lTime;
  lTime = cTime;

}


void setup() {
  Serial.begin(115200); //115200
  // put your setup code here, to run once:
  pinMode(ClockPin, INPUT);
  //  pinMode(DataPin, INPUT);
  attachInterrupt(digitalPinToInterrupt(ClockPin), onPin2CHANGECallBackFunction, RISING);
}

void loop() {
  //  long Counter;
  // bool DataPinValue
  float DeltaTime;
  float SpeedInRPM = 0;


  // Serial print is slow so only use it when you need to (10 times a second)
  static unsigned long SpamTimer;
  if ( (unsigned long)(millis() - SpamTimer) >= (100)) {
    SpamTimer = millis();
    noInterrupts ();
    // Because when the interrupt occurs the EncoderCounter and SpeedInRPM could be interrupted while they
    // are being used we need to say hold for a split second while we copy these values down. This doesn't keep the
    // interrupt from occurring it just slightly delays it while we maneuver values.
    // if we don't do this we could be interrupted in the middle of copying a value and the result get a corrupted value.
    //  Counter = EncoderCounter;
    //  DataPinValue = DataPinVal;
    DeltaTime = dTime;
    dTime = 0; // if no pulses occure in the next 100 miliseconds then we must assume that the motor has stopped this allows a speed of zero to occure 
    interrupts ();
    //   SpeedInRPM = Multiplier / ((DataPinValue) ? DeltaTime: (-1 * DeltaTime)); // Calculate the RPM Switch DeltaT to either positive or negative to represent Forward or reverse RPM
    SpeedInRPM = Multiplier / DeltaTime; // Calculate the RPM Switch DeltaT to either positive or negative to represent Forward or reverse RPM
    //   Serial.print(Counter );
    //   Serial.print("\t");
    Serial.print(SpeedInRPM , 3);
    Serial.print(" RPM");
    Serial.println();
  }
}

Z