Conteo de flancos

Buenas tardes.

Estoy tratando de tomar los flancos de unas señales para las siguientes variables:

Tengo la variable Cuenta para recibir los pulsos de un sensor.
Y la variable meta es una variable que va aumentando su valor por medio de 2 botones.

Si presiono el botón +10 (así se llama la variable), debe sumar +10 a la variable masdiez.
Si presiono el 2do botón debe sumar +50.

De tal manera que si presiono 3 veces +10 y 1 vez +50 debe mostrar +80.

Sin embargo al usar la opción IF (masdiez==HIGH) me toma 3 veces el valor, el tiempo que tarda en bajar el flanco.

busqué en internet la opción de attachInterrupt()

Pero no logro vincular la condición flanco a mi void loop

attachInterrupt(digitalPinToInterrupt(8), flanco, RISING);

En la conexión pin 8 es +10 y pin 9 +50.

Las variables las muestro en LCD que ya funciona.

Espero me puedan ayudar.
Muchas gracias.

¿Y el código?
Si no vemos tu código difícilmente podremos decirte que cosa modificar.


Por favor adjunta el código de acuerdo a la normas, capturas de pantalla no sirven, cómo hacemos para modificarlo en una imagen?
Encima está incompleto.

Me funcionó esto:

Buenas tardes,
A pesar de que en el código las condiciones se están cumpliendo; observo que el estado del pin tarda más de 1 segundo en irse a 0.
Por lo que realicé esta tabla:

