speed calculation using encoders

Hi everyone !
I'm quite new on arduino and I'm stuck on a project because of this lack of experience.
I have a rotary encoder (YUMO e6b2-cwz3e 1024P/R) and an Arduino Mega and I want to calculatea motor's rotation speed. What I have done so far is creating a programm which is supposed to get the number of turns read by the encoder each second and thus show the speed variation every second.
The problem is the programm doesn't seem to work when I launch it. However, when I tried the two parts of the programm separatly (the part where the encoder gets the number of turns and the part with the timer) they both worked.

Here is the programm I made :

#define encoder0PinA 2
#define encoder0PinB 4

unsigned long startTime=0;
unsigned long currentTime=0;
const unsigned long sampleTime=1000;
volatile unsigned int encoder0Pos = 0;
unsigned long turns1=0;
unsigned long turns2=0;
unsigned long v=0;

void setup() {
pinMode(encoder0PinA, INPUT);
digitalWrite(encoder0PinA, HIGH); // turn on pull-up resistor
pinMode(encoder0PinB, INPUT);
digitalWrite(encoder0PinB, HIGH); // turn on pull-up resistor

attachInterrupt(0, doEncoder, CHANGE); // encoder pin on interrupt 0 - pin 2
Serial.begin (9600);
startTime=millis();
}

/*
This function gets the number of turns read by the encoder
*/

void doEncoder() {
if (digitalRead(encoder0PinA) == digitalRead(encoder0PinB)) {
encoder0Pos++;
} else {
encoder0Pos--;
}
}

void loop() {
currentTime=millis();
turns1=encoder0Pos;
if (currentTime - startTime == sampleTime) // each second
{
turns2=encoder0Pos;
v=turns2-turns1;
startTime = currentTime;
Serial.println(turns1, DEC);
}

}

Could you tell me what's wrong ?
Thanks for any advise and please excuse my bad english

If you’re just checking speed you don’t need both encoder outputs. And it’s not clear why you’d ever count down. (Your software knows the direction.)

This can get you into trouble because the time has to be exactly equal:

if (currentTime - startTime == sampleTime) // each second

Try if (currentTime - startTime >= sampleTime) // each second

I already tried this, it still doesn't work :stuck_out_tongue:

Could you tell me what's wrong ?

turns1 and turns2 will have the same value, or very nearly the same, as they are read very close together in time. You want turns1 to be the previous value of turns2.

void loop() {
   currentTime=millis();
   //turns1=encoder0Pos;
   if (currentTime - startTime >= sampleTime) // each second
  {
    turns2=encoder0Pos;//new value of turns2
    v=turns2-turns1;
    startTime = currentTime;
    turns1 = turns2; //set turns1 to the last value of turns2
   //print whatever
  }
   
}

There are many things which could be improved with how you access the data from the ISR. See Nick Gammons interrupt tutorial https://gammon.com.au/interrupts

Thank you very much ! It seems to wwork with a low rotation speed, but it doesn't print any value when it turns fast.
Thanks for the tutorial, I'm going to read this.