Fundamentos · 11 min de lectura

Bloque si en Arduino: pulsador y LED con if-else, bloques y C++

Bloque si en Arduino con pulsador y LED: leer un pin, if-else, comparaciones =, ≠, <, >, condiciones anidadas, conmutación, antirrebote y luz nocturna LDR.

El bloque si en Arduino permite que un programa elija uno de dos caminos según una pregunta: «¿Está pulsado el pulsador? Si lo está, enciende el LED; si no, apágalo». En el C++ de Arduino esta estructura se llama if/else, y el bloque «si … hacer … sino» de la programación por bloques de BlueGrays es su equivalente exacto. En este artículo usarás un proyecto de pulsador y LED para aprender a configurar un pin como entrada y leerlo, y después el bloque si, los operadores de comparación, las condiciones anidadas y cómo unir dos condiciones con «y», bloque a bloque y línea a línea.

Este artículo es la parte 3 de la serie De los bloques al código. En la parte anterior escribimos el primer programa e hicimos parpadear un LED con bloques; en la siguiente veremos bucles y variables.

Hasta ahora nuestros programas siempre hacían lo mismo: el LED se encendía, esperaba, se apagaba y volvía a esperar. Nunca escuchaban al mundo exterior. Cuando entran las condiciones, la placa decide mirando un pulsador, un sensor de luz o una distancia que mide, y ahí empieza lo divertido de la programación de robots. Todos los ejemplos vienen de proyectos con bloques gratuitos, así que puedes abrir sus bloques y su código en la página de programación por bloques o en la app y seguir el artículo en paralelo.

Entrada y salida: ¿en qué dirección trabaja un pin?

Los pines digitales de Arduino hacen una de dos tareas. Un pin configurado como salida entrega 5 V (HIGH) o 0 V (LOW); así se controla un LED, un zumbador o un relé. Un pin configurado como entrada no entrega nada, solo escucha la tensión que tiene: en un Arduino Uno lee como HIGH todo lo que supera unos 3 V y como LOW lo que queda por debajo de 1,5 V. En bloques esto se elige en la sección de configuración: el bloque «configurar pin 13 como ENTRADA» se convierte en pinMode(13, INPUT); en C++, y «configurar pin 7 como SALIDA» en pinMode(7, OUTPUT);. Para leer el pin se usa el bloque «leer pin 13». Se ve distinto a los demás: no es una orden que se apila, sino un bloque de valor redondeado que encaja en un hueco de otro bloque. Su equivalente en C++ es digitalRead(13), que devuelve HIGH o LOW. Como en Arduino HIGH vale 1 y LOW vale 0, también puedes guardar el resultado en una variable como si fuera un número. En resumen, los bloques de orden hacen algo, los bloques de valor dan un resultado, y el hueco de condición del bloque si solo se llena con un resultado así.

BloqueEquivalente en C++Qué hace
configurar pin 13 como ENTRADApinMode(13, INPUT);Pone el pin en modo escucha (una vez, en la configuración)
configurar pin 7 como SALIDApinMode(7, OUTPUT);Permite que el pin entregue tensión
leer pin 13digitalRead(13)Devuelve HIGH (1) o LOW (0)
escribir ALTO en pin 7digitalWrite(7, HIGH);Pone 5 V en el pin y el LED se enciende
leer analógico A0analogRead(A0)Devuelve un número de 0 a 1023
si … hacer … sinoif (…) { … } else { … }Ejecuta uno de dos caminos según la condición

Conexión: pulsador en 13, LED en 7 y resistencia pull-down obligatoria

En el proyecto Encender un LED con pulsador (Push) el pulsador va a D13 y el LED a D7. Una pata del pulsador va a 5V y la otra a D13, y entre D13 y GND se coloca una resistencia pull-down de 10 kΩ. Con el pulsador suelto, la resistencia lleva el pin a GND y se lee LOW. Al pulsar, los 5V llegan directamente al pin y se lee HIGH. Como la resistencia es grande, mientras pulsas solo circula alrededor de medio miliamperio de 5V a GND. La pata larga del LED va a D7 a través de una resistencia de 220 Ω y la corta a GND.