void loop() {
  // put your main code here, to run repeatedly:
    
    EstadoActual = digitalRead(8);
    delay(10);
    if (EstadoActual != EstadoAnterior)  {
      meta=meta+10;
      EstadoAnterior = EstadoActual;
      }

Serial.print("meta: ");
Serial.println(meta);
delay(300);
Serial.print("EstadoActual: ");
Serial.println(EstadoActual);
delay(300);
Serial.print("EstadoAnterior: ");
Serial.println(EstadoAnterior);
delay(300);
Serial.println();

¿Por qué tarda tanto en cambiar el estado si el instante en el que presiono el pushbutton es muy corto?

Seguís subiendo mal el código e incompleto.

Tal vez sea por los 900 mseg de delay que pusiste en tu código.

Ve a Documentación y lee el tutorial de @victorjam

Observa que no debes usar delay() porque cada vez que lo haces agregas un tiempo en que el microcontrolador se cruza de brazos y ve como todo pasa delante de sus ojos.

Moderador:
Deja de poner capturas de códigos. Postea siempre aunque sea una sola línea usando etiquetas para códigos y/o errores.

Muchas gracias.
Con este post logré leer correctamente el estado de los pines.
Solamente, cuando se deja de presionar el botón, el estado del Led del pin 13 tarda en apagarse.

[escribe o pega el código aquí]
switch ( estado8 ) {
    case SUELTO8:   digitalWrite(13, HIGH);
    break; 
    case APRETANDOLO8: 
    meta=meta+10;
    break; // Mandamos un mensaje.
    case APRETADO8: digitalWrite(13, LOW);
    break; // Encendemos el led.
    case SOLTANDOLO8: //no hacemos nada
    break; // Mandamos un mensaje.
    default: break;
  }

Traté de eliminar la mayor cantidad de delays para no afectar, pero creo que esto es más o del controlador o de la placa Arduino.

Si este es el caso, tendría un gran problema por que estoy tratando de controlar un proceso con el Arduino, y tendría que leer el estado de un sensor y enviar la activación de una válvula en cuestión de milisegundos.

Espero que me puedan ayudar.
Saludos.

Pone todo el código que usaste para las pruebas porque "a ciegas" es difícil ayudarte.

Para responder en milisegundos no debes perder el tiempo en absolutamente nada, no puede haber un solo delay().
Si tienes dudas de donde estas parado, comienza haciendo caso a lo que te observamos.

Gracias. También observo que cuando mando una salida en cualquier pin, le luz del LED es muy tenue. Mientras que conectándolo directo sobre +5V, el LED enciende con mayor intensidad usando la misma resistencia que con la salida del Arduino.
Creo que algo no anda bien con el microcontrolador o la placa, por lo que haré pruebas nuevamente con otra placa.

Haré la prueba en una placa de Arduino Mega.

Voy a revisar si con esto, se elimina el problema de los tiempos de respuesta de los botones.
Me haría falta también en la secuencia del programa añadir una o varias líneas que me permitan detectar flancos en algún pin digital para monitorear el cambio de estado del sensor.

Hola..
Encontré una forma de leer botones a través de la librería EBZ de Mohammad Mahdi Nazari.
Descargué la librería y no tengo errores.

Solamente me falta asignar la variable al pin.
No encuentro como.

Comparto el código:

#include <LiquidCrystal.h>
#include <EZButton.h>   // librería EZB

#define BTN_PARO_22 22  //PIN
#define PARO 0

void ReadButtons(bool *states, int num) {
  //Read all button states however you want
  /*
	states[BTN_1] = !digitalRead(2);
	states[BTN_2] = touchRead(3) <= 50;
	states[BTN_3] = touchRead(4) <= 50;
	states[BTN_4] = touchRead(5) <= 50;
  */
  states[PARO] = digitalRead(BTN_PARO_22); 
}

EZButton _ezb(1, ReadButtons, 500, 200, 15);
//HoldThreshold: 500ms
//HoldInterval: 200ms
//DebounceTime: 15ms

LiquidCrystal lcd (7, 6, 5, 4, 3, 2); // cambié pin 12 por 7 & pin 11 por 6


//Variables para Dobladora
int meta=0;
int cuenta=0;

//Lectura pulsado de Botón pin 8
//Paro

const int led = 13; // Led
const int pin40 = 40; // Válvula SMC
const int pin13 = 13; // Led de prueba


//se asignan los pines a las variables
//BANDERAS DEL PROCESO

int salida40;
int arranque;
int paro;


void setup() {
  
  Serial.begin(9600);
  lcd.begin(16,2);  

pinMode(BTN_PARO_22, INPUT_PULLUP);  //Botón 22 Paro
pinMode(pin40, OUTPUT); // Salida de Solenoide       
pinMode(pin13, OUTPUT); // LED


    }  //Cierre de Void

void loop() {

_ezb.Loop();

//Impresión en LCD
lcd.setCursor(0,0); 
   lcd.print("META:");
   // se imprime la variable
   lcd.setCursor(9,0); 
   lcd.print(meta);  
   
   lcd.setCursor(0,1);
    lcd.print("Cuenta:");
    //lcd.print(porcentaje);  se imprime la variable
     // se imprime la variable
    lcd.setCursor(9,1); 
    lcd.print(cuenta);  
  
 }  //Cierre de Loop

void Btn1Pressed () {
  digitalWrite(LED_BUILTIN, HIGH);
}

Tal vez si miras los ejemplos de la librería...

Con la librería de Mahdi no logré asignar las variables de los botones a algún pin.
Y con el código para debouncing en la página de Arduino, tarda mucho en cambiar de estado el pin:

#include <LiquidCrystal.h> 
LiquidCrystal lcd (7, 6, 5, 4, 3, 2); // cambié pin 12 por 7 & pin 11 por 6 
//Variables para Dobladora 
int meta=0; 
int cuenta=0;
const int buttonPin = 9; //paro
const int ledPin = 13; //LED Arduino
const int pin40 = 40; // Válvula SMC
const int pin13 = 13; // Led de prueba

unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long debounceDelay = 50;    // the debounce time; increase if the output flickers

int ledState = HIGH;        // the current state of the output pin
int buttonState = LOW;             // the current reading from the input pin
int lastButtonState = LOW;  // the previous reading from the input pin

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600); 
  lcd.begin(16,2);    

pinMode(buttonPin, INPUT);  //Botón 22 Paro
pinMode(ledPin, OUTPUT); // LED
pinMode(pin40, OUTPUT); // Salida de Solenoide    

}

