@astro
perché solo 833Hz per canale? Comunque con tutti quegli interrupt, oltre al programma, ho un tempo ciclo di circa 150us, valore che acquisisco con la funzione micros() ad ogni inizio del loop.
#define encInterrA 0
#define encInterrB 1
#define encA 2
#define encB 3
volatile unsigned long contEnc = 0; //Valore del conteggio dell'encoder
void encoderA() {
unsigned char i = PINE; //Leggo il valore di PINE
unsigned char a = i & (1 << PE4); //Maschero gli altri bit per isolare quello corrisp. alla fase A
unsigned char b = i & (1 << PE5); //Maschero gli altri bit per isolare quello corrisp. alla fase B
if (a == (1 << PE4)) { //Se A è alto
if (b == 0) contEnc++; //e B è basso incrementa
else contEnc--; //altrimenti decrementa
}
else { //Se A è basso
if (b == (1 << PE5)) contEnc++; //e B è alto incrementa
else contEnc--; //Altrimenti decrementa
}
};
void encoderB() {
unsigned char i = PINE; //Leggo il valore di PINE
unsigned char a = i & (1 << PE4); //Maschero gli altri bit per isolare quello corrisp. alla fase A
unsigned char b = i & (1 << PE5); //Maschero gli altri bit per isolare quello corrisp. alla fase B
if (b == (1 << PE5)) { //Se B è alto
if (a == (1 << PE4)) contEnc++; //e A è alto incrementa
else contEnc--; //altrimenti decrementa
}
else { //Se B è basso
if (a == 0) contEnc++; //e A è basso incrementa
else contEnc--; //Altrimenti decrementa
}
};
void setup() {
digitalWrite(encA, HIGH); //Attivo i pullup degli ingressi dell'encoder
digitalWrite(encB, HIGH); //Attivo i pullup degli ingressi dell'encoder
attachInterrupt(encInterrA, encoderA, CHANGE); //Attivo il gestore di interrupt per gli ingressi dell'encoder
attachInterrupt(encInterrB, encoderB, CHANGE); //Attivo il gestore di interrupt per gli ingressi dell'encoder
}
Considera che ho utilizzato un encoder con uscite npn, quindi ho attivato le resistenze di pullup interne. Queste, però, a 20KHz sono troppo grandi e quindi ne ho messe altre due esterne di valore più piccolo.
P.S. Questo codice è stato scritto per l'Arduino Mega 2560, quindi per il processore ATMega2560. Se usi l'Arduino Uno sicuramente non ti va bene perché i pin di interrupt non saranno sulla porta E. A tal riguardo ti consiglio di controllare il pin mapping dei relativi processori: