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
    • Ivan Uriarte

    Estupendo Sergio. A seguir con ello.

  • Avatar for Charly
    • Sergio

    yasta,
    no estaban declarados LED y boton en el void loop. ;).

  • Avatar for Charly
    • Sergio

    buenos dias, seguro que esto solo me pasa a mi, pero la compilar me da error en :

    int valor = digitalRead(boton);

    no consigo encontrar el error ¿que está mal escrito?.

  • Avatar for Charly
    • Charly

    Basicamente, depende de lo que quieras leer cuando pulses el boton. SI ponemos un pull down a GND forzamos la lectura a 0 cuando no pulsamos el boton, es decir que leeremos 5V cuando lo pulsemos. Si usamos un pull up, leeremos 0V al pulsar. ¿Y para que esto? depende de lo que quierees hacer con la señal de salida. Si quieres encender un led directamente cuando pulses usa un pull down.

    Pero puedes querer hacer un circuito de hombre muerto (Se activa cuando no pulsas) o una luz de emergencia, y para ello encesitas un pull down

  • Avatar for Charly
    • JUAN ANTONIO

    Buenos días,
    Para aquellos ajenos al mundo de la electrónica, entiendo que utilizamos una resistencia Pull-Down, por ejemplo, en un pulsador, para mantener éste en estado bajo cuando no lo pulsamos (y así evitamos malas señales debido a la fluctuación de la corriente, y no pase a alto por ejemplo). Sin embargo, para que necesitaríamos una resistencia Pull-Up ¿cuál es el motivo de utilizar esta en una entrada de Arduino?. Muchas gracias,

  • Avatar for Charly
    • Ricardo

    Hola, buenas
    Estoy siguiendo el tutorial en detalle y veo que comentas:
    «Hemos definido valor como bool, porque podemos usar el valor de tensión alto como TRUE y el valor bajo como FALSE.»
    justo debajo del código:
    void loop()
    {
    int valor = digitalRead(boton) ; // leemos el valor de boton en valor
    digitalWrite( LED, !valor) ; //Escribimos valor en LED
    }
    supongo que será un pequeño error.
    Gracias por un tutorial tan interesante

  • Avatar for Charly
    • Ivan Uriarte

    Hola Luis, echa un ojo aquí que te ayudará https://www.prometec.net/condicionales-botones/ No tienes más que hacer que cuando detecte que se ha pulsado lo encienda y espere 30 segundos.

  • Avatar for Charly
    • Luis Antero

    Buenas , muy bueno los proyectos , muchS gracias ,
    Tengo un proyecto en mente
    Quisiera hacer algo parecido a este proyecto , pero solo cuando pulse el botón , encienda el Led por 30” y se apague , hasta que no le de la orden ( pulsar ) no encienda , he estado probando , incluso lo he hecho con retardo , porque me vendría bien , para un garaje , es decir cuando la gente pase su tarjeta la barrera se levanta y a continuación hay un portón , el portón no es más lento en subir y justo hay una rampa , que pasa , que al retroceder un poco han roto la barrera , por eso mi idea es retardar a la barrera . Cuando puedas me ayudas , muchas gracias

  • Avatar for Charly
    • Ivan Uriarte

    Hola David, lo tienes justo en la siguiente sesión del curso https://www.prometec.net/condicionales-botones/

  • Avatar for Charly
    • Ivan Uriarte

    Hola Octavio en este caso nos daría igual pero no es lo mismo:
    -Al usar #define LED 10 lo que haces es algo así como que buscar y reemplazar, donde ponga LED tu programa entenderá 10. No puedes cambiar el valor de LED más adelante en tu programa. Y por otra parte al no declarar variable, no ocupa espacio en memoria.

    -Al usar in LED = 10 estás declarando una variable de tipo integer, que ocupa memoria y que comienza valiendo 10. Pero este valor puedes cambiarlo cuando lo necesites.

    Como conclusión, al declarar pines es mejor usar int (o const int) para luego poder hacer declaraciones de muchos pines usando por ejemplo un for.

    Un saludo y muchas gracias!

  • Avatar for Charly
    • Octavio

    Hola Ivan que tal, no se si mi pregunta este argumentado o sea adecuada para este proyecto y foro, mi pregunta es: cuando se declara la variable int LED = 10; también se puede hacer son el #define LED 10

    int LED = 10;
    #define LED 10

    ¿es lo mismo?
    Gracias…Excelentes aportes

  • Avatar for Charly
    • David Ortega

    Hola, muchas gracias por el curso.
    Tengo una duda, ¿Cómo podría hacer para que al presionar el botón prenda y que no se apague hasta que lo vuelva a presionar?

  • Avatar for Charly
    • Juan

    Hola Ivan.
    Las resistencias de pull up o pull down, normalmente son de valores altos para evitar que drenen una innecesaria pérdida de mili-amperes, además hay que recordar que las entradas digitales estan en high z, es cierto que de 330 sirven, pero mejor de 10k o superior.
    atte. J.G.

  • Avatar for Charly
    • Ivan Uriarte

    La resistencia la usamos como pull up para el pulsador y con la de 330 nos vale perfectamente.

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