how to improve the accuracy of tachometer ?

hello , i’m new to the arduino programming
i have a code for calculating the RPM from IR sensor which i found
I’ve been trying to improve the accuracy but it still the same .
for example if the result supposed to be 60rpm it shows 59rpm
if its supposed to be 1020 it shows 1009 .

in this code its considered to be one white strip on the disc so we multiply by 60 ( or 60000 since it counts milli)
when i change the 60000 to 15000 ( consider 4 white strips to improve accuracy )
but still the same error

is there anything to change ? or to do regarding simulation
im just using simulation using protus and added arduino nano and attach to it hex file

code :

#include<LiquidCrystal.h>
LiquidCrystal lcd(12,11,6,5,4,3);
float value=0;
float rev=0;
int rpm;
int t1=0;
int time;

void isr() //interrupt service routine
{
rev++;
}

void setup()
{
lcd.begin(16,2); //initialize LCD
attachInterrupt(0,isr,RISING);//attaching the interrupt

}

void loop()
{
delay(1000);

detachInterrupt(0); //detaches the interrupt

time=millis()-t1; //finds the time

rpm=(rev/time)*60000; //calculates rpm

t1=millis(); //saves the current time

rev=0;

lcd.clear();
lcd.setCursor(0,0);
lcd.print(“TACHOMETER PR”);
lcd.setCursor(0,1);
lcd.print( rpm);
lcd.print(" RPM");
lcd.print(" CW "); // only assumption
attachInterrupt(0,isr,RISING);

}

Start off by:

  • using code tags (hint, read "How to use the forum")
  • by not making 'rev' a float
  • make 'rev' volatile
  • depending on the speed, is ms okay? You might want to use us instead if it's fast

Updating the LCD is not fast, it will probably take several tens of milliseconds at least. But your code assigns t1 to the current value of millis() before the LCD is updated. This means when you calculate the variable ‘time’, it will always be larger than it should be, so your rpm calculation is lower than it should be. To fix this, assign t1 to millis() just before enabling the interrupt.

This technique of counting the rising edges over a fixed period (like 1000ms used above) will give quite good accuracy at high rpm, but at lower speeds, it will become less and less accurate. If you fix the code like I suggested, the value of the variable ‘time’ will always be 1000 or close to it, because of the delay(1000). When you calculate rpm, you divide ‘revs’ by 1000 and multiply by 60000. That’s equivalent to multiplying ‘revs’ by 60. So a difference of only +/-1 in ‘revs’ gives a change of +/-60 in rpm. At 6000rpm, that’s only 1% difference, but at 1000rpm, it’s 6% difference, which I guess you will think is not accurate enough.

If would be better to time the period between rising edges.

Dahom_s:
for example if the result supposed to be 60rpm it shows 59rpm

How do you know that 59 is wrong?

Also, I agree with @PaulRB

…R