IR tachometer, weird readings

I’m working on a tachometer using an IR sensor. It mostly works but I keep getting some peculiar readings. Here is some serial output showing what I’m talking about…

currTime=1659791008 prevTime=1659664548 interval=126460 spindleRPM=474 rpmd=0
currTime=1659791008 prevTime=1659664548 interval=126460 spindleRPM=474 rpmd=0
currTime=1659917544 prevTime=1659791008 interval=126536 spindleRPM=474 rpmd=0
currTime=1660053264 prevTime=1660044076 interval=9188 spindleRPM=6530 rpmd=6056
currTime=1660053264 prevTime=1660044076 interval=9188 spindleRPM=6530 rpmd=0
currTime=1660170544 prevTime=1660053264 interval=117280 spindleRPM=511 rpmd=-6019
currTime=1660297076 prevTime=1660170544 interval=126532 spindleRPM=474 rpmd=-37
currTime=1660297076 prevTime=1660170544 interval=126532 spindleRPM=474 rpmd=0
currTime=1660423608 prevTime=1660297076 interval=126532 spindleRPM=474 rpmd=0
currTime=1660550084 prevTime=1660423608 interval=126476 spindleRPM=474 rpmd=0
currTime=1660550084 prevTime=1660423608 interval=126476 spindleRPM=474 rpmd=0

If the code helps, here it is…

// Screen dimensions
#define SCREEN_WIDTH  128
#define SCREEN_HEIGHT 128  

// You can use any (4 or) 5 pins 
#define SCLK_PIN 13 //clk/sck
#define MOSI_PIN 3 //din
#define DC_PIN   4 //data command
#define CS_PIN   5
#define RST_PIN  6

// Color definitions
#define  BLACK           0x0000
#define BLUE            0x001F
#define RED             0xF800
#define GREEN           0x07E0
#define CYAN            0x07FF
#define MAGENTA         0xF81F
#define YELLOW          0xFFE0  
#define WHITE           0xFFFF

#define LED_PIN     2
#define LED_COUNT  24
#define BRIGHTNESS 20 //0 to 255

#include <Adafruit_GFX.h>
//#include <Adafruit_SSD1351.h>
#include <Adafruit_SSD1331.h>

#include <Adafruit_NeoPixel.h>
#include <SPI.h>
#include <Fonts/FreeMono9pt7b.h>
//#include <Fonts/FreeMono12pt7b.h>
#include <Fonts/FreeMono18pt7b.h>
//#include <Fonts/FreeMono24pt7b.h>
#include <Fonts/FreeSans9pt7b.h>
#include <Fonts/FreeMonoBold18pt7b.h>

//Adafruit_SSD1351 tft = Adafruit_SSD1351(SCREEN_WIDTH, SCREEN_HEIGHT, CS_PIN, DC_PIN, MOSI_PIN, SCLK_PIN, RST_PIN);
Adafruit_SSD1331 tft = Adafruit_SSD1331(CS_PIN, DC_PIN, MOSI_PIN, SCLK_PIN, RST_PIN);

Adafruit_NeoPixel ring(LED_COUNT, LED_PIN, NEO_RGBW + NEO_KHZ800);


int spindleRPM = 0;
int prevRpm = 0;
volatile unsigned long rpmArray[2] = {0,0}; //array to hold the latest microseconds and previous microseconds
unsigned long tempArray[2] = {60000000, 0};  //temporary array for copying the value of rpmArray so it can be worked on after interrupts started again
long interval = 0; //time between IR pulses
int rightDigits = 0; //stores the portion of the rpm value from 0 to 99 for the ring display
int rpmDifference = 0;  //difference between the current rpm reading and the previous reading
//long currTime = 0;
//long prevTime = 0;
byte mappedPixel = 0;  //the pixel to light up on the ring representing RPM from 0 to 99
int tailSize = 0;  //the size of the "tail" trailing the lighted pixel
byte rpmDigits[4] = {0,0,0,0};  //array to hold digits of the RPM.  Max RPM 9,999.
byte rpmDigitsPrev[4] = {0,0,0,0};  //array to hold previous value of rpmDigits for comparison purposes


