sensor magnetico de puerta y arduino ,problema con codigo.

Hola a todos. Quiero hacer una alarma que mande al pin '4' un 'HIGH' durante 5 segundos al detectar la apertura de un interruptor magnetico de puerta conectado entre pin '8' y +5v . Y una resistencia 'pull-down' entre pin 8 y GND. Estos interruptores funcionan en 'normal cerrado' , o sea cuando se abre una puerta se ' abre el circuito' . Seria lo mismo que cortar el cable , se tendria que activar la alarma.
Escribi este codigo pero no logro que el led se apague luego de 5 segundos, en que me estoy equivocando?
Para uds seguro es una pavada lo que pregunto pero estoy empezando con arduino y no encuentro nada en internet sobre lo que quiero hacer. Si me dan una mano les agradezco

int pulsador=0; 

void setup() {
 pinMode(4, OUTPUT);
 pinMode(8, INPUT);
}

void loop() {
 pulsador = digitalRead(8);
 
 if(pulsador==HIGH) {
   digitalWrite(4, LOW);
 }
 
 if(pulsador==LOW) {
   digitalWrite(4, HIGH);
 delay(5000);
 digitalWrite(4, LOW); }
}

Hola. Entiendo que lo que quiere es que una vez pasado los cinco segundos se apague el LED y que no se vuelva a encender aunque la señal siga a nivel bajo. Si es así, es que tal como lo tienes, una vez transcurrido los cinco segundos todo vuelve a empezar y se vuelve a detectar la señal a nivel bajo, inmediatamente se vuelve a encender el LED y vuelve a esperar otros cinco segundos… así hasta que la señal se vuelva a poner a nivel alto.

La solución es esperar a que se ponga a nivel alto justo después de apagar el LED pasado los cinco segundos. Para ello puede poner un while. No es la opción más deseable ya que te bloquea el resto del programa y no puedes hacer nada y es susceptible a los rebotes, si al volver a conectar el circuito no lo hace “limpiamente”, se vuelve a disparar la alarma.

El código con el while que no hace otra cosa que esperar a que vuelva a estar a nivel alto:

int pulsador=0;

void setup() {
  pinMode(4, OUTPUT);
  pinMode(8, INPUT);
}

void loop() {
  pulsador = digitalRead(8);

  if (pulsador == HIGH) {
    digitalWrite(4, LOW);
  }

  if (pulsador == LOW) {
    digitalWrite(4, HIGH);
    delay(5000);
    digitalWrite(4, LOW); 
    while (digitalRead(8) == LOW) { }; // <--- No continúa mientras la señal se mantenga a nivel bajo
  }
}

Gracias IgnoranteAbsoluto , funciona bien con el While (probado en el simulador de tinkercad). Al abrirse el circuito , se prende el led durante 5 segundos y luego se apaga...Hasta que se vuelva a cerrar el circuito y eventualmente vuelva a abrirse.
En donde está el led va a haber un transistor que va a manejar un relay. Y el relay va a activar un llamador GSM.
No se si es la mejor manera de hacer una alarma con arduino . Va a estar 24/7 prendida en un campo con una bateria de 12v 55ah .

Supongo que la entrada del interruptor del que activa el arduino la tendras opto acoplada…
Si no tendras muuuchos problemas.
Vamos que como el cable tenga unos metros no te funcionara, bueno unas veces si, otras no, otras te dejara bloqueado el micro…

Saludos

No amigo , va un cable desde +5v pasa por el interruptor NC hasta el pin d8 . O sea, le está mandando un 1 continuamente al pin 8 y cuando se abre el interruptor pasa a 0 : Aca esta el esquema:

primero , si quieres un contador que no bloquee el programa no uses delay , fabrica tu propio contador a mano con sus escalas ,cuantas menos librerias y trucos utilices ,mejor funcionara tu programa , incluso puedes leer el sensor de apretura mil veces antes de confirmar que esta abierto o cerrado y asi evitar rebotes o ruido electrico.
segundo , un cable de 50 metros conectado al arduino es una temeridad , seguramente tendras problemas graves de ruido , el arduino es un juguete y no esta preparado para eso,sin contar con que haya una tormenta electrica y se queme todo.te recomiendo poner un rele con bobina de 12 o 24 volt comandado por el sensor magnetico conectado al cable de 50 metros y pones el rele bien cerca del arduino y conectas sus contactos (el 8?) asi te queda bien aislado

LE puse un optoacoplador pc817 a la entrada por las dudas. El switch activa el opto y el opto le deja pasar 5v al pin 8 . No se si se valla a dañar el optoacoplador , ya que va a estar siempre activado , y cuando el switch se abra, el opto deja de mandarle un 1 a la entrada , y ahí se dispara la alarma (al recibir un 0 en pin 8).
Todo comentario sera bienvenido . Yo no se nada de arduino soy nuevo y esto aprendiendo de los que seben

fernan2:
No amigo , va un cable desde +5v pasa por el interruptor NC hasta el pin d8 . O sea, le está mandando un 1 continuamente al pin 8 y cuando se abre el interruptor pasa a 0 : Aca esta el esquema:

Buenas, no sé si será una tontería lo que te voy a decir, pero ¿no sería mas apropiado que realizaras el proceso de disparo de la alarma mediante una interrupción hardware de arduino? Es decir atas lo que tienes en el pin 8 a un pin con interrupción de arduino y cuando se produce un cambio en la señal (de High a Low) ejecuta un funcion que hace lo que quieras, como disparar la alarma o incrementar un contador para hacer un filtro software de ruido...en fin, es una idea que te doy. El único problema es que el ruido te dispare la interrupción, pero puedes filtrarlo por software también (ya veo que de electronica sabes).

Saludos,

