WIFI KIT 32 V3 - Interrupt on external pin falling edge not working as expected

I’m using a Heltec Wifi Kit 32 V3 card
I use the GPIO4 and GPIO2 pins to read the two signals of an A-B incremental encoder (two square waves 90 degrees out of phase)
The idea is to use the falling edge of the GPIO2 pin (pin_B in the code) to check whether the GPIO4 pin (pin_A in the code) is high or low, and depending on the status of the GPIO4 pin increase or decrease the counter variable ’ which contains the number of steps counted up to the current moment
Inside the interrupt management routine I use a third pin, GPIO42 (pin_CLOCK_sync_interrupt in the code) as an output to verify with the oscilloscope exactly the moment of input and output in the routine
I am verifying that the interrupt management routine starts both on the falling edge and on the rising edge of the signal applied on the external GPIO2 pin
I can’t identify the problem in the code, so I would like to ask if:
1 Is the code set correctly?
2 Can the GPIO2 and GPIO4 pins be used as an interrupt source from an external signal?
3 For correct operation, what characteristics must the signal applied to pins GPIO2 and GPIO4 have (transition speed I mean)?

#include <Wire.h>
#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_rising() {
digitalWrite(pin_CLOCK_sync_interrupt, HIGH);

// Leggi lo stato del pin A
bool stato_A = digitalRead(pin_A);

if (stato_A == 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);
pinMode(pin_B,INPUT);
pinMode(pin_CALIBRATE,INPUT);

attachInterrupt(digitalPinToInterrupt(pin_A), pin_A_isr_rising, FALLING);
conteggio=8000000;
Serial.println("----------------------");
Serial.println(String(conteggio));
}

void loop() {
verifica_pin_calibrate();
}

void verifica_pin_calibrate() {
int reading = digitalRead(pin_CALIBRATE);

if (digitalRead(pin_CALIBRATE) == LOW) {
Serial.println(“Pulsante CALIBRATE premuto…”);
delay_rob(20000);
}
}

A few things:

  • I can’t read Italian, so the comments and some of the variables don’t make much sense to me
  • The setup with an AB counter in place is more complex than the problem - is it possible to reduce the problem to a smaller setup?
  • What are we seeing on the oscilloscope? Which line is which?

The yellow trace is an input for the board and is connected to the encoder to signal A (the encoder has two lines, line A and line B which are square waves 90 degrees out of phase with each other) and enters on pin 15 of connector J2, corresponding to GPIO4

The blue trace is connected to a pin on the board that I use as an output directly from the code and that I use to ‘see’ how the code works, it is the one that appears in the code as pin_CLOCK_sync_interrupt and is connected to the board on pin 16 of J3 and corresponds to GPIO42

What I’m trying to do is execute a code routine ( pin_A_isr_rising() ) when the signal applied on pin pin_A has a falling edge
The signal applied on pin_A is the one visible as the yellow trace on the oscilloscope screen
So if you only see the code relating to pin_A (physically pin 15 on J2 of the board) it is configured as a pullup input in the setup, and then it is connected to an interrupt with the command

attachInterrupt(digitalPinToInterrupt(pin_A), pin_A_isr_rising, FALLING);

I would expect to see the pin_A_isr_rising() routine start only on the falling edge of the signal on pin_A
Instead, as can be seen from the oscilloscope signal (the blue trace below the yellow one) it is perfectly clear that the interrupt starts both on the rising edge and on the falling edge of the pin_A signal

The blue oscilloscope trace is an output pin that I use to ‘see’ how things are going and is connected to the pin_CLOCK_sync_interrupt signal, physically the GPIO42, pin 16 of J3 (on the PIN ASSIGNEMENT pdb of the Heltec Wifi Kit 32 V3 card)

The question is: why does the interrupt also start on the rising edge of the pin_A signal?