bclose

Las entradas digitales de Arduino

Leyendo un pulsador con Arduino

 

Objetivos

.

 
    • Conocer las entradas digitales.
    • Leer el primer pulsador.
    • Presentar los valores booleanos.
    • Un operador: Negación.

 

Material requerido.

 

  Tienda España Tienda Mexico
Kit Arduino Uno  Kit inicio UNO Kit inicio UNO
Kit Arduino MEGA Kit Inicio Mega Kit Inicio Mega

Entradas digitales

 

Con frecuencia en electrónica necesitamos saber si una luz está encendida o apagada, si alguien ha pulsado un botón o si una puerta ha quedado abierta o está cerrada.

A este tipo de señales todo / nada, SI / NO, TRUE /FALSE, 0/1  se les llama digitales, y podemos manejarlas con los pines de 0 al 13 de Arduino y por eso hablamos de pines digitales.

Muchos de los sensores y actuadores que vemos en el mundo real son digitales:

 
  • Como actuadores digitales, tenemos luces, alarmas, sirenas, desbloqueo de puertas, etc.
  • Como sensores digitales podemos mencionar botones y pulsadores, Finales de carrera, desbordamiento de nivel, sensores de llamas, humo o gases tóxicos.
 

Hemos visto que Arduino pueden usar los pines digitales como salidas todo o nada para encender un LED. De la misma manera podemos leer valores, todo o nada, del mundo exterior.

En esta sesión veremos que los pines digitales de Arduino pueden ser usados tanto de entrada como de salida. Vamos a leer un botón o pulsador externo y vamos a encender o apagar un LED en función de que el botón se pulse o no.

 

Esquema electrónico del circuito.

.

Montaremos un circuito con un diodo LED y resistencia conectado al pin digital 10 de Arduino, tal y como vimos en las sesiones previas y ademas un segundo circuuito con un pulsador S1 conectado al pin 6 con una resitencia como se muestra en el diagrama siguiente.

Circuito con pulsador

 

Obsérvese que mientras no pulsemos S1 el pin 6 de Arduino está conectado a 5V a través de la resistencia R3 forzando una lectura de tensión alta (HIGH). En cambio cuando pulsemos S1 cerraremos el circuito del pin 6 a Ground con lo que leerá tensión baja, LOW. En ambos casos tenemos un valor de tensión definido.

Si no pusiéramos la resistencia R3, al pulsar S1 leeríamos correctamente LOW en el pin 6. Pero al dejar de pulsar S1 el pin 6 estaría en un estado flotante, que es ni HIGH ni LOW  sino indeterminado. Como esto es inaceptable en circuitos digitales forzamos una lectura alta con R3.

 
  • A esta resistencia que fuerza el valor alto en vacio se le conoce como pullup Si la conectáramos a masa para forzar una lectura a Ground se le llamaría pulldown resistor.
  • Esta resistencia es clave para que las lecturas del pulsador sean consistentes. El circuito, simplemente, no funcionará bien si se omite (volveremos sobre esto).
 

Y aquí tenemos el esquema para protoboard del circuito.

Esquema protoboard

 

 
  • En este esquema hemos seguido la práctica habitual de usar cables negros para conectar a masa y cables rojos para conectar a tensión (5V).
  • Obsérvese que el pulsador S1 tiene cuatro pines (el que está sobre la resistencia horizontal). Esto es porque cada entrada del interruptor tiene dos pines conectados. En nuestro circuito simplemente ignoramos los pines secundarios.
 

 

Leyendo los pulsadores

 

Empecemos haciendo un programa que haga que el LED se encienda cuando pulsamos el botón y se apague cuando lo soltamos. Para ello pediremos a Arduino que configure el pin digital 10 (D10) como salida para manejar el LED, y el pin digital 6 (D6) como entrada para leer el botón.

Normalmente en programas sencillos basta con poner el número de pin en las instrucciones. Pero a medida que el programa se complica esto tiende a provocar errores difíciles de detectar.

