Incremental encoder

Hi, everyone, my query is mainly that they help me with my encoder program, that I can not make me read 1 pulse / rev. but it reads me like 800 pulses. I want it more than anything to measure engine RPM.
I show you the code that I am occupying

volatile unsigned int temp, contador = 0; //Esta variable aumentará o disminuirá dependiendo de la rotación del encoder.
    
void setup() {
  Serial.begin (9600);

  pinMode(2, INPUT_PULLUP); // pin 2 como entrada, se activa el pullup interno  
  
  pinMode(3, INPUT_PULLUP); // pin 3 como entrada, se activa el pullup interno 
  
//Configuracion de interruptor
  //Un pulso ascendente del encoder activa ai0(). AttachInterrupt 0 esta en el pin digital 2 de nuestro Arduino.
  attachInterrupt(0, ai0, RISING);
   
  //Un pulso descendente del encoder activa ai1(). AttachInterrupt 1 esta en el pin digital 3 de nuestro Arduino.
  attachInterrupt(1, ai1, RISING);
  }
   
  void loop() {
  // Enviar el valor del contador
  if( contador != temp ){
  Serial.println (contador);
  temp = contador;
  }
  }
  
  void ai0() {
  // ai0 esta activado si el pin digital 2 va desde LOW a HIGH
  // Comprueba el pin 3 para determinar la direccion
  if(digitalRead(3)==LOW) {
  contador++;
  }else{
  contador--;
  }
  }
   
  void ai1() {
// ai0 esta activado si el pin digital 3 va desde LOW a HIGH
  // Comprueba el pin 2 para determinar la direccion
  if(digitalRead(2)==LOW) {
  contador--;
  }else{
  contador++;
  }
  }

Any help is welcome, thanks :slight_smile:

I see two problems with this.

  void loop() {
  // Enviar el valor del contador
  if( contador != temp ){
  Serial.println (contador);
  temp = contador;
  }
  }

First, attempting to print something for every pulse is probably unrealistic unless the encoder is rotating VERRRRRYYY slowly. Printing is itself a slow process.

Second you need to pause interrupts while reading a multi-byte value from an ISR to prevent the value changing while you are reading it - something like this

noInterrupts()
   latestContador = contador;
interrupts()

If you want to be able to check, in loop(), if an interrupt has happened get the ISR to set a boolean variable to true - for example
newPulse = true; and then in loop() you can have

if (newPulse == true) {
  // do stuff
  newPulse = false;
}

...R