Medir frecuencia de una onda cuadrada maximo 120hz

Hola, como estan? Estoy necesitando un buen medidor de frecuencia para poder sacar RPM. La frecuencia maxima es de 120hz por lo que no preciso un codigo como nick gammon ya que no funciona bien porque tengo una pantalla conectada por medio del puerto serie 3 de un arduino mega. La parte hardware esta resuelta con un 4N35 con un pullup de 4.7kohm. El problema que tengo es que tengo saltos de RPM entre 200/300, en cuanto al delay necesito usar lo minimo posible. El codigo que estoy usando es el siguiente:

volatile byte rpmcount;
unsigned int rpm;
unsigned long timeold;

void rpm_fun()
{
//Each rotation, this interrupt function is run twice, so take that into consideration for
//calculating RPM
//Update count
rpmcount++;
}

void setup()
{
lcd.begin(16, 2); // intialise the LCD

//Interrupt 0 is digital pin 2, so that is where the IR detector is connected
//Triggers on FALLING (change from HIGH to LOW)
attachInterrupt(0, rpm_fun, FALLING);

//Turn on IR LED
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, HIGH);

rpmcount = 0;
rpm = 0;
timeold = 0;
}

void loop()
{
//Update RPM every second
delay(10);
//Don't process interrupts during calculations
detachInterrupt(0);
//Note that this would be 60*1000/(millis() - timeold)*rpmcount if the interrupt
//happened once per revolution instead of twice. Other multiples could be used
//for multi-bladed propellers or fans
rpm = 30*1000/(millis() - timeold)*rpmcount;
timeold = millis();
rpmcount = 0;

//Print out result to lcd
lcd.clear();
lcd.print( "RPM=" );
lcd.print(rpm);

//Restart the interrupt processing
attachInterrupt(0, rpm_fun, FALLING);
}

El código de Nick gammon funciona y lo hace perfectamente, asi que tu afirmación no es cierta y menos tinee que ver esto

La frecuencia maxima es de 120hz por lo que no preciso un codigo como nick gammon ya que no funciona bien porque tengo una pantalla conectada por medio del puerto serie 3 de un arduino mega.

Usas un MEGA pero donde usas un puerto serie, en el código no se lee nada de eso.

Cuando mides algo de baja frecuencia y lo haces con apenas una ventana de 10 mseg es lógico que falle.
Frecuencias bajas requieren ventanas grandes y una ventana digamos minima sería de 1000 mseg

Si quieres medir mas rápido entonces lee el periodo y no la frecuencia.

Hola surbyte gracias por contestar, el resto del codigo no viene al caso porque tengo problemas solamente con esto, uso el puerto serie 3.

Como hago para medir el periodo de una señal cuadrada usando interrupciones? Me podes ayudar?

Gracias.

Te escribí toda una respuesta explicando porque la rutina de nick Gammon funciona y luego me acordé que hace unos dias alguien usó esta librería y dije porque no? Será mas facil para esta persona usar una librería que tiene ejemplos y es mas intuitiva que un código largo que usa TIMERS.

Frequency Period Counter Library

Mirala sus ejemplos y verás que fácil es, acá esta la pagina del autor link

En inglés por supuesto pero verás que es intuitiva o usa Google Translate y se comprenderá.

Algo como esto no se puede dejar de usar, muy pero muy fácil!!

#include <FreqPeriodCounter.h>
  
const byte counterPin = 3;
const byte counterInterrupt = 1; // = d3
FreqPeriodCounter counter(counterPin, micros);
  
void setup(void)
{ attachInterrupt(counterInterrupt, counterISR, CHANGE);
}
  
void loop(void)
{ int period;
  if(counter.ready()) period = counter.period;
}
  
void counterISR()
{ counter.poll();
}