Condicional if que permita enviar pulso con la con input constante

Buenas noches amigos, soy nuevo con este interesante mundo del arduino, estoy desarrollando un proyecto para mi trabajo y necesito ayuda de ustedes ya que soy nuevo con este tema, el problema es el siguiente, en la D2 de mi arduino nano llegara un pulso constante y cuando el tenga este pulso quiero que este en high la salida D4 por un tiempo de 1.5seg y luego quede en Low, el problema lo tengo es que el pulso de entrada es un Switch y no un pulsador, es decir la señal estara fija en la entrada y por lo tanto la condicional me mantiene en high la salida D4, espero hayan podido entender mi problema. les dejo mi codigo, ya intente con delays y tambien intente hacer como un loop dentro de la condicional if pero no me sale, gracias de antemano

const int GPS=2;
const int BLOQUEO=4;
int variable;
void setup() {
pinMode (2,INPUT);
pinMode (4,OUTPUT);
}

void loop() {
variable = digitalRead (GPS);
if (variable==HIGH) {digitalWrite (BLOQUEO,HIGH);}
else {digitalWrite (BLOQUEO,LOW);} 
}

Algo así?

Tenés que trabajar con el flanco de la señal, o sea, reaccionar al cambio de la señal no al nivel de la misma.
Entonces, lees el pin y comparas su estado con el estado de la ultima lectura (que guardas en una variable.
Si son distintos es porque hay un cambio entonces te fijas si es el estado que te interesa y ejecutas lo que deseas.

Suponiendo que el switch está activo cuando cierra a masa (GND) y que has declarado una variable estadoanterior

byte estadoactual = digitalRead(tupin);
if (estadoactual != estadoanterior) {
  if (estadoactual == LOW) {
  // aca tus acciones
  }
}
estadoanterior = estadoactual;

Hola, si amigo es correcto, la señal en D2 queda fija y necesito que cuando detecte esa señal me de ese pulso de 1.5 seg

Que pasa después?

Esperar a que D2 sea LOW y cuando regrese a HIGH emitir otro pulso de 1.5seg en D4 ad Infinitum?

Bueno la idea es que cuando D2 este en high me de un pulso de 1.5 seg en D4 y cuando D2 este este en Low me de un pulso de 1.5 seg en D6, el tema está en que la duración de la señal que lee D2 tiene un tiempo indefinido, como puede durar 2 min hasta 2 horas, no se me hago entender

Entiendo su idea, me quedaría revisar un poco más de código con los manuales para lograr hacerlo pero entiendo la esencia de la idea, está interesante la desarrollaré más

Una gráfica de tiempos explica todo con más claridad…

Así como te lo planteé, el switch puede estar 20 años en LOW o en HIGH que tu código solo va a reaccionar cuando lo cambies y si es el estado que quieres.


Moderador
Por favor lee el punto 5 de las normas y de paso todas las normas y modifica el título " [Ayuda con un condicional por favor"
Ni "Ayuda" ni "por favor".
Son titulo que no dicen NADA o considerados inútiles
Debes colocar algo que exprese tu consulta, tu problema.
El foro solo AYUDA y solo pida a cambio que se respeten las normas cosa que no ha ocurrido pero tienes la oportunidad de modificarlo y seguimos adelante.

A ver si esto resuelve tu problema

No respondas sin antes corregir el título

Pues a mi el cuerpo me pide usar una interrupción en modo "CHANGE" en el pin 2 que las admite, algo así:

#define GPS 2
#define BLOQUEO_1 4
#define BLOQUEO_2 6

volatile boolean flag = false;

void RdSdI () {
  flag = true;
}

void setup() {
  pinMode (GPS, INPUT);
  pinMode (BLOQUEO_1, OUTPUT);
  pinMode (BLOQUEO_2, OUTPUT);
  attachInterrupt(digitalPinToInterrupt(GPS), RdSdI, CHANGE);
}

void loop() {

  if (flag == true) {
    if (digitalRead (GPS) == HIGH) {
      digitalWrite ( BLOQUEO_1, HIGH);
      delay (1500);
      digitalWrite ( BLOQUEO_1, LOW);
    }
    else {
      digitalWrite ( BLOQUEO_2, HIGH);
      delay (1500);
      digitalWrite ( BLOQUEO_2, LOW);
    }
    flag = false;
  }

}

He usado "delays" por simplificar, es solo un ejemplo posiblemente haya que cambiarlos por "millis" como hace @Surbyte

Me parece que CHANGE no es la opción correcta porque envías el pulso con cada flanco, y el PO solo necesita disparar la señal con uno de los flancos, RISING o FALLING.

Va en gustos pero, salvo que el tiempo de respuesta sea crítico, usar una interrupción para leer un interruptor me parece desproporcionado, además es más complicado filtrar los rebotes (algo que en el código de #3 no puse).

La simulación de lo que propuse

Si es cuestión de gustos.

¿ Y redefinir la interrupción recordando que nivel la activo anteriormente ?. Recuerda el #6, el PO también quiere otro pulso de salida en D6 al cambiar a LOW.

Y piénsalo bien si se producen rebotes " flag " siembre retorna "true", ya estamos eliminando los posibles rebotes.

Pensá a la velocidad del micro, no a la nuestra, vas a detectar rebotes igual porque loop() dura algunos useg y los rebotes varios mseg.

Y no leído el post #6, tenés razón, es CHANGE. Mala mía.

Aunque hayan rebotes no se tratan, la ISR no cambia el valor de "flag", (no contamos pulsos), lo hace siempre verdadero, es el loop cuando trata la interrupción y tras 1,5 seg. Tiempo mas que suficiente para eliminar cualquier rebote.

Parece que mi cerebro se niega a los delays, no los vi, a ninguno de los 2. :man_facepalming:t2:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.