Arduino Tacho

EDIT: I see that PaulRB beat me to it with the answer to the imprecision.

I'm glad you are making progress, and can focus on the sensor and not your code. What rpm are you trying to measure? What mechanical constraints do you have? There may be better solutions with magnetic hall sensors or slotted transmisson (rather than reflective)ir sensors.

Running the sketch on the serial monitor the readings alternated between 11,970 and 12,000. (I did wonder why these readings were not steady and suspected a faulty Arduino board, however, I tried a different one and got the same results.)

I noticed this as well, but 30 out of 12000 or (.25%) variation did not seem like an issue given what you said about the the observed instability.

The root cause is due to the imprecision of micros() used in the determination of the period. The fundamental resolution of micros() is 4. There is also some other slight variation in measured period going on.

The other issue for precision is declaring rpm as an integer, and there is some truncation/rounding going on.

You can see both these effects, if you print out the period, and declare rpm as a float as well as an integer.

#include <TimerOne.h>

//counts time elapsed during 30 pulses and displays as RPM on an Serial.
//#include <LiquidCrystal.h>

//LiquidCrystal Serial(8, 9, 4, 5, 6, 7); //defining Serial pins

unsigned long startMicros;
const int maxCount = 30;
const int IRpin = 2;    //IR sensor on pin 2
int previousIRpinState;
int count = 0;

void setup()
{
   Serial.begin(115200); 
   pinMode(IRpin, INPUT);
   Serial.print("RPM = ");

   Timer1.initialize(5000); //pulse every 5 ms = 200rps = 12000rpm
   pinMode(10,OUTPUT);//jumper pin9 to pin2   

}
void loop()
{
  //Timer1 reference 100% is 1023 
  //1018/1023 = approx .5% duty cycle LOW. Similar to LOW for 2 degrees out of 360.
  //1018/1023 * .005 = approx 25 microseconds LOW signal
 
 Timer1.pwm(10,1018);
  
  unsigned long currentMicros = micros();

  int currentIRpinState = digitalRead(IRpin); //state of IR pin is whatever pin 2 is, (High or low)
  if (currentIRpinState == LOW and previousIRpinState == HIGH)  //a pulse has been received
  {
    count++;    //increment count
    if (count == 1) //if this is the first pulse received, record the time
    {
      startMicros = currentMicros;  //reset timer to start at first pulse
    }
    else if (count > maxCount)  //true when the required number of counts has been made
      
    {      
      unsigned long period = currentMicros - startMicros;  //calculate the length of the period
      int rpm = (60000000UL / period *  maxCount);  //if the period is time taken for 10 counts then, time taken for 1 count = period / maxcount 
      float rpm1 = (60000000.0/period *maxCount);
     
      Serial.print(period);
      Serial.print('\t');
      Serial.print(rpm);
      Serial.print('\t');
      Serial.println(rpm1,1);                 
      count = 0; // reset the count ready for the next first pulse
    }
  }
  previousIRpinState = currentIRpinState;
}