void loop() {
  // put your main code here, to run repeatedly:

  int reading = digitalRead(buttonPin);

if (reading != lastButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
  }

if ((millis() - lastDebounceTime) > debounceDelay) {
     if (reading != buttonState) {
      buttonState = reading;

      if (buttonState == HIGH) {
        ledState = !ledState;
        meta=meta+10;  //variable dobladora        
        }
    }

    Serial.print("META: ");
        Serial.println(meta);
        Serial.print("Button pin:   ");
        Serial.print(buttonPin);
        Serial.print("  Button state:   ");
        Serial.print(buttonState);
        Serial.print("   Last button state:   ");
        Serial.print(lastButtonState);
        Serial.print("   reading:    ");
        Serial.print(reading);

  }
 
 // set the LED:
digitalWrite(ledPin, ledState);
lastButtonState = reading;


lcd.setCursor(0,0);  
   lcd.print("META:"); 
   // se imprime la variable 
   lcd.setCursor(12,0);  
   lcd.print(meta);   
    
   lcd.setCursor(0,1); 
    lcd.print("Cuenta:"); 
    //lcd.print(porcentaje);  se imprime la variable 
     // se imprime la variable 
    lcd.setCursor(12,1);  
    lcd.print(cuenta);

} // cierre de void Loop