void setup(){
  pinMode(21, INPUT_PULLUP);
  Serial.begin(9600);
  tft.begin(); 
  attachInterrupt(digitalPinToInterrupt(21), isr, FALLING); //Interrupts are called on Rise of Input
  ring.begin();           // Initialize NeoPixel ring object
  ring.show();            // Turn OFF all pixels ASAP
  ring.setBrightness(20); // Set brightness to about 1/5 (max = 255)
  tftPrintBackground();
}

 
void loop(){
  noInterrupts();
  memcpy(tempArray, rpmArray, sizeof tempArray); 
  interrupts();
  interval = (tempArray[0] - tempArray[1]);
  spindleRPM = (60*1000000)/interval;
  if (spindleRPM < 0) spindleRPM = 0;  //prevent rpm from being negative from dividing by 0, issue on startup
  rpmDifference = (spindleRPM - prevRpm);
  rightDigits = (spindleRPM % 100);
  displayDigits();  //Displays the RPM digits on the display


  

  if (spindleRPM > 0 ) {
    tftPrintSpindleRPM();
    memcpy(rpmDigitsPrev, rpmDigits, sizeof rpmDigits);
    printx100(); //prints "x100" under RPM if the RPM is > 100
    displayPixel(ring.Color(255,   0,   0), rightDigits, rpmDifference);
    ring.show();
    prevRpm = spindleRPM;
    Serial.print("currTime=");
    Serial.print(tempArray[0]);
    Serial.print(" prevTime=");
    Serial.print(tempArray[1]);
    Serial.print(" interval=");
    Serial.print(interval);
    Serial.print(" spindleRPM=");
    Serial.print(spindleRPM);
    Serial.print(" rpmd=");
    Serial.println(rpmDifference);
    //prevTime = currTime;
  }  
}

void isr(){
  rpmArray[1] = rpmArray[0];
  rpmArray[0] = micros();
}

void displayDigits(){  //breaks out the digits of the RPM and puts them in an array for display.
  int myRPM = spindleRPM;
  if (spindleRPM > 99) myRPM /= 100;
  for (byte i = 0; i < 2; i++) {
    rpmDigits[i] = myRPM % 10;
    myRPM /= 10;
  }
}

void printx100(){
  if (spindleRPM >= 100 && prevRpm < 100) {
    tft.setCursor(5, 20);
    tft.setTextColor(RED);  
    tft.println("x100");
    tft.setFont();
  }
  else if (spindleRPM < 100 &&  prevRpm >= 100) {
    tft.setCursor(5, 20);
    tft.setTextColor(BLACK);  
    tft.println("x100");
    tft.setFont();
  }
}




void displayPixel(uint32_t color, byte rightDigits, int rpmDifference){
//  Serial.print("rpmd= ");
//  Serial.print(rpmDifference);
  rpmDifference = constrain(rpmDifference, -50, 50);  //limiting the acceleration value to 100 or less in either direction
//  Serial.print(" rpmdc= ");
//  Serial.print(rpmDifference);
  
  mappedPixel = map(rightDigits, 0, 99, 0, 23);
  tailSize = map(rpmDifference, -50, 50, -23, 23);
//  Serial.print(" tailsize= ");
//  Serial.println(tailSize);
  ring.clear();
  ring.setPixelColor(mappedPixel, color);         //  Set pixel's color (in RAM)
  
//  Serial.print("Mapped=");
//  Serial.println(mappedPixel);
 
  int m = mappedPixel;
  int brightness = 50;
  int x = 50;
  for (int i=mappedPixel-tailSize; i < mappedPixel; i++){
    uint32_t rgbcolor = ring.ColorHSV(65000, 255, 255);
    x += 10;
    m = i;
    if (m < 0) {
      m=m+24;
    }
//    Serial.println(m);
    ring.setPixelColor(m, rgbcolor);
  }
  
}




void tftPrintSpindleRPM(){
  tft.setFont(&FreeMono18pt7b);
  tft.setTextSize(1);

 //print previous spindleRPM in black to clear it
  tft.setCursor(50, 23);
  tft.setTextColor(BLACK);
  
  if (rpmDigits[1] != rpmDigitsPrev[1]){
    tft.print(rpmDigitsPrev[1]);
  }
  tft.setCursor(70, 23);
  if (rpmDigits[0] != rpmDigitsPrev[0]){
    tft.print(rpmDigitsPrev[0]);
  }
    
  //print the spindleRPM in white
  tft.setCursor(50, 23);
  tft.setTextColor(WHITE);
  
  if (rpmDigits[1] > 0 && rpmDigits[1] != rpmDigitsPrev[1]){
    tft.print(rpmDigits[1]);
  }
  tft.setCursor(70, 23);
  if (rpmDigits[0] != rpmDigitsPrev[0]){
    tft.print(rpmDigits[0]);
  }
  tft.setFont();
}
  

   





