lettura imprecisa di un encoder

ciao
sto facendo prove con un encoder da 360 impulsi giro, utilizzando alcuni degli sketch presenti nel play ground, ma alcuni non sono precisi perdendo degli impulsi come ho notato con il semplice programma di lettura degli impulsi con questo sketch

//valido per contare con interrupt

#define encoder0PinA 2
int count=0;
int A;

void setup()
{
  pinMode(encoder0PinA, INPUT); 
attachInterrupt(0,sensore1,CHANGE); //sensore induttivo collegato al pin 2
 
  Serial.begin(9600); // initialize serial communication:

}

void loop()
{
Serial.print(count);
Serial.print('\t');
Serial.println(A);

}

void sensore1()
{
    count++;
//   A=digitalRead(encoder0PinA);

}

perde degli impulsi, mentre se tolgo il digitalRead la lettura viene fatta correttamente, sbaglio se dico che la digitalRead non è rapida

grazie
stefano

Le variabili usate negli external interrupt devono essere dichiarate volatile.
volatile int count = 0;
volatile int A = 0;

Le variabili usate negli external interrupt devono essere dichiarate volatile.

oltre a quello suggerito da Cyberhs, Ti basta definire le variabili come INT ? Quanti giri fa' quel motore ?
E perche CHANGE nell'attachInterrupt ? non e' meglio metterlo come RISING, o FALLING o LOW ?
In CHANGE ti conta doppio

ciao
grazie per le risposte
ho dichiarato volatile le variabili come indicato ma senza risultato, continua a perdere valori, anche se ho notato che settando la velocità della seriale a 115200 i valori li leggo meglio, ne "perdo meno",
per la variabile CHANGE si conta il doppio, ma cosi raddoppio la precisione dello spostamento
il numero di giri sono circa 5 giri/sec, cioè 3600 impulsi (CHANGE) al secondo, 0.00027sec per impulso.

stefano

Quando viene invocata la tua routine di conteggio, perché effettui la lettura dello stato?
Forse vorresti leggere, invece, lo stato del canale B in modo da valutare la direzione?
Comunque, più che una lettura di stato, io effettuerei una inversione di stato e userei una variabile boolean:
volatile boolean A = 0;
...
void sensore1() {
count++;
A = !A;
}

ciao
l'encoder è un 2 canali A e B, per verificare la velocità di digitalRead nella routine dell'interrupt, in prospettiva, mi piacerebbe leggere il senso di rotazione.
Appena posso provo quanto suggerito.
Grazie

stefano

Non usare del tutto la seriale, quella di arduino è bufferizzata e l'invio o ricezione avviene dentro una ISR che per default disabilita gli interrupt, quindi quando stampi gli interrupt sono disabilitati, terminata la stampa vengono riabilitati.

Per ovviare, puoi creare un contatore che farai andare avanti e indietro tante volte di tot step, solo dopo che una decina di secondi stampi il valore del contatore e e poco prima di 10 secondi non tocchi per niente l'encoder.

Ciao.

ok grazie
in questa fase, mi serviva per fare dei controlli, nell'applicazione finale verrà commentata.

stefano

MauroTec:
Non usare del tutto la seriale, quella di arduino è bufferizzata e l'invio o ricezione avviene dentro una ISR

Durante questo tempo ogni fronte doppio sull'encoder viene perso

Controlla comunque che l'encoder butti fuori impulsi puliti, non si sà mai

Non sarebbe male se arduino avesse una libreria per il debug via seriale non bufferizzata, io la uso sempre non bufferizzata e posso fare debug facilmente anche quando ci sono parecchi eventi, in questo caso sarà la print che viene interrotta da gli altri eventi e raramente le ISR prendono molto tempo CPU per cui non noto nemmeno rallentamenti nella seriale. Ancora meglio sarebbe se la serial non bufferizzata non usasse del tutto le classi o comunque fare una routine stretta stretta e solo per fare debug, tipo stampa stringa e stampa long int.

Ciao.