Problem with rotary encoder

Hello dear friends,
I want to read pulse from a 5000 pulse per rev direct drive encoder with an ardoino mega 2560 , but when speed goes upper than 240 rpm , arduino can not count pulses.

I use this library Encoder Library, for Measuring Quadarature Encoded Position or Rotation Signals

And encoder A sore connected to interrupt 0 and B wire connected to interrupt 1

How can i count this ?

Arduino mega is 16Mhz but can not read more than 20Khz why ?

If you are interrupting on both pulse edges (rising AND falling) on both channels (A and B), you are getting 2 * 2 * 5000 = 20000 PPR * 4 RPS = 80000 PPS. Is that within the library's capability?

Where's the source to that library?

edgemoron:
If you are interrupting on both pulse edges (rising AND falling) on both channels (A and B), you are getting 2 * 2 * 5000 = 20000 PPR * 4 RPS = 80000 PPS. Is that within the library's capability?

You are right .
I don't know. Do you know a library support that ?

MarkT:
Where's the source to that library?

Here

If you are interrupting on both pulse edges (rising AND falling) on both channels (A and B), you are getting 2 * 2 * 5000 = 20000 PPR

What are you doing that requires that kind of resolution at 4 rps?

An encoder can be read with 1,2, or 4 counts per pulse. The interrupt overhead can be reduced accordingly.

cattledog:
What are you doing that requires that kind of resolution at 4 rps?

An encoder can be read with 1,2, or 4 counts per pulse. The interrupt overhead can be reduced accordingly.

I have a machine and use in it.
I found only this library usefully, others did not work good.
Is there any way to reduce 4x resolution to 1x in this library ?

Is there any way to reduce 4x resolution to 1x in this library ?

Not that I see. If you put one pin on an interrupt pin and the other on one which does not support an external interrupt the library will read the encoder at 2x resolution.

You may also wish to experiment with the addition of this line to speed things up.

#define ENCODER_OPTIMIZE_INTERRUPTS

This quote is from the encoder.h library example "Speed Test"

// This optional setting causes Encoder to use more optimized code,
// but the downside is a conflict if any other part of your sketch
// or any other library you're using requires attachInterrupt().
// It must be defined before Encoder.h is included.
//#define ENCODER_OPTIMIZE_INTERRUPTS

This is the simplest code for single 1x that I know of it uses pins 2 and 3

#define ClockPin 2 // Must be pin 2 
#define DataPin 3 // Must be pin 3
#define readA bitRead(PIND,2)//faster than digitalRead()  (((value) >> (bit)) & 0x01)
#define readB bitRead(PIND,3)//faster than digitalRead()  (((value) >> (bit)) & 0x01)
volatile long count = 0;
long lastCtr;
unsigned long SpareCycles;

void Encoder(bool A) {
  (readB == A)  ? count++ : count--;
}

void setup() {
  Serial.begin(115200); //115200
  pinMode(ClockPin, INPUT);
  pinMode(DataPin, INPUT);
  /* 1 Step */
  attachInterrupt(digitalPinToInterrupt(ClockPin), [] {Encoder( true);}, RISING);
  /**/

  /*  2 step count
  attachInterrupt(digitalPinToInterrupt(ClockPin), [] {Encoder( readB);}, CHANGE);
  */
  
  /* Full 4 Step Count
  attachInterrupt(digitalPinToInterrupt(ClockPin), [] {Encoder( readB);}, CHANGE);
  attachInterrupt(digitalPinToInterrupt(DataPin ), [] {Encoder( !readA);}, CHANGE);
  */
}

void loop() {
  long Counter;
  SpareCycles++;
  noInterrupts ();
  Counter = count;
  interrupts ();
  if ((lastCtr != Counter) & (SpareCycles > 10)) {
    Serial.println(Counter);
    SpareCycles = 0;
  }
  lastCtr = Counter;
}

Z