The fluctuations come from a big part of the math, the faster you want to measure the more inprecise the measurements will be
if you display per second and you have a measurement of R pulses in one second you multiply by 60, if there is one pulse more or less that means on the RPM scale you get + or - 60 !! that is quite a difference
Here a minimized version of your code that shows this effect
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2); //set the LCD address to 0x27 for a 16 chars and 2 line display
//TESTPIN
const int testpin = 3;
//MAIN INPUTS
const int DispSampleTime = 1000; //[millisec] //= 0.1sec
// variables:
volatile unsigned long rpm_count = 0;
unsigned long prev_rpm_count = 0;
unsigned long disp_timeold = 0UL;
unsigned long timetemp = 0L;
unsigned long Rpm = 0UL;
//SETUP RUN ONLY ONCE @ start
void setup()
{
//DEBUG
TCCR2B = TCCR2B & 0b11111000 | 0x07 ; // sets PWM to 30.517578125 Hz on pin 3 and 11 //timer 2
//testpin TESTESTESTEST----------------------<<<<<<<<<<<<>>>>>>>>>>>>>
pinMode(testpin, OUTPUT);
analogWrite(testpin, 1); //sample 30.51757 hz pulse 1/255 uptime.
lcd.init(); // initialize the lcd
lcd.backlight();
//set interrupt on pin 2 and call function rpm_interrupt when pin is falling
attachInterrupt(0, rpm_interrupt, FALLING);
}
void loop()
{
// DISPLAY RPM
timetemp = millis() - disp_timeold;
if( timetemp >= DispSampleTime)
{
disp_timeold += timetemp;
unsigned long t = rpm_count;
Rpm = t - prev_rpm_count; // rounds made since last display
prev_rpm_count = t; // remember previous counter
Rpm = Rpm * 60000UL / timetemp; // convert to rounds per minute
//disp stuff
lcd.clear();
lcd.print("Rpm: ");
lcd.print(Rpm);
}
}
//FUNCTIONS________________________________________
void rpm_interrupt()
{
rpm_count++;
}
another version is coming soon