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 =211
Si, 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 =203
Depende 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