ComponenteSe conecta aPin de Arduino Uno
Pulsador, pata 1Directamente5V
Pulsador, pata 2 (en diagonal)DirectamenteD13
Resistencia de 10 kΩ (pull-down)Entre D13 y GNDD13 – GND
Pata larga del LED (ánodo)A través de una resistencia de 220 ΩD7
Pata corta del LED (cátodo)DirectamenteGND
Si te saltas la resistencia pull-down, D13 queda sin conectar a nada cuando sueltas el pulsador; es lo que se llama una entrada flotante. El pin capta ruido eléctrico, digitalRead() devuelve HIGH y LOW al azar y el LED parpadea sin que toques nada, o incluso se enciende al acercar la mano. En los pulsadores de cuatro patas, las dos del mismo lado ya están unidas por dentro, así que usa patas en diagonal. Tienes más detalles en cómo conectar un pulsador a Arduino y resistencias pull-up y pull-down.

El bloque si e if/else: el LED se enciende mientras pulsas

La versión en bloques del proyecto tiene dos secciones. En «configuración (una vez)» el pin 13 se configura como ENTRADA y el pin 7 como SALIDA. En «repetir siempre» hay un único bloque grande: si … hacer … sino. En su hueco hexagonal de condición está la comparación «leer pin 13 = ALTO». Si la condición es verdadera, se ejecuta el bloque «escribir ALTO en pin 7» de la rama «hacer»; si es falsa, el bloque «escribir BAJO en pin 7» de la rama «sino».

Bloque si en Arduino con pulsador y LED: bloques del proyecto Encender un LED con pulsador (Push)
El pin 13 es ENTRADA y el pin 7 SALIDA; si el pin 13 lee ALTO el LED se enciende, si no, se apaga.
C++ (Arduino IDE)
1void setup() {
2  pinMode(13, INPUT);    // Buton girişi (harici pull-down) / Button input (external pull-down)
3  pinMode(7, OUTPUT);    // LED çıkışı / LED output
4}
5
6void loop() {
7  if (digitalRead(13) == HIGH) {   // Buton basılı mı? / Is the button pressed?
8    digitalWrite(7, HIGH);         // Basılı: LED yanar / Pressed: LED on
9  } else {
10    digitalWrite(7, LOW);          // Bırakıldı: LED söner / Released: LED off
11  }
12}
13

Si pones el código al lado de los bloques, la correspondencia salta a la vista. La palabra if equivale a «si», la condición digitalRead(13) == HIGH entre paréntesis al hueco de condición, el primer par de llaves a la rama «hacer» y else con sus llaves a la rama «sino». Cada bloque que colocas en una rama se convierte en una línea dentro de las llaves correspondientes. Como loop() se repite decenas de miles de veces por segundo, la placa lee el pulsador una y otra vez; en cuanto levantas el dedo, la condición es falsa en la siguiente vuelta y el LED se apaga. Por eso el proyecto se llama «Push»: el LED solo está encendido mientras mantienes pulsado. La rama «sino» es opcional; un bloque si con solo la rama «hacer» se convierte en un if sin else. Pero si aquí quitas la rama «sino», el LED no se apaga nunca después de encenderse, porque ya no queda ninguna línea que lo apague. Pensar en las dos ramas de cada condición es un buen hábito.

Bloques de comparación: =, ≠, < y >

Signo en el bloqueC++SignificadoEjemplo de los proyectos
===igual adigitalRead(13) == HIGH (LED con pulsador, Push)
≠!=distinto debutton != lastButton (encender y apagar un LED)
<<menor quevalue < 50 (luz nocturna con LDR)
>>mayor quedistance > minDistance (distancia con HC-SR04)
El signo «=» del bloque de comparación se escribe == en C++. Un solo signo igual en C++ no compara, sino que asigna. Si escribes if (button = 1), el compilador no te detiene: button pasa a valer 1, el resultado es distinto de cero, así que la condición es verdadera en cada vuelta y el LED se enciende sin mirar nunca el pulsador. Con bloques no puedes cometer este error, porque la asignación («establecer … a …») y la comparación son bloques distintos. Pero en cuanto pasas al código, es el error más común de todos.