void tftPrintBackground() {
  tft.fillScreen(BLACK);

  tft.drawRect(0, 33, 96, 31, GREEN);
  tft.drawLine(31, 33, 31, 64, GREEN);
  tft.drawLine(62, 33, 62, 64, GREEN);

  tft.setFont(&FreeSans9pt7b);
  tft.setCursor(1, 13);
  tft.setTextColor(RED);  
  tft.println("RPM");
  tft.setFont();

  tft.setCursor(7, 38);
  tft.setTextColor(RED);
  tft.setTextSize(1);
  tft.println("MTR");

  tft.setCursor(3, 52);
  tft.setTextColor(WHITE);
  tft.setTextSize(1);
  tft.println("3600");
  
  tft.setCursor(38, 38);
  tft.setTextColor(RED);
  tft.setTextSize(1);
  tft.println("DRV");

  tft.setCursor(35, 52);
  tft.setTextColor(WHITE);
  tft.println("1350");
  tft.setFont();

  tft.setCursor(71, 38);
  tft.setTextColor(RED);
  tft.setTextSize(1);
  tft.println("FPR");

  tft.setCursor(64, 52);
  //tft.setCursor(60, 72);
  tft.setTextColor(WHITE);
  tft.println(".0209");
  tft.setFont();
}

We don't know what doing.You need to give more information.
Like what are you expecting, other than the numbers look funny.

What are you expecting from the numbers?
What are you measuring the rpm of ( a motor spindle) ?
Is what ever your measuring constant speed.

I looks like there is gearing of some kind involved. 126 milliseconds is about 8 rpms but you have
474 rpms.

Your turning off interrupts to do a copy. Could you be missing interrupts in that period of time?
Whats your loop time ? If it is fast compared to the interrupts you don't have to turn off interrupts.

set a flag in the interrupt and in loop when the flag is 1 then do the copy or any other stuff that way
your not doing it more than once.

You might want to look at the .h files for these include files. This could help you see some pins have already defined.

#include <Adafruit_GFX.h>
#include <Adafruit_SSD1331.h>
#include <Adafruit_NeoPixel.h>
#include <SPI.h>
#include <Fonts/FreeMono9pt7b.h>
#include <Fonts/FreeMono18pt7b.h>
#include <Fonts/FreeSans9pt7b.h>
#include <Fonts/FreeMonoBold18pt7b.h>

noweare:
We don't know what doing.You need to give more information.
Like what are you expecting, other than the numbers look funny.

What are you expecting from the numbers?
What are you measuring the rpm of ( a motor spindle) ?
Is what ever your measuring constant speed.

I looks like there is gearing of some kind involved. 126 milliseconds is about 8 rpms but you have
474 rpms.

Your turning off interrupts to do a copy. Could you be missing interrupts in that period of time?
Whats your loop time ? If it is fast compared to the interrupts you don't have to turn off interrupts.

set a flag in the interrupt and in loop when the flag is 1 then do the copy or any other stuff that way
your not doing it more than once.

Sorry for not giving more information. There is a lot of code that I posted that doesn't have anything to do with the problem but I've seen people before get upset when the entire code isn't posted.

I've got an IR sensor that's looking at a piece of reflective tape on a rotating wheel. Each time it sees the tape the ISR is called. When it's called it measures the time in microseconds into an array and moves the previous value stored to a second position in the array. Each trip through the sketches main loop it is looking at these two times and calculating what the latest RPM is.

What I posted is the serial output I recorded on the console. It is showing the two time values from the array (currTime and prevTime), the difference between these two times (interval), the calcluated RPM based on this interval, and the RPM difference from the previous time it was calculated.

During the serial output I posted the motor is running at a near constant RPM of 474. Even though the wheel is spinning at a constant RPM I will periodically get "noise." You can see where the RPM jumps to approximately 6500 all of the sudden when in reality the wheel was running at a constant RPM.

It's microseconds, not milliseconds I'm measuring thus the formula of 60*1000000/interval to come up with the RPM. So no, no gearing involved.

I am turning off interrupts to do a copy as that's what I've seen suggested in other posts. Yes, I could be missing interrupts with each trip through the main loop of the sketch but it really shouldn't matter. Or at least I don't believe it should. It's obvious through the serial output I posted that the ISR is running at least more than once with each trip through the loop otherwise the prevtime value would always be equal to the previous currtime value.