Por eso es costumbre definir variables con los números de pin que usamos, de forma que podamos modificarlos tocando en un solo lugar (y no teniendo que buscar a lo largo del programa). Vamos a escribir esto un poco más elegantemente:

     int LED = 10 ;
     int boton = 6;
 
     void setup()
          {
               pinMode( LED, OUTPUT) ; // LED como salida
               pinMode( boton  , INPUT) ;            //botón  como entrada
          }
 
  • Atención: C++ diferencia entre mayúsculas y minúsculas y por tanto LED, Led y led no son lo mismo en absoluto. Del mismo modo, pinMode es correcto y en cambio pinmode generará un error de compilador fulminante.
  • He usado la variable boton sin acento porque no es recomendable usarlos ni la ñ en los nombres de variables, porque pueden pasar cosas extrañas.
 

Vimos que para encender el LED bastaba usar digitalWrite( LED, HIGH). Para leer un botón se puede hacer algo similar: digitalRead( botón). Veamos cómo podría ser nuestro loop:

     void loop()
          {
              int valor = digitalRead(boton) ;          // leemos el valor de boton en valor
              digitalWrite( LED, valor) ; 
          }

¿Fácil no? Aunque el LED está encendido hasta que pulsamos el botón y se apaga al pulsar.

¿Cómo podríamos hacer lo contrario, que el LED se encienda al pulsar y se apague si no? Bastaría con escribir en LED lo contrario de lo que leamos en el botón.

Existe un operador que hace eso exactamente el operador negación “ ! “ . Si una valor dado x es HIGH, entonces !x es LOW y viceversa.

 
  • Un operador es un símbolo que relaciona varios valores entre sí, o que modifica el valor de una variable de un modo previsible.
  • Ejemplos de operadores en C++ son los matemáticos como +,-,* , / ; y hay otros como la negación ! o el cambio de signo de una variable : – x. Iremos viendo más.
 

De hecho este tipo de operaciones son tan frecuentes que C++ incorpora un tipo llamado bool o booleano que solo acepta dos valores TRUE (cierto) y FALSE y son completamente equivalentes al 1 / 0, y al HIGH / LOW

Este nuevo programa sería algo así:

     void loop()
          {
              int valor = digitalRead(boton) ;      // leemos el valor de boton en valor
              digitalWrite( LED, !valor) ;          //Escribimos valor en LED 
           }

Hemos definido valor como bool, porque podemos usar el valor de tensión alto como TRUE y el valor bajo como FALSE.

SI el botón no está pulsado el D6 leerá TRUE y por tanto pondrá LED a FALSE. En caso contrario encenderá el LED.

De hecho podríamos escribir una variante curiosa del blinking LED usando el operador negación:

     void loop()
         {
             bool valor = digitalRead (LED) ;
             digitalWrite(  LED, !valor) ;
             delay ( 1000) ;
         }
 
  • Podemos leer la situación actual de un pin (nos devuelve su estado actual), aún cuando lo hayamos definido como salida, En cambio no podemos escribir en un pin definido como entrada.
 

La primera  linea lee la situación del LED y la invierte en la segunda línea, después escribe esto en LED. Y puestos a batir algún record, podemos escribir el blinking led en solo dos líneas:

     void loop()
          {
               digitalWrite(  LED , ! digitalRead( LED)) ;
               delay ( 1000) ;
          }
 
  • Las instrucciones dentro de los paréntesis se ejecutan antes que las que están fuera de ellos. Por eso el digitalRead se ejecuta antes que el digitaWrite..
 

 

Resumen del curso

.

 
 
    • Hemos visto una forma de leer señales digitales en Arduino del mundo exterior además de poder enviarlas:
      • digitalRead( pin)
      • digitalWrite( pin , valor)
    • Hemos conocido un nuevo componente: el pulsador.
    • Conocemos un nuevo tipo en C++, el booleano y un nuevo operador de negación.
 

 

 

Para porder realizar consultas a nuestros expertos, tienes que ser suscriptor. Suscribiendote nos ayudas a mantener este proyecto en marcha.

¡ Quiero Suscribirme !

Si ya eres premium y no puedes comentar haz login. Hacer login