No se si se valla a dañar el optoacoplador , ya que va a estar siempre activado , y cuando el switch se abra, el opto deja de mandarle un 1 a la entrada , y ahí se dispara la alarma (al recibir un 0 en pin 8).

Como puede dañarse un opto por estar activado? Para eso fue diseñado. Si le haces circular la corriente que indica el datasheet nada pasará dentro del MTBF.
Además si tu contacto es NC, tienes dos opciones, o haces conducir el led del opto o esperas a que se abra y entonces el led conduce.

Luego del otro lado (fototransitor de salida) lo mismo, usas emisor o colector común y decides que hacer y como hacerlo.

alfredomrh:
Buenas, no sé si será una tontería lo que te voy a decir, pero ¿no sería mas apropiado que realizaras el proceso de disparo de la alarma mediante una interrupción hardware de arduino? Es decir atas lo que tienes en el pin 8 a un pin con interrupción de arduino y cuando se produce un cambio en la señal (de High a Low) ejecuta un funcion que hace lo que quieras, como disparar la alarma o incrementar un contador para hacer un filtro software de ruido...en fin, es una idea que te doy. El único problema es que el ruido te dispare la interrupción, pero puedes filtrarlo por software también (ya veo que de electronica sabes).

Saludos,

Esactamente es lo que yo hubiera querido pero no se como hacerlo . No encontre nadie en la web que haya echo la conexion entre arduino y un switch magnetico de puerta como tu dices. ME encanta la plataforma arduino pero es bien dificil la programacion .

No es dificil para nada.
Lo es si a los saltos justamente no lees capítulos de un libro, por cierto ve a Documentación y mira las recomendaciones de libros que ahi hay.

Tienes un sensor NC y no quieres que este el opto pc817

Olvida el modelo que ponga, porque solo quiero ilustrar la idea


A la izquierda opto en configuración colector común a la derecha emisor común.
Como ves la salida tiene el colector directo a VCC

Cada vez que el diodo se ilumine el fototransitor conduce, si conduce tienes diferentes situaciones en uno u otro caso.
A la izquierda con diodo iluminado, tienes una salida que intenta llegar a VCC
A la derecha con diodo iluminado, tienes circulación de corriente por la R de coletor, pero un transitor saturado tiene a presentar una baja tensión Vcesat que esta entre 0.2 a 0.5 para estos casos.
O sea un 0
En el primer caso tienes uno 1 y en el segundo un 0, pero ambos con diodo iluminado a la entrada
Ahi estan los dos casos que te sugerí antes.

Tu tienes un sensor NC, o sea algo que hará que tu diodo del lado izq del opto este siempre conduciendo. Si eliges el esquema de la izquierda tu NC te dará un uno, si eliges el de la derecha tu NC cerrado te dará un 0.

Se entiende o ha sido un trabalenguas?

fernan2:
Esactamente es lo que yo hubiera querido pero no se como hacerlo . No encontre nadie en la web que haya echo la conexion entre arduino y un switch magnetico de puerta como tu dices. ME encanta la plataforma arduino pero es bien dificil la programacion .

Como dice surbyte no es dificil en absuluto, la plataforma arduino está pensada para que sea fácil de programar. Yo de la parte hardware no te puedo decir nada por que no entiendo, pero si como dices tu tienes una señal continuamente enviando un 1 es decir High y cuando salta la alarma la pones a 0 Low, ya lo tienes hecho. Solo tienes que conectar esa señal a un pin con interrupción de arduino, por ejemplo el numero 2 en un UNO, que corresponde a la interrupción 0 si mal no recuerdo, y programar la función que se dispara cuando tu señal cambie de 1 a 0.

Mirate este tutorial, como en todo hay que estudiar un poquito.

Saludos,

Tiene sentido el diagrama que hice usando un optoacoplador de esa manera ? Ahí estoy optoacoplando la entrada d8 con 5v y una pulldown. Cuando el switch se abre , se apaga el opto y el pin 8 recibe un 0 . El opto va a estar conectado a 12v y el arduino a la misma batería mediante un reg 9v .

Creo que la resistencia R1, de 10K, ha de ir a los 5V del Arduino en lugar de GND. Y el pin 3 del octoacoplador (el emisor) ha de ir a GND en lugar de 5V. Los tienes al revés de como han de ir. Mira en este sitio: Salidas y entradas aisladas con Arduino y optoacoplador

Tienes varios errores.
Te puse un esquema Fernan2.
La R va entre 5V y el colector del transitor (OPTO) , y del mismo colector al pin D8 del Arduino. Emisor a GND.

surbyte:
Tienes varios errores.
Te puse un esquema Fernan2.
La R va entre 5V y el colector del transitor (OPTO) , y del mismo colector al pin D8 del Arduino. Emisor a GND.

me estan haciendo doler cabeza !!!si lo hago como me dicen uds (salida inversora), me funciona esactamente al reves : dispara cuando se cierra el switch. En el diagrama me equivoque porque invertí las conexiones de los pines emisor y colector . Pero sino estaría bien como (no inversora) o me equivovo? Así me está funcionando en el simulador , y no explota nada!! : cuando se suelta el switch o 'cortas el cable', se dispara la alarma :

int pulsador=0;

void setup() {
pinMode(4, OUTPUT);
pinMode(8, INPUT);
}

void loop() {
pulsador = digitalRead(8 );

if (pulsador == HIGH) {
  digitalWrite(4, LOW);
}

if (pulsador == LOW) {
  digitalWrite(4, HIGH);
  delay(5000);
  digitalWrite(4, LOW); 
  while (digitalRead(8 ) == LOW) { }; 
}
}

Si inviertes el transistor del opto esta bien.
Y es no inversora o sea que esta bien, pero sino solo tienes que hacer esta cosa simple

pulsador = !digitalRead(8 );