There are two approaches to calculating RPM. One is to run the loop at some interval and count the number of pulses during that interval. This proved to be very inaccurate and causes the RPM to jump by multiples of 60 which has been documented in lots of other posts. The solution everyone offered was to calculate the time between pulses of the IR instead which is what I'm doing. Seems to work fine except for the random odd numbers as I posted above. Something is going on I just can't seem to figure out what. It's almost like I'm making it through the loop twice before the ISR has had a chance to fire?

Gates:
You might want to look at the .h files for these include files. This could help you see some pins have already defined.

I looked at the libraries and don't see any pins defined in them that I'm trying to use. I also just tried using a different IR sensor on a different pin. Results don't change.

After removing the double-sampling (reporting the same 'curr' and 'prev' times twice):

currTime=1659791008 prevTime=1659664548 interval=126460 spindleRPM=474 rpmd=0
currTime=1659917544 prevTime=1659791008 interval=126536 spindleRPM=474 rpmd=0
Note: One rotation not reported. Next 'prevTime' is 126532 microseconds after previous 'currTime'
currTime=1660053264 prevTime=1660044076 interval=9188 spindleRPM=6530 rpmd=0
currTime=1660170544 prevTime=1660053264 interval=117280 spindleRPM=511 rpmd=-6019
currTime=1660297076 prevTime=1660170544 interval=126532 spindleRPM=474 rpmd=-37
currTime=1660423608 prevTime=1660297076 interval=126532 spindleRPM=474 rpmd=0
currTime=1660550084 prevTime=1660423608 interval=126476 spindleRPM=474 rpmd=0

I note that 117280 + 9188 = 126468 so it looks like there was one spurious interrupt part way through a rotation. Perhaps a flash of light or some electrical noise triggered the interrupt.

johnwasser:
After removing the double-sampling (reporting the same ‘curr’ and ‘prev’ times twice):

currTime=1659791008 prevTime=1659664548 interval=126460 spindleRPM=474 rpmd=0
currTime=1659917544 prevTime=1659791008 interval=126536 spindleRPM=474 rpmd=0
Note: One rotation not reported. Next ‘prevTime’ is 126532 microseconds after previous ‘currTime’
currTime=1660053264 prevTime=1660044076 interval=9188 spindleRPM=6530 rpmd=0
currTime=1660170544 prevTime=1660053264 interval=117280 spindleRPM=511 rpmd=-6019
currTime=1660297076 prevTime=1660170544 interval=126532 spindleRPM=474 rpmd=-37
currTime=1660423608 prevTime=1660297076 interval=126532 spindleRPM=474 rpmd=0
currTime=1660550084 prevTime=1660423608 interval=126476 spindleRPM=474 rpmd=0

I note that 117280 + 9188 = 126468 so it looks like there was one spurious interrupt part way through a rotation. Perhaps a flash of light or some electrical noise triggered the interrupt.

I too have been thinking this is some kind of “noise” or spurious interrupt. Perhaps the IR sensor when it sees the reflective tape is quickly rising and falling twice or something. In order to make this more understandable I stripped out all the other code and tried to simplify it for understanding it here. With the other code stripped out, here’s what I have…

int spindleRPM = 0;
int prevRpm = 0;
volatile unsigned long rpmArray[2] = {0,0}; //array to hold the latest microseconds and previous microseconds
unsigned long tempArray[2] = {60000000, 0};  //temporary array for copying the value of rpmArray so it can be worked on after interrupts started again
long interval = 0; //time between IR pulses
int rpmDifference = 0;  //difference between the current rpm reading and the previous reading



void setup(){
  pinMode(21, INPUT);
  Serial.begin(9600);
  attachInterrupt(digitalPinToInterrupt(20), isr, FALLING); //Interrupts are called on Rise of Input
  
}

 
void loop(){
  noInterrupts();
  memcpy(tempArray, rpmArray, sizeof tempArray); 
  interrupts();
  interval = (tempArray[0] - tempArray[1]);
  spindleRPM = (60*1000000)/interval;
  if (spindleRPM < 0) spindleRPM = 0;  //prevent rpm from being negative from dividing by 0, issue on startup
  rpmDifference = (spindleRPM - prevRpm);
  


  

  if (spindleRPM > 0 ) {
   
    prevRpm = spindleRPM;
    Serial.print("currTime=");
    Serial.print(tempArray[0]);
    Serial.print(" prevTime=");
    Serial.print(tempArray[1]);
    Serial.print(" interval=");
    Serial.print(interval);
    Serial.print(" spindleRPM=");
    Serial.print(spindleRPM);
    Serial.print(" rpmd=");
    Serial.println(rpmDifference);
  }  
}

