¿Sabes que tu Arduino puede quemarse utilizando pulsadores?
Un pulsador no es más que un interruptor como el de tu casa. Cuando no está pulsado el circuito está abierto (vaya, que está suelto y la corriente no pasa) y al pulsarlo el circuito se cierra. Vamos con los ingredientes del día.
Utilizando un interruptor en Arduino
Lo primero que vas a hacer es replicar el circuito del led. El cable sale del pin 13 hasta la pata más larga del led y la pata corta del led va a GND pero antes de llegar al led (o después) lo que haces es colocar el pulsador. ¿Que cómo se coloca el pulsador? Fíjate en las patas. Están unidas lateralmente, así que puedes girar el componente y por detrás verás cómo 3 líneas. Están conectadas dos a dos por lo que utilizarás una pata de arriba y otra de abajo.
Cómo estás utilizando el pin 13 con este código basta:
void setup() { pinMode(13, OUTPUT); digitalWrite(13, HIGH); } void loop() { }
Cómo estas jugando con el pin 13 y no 5 Voltios directamente te puedes permitir el lujo de conectar la pata positiva del led en una pata del pulsador y luego en el otro lado conectar el cable. Si hay luz es que lo estás haciendo mal ya que el interruptor no está cortando el circuito. Si no la hace, pulsa el pulsador y si hace luz es que está conectado a la perfección. He aquí el circuito que debería quedarte. También puedes añadirle una resistencia de 220 Ohms por si hay algún cortocircuito.
Una resistencia te salvará de disgustos
Pero bueno, esto es algo muy básico para que veas que el botoncito dichoso al final es un interruptor, cómo esos trozos metálicos que utilizábamos en tecnología, ¿te acuerdas? Ahora vamos a utilizar el pulsador cómo una señal digital de entrada. Vamos a hacer lo mismo pero teniendo el led en el pin 13 y el pulsador en el pin 8. Vale cualquier pin pero me ha dado por el 13 y el 8, random.
El montaje es éste:
Como ves he conectado el led al pin 13 y a GND. En cuanto al pulsador, lo he conectado a 5 Voltios y a 0 y en medio al pin 8. ¿Te imaginas porqué está esa resistencia ahí? Porque sino la corriente se iría a GND. Esto es lo que se llama un cortocircuito, cuando un voltaje y GND se conectan directamente. Entonces le pongo la resistencia para que lo que toque vaya al pin y lo que no se consuma vaya a la resistencia. Vimos cómo afectaba a un led la corriente, en este caso petaría tu Arduino. Aunque la verdad es que alguna vez he hecho un corto y el Arduino se queda sin iluminarse pero cuando te deshaces del corto vuelve a la normalidad 😉
La resistencia la he puesto de 10K pero podría ser de menos. ¿Qué cómo se calculaba esto? ¿Te acuerdas de las mallas que hacíamos? Esta sería una malla que tiene como voltaje de 5 Voltios y que es igual a la intensidad que circula por la resistencia que buscamos. Arduino, en la página oficial dice que la corriente que puede circular en los pines de entrada y salida son 20mA por lo que calculando tenemos que:
Hay quien pone 1K, otros que ponen 4K7 yo pongo 10K (sería el equivalente a que pasaran 5mA, que eso ya no es nada) como medida de protección. El código que utilizo es el siguiente:
void setup() { pinMode(13, OUTPUT); pinMode(8, INPUT); } void loop() { if(digitalRead(8)==HIGH){ digitalWrite(13, HIGH); } else{ digitalWrite(13, LOW); } }
Cómo puedes ver he declarado el pin 13 como salida y el 8 como entrada. y lo que hago en el loop es decirle que cuándo el pin 8 reciba un HIGH (cuando pulse) el pin 13 se encienda. Al pulsar el botón el led se enciende.
Esto está muy bien, pero llevo dos minutos con el dedo pegado al botón y me estoy cansando. Así que lo voy a programar para que al pulsar se quede encendido. Para ello la configuración es la misma. Lo que cambia es el código:
bool encendido = false; void setup() { pinMode(13, OUTPUT); pinMode(8, INPUT); } void loop() { if(digitalRead(8)==HIGH && !encendido){ digitalWrite(13, HIGH); encendido = true; } else if(digitalRead(8)==HIGH && encendido){ digitalWrite(13, LOW); encendido = false; } }
Lo que he cambiado son los condicionales. he creado un boolean (un tipo de variables que solo tienen dos estados: o verdadero o falso) para saber cómo está el led. Cuando está apagado y pulso el botón enciendo el led del pin 13 y cambio el valor de la variable para saber que lo acabo de encender. Cuando está encendido y toco el pulsador se apaga el led y se cambia el valor de la variable a falso. Fíjate que !encendido es lo mismo que encendido = false pero por ahorrar lo he escrito así.
Los rebotes, esos hijos del mal
Bueno, ¿qué? ¿Te ha dado tiempo a ver qué lo que acabamos de hacer es un desastre? A veces se apaga, a veces no. El truco es mantener pulsado y aún así va cuando quiere. Esto es debido a los rebotes. Una señal cuadrada perfecta o es 0 o es 5 Voltios y no hay transición de por medio, la línea es totalmente recta. En la realidad las cosas no son así y hay una pequeña transición que crea una pequeña pendiente en la onda. Pues con los botones es aún peor porque en lugar de ser una pendiente son curvas que no dejan muy bien saber si está en LOW o en HIGH. He encontrado esta imagen que representa bien lo que quiero decir.
La razón de estas curvas es que Arduino no lee una vez sino que al ir tan rápido el loop se hace muchas veces y la pulsación se lee tropecientas veces, haciendo que el pobre se haga un lío fino fino. Además, estamos vigilando un proceso analógico. En el mundo real las cosas no son unos y ceros y el hecho de pulsar el botón crea interferencias. Es como cuando unimos dos cables y saltan chispas, la unión no es un camino dulce, sino que es algo violento y marcado cómo has visto en la imagen.
¿Cómo solventar esto? Bueno, una espera debería hacer el papel. Cuando detecte el valor que se espere un poco, así evitamos tomar esos valores que no nos interesan. Y sí, es una espera de las que no molan, pero oyga que es una luz, no un asunto de seguridad nacional.
bool encendido = false; void setup() { pinMode(13, OUTPUT); pinMode(8, INPUT); } void loop() { if(digitalRead(8)==HIGH && !encendido){ digitalWrite(13, HIGH); encendido = true; delay(200); } else if(digitalRead(8)==HIGH && encendido){ digitalWrite(13, LOW); encendido = false; delay(200); } }
Cómo ves, he añadido un delay de 200 milisegundos. La razón es que con 100 no funcionaba bien y con 500 iba demasiado lento. Así que jugando con el pulsador he decidido utilizar ese valor.
Cambiando la resistencia de lado
Bueno, antes he decidido poner la resistencia del pulsador del lado de GND. Pero, ¿Ha sido aleatorio? ¿Se puede poner del lado de los 5 Voltios? ¡Probémoslo! Te debería quedar algo tal que así:
Ahora, si lo pruebas verás que lo que sucede es un desastre. El led parpadea y si pulsas el interruptor a veces se mantiene la luz y a veces se apaga. Ahora métele este código:
bool encendido = false; void setup() { pinMode(13, OUTPUT); pinMode(8, INPUT); Serial.begin(9600); } void loop() { Serial.println(digitalRead(8)); Serial.println(encendido); delay(40); if(digitalRead(8)==LOW && !encendido){ digitalWrite(13, LOW); encendido = true; delay(200); } else if(digitalRead(8)==LOW && encendido){ digitalWrite(13, HIGH); encendido = false; delay(200); } }
Prueba ahora y verás que funciona como antes. La cosa es que si te fijas solamente he cambiado los HIGH del interruptor por LOW. ¿Y porqué esta tontería? Por una cosa que no lo es tanto…
Resistencias de pull-up y de pull-down
La resistencia en este segundo caso está actuando como lo que se conoce como resistencia pull-up mientras que antes lo que hacía era actuar como resistencia pull-down. Pull en inglés es estirar. Ahora estamos en el caso en que la resistencia estira hacia arriba (Mira: Up!, como la peli), de esta manera lo que sucede es que la tensión que llega al pin es la que viene de 5 Voltios ya que GND está a la otra parte del interruptor y aún no lo hemos pulsado.
Cuando pulsamos, lo que ocurre es que la corriente es muy vaga y busca el camino fácil. El camino fácil es que el pin 8 busque a GND ya que por el otro camino está la resistencia y eso no es algo directo así que rehuye de eso que al final es un jaleo. Antes lo aceptaba porque no había más remedio pero ahora…ahora ya se apañará.
En el primer caso, cuando estábamos en pull-down lo que sucedía era que la resistencia estiraba hasta 0. De esta manera al no pulsar el botón el pin 8 iba a parar a GND pero al conectar el botón, rápidamente va a buscar los 5 Voltios ya que la resistencia lo ahuyenta. Eso hace que si vuelves a la configuración inicial, la del led y el botón directamente alimentados por 5 Voltios, lo que sucede es que en pull-down el led está inicialmente apagado y en pull-up está inicialmente encendido.
Te dejo una imagen que aclarará mejor eso que te he contado de la corriente esa que va y viene y huye de nuestra resistencia. De hecho esta imagen pertenece a esta explicación que seguro te aclara alguna duda que pueda surgir.
En fin, serafín…
En conclusión, espero que te haya servido todo esto. Al final esto lo hago para ti, somos un pequeño equipo a distancia. Así que me ayudaría mucho si ahí abajo, en los comentarios, me contaras qué te preocupa. Qué es eso que te gustaría hacer y que no te sale ni a la de tres. Vamos esa cosa con la que te haces un pajuel cada vez que aparece y no te deja avanzar. ¡Nos vemos pronto rufián!
Información básica sobre Proteción de datos
Responsable ➥ Sergio Luján Cuenca
Finalidad ➥ Gestionar el envío de correos electrónicos con artículos, noticias y publicidad. Todo relacionado con los temas de rufianenlared.com
Legitimación ➥ Consentimiento del interesado
Destinatarios ➥ Estos datos se comunicarán a MailRelay para gestionar el envío de los correos electrónicos
Derechos ➥ Acceder, rectificar y suprimir los datos, así como otros derechos, como se explica en la política de privacidad
Plazo de conservación de los datos ➥ Hasta que se solicite la supresión por parte del interesado
Información adicional ➥ Puedes encontrarla en la política de privacidad y el aviso legal
Déjame un comentario que en el fondo soy buen chaval
Me encanta la forma en la que lo has explicado. Mil gracias!