80 Khz loop frequency for encoder reading

I am reading a quadrature encoder for a motor with the specs;

4500 RPM max. speed
256 Counts per revolution

Here I calculate the minimum loop frequency for reading the encoder properly.

(4500*256)/60 = 19200 counts per second

1/19200 = 0.05 ms.

0.05/4 = 0.0125 ms = 80 Khz

Division by 4 is due to 4 different possible combination due to quadrature encoder

Do you think that is correct, does it make sense ?

My actual question is; Is it possible to have a loop frequency of 80 Khz ? and how can I measure the frequency of my overall code ?

If the encoder has digital outputs, you can connect both lines to digital pins and use an interrupt handler to track the position. The RPM, if needed, can be computed from the ticks and difference of the sample time.

If not, make the signals digital, or specify what you want to achieve.

DrDiettrich:
If the encoder has digital outputs, you can connect both lines to digital pins and use an interrupt handler to track the position. The RPM, if needed, can be computed from the ticks and difference of the sample time.

If not, make the signals digital, or specify what you want to achieve.

This is exactly what I am doing. both A and B pins of encoder, which are digital pins, are connected to same input ISR.

However, I am having problems with calculating the RPM. I need a fixed sample time which can only be obtained through a timer ISR, I reckon.

Yet, would input ISR be fast enough to catch all the ticks ?

If you have another (index) sensor for one rotation, you can use it for another interrupt and measure the time between subsequent invocations. When you know the time for one rotation, you know the RPM as well.

Or wait in your existing ISR for N pulses, then take the time and compute the RPM.

Or add some code to loop(), that records the current position, waits some time, then takes the next position. See "blink without delay" for the timing. Then calculate the RPM from the actual time and position difference. Take into account that very many position ticks may arrive during that time, when the motor turns fast. You can reset the position counter whenever you took a new sample, to prevent an counter overrun.

A high speed motor and a high count encoder, are not a good match to simply determine rpm. You will not need full resolution of the quadrature. If you don't need direction you can simply read one pin either RISING or FALLING and only count one of four available states. If you need direction, then you can read one pin CHANGING and then determine direction by a read of both pins to see if they are in the same or different state.

I need a fixed sample time which can only be obtained through a timer ISR, I reckon.

As DrDiettrich suggests, you can create your own timer with the approach of "blink without delay". A one second timer looks like

if (millis() - lastRead >=1000)
  { last Read = millis();
     //add code block read the counts from an ISR and determine rpm
  }

I think you will get more accurate RPM values if you measure the time for a fixed number of pulses. Save the value of millis() or micros() when the first pulse happens and again when the Nth pulse happens. Figure out the elapsed time and divide by N-1 for the interval between pulses. To make the maths easy for the Arduino choose a value for N which is a power 2 plus 1 - for example 17 or 33 or 129.

...R

I don't agree with the increment/decrement by 1. In continuous measuring the end time is used for the next start time, with N (2^n) pulses in between.

Depending on the expected rotation speed, one of two algorithms should be used. For slow speed one waits for a fixed number of counts (down to 1), then the elapsed time is taken. For high speed the counts between a constant time delay is used instead. The number of counts, or the time delay, determines the range and resolution of the measured value.

DrDiettrich:
I don't agree with the increment/decrement by 1. In continuous measuring the end time is used for the next start time, with N (2^n) pulses in between.

I confess to being confused. I would need to try it out to be certain. I wonder if the difference between us is whether to count pulses, or intervals between pulses ?

...R

The number of pulses and pauses should be the same in every interval, shouldn't it?
When you take the time after N, 2N, 3N ... pulses, the time difference applies to N pulses.

Generally the number of events is 1 more than the number of intervals between them.

...R

If the first event is used to start the clock and the Nth event is used to stop it, then the elapsed time is (stoptime-starttime)/(N-1).

jremington:
If the first event is used to start the clock and the Nth event is used to stop it, then the elapsed time is (stoptime-starttime)/(N-1).

How do you count (number) the events?

When you reset the event counter to zero on some event and take the start time, then wait for N events and take the stop time, then N events have occured in between. When you reset the counter to 1, then wait it to reach N, you got N-1 events, of course, but that's only confusing.

The encoder ticks are used to increment event counts. No resetting is necessary.

More relevant to this discussion, the most practical way to implement encoder driven timing is as follows.

If the Nth encoder pulse causes start_time to be stored and the Mth pulse causes stop_time to be stored, the elapsed time is (stop_time-start_time)/(M-N).

@OP: If you use a 16 MHz Arduino and the encoder tick frequency is 80 kHz, you have time for at most 200 machine instructions for each encoder tick. That is certainly doable (probably only using an interrupt for each encoder channel) but the Arduino won't have much time to do anything else. There are number of dedicated ICs that can handle quadrature encoders and do the counting for you.

Do you really need that much resolution? For example, is the motor geared and can you put the encoder on the gearbox output shaft?