void isr(){
  rpmArray[1] = rpmArray[0];
  rpmArray[0] = micros();
}

I decided to go ahead and run it to verify I didn’t remove anything that should have been left in. What’s interesting is that now that I stripped everything else out, the problem goes away. I can sit and watch the serial monitor and don’t see the problem ever occur where as with all the other code in there the problem seems to occur at least once every 15 seconds or so. Now I’m really stumped. I didn’t figure stripping out all the other code would make a difference.

I spoke to soon. I let it run for about 5 minutes and never observed the problem then suddenly saw it again. But now it seems to only occur once every 5 to 7 minutes where with the other code it was happening every 10 to 15 seconds.

I'm almost to the point of trying to set this up with a hall sensor instead to see if I observe the same problem. But seems way too much of a coincidence that with the other code taken out it almost never occurs.

And of course now I'm running it with all the other code and almost can't get it to occur. Ran for 10 minutes without seeing it.

John, I went back and read your post again. Interesting observation you had about the sum of those two numbers. I'm thinking you may be right. During my latest run I only got it to happen once in 5 minutes but when it did, the two numbers added up to close to all the other intervals that were being measured. I wonder if it's not stray light triggering the sensor.

johnwasser:
After removing the double-sampling (reporting the same 'curr' and 'prev' times twice):

currTime=1659791008 prevTime=1659664548 interval=126460 spindleRPM=474 rpmd=0
currTime=1659917544 prevTime=1659791008 interval=126536 spindleRPM=474 rpmd=0
Note: One rotation not reported. Next 'prevTime' is 126532 microseconds after previous 'currTime'
currTime=1660053264 prevTime=1660044076 interval=9188 spindleRPM=6530 rpmd=0
currTime=1660170544 prevTime=1660053264 interval=117280 spindleRPM=511 rpmd=-6019
currTime=1660297076 prevTime=1660170544 interval=126532 spindleRPM=474 rpmd=-37
currTime=1660423608 prevTime=1660297076 interval=126532 spindleRPM=474 rpmd=0
currTime=1660550084 prevTime=1660423608 interval=126476 spindleRPM=474 rpmd=0

I note that 117280 + 9188 = 126468 so it looks like there was one spurious interrupt part way through a rotation. Perhaps a flash of light or some electrical noise triggered the interrupt.

John, I think you nailed it. I've been sitting here watching it run and looking at each instance where it occurs. So far each time it happens if you add the two up they come out to right at what the interval should have been. It must be seeing some stray light that's somehow triggering it part way through a rotation.

HI,
Just out of curiosity, you have an IR sensor, reflective tape.
What is your source of IR energy to reflect off the tape?
Is the tape specified for IR reflection?

Tom... :slight_smile:

I’m using these emitter/sensors:

FTCBlock 10PCS IR Infrared Obstacle Avoidance Sensor Module for Arduino Smart Car Robot Amazon.com: FTCBlock 10PCS IR Infrared Obstacle Avoidance Sensor Module for Arduino Smart Car Robot: Camera & Photo

The tape is tape that came with a handheld IR tachometer so I assume so.

From what I’m observing it doesn’t seem to have any problem sensing the tape. It seems like it’s sensing an extra pulse during a revolution.

travisr100:
From what I’m observing it doesn’t seem to have any problem sensing the tape. It seems like it’s sensing an extra pulse during a revolution.

Does the extra pulse usually come around the same place in the revolution? If so you might just have a shiny spot.

Not in front of the setup at the moment to check that. But I’ll give it a look when I can. That is possible. Seems to be awfully intermittent though. It can run over 1000 revolutions without the problem happening. I’ve got a hall sensor on order and going to see if that fixes the problem although I wanted to stay away from using any magnets.

Travisr100.

Did you get this issue fixed? I have the same exact problem using these sensors. I suspect my issue is stray light, but not sure--I feel my setup is well hidden from light.

I've implemented software and hardware debouncers, and that seemed to help but not totally fixed my issue. Hoping you have the magic sauce :slight_smile:

