The number of statements and statement types in your ISR routine will normally be the limiting factor in how fast you can keep up with encoder generated interrupts. Perhaps if you could post your sketch there might be some improvements that can be made.
One simple speed up one can take is to use direct port access when reading I/O pins inside the IRS Vs doing DigitalRead statements.
288 PPR is outrageously large to do in software via interrupts. If you can do it, your robot may not get anything else done. For that much resolution people usually go to a hardware encoder interface chip.
you may use this simplified code, it would help you up to certain speed...better than nothing!
//PIN's definition #define encoder0PinA 2 #define encoderHome 3 #define encoder0PinB 12 #define CountsPerRound 5200*2/5 //DEFINE HERE YOUR NUMBERS!!!
volatile int Rounds = 0;
volatile int encoder0Pos = 0;
volatile boolean PastA = 0;
volatile boolean PastB = 0;
void setup()
{
pinMode(encoder0PinA, INPUT);
//turn on pullup resistor
//digitalWrite(encoder0PinA, HIGH); //ONLY FOR SOME ENCODER(MAGNETIC)!!!!
pinMode(encoder0PinB, INPUT);
//turn on pullup resistor
//digitalWrite(encoder0PinB, HIGH); //ONLY FOR SOME ENCODER(MAGNETIC)!!!!
PastA = (boolean)digitalRead(encoder0PinA); //initial value of channel A;
PastB = (boolean)digitalRead(encoder0PinB); //and channel B
Serial.begin(19200);
// encoder A channel on interrupt 0 (arduino's pin 2)
attachInterrupt(0, doEncoderA, RISING);
// encoder B channel pin on interrupt 1 (arduino's pin 3)
attachInterrupt(1, doEncoderB, CHANGE);
}
void loop()
{
//just to print the rounds..you may exploit
//index channel of the encoder...but you'll need
//an other interrupt on the board
if(encoder0Pos > CountsPerRound)
{Rounds++;
//not just encoder0Pos = 0, in the meanwile....
encoder0Pos = -CountsPerRound + encoder0Pos;
Serial.println(Rounds,DEC);
}
else if (encoder0Pos < -CountsPerRound)
{Rounds--;
encoder0Pos = CountsPerRound +encoder0Pos;
Serial.println(Rounds,DEC);
}
//your staff....ENJOY!
}
//you may modify the algorithm easily to get quadrature..
//..but be sure this whouldn't let Arduino back!
void doEncoderA()
{
PastB ? encoder0Pos--: encoder0Pos++;
}
50KHz is feasible, folks do it for micromouse.
How fast does the motor rotate?
More than 170 revs/second?
Does it work better without the "Serial.println(Rounds,DEC);"?
That is slower than anything else in their, so you may be getting weird results just because of that.
With "Serial.begin(19200);"
it will take 0.5 milli seconds/character.
You could make the interrupt response faster by using ISR's directly rather than attachInterrupt.
But...in a few words...how interrupt input is fast?
My early test now work until 10khz...no more...is this a limit??
Or something wrong in my setting...
This "value" is not mentioned in specification, i need this.
You know, a low cost PLC (like S7-222 Siemens, about 150$) have a 2 counter up to 30khz, can i have same results with Arduino. 1 fast counter is enough for me...but fast...
My early test now work until 10khz...no more...is this a limit??
As was stated before the limit is defined by what you do inside the ISR. Try and cut down on the number of instructions and try direct port mapping to speed things up.