Encender y apagar con un pulsador: si anidados y una variable de estado

En el proyecto Push el LED solo estaba encendido mientras mantenías el pulsador. Si quieres que funcione como un interruptor de verdad, «pulsa una vez para encender y otra para apagar», el programa tiene que recordar dos cosas: si el LED está encendido ahora y qué leyó el pulsador en la vuelta anterior. El proyecto Encender y apagar un LED con un botón declara para ello dos enteros en la sección «variables globales (al principio)»: ledState (0 = apagado, 1 = encendido) y lastButton (la lectura anterior). El circuito es el mismo: pulsador en D13 con pull-down externa y LED en D7.

Bloques del proyecto Encender y apagar un LED con un botón: si anidado, comparación ≠ y bloque no
El si exterior detecta un cambio en el pulsador y el interior comprueba que sea una pulsación; no ledState invierte el estado del LED.
C++ (Arduino IDE)
1int ledState = 0;     // LED durumu: 0 = sönük, 1 = yanık / LED state: 0 = off, 1 = on
2int lastButton = 0;   // Butonun önceki okuması / Previous button reading
3
4void setup() {
5  pinMode(13, INPUT);   // Buton girişi (harici pull-down) / Button input (external pull-down)
6  pinMode(7, OUTPUT);   // LED çıkışı / LED output
7}
8
9void loop() {
10  int button = digitalRead(13);   // Butonu oku / Read the button
11  if (button != lastButton) {     // Buton durumu değişti / Button state changed
12    if (button == 1) {            // Yalnız basış anında (LOW -> HIGH) / Only at the press (LOW -> HIGH)
13      ledState = !ledState;       // Durumu ters çevir / Flip the state
14      digitalWrite(7, ledState);
15    }
16    delay(50);                    // Sıçramayı atlamak için kısa bekleme / Short wait to skip the bounce
17    lastButton = button;          // Bu okumayı sakla / Store this reading
18  }
19}
20
BloqueLínea de C++Función
declarar entero (int) ledState = 0int ledState = 0;Guarda el estado del LED
declarar entero (int) lastButton = 0int lastButton = 0;Guarda la lectura anterior del pulsador
establecer button a leer pin 13int button = digitalRead(13);Lee el estado actual del pulsador
si button ≠ lastButtonif (button != lastButton) {Entra si el estado del pulsador cambió
si button = 1if (button == 1) {Entra si el cambio es una pulsación (de 0 a 1)
establecer ledState a no ledStateledState = !ledState;Convierte 0 en 1 y 1 en 0
escribir ledState en pin 7digitalWrite(7, ledState);Lleva el LED al nuevo estado
esperar 50 msdelay(50);Salta el rebote del contacto
establecer lastButton a buttonlastButton = button;Guarda esta lectura para la siguiente vuelta

El corazón del programa son los dos bloques si anidados. La condición exterior button ≠ lastButton solo es verdadera en la vuelta en la que cambia el estado del pulsador; en las miles de vueltas en las que lo mantienes pulsado o no lo tocas, no pasa nada. Un cambio puede ir en dos direcciones: pulsar (de 0 a 1) o soltar (de 1 a 0). La condición interior button = 1 se queda solo con la pulsación. Así, el LED cambia una vez por pulsación y nada al soltar. En el código, los if anidados se ven como llaves dentro de llaves. En bloques, el si interior se coloca en la rama «hacer» del exterior, y de un vistazo se entiende qué línea depende de qué condición.

El bloque no ledState se escribe !ledState en C++. El signo de exclamación da el contrario lógico: el contrario de 0 es 1, y el de cualquier número distinto de cero es 0. Asignar a ledState su propio contrario invierte el estado en cada pulsación. El bloque siguiente, «escribir ledState en pin 7», es la línea digitalWrite(7, ledState); como HIGH vale 1 y LOW vale 0, el valor de la variable se puede escribir directamente en el pin. Al final, lastButton recibe la lectura de esta vuelta para que la comparación de la siguiente sea correcta. Si olvidas esta asignación, lastButton se queda siempre en 0; mientras mantienes pulsado, la condición exterior es verdadera en cada vuelta y el LED parpadea muy rápido.

El bloque esperar 50 ms no es decorativo: es una forma sencilla de antirrebote (debounce). Los contactos metálicos de un pulsador se abren y cierran varias veces durante unos milisegundos al pulsar; la placa lee tan rápido que puede tomar una pulsación por varias y el LED queda encendido o apagado al azar. Esperar 50 ms tras un cambio da tiempo a que el rebote termine. Mientras delay() espera, la placa no puede hacer nada más; para temporizar sin detener el programa, consulta millis() y delay().

Condición analógica: luz nocturna con LDR

Las condiciones no son solo para HIGH y LOW. En el proyecto Luz nocturna con LDR, el bloque «establecer value a leer analógico A0» convierte la tensión de A0, donde está conectada la LDR, en un número entre 0 y 1023; en C++ es la línea value = analogRead(A0);. Después, el bloque si comprueba value < 50. Si el valor es menor que 50, se considera que está oscuro y el LED de D13 se enciende; si no, se apaga. La estructura es la misma que en el proyecto Push; solo cambia la comparación del hueco de condición.

Bloques del proyecto Luz nocturna con LDR: leer analógico A0 y la condición value < 50
La lectura analógica da un número de 0 a 1023; si value es menor que 50 el LED se enciende, si no, se apaga.
C++ (Arduino IDE)
1int value;   // Işık okuması (0-1023) / Light reading (0-1023)
2
3void setup() {
4  pinMode(13, OUTPUT);   // LED çıkışı / LED output
5}
6
7void loop() {
8  value = analogRead(A0);   // Işık seviyesini oku / Read the light level
9
10  // Eşik 50: altı karanlık sayılır, hassasiyeti bu sayıyla ayarla
11  // Threshold 50: anything below counts as dark. Tune the sensitivity with this number
12  if (value < 50) {
13    digitalWrite(13, HIGH);   // Karanlık: LED yanar / Dark: LED on
14  } else {
15    digitalWrite(13, LOW);    // Aydınlık: LED söner / Bright: LED off
16  }
17}
18

Según tu LDR y la resistencia del circuito, el umbral de 50 puede quedarse bajo o alto para tu habitación. Para dar con el número correcto, usa primero el proyecto Medir la intensidad de luz con LDR y observa en el monitor serie los valores con luz y a oscuras; luego pon el umbral entre ambos. Si el valor oscila justo alrededor del umbral, el LED puede parpadear; usar dos umbrales distintos para encender y apagar lo soluciona muy bien. Cómo funciona una LDR lo tienes en el artículo sensor de luz LDR.

Combinar condiciones: el bloque y y &&

A veces una condición no basta. En el proyecto HC-SR04 Medición de distancia (pantalla en serie), la distancia medida solo se muestra en el monitor serie si está entre 3 cm y 100 cm. En bloques, dos comparaciones se unen una al lado de la otra con un bloque y: «distance > minDistance y distance < maxDistance». En C++ esa línea queda if (distance > minDistance && distance < maxDistance). El operador && da verdadero solo si los dos lados son verdaderos; si uno solo es falso, la condición es falsa. Así, los valores sin sentido fuera del rango del sensor nunca llegan a la pantalla. En C++ «o» se escribe || y basta con que una condición sea verdadera. Puedes probar las tablas de verdad de Y, O y NO en la herramienta de puertas lógicas.

Las mismas condiciones en ESP32: pull-up interna y lógica invertida

El proyecto Control de LED con pulsador en ESP32 (Push) usa el mismo bloque si en un ESP32, con dos diferencias. El LED va a GPIO 5, el pulsador a GPIO 4, y al pin del pulsador se le da la opción de entrada con pull-up del bloque de pin. En C++ es pinMode(BUTTON_PIN, INPUT_PULLUP);: una resistencia dentro del chip lleva el pin a HIGH y no hace falta resistencia externa. Esta vez el pulsador va a GND, así que el pin lee LOW al pulsar y la condición pasa a ser «leer pin BUTTON_PIN = BAJO». El proyecto Control de LED con botón en ESP32 (Toggle) resuelve el encendido y apagado con el bloque de tiempo transcurrido, millis(), en lugar de esperar 50 ms, y vuelve a unir dos condiciones con un bloque y. Los pines del ESP32 trabajan a 3,3 V; no conectes el pulsador a 5 V.

Errores frecuentes y soluciones

ErrorSíntomaSolución
Sin resistencia pull-downEl LED parpadea solo y se enciende al acercar la manoPon 10 kΩ entre D13 y GND, o usa INPUT_PULLUP e invierte la lógica
Un solo igual en la condición: if (button = 1)El LED siempre está encendido e ignora el pulsadorUsa == para comparar
Punto y coma al final de la línea ifEl código entre llaves se ejecuta en cada vuelta sin importar la condiciónBorra el ; detrás de if (…)
Patas del pulsador del mismo ladoEl pin siempre lee HIGH o siempre LOWUsa patas en diagonal
lastButton no se actualiza o falta la esperaEl LED parpadea al mantener pulsado o queda al azarAñade lastButton = button y la espera de 50 ms
Creer que HIGH es pulsado con INPUT_PULLUPEl LED funciona al revés y se enciende al soltarCon pull-up interna, LOW significa pulsado
El umbral de la LDR no encaja con la habitaciónEl LED nunca se enciende o siempre está encendidoObserva el valor en el monitor serie y elige otro umbral

Abrir bloques y código lado a lado en la app

Todos los proyectos de este artículo están entre los proyectos con bloques gratuitos de la app BlueGrays. Si activas el interruptor Ver en bloques en la sección de código de un proyecto, el código se sustituye por el mismo programa en bloques; al tocar la imagen se abre a pantalla completa. La pestaña Entiende los bloques explica el programa paso a paso: cada paso muestra solo sus bloques y lo que hacen, así puedes seguir los bloques si anidados uno a uno. Los ejemplos de if/else y digitalRead de la Guía de código también aparecen en bloques. Los bloques no se cargan directamente en la placa y, por ahora, no puedes montar tus propios programas con bloques; a la placa siempre va el código C++ real del proyecto, que copias en el Arduino IDE y subes. Si quieres repasar lo aprendido, Preguntas del día te plantea 5 preguntas cada día con niveles de A1 a C2.

Ahora que conoces las condiciones, el siguiente paso es manejar repeticiones y contadores: en la parte de bucles y variables verás cómo «repetir siempre» se relaciona con loop() y el bloque de contar con un bucle for. Mientras tanto, en la app BlueGrays puedes ver el esquema y el código de los proyectos de LED con pulsador, luz nocturna con LDR y pulsador con ESP32, pasar a la vista en bloques con Ver en bloques y a la explicación paso a paso con Entiende los bloques.

Preguntas frecuentes

¿Para qué sirve el bloque si en la programación por bloques?

El bloque si permite que un programa tome una decisión: si la condición es verdadera, se ejecutan los bloques de la rama «hacer»; si es falsa, los de la rama «sino». En proyectos de Arduino se usa sobre todo para comprobar si un pulsador está pulsado o si el valor de un sensor ha superado un umbral. Su equivalente en C++ es la sentencia if/else.

¿Qué diferencia hay entre if y else en Arduino?

if ejecuta el código entre sus llaves cuando la condición entre paréntesis es verdadera. else es opcional y contiene el código que solo se ejecuta cuando la condición es falsa. Sin else, no pasa nada cuando la condición es falsa y el programa sigue con la siguiente línea.

¿Qué diferencia hay entre = y == en Arduino?

Un solo igual (=) asigna un valor a una variable y el doble igual (==) compara dos valores. Escribir if (x = 1) asigna 1 a x y hace que la condición sea siempre verdadera; lo correcto es if (x == 1). En bloques, el signo «=» del bloque de comparación se traduce a == en el código.

¿Por qué se enciende el LED de Arduino sin pulsar el botón?

Lo más probable es que el pin del pulsador esté flotando, es decir, que falte la resistencia pull-down o pull-up. Entonces el pin lee el ruido del entorno y parece HIGH o LOW al azar. Pon una resistencia de 10 kΩ entre el pin y GND, o usa pinMode(pin, INPUT_PULLUP) y conecta el pulsador a GND.

¿Cómo encender y apagar un LED con un pulsador en Arduino?

Guarda el estado del LED en una variable (ledState) y la lectura anterior del pulsador en otra (lastButton). Cuando cambie el estado del pulsador y el nuevo estado sea pulsado, invierte el estado con ledState = !ledState y escríbelo en el LED con digitalWrite. Añade una espera corta, por ejemplo 50 ms, para saltar el rebote; el proyecto Encender y apagar un LED con un botón hace justo eso.

¿Puedo cargar los bloques de BlueGrays en mi Arduino?

No, los bloques no se cargan directamente en la placa. Corresponden uno a uno con el código real del proyecto y sirven para entender el programa. A la placa siempre subes el código C++ del proyecto, copiándolo en el Arduino IDE.

Ver todos los proyectos
Encender un LED con pulsador (Push)
#9Principiante

Encender un LED con pulsador (Push)

Como un timbre: la luz se enciende mientras pulsas y se apaga cuando sueltas. El Arduino escucha el botón todo el rato; mientras está pulsado enciende el LED, y en cuanto levantas el dedo lo apaga. Co

4.8(113)
229
Encender y apagar un LED con un botón
#10Principiante

Encender y apagar un LED con un botón

Pulsas el botón una vez y la luz se enciende, lo pulsas otra vez y se apaga, igual que el interruptor de tu habitación. El Arduino nota cada pulsación y cambia el LED al estado contrario, esperando un

4.8(100)
167
Luz nocturna con LDR
#12Principiante

Luz nocturna con LDR

Una pequeña lamparita que se enciende sola cuando oscurece y se apaga cuando llega la mañana. Un sensor de luz mide la claridad de la habitación, y el Arduino enciende el LED cuando está lo bastante o

4.8(102)
205
HC-SR04 Medición de distancia (pantalla en serie)
#27Principiante

HC-SR04 Medición de distancia (pantalla en serie)

El sensor HC-SR04 funciona igual que un murciélago que se orienta en la oscuridad: emite un sonido que no puedes oír, escucha el eco y mide a qué distancia está el objeto que tiene delante. El Arduino

4.6(46)
71
Control de LED con pulsador en ESP32 (Push)
#104Principiante

Control de LED con pulsador en ESP32 (Push)

El LED se enciende cuando se pulsa el botón y se apaga cuando se suelta. Muestra cómo se utiliza el pin de entrada digital del ESP32 y la resistencia pull-up interna. Gracias al modo INPUT_PULLUP, no se necesita ninguna resistencia externa.

4.6(36)
55
Control de LED con botón en ESP32 (Toggle)
#105Principiante

Control de LED con botón en ESP32 (Toggle)

Cada vez que se pulsa el botón, cambia el estado del LED: si está encendido se apaga, si está apagado se enciende. Patrón de conmutación clásico. Con debounce limpiamos el ruido mecánico del pulsador para garantizar una sola conmutación con una sola pulsación.

4.6(39)
57
Medir la intensidad de luz con LDR
#11Principiante

Medir la intensidad de luz con LDR

¿Quieres ver en números cuánta luz hay en tu habitación? El LDR, una pequeña pieza sensible a la luz, mide la luz ambiente y el Arduino escribe el valor en la pantalla del ordenador cada medio segundo

4.6(81)
139
Parpadeo de LED
#1Principiante

Parpadeo de LED

El primer hola de la electrónica: encender y apagar un solo LED. El Arduino enciende y apaga el LED a intervalos cortos, así que la luz parpadea rápido. Ves de la forma más sencilla cómo la placa cont

4.6(188)
1127