Not yet. Stray light could be my problem as well. Going to try shielding it as best I can and see what the results are. I believe these sensors are extremely sensitive.

Debouncing in code would be difficult for me because of the range of rpm I’m measuring. Most values I would exclude with denounce code would be acceptable values at other RPM’s. What I could do is check for a percentage variance from the last reading and discard it if it was higher than x% difference. Even then however I have to take acceleration into account.

Well, it's not stray light. Hall sensor came in today and got it hooked up. I'm still seeing the same problem. Here's another copy of some console output...

currTime=302183396 prevTime=302083416 interval=99980 spindleRPM=600 rpmd=0
currTime=302283356 prevTime=302183396 interval=99960 spindleRPM=600 rpmd=0
currTime=302383316 prevTime=302283356 interval=99960 spindleRPM=600 rpmd=0
currTime=302483308 prevTime=302383316 interval=99992 spindleRPM=600 rpmd=0
currTime=302483308 prevTime=302383316 interval=99992 spindleRPM=600 rpmd=0
currTime=302583328 prevTime=302483308 interval=100020 spindleRPM=599 rpmd=-1
currTime=302683328 prevTime=302583328 interval=100000 spindleRPM=600 rpmd=1
currTime=302783284 prevTime=302683328 interval=99956 spindleRPM=600 rpmd=0
currTime=302883220 prevTime=302783284 interval=99936 spindleRPM=600 rpmd=0
currTime=302886808 prevTime=302883220 interval=3588 spindleRPM=16722 rpmd=16122
currTime=302983180 prevTime=302886808 interval=96372 spindleRPM=622 rpmd=-16100
currTime=303083176 prevTime=302983180 interval=99996 spindleRPM=600 rpmd=-22
currTime=303183220 prevTime=303083176 interval=100044 spindleRPM=599 rpmd=-1
currTime=303283256 prevTime=303183220 interval=100036 spindleRPM=599 rpmd=0
currTime=303283256 prevTime=303183220 interval=100036 spindleRPM=599 rpmd=0
currTime=303383236 prevTime=303283256 interval=99980 spindleRPM=600 rpmd=1
currTime=303483140 prevTime=303383236 interval=99904 spindleRPM=600 rpmd=0
currTime=303583056 prevTime=303483140 interval=99916 spindleRPM=600 rpmd=0
currTime=303683028 prevTime=303583056 interval=99972 spindleRPM=600 rpmd=0
currTime=303683028 prevTime=303583056 interval=99972 spindleRPM=600 rpmd=0
currTime=303783068 prevTime=303683028 interval=100040 spindleRPM=599 rpmd=-1
currTime=303883140 prevTime=303783068 interval=100072 spindleRPM=599 rpmd=0
currTime=303983188 prevTime=303883140 interval=100048 spindleRPM=599 rpmd=0

johnwasser still seems to be on to something. If you look at the two oddball intervals above, 3588 and 96372, they add up to 99,960 which would be right in line with the other intervals. I'm stumped as to what may be causing this.

I'm having an even harder time explaining these...

currTime=166339132 prevTime=166289152 interval=49980 spindleRPM=1200 rpmd=-1
currTime=166439184 prevTime=166389140 interval=50044 spindleRPM=1198 rpmd=-2
currTime=166539364 prevTime=166489260 interval=50104 spindleRPM=1197 rpmd=-1
currTime=166589480 prevTime=166539364 interval=50116 spindleRPM=1197 rpmd=0
currTime=166689708 prevTime=166639596 interval=50112 spindleRPM=1197 rpmd=0
currTime=166789832 prevTime=166739792 interval=50040 spindleRPM=1199 rpmd=2
currTime=166839816 prevTime=166791540 interval=48276 spindleRPM=1242 rpmd=43
currTime=166939668 prevTime=166889764 interval=49904 spindleRPM=1202 rpmd=-40
currTime=166989556 prevTime=166939668 interval=49888 spindleRPM=1202 rpmd=0
currTime=167089352 prevTime=167039448 interval=49904 spindleRPM=1202 rpmd=0
currTime=167189236 prevTime=167139276 interval=49960 spindleRPM=1200 rpmd=-2
currTime=167239228 prevTime=167189236 interval=49992 spindleRPM=1200 rpmd=0
currTime=167339328 prevTime=167289260 interval=50068 spindleRPM=1198 rpmd=-2

my units have a sensitivity pot, maybe you can adjust it's sensitivity?

maybe buy an oscilloscope to test your signal speed/s.