(174) Comments

  • Avatar for Charly

    tengo los pulsadores con sus respectivas resistencias a tierra y el otro pin del pulsador a los 5v y aun asi me pasa eso que comente. la resistencia es de 330 ohm, sin embargo cuando desconecto el cable del proto y solo queda conectado al pin de arduino es cuando sucede eso como si pulsara y soltara el pulsador.

  • Avatar for Charly
    • Ivan

    Hola Víctor, si dejas los pines de las entradas digitales sin conectar, o si los conectas con el pulsador directamente sin una resistencia en pullup o pulldown, es normal que el valor que leen fluctúe entre los dos estados continuamente. Por eso te detecta como si estuvieses apretando y soltando el pulsador.
    Un saludote!

  • Avatar for Charly
    • Victor Hugo

    hola de nuevo, una pregunta, es normmal que me pase esto? es que cuando realizo un programa utilizando pulsadores, indico que cuando esten presionados me impriman una sola vez un mensaje, y cuando lo suelte me imprima igual una sola vez un mensaje de que ya se solto, esto con el fin de adaptarlo a mi programa de envio de email y solo se envie uno cada vez que presiono el pulsador, pero mi problema es que al abrir el monitor serial, si tengo todo cableado funciona de maravilla sin embargo al quitar de los pines algunos de los cables el programa me imprime ambas instrucciones como si estuviera presionando y soltando el pulsador sin embargo creo que no deberia de hacer eso aunque no tenga cableado nada, y despues al colocar de nuevo el cable en su pin correspondiente el programa vuelve a la normalidad, y al parecer es con todos los pines digitales, no se cual sea el problema. saludos y espero tu respuesta, y gracias por todo

  • Avatar for Charly
    • Ivan

    Hola Edwin! Puedes hacerlos con la aplicación Fritzing, que es gratuita.

    Un saludote!

  • Avatar for Charly

    Que aplicación usas para documentar los esquemas con protoboard. Requiero documentar un proyecto y veo que este tipo de imagenes se usan en varios sitios pero no se como tener acceso a ellas.

    atte. Edwin

  • Avatar for Charly

    hola, existe alguna posibilidad de trabajar con, los pines que traen pwm pero sin que envien algun pulso? esque necesito trabajar con todos los pines digitales, y que cada uno solo me lea el primer pulso que se hace cuando presionamos un pulsador, esto con el fin de enviar un correo, tengo el codigo que realiza esa accion sin embargo cuando trabajo con los de pwm me lee dos pulsos, y creo que es porque ellos por defecto envian un pulso aparte del que yo doy con el pulsador, otra pregunta, limpiar los pines digitales, esque cuando cargo un programa y por ejemplo no ocupo el pin No2 pero al conectarle el pulsador a ese pin me realiza una accion algo que no deberia de ser ya que no lo tengo declarado.

    atte victor hugo

  • Avatar for Charly
    • Cristian

    Hola TORKIN, creo que el error está en que declaraste «int valor» con minusculas y despues en digitalWrite lo nombras como «VALOR» con mayusculas, lo cual son dos variables diferentes. Saludos.

  • Avatar for Charly
    • Guilher

    muy buenooooo!!!!!!!!!!!!!!!!!!!!

  • Avatar for Charly
    • Admin

    Creo que Luis, que es necesario que comprendas que no hay una conexion fisica entre el boton y el LED: Esto es conceptualmente importante porque podemos leer el boton y hacer con esa informacion lo que nos parezca: encenderlo o apagarlo o cualquier otra cosa que se te ocurra. Es la ventaja de disponer de un controlador programable, aun cuando no hay conexion fisica podemos emular o programar cualquier comportamiento.
    CUando defines un pin como entrada esperas valores de tension entre digamos, 0 y 0,5 voltios, lo que entendera como un cero logico y valores entre 4,5 y 5 Voltios los entendera como un 1 logico, pero tu arduino ya esta calibrado para leer los vlaores asi y no hay mucho que tengas que hacer.

    FIjate que si fuese un arduino de 3,3 voltios entonces lo niveles de tension que espera son diferentes pero tu programa seria exactamente igual ¿Vale?

  • Avatar for Charly

    Muy buenas, tengo una duda y es que no entiendo muy bien la relación entre el pulsador y el circuito del LED. Es decir, ¿por qué en el primer ejemplo, al pulsar el botón el LED se apaga? Yo pienso que debe ser porque en esa situación, la tensión que hay en el extremo de la resistencia es mayor que la que sale por el pin 10 y por tanto el diodo no conduce, ¿no es así? Y ya puestos, ¿por lo pines de salida, la tensión que sale es siempre la misma y de ser así cuál es su valor?

    Por último, siempre que queramos usar un pin como entrada, ¿es necesario alimentarlo con el ‘pin 5v? Es que tampoco me queda claro su uso.

    Un saludo y gracias de antemano.

  • Avatar for Charly

    Justamente esa era la duda que tenia en mente. La R3 no solo esta para mantener un estado sino para evitar un corto al conectar directo 5V con masa.

  • Avatar for Charly
    • Admin

    ten en cuenta Albert que cuanto ma stiempo alargas el delay menos frecuentemente mira si has pulsado el boton. Normalmente la situacion optima para el delay seria de 200 – 250 y siempre y cuando no pulses demasiado seguido, sino que hagas una pulsacion rapida y esperes al menos un poco mas del delay antes de pulsar de nuevo

  • Avatar for Charly
    • Albert

    Buenas, Charly.
    Felicidades por el tutorial y las explicaciones. Así casi no tiene mérito aprender!!
    He montado el circuito, y me funciona, pero veo que cuando he pulsado dos o tres veces el botón, tarda un tiempo en poder volver a responder. He subido el delay a 1500 y aún se enciende, pero mantiene elmismo problema. A delay=2000 ya pasa de mí. Si lo bajo a 500, el tiempo que aguanta antes de pasar de mí es mayor. Es decir, parece que, a medida que incremento el delay, se dificulta más la respuesta. A qué se debe?.
    Gracias.
    Albert

  • Avatar for Charly
    • Admin

    Hola Ricardo, en principio el codigo que me pasas esta pensado para hacer el blinking led de otro modo independientemente del valor del boton. Lo que hace es leer el estado del LED y despues lo invierte escribiendo lo contrario.
    Por eso si esta encendido lo apaga, y si esta apagado lo enciende. Era para mostraros que aunque hayamos definido LED como salida podemos leer su estado actual y usarlo para invertirlo por ejemplo

  • Avatar for Charly

    Primero darte las gracias por los tutoriales y ayudar a entender el mundo ARDUINO 🙂
    Segundo, tengo una duda, en la variante final que pones:

    void loop()
    {
    bool valor = digitalRead (LED) ;
    digitalWrite( LED, !valor) ;
    delay ( 1000) ;
    }
    El valor que leemos no debería ser la variable boton en vez de LED?
    o sea, la linea deberia ser: bool valor=digitalRead(boton);

    ¿no?

  • Avatar for Charly

    Muchas gracias por unos tutoriales tan estupendos. simplemente genial. y a los críticos decirles que más ánimos y menos criticas.

  • Avatar for Charly
    • Admin

    Mas adelante hablaremos de los conceptos de variables globales y locales. Pero de momento baste decir que las variables que definies al principio fuera del loop y del setup son globales, lo que significa que se ven desde todo el program, mientra que si las defines dentro del setup como me comentas, solo se pueden ver desde el setup y te dara un error si las llamas desde el loop

  • Avatar for Charly
    • Admin

    Hola Miguel Angel, Normalmente cuando los metes en un program los puedes considerar como cierto o falso y entonces se pueden usar para tomar una decision. Por ejemplo si defines una variable bool como finalizado, puedes usar un programa que sea :
    if (finalizado)
    { …….}
    Si finalizado es true ( 1 si prefieres) ejecutará las instrucciones entre parentesis, mientras que se las saltará si finalizado es falso o cero

  • Avatar for Charly
    • Miguel Angel

    Buenos días;

    Tengo la siguiente duda y es que no entiendo los valores booleanos. Exactamente que son instrucciones? variables?, que son?. Lo único que entiendo es que sólo pueden tomar valores True o false, pero cuando lo metes en el programa no entiendo su función.

  • Avatar for Charly
    • Admin

    Iba a responderte a este pero ya veo que has visto la solucion tu solo. En efecto era un problema de debouncing

Para porder realizar consultas a nuestros expertos, tienes que ser suscriptor. Suscribiendote nos ayudas a mantener este proyecto en marcha.

¡ Quiero Suscribirme !

Si ya eres premium y no puedes comentar haz login. Hacer login