gpb01:
... NON hai gli interrupt disabilitati e quindi altri interrupt possono funzionare ed essere asserviti.
Quella in effetti era la preoccupazione ... cerco di spiegarmi meglio con degli esempi (solo concettuali e buttati li al volo, quindi non iniziate a tirare torte se fanno schifo ... o almeno tirate torte buone :P) ... potrei infilare tutto in una ISR, piu o meno cosi ...
int inpe1 = 2; // ingressi pin encoder
int inpe2 = 3;
int valpe1 = 0; //valore pin encoder
int valpe2 = 0;
int valore = 0; //variabili per conversione
int valprec = 0;
int lettura = 0;
long totale = 0; //variabile da incrementare/decrementare
void setup() {
pinMode(inpe1, INPUT_PULLUP);
pinMode(inpe2, INPUT_PULLUP);
attachInterrupt(0, encoder, CHANGE);
attachInterrupt(1, encoder, CHANGE);
}
void loop(){
.... programma ....
}
void encoder(){
valpe1 = digitalRead(inpe1); //bit piu significativo
valpe2 = digitalRead(inpe2); //bit meno significativo
valore = (valpe1 << 1) |valpe2; //unisci i due bit letti
lettura = (valprec << 2) | valore; //alla lettura precedente
if(lettura == 0b1101 || lettura == 0b0100 || lettura == 0b0010 || lettura == 0b1011) totale ++;
if(lettura == 0b1110 || lettura == 0b0111 || lettura == 0b0001 || lettura == 0b1000) totale --;
valprec = valore; //salva per il prossimo ciclo
}
Cosi avrei tutto nella ISR (sempre che il mio ragionamento sul come leggere gli stati funzioni, cosa che non ho provato perche' non ho il materiale per farlo al momento), non rischierei che un'altro interrupt mi sballi il controllo interrompendolo a meta', pero' mi sembra che nella ISR ci sia troppa roba, rispetto a come dovrebbero essere gestite al meglio le ISR ... e se arriva un secondo interrupt mentre effettuo i controlli lo perdo ...
Oppure fare in questo modo e gestire i controlli con un'if fuori dalla ISR
int inpe1 = 2; // ingressi pin encoder
int inpe2 = 3;
int valpe1 = 0; //valore pin encoder
int valpe2 = 0;
int valore = 0; //variabili per conversione
int valprec = 0;
int lettura = 0;
long totale = 0; //variabile da incrementare/decrementare
void setup() {
pinMode(inpe1, INPUT_PULLUP);
pinMode(inpe2, INPUT_PULLUP);
attachInterrupt(0, encoder, CHANGE);
attachInterrupt(1, encoder, CHANGE);
}
void loop(){
.... programma ....
if (encodermosso == true) {
valpe1 = digitalRead(inpe1); //bit piu significativo
valpe2 = digitalRead(inpe2); //bit meno significativo
valore = (valpe1 << 1) |valpe2; //unisci i due bit letti
lettura = (valprec << 2) | valore; //alla lettura precedente
if(lettura == 0b1101 || lettura == 0b0100 || lettura == 0b0010 || lettura == 0b1011) totale ++;
if(lettura == 0b1110 || lettura == 0b0111 || lettura == 0b0001 || lettura == 0b1000) totale --;
valprec = valore; //salva per il prossimo ciclo
encodermosso = false;
}
}
void encoder(){
encodermosso = true;
}
pero' cosi prima di tutto se il loop e' pieno di roba, l'if potrebbe essere eseguito anche parecchio in ritardo dopo la ISR, e secondo se mentre esegue i controlli nell'if (o prima di arrivarci) arriva un secondo interrupt, cosa succede, mi incasina tutto o perdo il primo interrupt ?
Quale dei due sistemi andrebbe meglio ? (meglio, relativamente parlando ... lo so che non esiste un sistema "perfetto", salvo forse usare un chip esterno o delle porte logiche per convertire i segnali dell'encoder in due diversi segnali, un DIR ed un PULSE in modo hardware come si faceva in passato, pero' cosi si complica di piu la parte hardware)
EDIT: o magari usare una seconda piccola MCU che faccia SOLO quello che in passato facevamo hardware, convertire la quadratura in segnali PULSE e DIR ...