Creo que es un tema de conexión
![image|635x500](upload://5qUb5JPLgda5Uxdjgqztj4eAWrh.png)

Del ejemplo MultipleButtonAll

#include <ezButton.h>

ezButton button1(6);  // create ezButton object that attach to pin 6;
ezButton button2(7);  // create ezButton object that attach to pin 7;
ezButton button3(8);  // create ezButton object that attach to pin 8;

Entonces si los números de los pines los asignas a variables/constantes, por ejemplo

#include <ezButton.h>

const byte BTN1 = 6;
const byte BTN2 = 7;
const byte BTN3 = 8;

ezButton button1(BTN1);  // create ezButton object that attach to pin 6;
ezButton button2(BTN2);  // create ezButton object that attach to pin 7;
ezButton button3(BTN3);  // create ezButton object that attach to pin 8;

Si acaso no es éste el problema, disculpa, no te estaría entendiendo.

Explico el proceso.
Tengo 3 botones.
pin22 = +10
pin24 = +50
pin26 = +100
Cada que presiono estos botones, va sumando una variable de nombre meta.

Puedo resetear la variable, y presionar el botón de arranque; solamente si el valor es diferente de 0.

Quiero que el controlador vaya por paso o etapas, así que elegí la opción de Enum

#include <LiquidCrystal.h> 
LiquidCrystal lcd (7, 6, 5, 4, 3, 2); // cambié pin 12 por 7 & pin 11 por 6 

enum {Stg1, Stg2, Stg3, Stg4};
unsigned char Estado=0;
//Estados de la máquina = 4
//Stg1 Menú para ingresar META.
//Stg2 Arranque
//Stg3 Paro solicitado por usuario, pero aún queda número en META.
//Stg4 Finalizado. No queda número en cuenta y regresamos a Stg1.

Veo que si entra al primer paso y realiza lo que en él está. Pero al cambiar al siguiente paso el controlador no realiza la secuencia. (Quizá nunca entra al paso 2 o stage 2).

Para intercambiar entre estados uso una variable flag que inicializo en 0.
Y conforme voy entrando a cada paso, voy sumando flag + 1 para avanzar al siguiente stage.

El siguiente código lo hace a a perfección, pero no logro brincar a los stages subsecuentes.

void loop() {
  // put your main code here, to run repeatedly:
Serial.print("Etapa del proceso: "); 
Serial.println(Estado); 
Serial.print("Bandera "); 
Serial.println(flag); 
Serial.print("Arranque "); 
Serial.println(reading22);
//delay(300);

if (flag==0){
Estado=Stg1;
}
if (flag==1){
Estado=Stg2;
}
if (flag==2){
Estado=Stg3;
}
  switch (Estado) {

    case Stg1:     //flag0
      //+10 PIN 32
      int reading32 = digitalRead(diez);
      if (reading32 != lastButtonState32) {
      // reset the debouncing timer
      lastDebounceTime32 = millis();
      }
      if ((millis() - lastDebounceTime32) > debounceDelay32) {
      if (reading32 != buttonState32) {
      buttonState32 = reading32;
      if (buttonState32 == HIGH) {
        ledState32 = !ledState32;
        meta=meta+10;  //variable dobladora        
        }
    }
}

    //+50 PIN 34
    int reading34 = digitalRead(cincuenta);
if (reading34 != lastButtonState34) {
    // reset the debouncing timer
    lastDebounceTime34 = millis();
  }
if ((millis() - lastDebounceTime34) > debounceDelay34) {
     if (reading34 != buttonState34) {
      buttonState34 = reading34;
      if (buttonState34 == HIGH) {
        ledState34 = !ledState34;
        meta=meta+50;  //variable dobladora        
        }
    }
}

 //+100 PIN 36
  int reading36 = digitalRead(cien);
if (reading36 != lastButtonState36) {
    // reset the debouncing timer
    lastDebounceTime36 = millis();
  }
if ((millis() - lastDebounceTime36) > debounceDelay36) {
     if (reading36 != buttonState36) {
      buttonState36 = reading36;
      if (buttonState36 == HIGH) {
        ledState36 = !ledState36;
        meta=meta+100;  //variable dobladora    
        }
    }
} 

//Arranque PIN 22


  int reading22= digitalRead(arranque);
if (reading22 != lastButtonState22) {
    // reset the debouncing timer
    lastDebounceTime22 = millis();
  }
if ((millis() - lastDebounceTime22) > debounceDelay22) {
     if (reading22 != buttonState22) {
      buttonState22 = reading22;
      if (buttonState22 == HIGH) {
          if (meta!=0) {
        ledState22 = !ledState22;
         lcd.clear(); 
         lcd.setCursor(3,0);  
         lcd.print("ARRANQUE"); 
         delay(1000); 
         lcd.clear();
        flag = 1; //
        Estado = Stg2; // Avance al siguiente estado   
          }
        }
    }
} 

//RESET PIN 26
  int reading26= digitalRead(reset);
if (reading26 != lastButtonState26) {
    // reset the debouncing timer
    lastDebounceTime26 = millis();
  }
if ((millis() - lastDebounceTime26) > debounceDelay26) {
     if (reading26 != buttonState26) {
      buttonState26 = reading26;
      if (buttonState26 == HIGH) {
        ledState26 = !ledState26;
        lcd.clear(); 
        meta=0;  //variable dobladora    
        }
    }
} 

  // set the LED:
//digitalWrite(ledPin, ledState32);

  lastButtonState22 = reading22;
  lastButtonState24 = reading24;
  lastButtonState26 = reading26;
  
  lastButtonState32 = reading32;
  lastButtonState34 = reading34;
  lastButtonState36 = reading36;
    
    lcd.setCursor(0,0);  
    lcd.print("META:"); 
     // se imprime la variable 
    lcd.setCursor(12,0);  
    lcd.print(meta);   
    
    lcd.setCursor(0,1); 
    lcd.print("Cuenta:"); 
    //lcd.print(porcentaje);  se imprime la variable 
     // se imprime la variable 
    lcd.setCursor(12,1);  
    lcd.print(cuenta);  
        
           
break; //termina Stg1

No sé si no estoy tomando en cuenta algo.

Espero que me puedan ayudar.

Mil gracias.

En lo personal no le encuentro sentido a usar 2 variables para hacer el mismo trabajo.
El valor de Estado depende directamente del valor de flag, usa flag en el switch() y listo.

Todo lo que pusiste en el case (excepto la sentencia break;) sería conveniente ponerlo en una función aparte para mayor claridad.
Por cierto, mínimamente deberías poner todo entre llaves.

La usé con 1 sóla variable, pero sólo realiza el primer paso. en este caso Stg1 (con valor 0).

enum {Stg1, Stg2, Stg3, Stg4};
unsigned char Estado;

Cuando presiono el botón de arranque, logra pasar al siguiente valor, el monitor de serial me indica que el valor de Estado cambia del valor 0 al 1.
Solamente que al activar la salida en esa etapa, nunca lo hace.
Y ahí se estanca el Bucle.
Ya no puedo sumar +10, +50 o +100, resetear o nada.
Necesito saber cómo el controlador puede respetar cada etapa.