Dispongo di una schedina Heltec wifi kit 32 V3, e' la classica Esp32-S3 con piccolo display oled, si programma via usb con ide Arduino
Vorrei leggere un encoder incrementale, coi classici due segnali A-B sfasati di 90 gradi tra loro
L'idea e' di settare uno dei due pin sui quali fornisco i segnali A e B come sorgente di un interrupt, e quando viene rilevato l'evento dalla cpu, nella routine di gestione dell'interrupt verificare se l'altro pin sia alto o basso e di conseguenza aumentare o diminuire il contatore che tiene conto dei ‘colpi’ encoder letti
Il codice usato e' quello riportato sotto
L'interrupt viene settato sul fronte di discesa del segnale A (collegato al pin GPIO4 nel mio caso, il pin 15 di J2)
Rilevo un'anomalia sostanziale, la routine di gestione dell'interrupt viene fatta partire sia sul fronte di salita che su quello di discesa del segnale A, e questo lo vedo chiaramente perche' nella routine di gestione dell'interrupt alzo un pin uscita e lo abbasso prima di terminare la routine isr, e mi consente di ‘vedere’ con l'oscilloscopio l'attivita' del codice, e quindi sono sicuro che lesecuzione della routine isr avviene sia sul fronte di salita che su quello di discesa del segnale A
Sto usando il fronte di discesa perche' e' quello piu' ripido tra i due e quindi immagino possa funzionare meglio a livello elettrico del fronte di salita che e' leggermente meno rapido
Riguardando il codice, non riesco a trovare nessuna anomalia che porti a pensare il motivo per cui l'isr parta anche in corrispondenza del fronte di salita, dovrebbe partire solamente sul fronte di discesa del segnale A, ma cosi' non e' purtroppo
Qualcuno di voi ha usato questa scheda o simili ed ha rilevato lo stesso problema?
#define pin_A 4 // pin 15 - J2
#define pin_B 2 // pin 17 - J2
#define pin_CALIBRATE 6 // pin 13 - J2
#define pin_CLOCK_sync_interrupt 42
// Variabile per il conteggio
volatile unsigned int verso = 0;
volatile unsigned long conteggio ; // Esempio di valore iniziale per test
void IRAM_ATTR pin_A_isr() {
digitalWrite(pin_CLOCK_sync_interrupt, HIGH);
// Leggi lo stato del pin B
bool stato_b = digitalRead(pin_A);
if (stato_b == HIGH) {
// Rotazione in senso orario
// Aggiungi qui il codice per la rotazione in senso orario
verso=1;
conteggio++;
} else {
// Rotazione in senso antiorario
// Aggiungi qui il codice per la rotazione in senso antiorario
verso=0;
conteggio--;
}
delay_rob(50);
digitalWrite(pin_CLOCK_sync_interrupt, LOW);
}
void delay_rob(unsigned long attesa_microsecondi) {
unsigned long tempoInizio = micros(); // Registra l'istante iniziale
while (micros() - tempoInizio < attesa_microsecondi) {
// Questo loop vuoto permette agli interrupt di essere eseguiti
// mentre si attende che passino 'attesa_microsecondi'
}
}
void setup() {
Serial.begin(115200);
pinMode(pin_CLOCK_sync_interrupt, OUTPUT); digitalWrite(pin_CLOCK_sync_interrupt, LOW); // Assicurati che il pin sia basso all'avvio
pinMode(pin_A,INPUT_PULLUP);
pinMode(pin_B,INPUT_PULLUP);
pinMode(pin_CALIBRATE,INPUT);
attachInterrupt(digitalPinToInterrupt(pin_A), pin_A_isr, FALLING);
conteggio=8000000;
Serial.println("----------------------");
}
void loop() {
Serial.println(String(conteggio));
}