Follow along with the video below to see how to install our site as a web app on your home screen.
							 
						
Nota: This feature currently requires accessing the site using the built-in Safari browser.
@cosmefulanito04 : he probado por polling y va perfecto, ni rebotes ni filtros ni falsos nada. Cuenta 100, alguna vez 101 y alguna 99 pero una de cada bastantes. Va mejor que el mejor filtrado de las interrupciones.
...
#define IDLE_STATE                            0
#define DPC_FIRST_CHECK_STATE                1
#define SET_HIGH_TRC_STATE                    2
#define SET_LOW_TRC_STATE                    3
#define WAIT_STATE                            4
 
#define DPC_PIN DO
#define TRC_PIN D1
#define MAX_WAIT_TIME                        50
void timer(){
 
    switch(stateVar)
    {
        case DPC_FIRST_CHECK_STATE:
            if(digitalRead(D0) > 0)
            {
                // First check pass after 100uS later
                stateVar = SET_HIGH_TRC_STATE;
            }
            else
            {
                // Bounce or noise
                stateVar = IDLE_STATE;
                FlexiTimer2::stop();
            }
            break;
        case SET_HIGH_TRC_STATE:
            if(digitalRead(DPC_PIN) > 0)
            {
                // Second check pass after 200uS later
                stateVar = SET_LOW_TRC_STATE;
            
                digitalWrite(TRC_PIN, HIGH);
                FlexiTimer2::stop();
                FlexiTimer2::set(waitTime, 1.0/10000, timer); // Set waitTime*100uS "tick"
                FlexiTimer2::start();
            }
            else
            {
                // Bounce or noise
                stateVar = IDLE_STATE;
                FlexiTimer2::stop();
            }
            break;
        case SET_LOW_TRC_STATE:
            // Clear TRC PIN  after waitTime*100uS later
            stateVar = WAIT_STATE;
        
            digitalWrite(TRC_PIN, LOW);
            FlexiTimer2::stop();
            FlexiTimer2::set(1, 1.0/10000, timer); // Set 100uS "tick"
            FlexiTimer2::start();
            break;
        case WAIT_STATE:
            if((waitTime > MAX_WAIT_TIME) || (digitalRead(DPC_PIN) < 1))
            {
                stateVar = IDLE_STATE;
                FlexiTimer2::stop();
            }
            break;
        default:
            // Wrong state!
            stateVar = IDLE_STATE;
            FlexiTimer2::stop();
    }
}
.../*
Esp32 detección de paso por cero
*/
#define entrada D0
#define salida D2
static unsigned long hora=0;
static unsigned int ISRs=0;
static int pCero = 0;    //Cuenta de pasos por cero
void IRAM_ATTR interr(){
disableInterrupt(entrada);
 if (micros()-hora>70){
    digitalWrite(salida,HIGH);
    pCero++;
    digitalWrite(salida,LOW);
    hora = micros();
  }
ISRs++;
enableInterrupt(entrada);
}
void setup() {
  // put your setup code here, to run once:
Serial.begin(115200);
Serial.println("Detección de paso por cero");
pinMode(entrada,INPUT_PULLUP);
pinMode(salida,OUTPUT);
attachInterrupt(D0,interr,RISING);    // En el ESP32 hagas lo que hagas solo va HIGH
}
void loop() {
  // put your main code here, to run repeatedly:
Serial.print("Pasos por cero :   ");
Serial.print(pCero);
pCero = 0;
Serial.print("     ISRs realizadas =");
Serial.println(ISRs);
ISRs=0;
delay(1000);
}Detección de paso por cero
Pasos por cero :   0     ISRs realizadas =0     <<<Aquí está sin enchufar a la red
Pasos por cero :   0     ISRs realizadas =0
Pasos por cero :   0     ISRs realizadas =0
Pasos por cero :   0     ISRs realizadas =0
Pasos por cero :   0     ISRs realizadas =0
Pasos por cero :   193     ISRs realizadas =239  <<<Se enchufa en este momento; chisporroteos
Pasos por cero :   202     ISRs realizadas =207  <<< Tiene que dar 200 porque lee los pulsos de subida y bajada
Pasos por cero :   200     ISRs realizadas =211
Pasos por cero :   200     ISRs realizadas =206
Pasos por cero :   200     ISRs realizadas =214
Pasos por cero :   202     ISRs realizadas =205
Pasos por cero :   200     ISRs realizadas =206
Pasos por cero :   202     ISRs realizadas =206
Pasos por cero :   200     ISRs realizadas =208
Pasos por cero :   200     ISRs realizadas =205
Pasos por cero :   200     ISRs realizadas =207
Pasos por cero :   202     ISRs realizadas =211
Pasos por cero :   200     ISRs realizadas =204
Pasos por cero :   201     ISRs realizadas =207
Pasos por cero :   201     ISRs realizadas =207
Pasos por cero :   200     ISRs realizadas =204
Pasos por cero :   200     ISRs realizadas =209
Pasos por cero :   202     ISRs realizadas =208
Pasos por cero :   200     ISRs realizadas =205
Pasos por cero :   200     ISRs realizadas =211Si, eso se vé en el código fuente que subí. En ninguna parte toca un registro de interrupciones ni las deshabilita...Sin el enable y disable interrupt saca como 3000 ISRs realizadas
Me acabé liando y las declaré static en lugar de volatile. Las he puesto volátiles pero es indiferente el resultado.Scooter, solo por asegurar: has probado a que las variables de la interrupción sean volátiles?
/*
Esp32 detección de paso por cero
*/
#define entrada D0
#define salida D2
volatile unsigned long hora=0;
volatile unsigned int ISRs=0;
volatile unsigned int pCero = 0;    //Cuenta de pasos por cero
void IRAM_ATTR interr(){
disableInterrupt(entrada);
 if (micros()-hora>70){
    digitalWrite(salida,HIGH);
    pCero++;
    digitalWrite(salida,LOW);
    hora = micros();
  }
ISRs++;
enableInterrupt(entrada);
}
void setup() {
  // put your setup code here, to run once:
Serial.begin(115200);
Serial.println("Detección de paso por cero");
pinMode(entrada,INPUT_PULLUP);
pinMode(salida,OUTPUT);
attachInterrupt(D0,interr,RISING);    // En el ESP32 hagas lo que hagas va CHANGE
}
void loop() {
  // put your main code here, to run repeatedly:
Serial.print("Pasos por cero :   ");
Serial.print(pCero);
pCero = 0;
Serial.print("     ISRs realizadas =");
Serial.println(ISRs);
ISRs=0;
delay(1000);
}Pasos por cero :   202     ISRs realizadas =205
Pasos por cero :   200     ISRs realizadas =214
Pasos por cero :   200     ISRs realizadas =205
Pasos por cero :   200     ISRs realizadas =201
Pasos por cero :   202     ISRs realizadas =220
Pasos por cero :   200     ISRs realizadas =200
Pasos por cero :   200     ISRs realizadas =206
Pasos por cero :   200     ISRs realizadas =206
Pasos por cero :   202     ISRs realizadas =211
Pasos por cero :   200     ISRs realizadas =201
Pasos por cero :   202     ISRs realizadas =209
Pasos por cero :   200     ISRs realizadas =205
Pasos por cero :   200     ISRs realizadas =201
Pasos por cero :   200     ISRs realizadas =209
Pasos por cero :   202     ISRs realizadas =209
Pasos por cero :   200     ISRs realizadas =206
Pasos por cero :   200     ISRs realizadas =203Depende que quieras hacer. Sirve para esconderlas y que sean globales solo en el archivo donde se declaran.Static en variables globales no tiene mucho sentido.
que yo he puesto:attachInterrupt(D0,interr,RISING); // En el ESP32 hagas lo que hagas va CHANGE
attachInterrupt (digitalPinToInterrupt(DO), interr, RISING);In function 'void handleInterrupt()':
warning: '++' expression of 'volatile'-qualified type is deprecated [-Wvolatile]El problema es que la operación ++ no es segura para variables volatile
porque la operación de incremento puede implicar múltiples pasos (lectura, incremento, y escritura),
 y el compilador no garantiza que la variable no cambie en medio de estos pasos.
En consecuencia, usar ++ directamente con variables volatile puede llevar a resultados inesperados o a comportamientos indeseados.  int temp = variableVolatil;  // Leer el valor y lo almacena en variable local temporal
  temp++;              // Incrementar el valor temporal
  variableVolatil= temp;Buenas:RISING, FALLING o CHANGEn es indiferente, hace un tren de pulsos mientras la señal sube y mientras la señal baja






 
  