Created
May 17, 2025 02:01
-
-
Save CravApp/f781fe6856111082c5aaca9d129249df to your computer and use it in GitHub Desktop.
Programar Arduino
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Proyecto: ARPS2-Intro-2-Variables | |
Actividad: mirobo.tech/arps-intro-2 | |
Actualizado: 21 de febrero de 2025 | |
Esta actividad introductoria de programación para el circuito mirobo.tech ARPS2 | |
demuestra el uso de una variable para contar pulsaciones de botón y comparaciones | |
constantes dentro de condiciones para activar una acción cuando se alcanza un límite. | |
Análisis de programa adicional y actividades de programación demuestran el uso de | |
variables booleanas (o bool) para almacenar el estado durante bucles de programa | |
sucesivos, la creación de un juego de clics rápidos para dos jugadores, la simulación | |
de botones de alternancia y multifunción del mundo real, y alientan a los aprendices | |
a crear código de programa para medir y mitigar el rebote de contacto del interruptor. | |
Consulta la página web https://mirobo.tech/arps para obtener recursos | |
adicionales de ARPS2, actividades de programación y programas de inicio. | |
*/ | |
// Dispositivos de E/S de inicio educativo ARPS2 | |
const int SW2 = 0; // Los pulsadores SW2 y SW3 son totalmente compatibles en | |
const int SW3 = 1; // Arduino UNO R4 Minima y Arduino UNO R4 WiFi | |
const int SW4 = 2; // Los pulsadores SW4 y SW5 funcionan en todas las placas | |
const int SW5 = 4; // de circuito Arduino UNO | |
const int LED2 = 3; // LEDs ARPS2 | |
const int LED3 = 9; | |
const int LED4 = 10; | |
const int LED5 = 11; | |
const int BEEPER = 6; // Zumbador piezoeléctrico LS1 de ARPS2 | |
// LED predefinido de Arduino UNO | |
// LED_BUILTIN (D13) // LED integrado (compartido con H2 y SONAR TRIG) | |
// Define constantes del programa | |
const int maxCount = 50; | |
// Define variables del programa | |
int SW2State; | |
int SW3State; | |
int SW4State; | |
int SW5State; | |
int SW2Count = 0; | |
bool SW2Pressed = false; | |
// El código de configuración se ejecuta una vez para configurar los pines de E/S antes de ejecutar el bucle principal | |
void setup() { | |
pinMode(SW2, INPUT_PULLUP); | |
pinMode(SW3, INPUT_PULLUP); | |
pinMode(SW4, INPUT_PULLUP); | |
pinMode(SW5, INPUT_PULLUP); | |
pinMode(LED2, OUTPUT); | |
pinMode(LED3, OUTPUT); | |
pinMode(LED4, OUTPUT); | |
pinMode(LED5, OUTPUT); | |
pinMode(BEEPER, OUTPUT); | |
pinMode(LED_BUILTIN, OUTPUT); | |
tone(BEEPER, 4000, 100); // ¡Hola! | |
} | |
// El código del bucle principal se repite indefinidamente | |
void loop() { | |
SW2State = digitalRead(SW2); // Cambiar a SW4 para Arduino UNO R3 | |
SW5State = digitalRead(SW5); | |
// Cuenta las pulsaciones del botón SW2 | |
if (SW2State == LOW) { | |
digitalWrite(LED2, HIGH); | |
SW2Count = SW2Count + 1; | |
} | |
else { | |
digitalWrite(LED2, LOW); | |
} | |
// Enciende el LED D3 cuando se ha alcanzado el conteo máximo | |
if (SW2Count >= maxCount) { | |
digitalWrite(LED3, HIGH); | |
} | |
// Apaga el LED D3 y reinicia el conteo si se presiona SW5 | |
if (SW5State == LOW) { | |
digitalWrite(LED3, LOW); | |
SW2Count = 0; | |
} | |
delay(10); // El retardo añadido ayuda a los simuladores a ejecutar este programa | |
} | |
/* Aprende Más -- Actividades de Análisis del Programa | |
1. La variable 'SW2Count' se define como una ubicación de memoria de 16 bits dentro de | |
la RAM del microcontrolador mediante la declaración del programa: 'int SW2Count = 0;' | |
¿Qué rango de números puede almacenar una variable int de 16 bits? ¿Qué sucederá | |
si intentas almacenar un número mayor que el límite superior de un 'int' en | |
la variable SW2Count? | |
2. La instrucción del programa 'const int maxCount = 50;' define una constante | |
del programa utilizando exactamente el mismo tipo de declaración que se usó para | |
definir los pines de E/S del microcontrolador. ¿Cómo crees que el | |
IDE de Arduino sabe que 'SW3' es un pin de E/S de hardware y que | |
'maxCount' es un número? No parece haber ninguna diferencia real | |
entre las dos declaraciones, entonces, ¿qué más podría llevar a que | |
SW3 y maxCount se interpreten de manera diferente? | |
3. La constante maxCount se utiliza al comienzo de una condición if: | |
if(SW2Count >= maxCount) { | |
La condición compara el valor de la variable SW2Count con | |
la constante maxCount para verificar si se ha alcanzado un límite. | |
Definir una constante para esto parece un trabajo extra cuando la | |
declaración condicional simplemente podría haberse escrito como: | |
if(SW2Count >= 50) { | |
¿Se te ocurren algunas ventajas de definir y usar la constante maxCount | |
en lugar de simplemente incrustar el número 50 en la | |
condición? Enumera al menos dos ventajas. | |
4. A primera vista, parece que este programa debería encender el LED D2 | |
e incrementar la variable SW2Count cada vez que se presiona SW2, | |
pero ese no es el caso. | |
Carga el programa y ejecútalo, contando mentalmente cuántas veces | |
presionaste SW2 hasta que se enciende el LED D3. El conteo y el LED D3 | |
se pueden reiniciar presionando SW5 para que puedas intentarlo varias veces. | |
¿El conteo llegó a 50? Si no, ¿puedes describir por qué o qué | |
podría estar sucediendo en el programa para que cuente mal? Puede que | |
obtengas alguna idea de lo que podría estar sucediendo | |
presionando y soltando rápidamente SW2 durante un intento de alcanzar | |
50, borrando el conteo con SW5 y luego repitiendo el intento | |
presionando y soltando SW2 lentamente. | |
5. Está bien si aún no has identificado ningún problema obvio con el | |
programa. Podemos agregar algo de código de depuración que podría ayudar a | |
descubrir la naturaleza del problema. Parece que el programa | |
está contando demasiado rápido. Para verificarlo, agreguemos otra condición para | |
apagar el LED D3 si el conteo se vuelve muy grande, digamos diez veces mayor | |
de lo esperado. Agregaremos esta nueva condición justo después de la | |
condición existente que enciende el LED D3, así: | |
// Enciende el LED D3 cuando se ha alcanzado el conteo máximo | |
if(SW2Count >= maxCount) { | |
digitalWrite(LED3,HIGH); | |
} | |
// Apaga el LED D3 si el conteo real es enorme. | |
if(SW2Count >= maxCount * 10) { | |
digitalWrite(LED3,LOW); | |
} | |
Ahora, mantén presionado el pulsador SW2 durante al menos 10 segundos mientras | |
observas el LED D3. El LED D3 debería permanecer apagado hasta que el valor de | |
la variable SW2Count se vuelva mayor que maxCount. Si el LED D3 se enciende, | |
debería permanecer encendido hasta que el valor de SW2Count se vuelva diez | |
veces mayor que maxCount. Si el LED D3 se apaga mientras aún mantienes | |
presionado SW2, el SW2Count debe ser al menos diez veces el valor de maxCount. | |
Si el LED D3 hace eso, ¿puedes explicar cómo el conteo podría llegar tan | |
alto mientras SW2 solo se presionó una vez? | |
6. Uno de los desafíos fundamentales al crear programas que se ejecutan | |
dentro de un bucle de programa principal es separar los eventos de entrada del | |
estado de entrada. Dado que el estado de SW2 se detecta en cada ciclo a través de | |
la función principal loop(), leer su estado como LOW simplemente significa que | |
el botón resultó estar presionado durante el ciclo actual del bucle. | |
Dado que los humanos somos lentos y los microcontroladores pueden ejecutar un | |
bucle simple como este muy rápido, es probable que el botón se lea | |
como presionado durante muchos ciclos a través del bucle. Esto explica por qué | |
SW2Count excede rápidamente maxCount. | |
Para resolver este problema, el programa no puede simplemente leer el estado | |
del interruptor y asumir que una entrada LOW es una nueva pulsación de botón. | |
En cambio, el programa tiene que identificar el cambio de una entrada HIGH a | |
una entrada LOW durante bucles sucesivos, ya que este *cambio* de estado | |
es el único indicador confiable de que ha ocurrido una nueva pulsación de botón. | |
Para hacer esto, se requiere una nueva variable para almacenar el estado del | |
botón del ciclo anterior a través del bucle. El tipo de variable más simple, | |
y uno que es ideal para esto, es una variable booleana (o bool). Las variables | |
booleanas almacenan uno de dos valores binarios; en el lenguaje de programación C, | |
los valores están representados por las palabras 'false' y 'true'. | |
A continuación, se muestra una función de entrada reescrita que incorpora la variable | |
booleana SW2Pressed que se ha predefinido en el encabezado del programa. | |
Reemplaza la primera estructura condicional 'if-else' de SW2 con las siguientes | |
dos nuevas estructuras condicionales 'if': | |
// Cuenta las pulsaciones del botón SW2 | |
if(SW2State == LOW && SW2Pressed == false) { | |
digitalWrite(LED2,HIGH); | |
SW2Pressed = true; | |
SW2Count += 1; | |
} | |
if(SW2State == HIGH) { | |
digitalWrite(LED2,LOW); | |
SW2Pressed = false; | |
} | |
La primera condición 'if' ahora combina lógicamente (AND) tanto el estado | |
actual del botón como la variable booleana SW2Pressed que representa | |
el estado anterior del botón. Usando esta lógica, el botón debe | |
estar actualmente presionado y su estado anterior debe ser falso | |
para que se cuente como una nueva pulsación de botón. Cuando ambas condiciones | |
se cumplen, el LED D2 se encenderá, la variable booleana SW2Pressed se | |
establecerá en 'true' y la variable SW2Count se incrementará en 1 | |
usando el operador compuesto en la instrucción 'SW2Count += 1;' | |
(esto produce el mismo resultado usando menos código que la instrucción original | |
'SW2Count = SW2Count + 1;'). | |
Observa que incluso si SW2State sigue siendo LOW la próxima vez que se pasa | |
por el bucle principal, la variable SW2Pressed siendo 'true' evitará que | |
la misma pulsación de botón se cuente más de una vez. Se utiliza una segunda | |
condición if para restablecer la variable booleana SW2Pressed a 'false' | |
cuando se ha soltado el interruptor. | |
Prueba estos nuevos bloques de código en tu programa y verifica que cada | |
pulsación de botón individual ahora se cuenta correctamente. | |
7. La declaración condicional en la primera condición if también se puede | |
escribir: | |
if(SW2State == LOW && !SW2Pressed) { | |
La expresión '!SW2Pressed' se lee como 'no SW2Pressed' y es | |
equivalente a que SW2Pressed sea falso (o *no verdadero*). De manera similar, | |
usar el nombre de la variable booleana SW2Pressed por sí solo es | |
equivalente a que sea verdadero. Intenta reemplazar la primera condición if | |
en tu programa con esta expresión y verifica que funcione como | |
se esperaba. | |
8. Las declaraciones de constantes, como las que se utilizan en la parte superior del programa | |
para asignar pines de E/S y establecer maxCount, también se pueden utilizar para | |
representar el estado de un pulsador. Hacer esto puede hacer que el código | |
del programa sea más fácil de leer. | |
Agrega las siguientes definiciones de constantes a la sección 'Define program | |
constants' del encabezado del programa: | |
const int pressed = LOW; | |
const int notPressed = HIGH; | |
Ahora, en lugar de comparar el estado del pulsador con 'LOW' o 'HIGH', | |
el estado del botón se puede comparar con una de estas definiciones | |
recién nombradas. Prueba el siguiente código en tu programa y luego | |
modifica el código del botón de reinicio SW5 para usar las mismas | |
definiciones 'pressed' y 'notPressed'. | |
// Cuenta las pulsaciones del botón SW2 | |
if(SW2State == pressed && !SW2Pressed) { | |
digitalWrite(LED2,HIGH); | |
SW2Pressed = true; | |
SW2Count += 1; | |
} | |
if(SW2State == notPressed) { | |
digitalWrite(LED2,LOW); | |
SW2Pressed = false; | |
} | |
9. ¿Puedes crear términos constantes similares 'on' y 'off' y usarlos | |
para controlar los LEDs en tu circuito? Por ejemplo, podrías escribir | |
'digitalWrite(LED2,on);' en lugar de 'digitalWrite(LED2,HIGH);'. | |
¿Cuándo podría no ser una buena idea usar 'on' u 'off' en lugar de | |
HIGH o LOW? | |
Actividades de Programación | |
1. Crea un juego de estilo "rapid-clicker" para dos jugadores utilizando este programa | |
como punto de partida. ¡El único propósito del juego será ver | |
qué jugador puede presionar un botón más rápido y convertirse en el primer | |
jugador en alcanzar el conteo máximo y ganar el juego! | |
Usa SW4 para el segundo jugador y enciende el LED D5 cuando se presiona el botón SW4. | |
Enciende el LED D4 para mostrar cuándo el conteo del segundo jugador | |
iguala el maxCount. | |
Comienza duplicando las variables del programa existentes para crear un | |
conjunto similar para el segundo jugador. Luego, crea copias de las | |
estructuras condicionales if para el segundo jugador y modifícalas para | |
usar las variables creadas para el segundo jugador. Finalmente, modifica | |
SW5 para reiniciar los conteos y los LEDs para ambos jugadores. | |
Nota: cuando uses ARPS-2 con Arduino UNO Rev 3, SW2 y SW3 no | |
serán utilizables. En este caso, usa SW4 y SW5 para los interruptores | |
de dos jugadores y el botón Reset (SW1) para reiniciar el juego. | |
2. Cuando dos jugadores igualados están jugando al "rapid-clicker", | |
puede ser difícil saber qué jugador alcanzó primero el valor | |
maxCount. Utiliza tu conocimiento de las variables booleanas para evitar | |
que más pulsaciones aumenten los conteos de los jugadores una vez que un | |
jugador ha alcanzado el conteo máximo. | |
3. Usa una variable booleana para crear un programa que simule el | |
funcionamiento de un botón de alternancia. Cada nueva pulsación del botón | |
de alternancia debe 'alternar' un LED a su estado opuesto. (Los botones | |
de alternancia se usan comúnmente como botones de encendido/apagado en | |
dispositivos digitales, como el botón de encendido que enciende y apaga | |
un monitor de computadora). | |
Presionar y mantener presionado el botón de alternancia solo debe hacer que | |
el LED cambie de estado, o se alterne, una vez, y no que se encienda y apague | |
rápidamente de forma continua. Prueba la acción de tu botón para verificar | |
su confiabilidad. | |
4. Se puede usar un botón multifunción para iniciar una acción cuando | |
se presiona, y una segunda acción o alternativa cuando se mantiene | |
presionado durante un cierto período de tiempo. Una forma de implementar | |
un botón multifunción es usar una variable que cuente los bucles de | |
programa cronometrados, ¡exactamente como lo hizo este programa inicialmente | |
(e involuntariamente)! | |
Crea un programa que implemente un botón multifunción para encender | |
un LED tan pronto como se presiona un botón, y enciende un segundo LED | |
si el botón se mantiene presionado durante más de un segundo. Haz que ambos | |
LEDs se apaguen cuando se suelta el botón. | |
5. ¿Rebotan tus pulsadores? El rebote de interruptor es el término utilizado para | |
describir los contactos del interruptor que se cierran y abren repetidamente | |
antes de asentarse en su estado final (cerrado). El rebote de interruptor en | |
el interruptor de luz de una habitación podría no ser una gran preocupación porque | |
sucede tan rápido que no notaríamos que las luces parpadean brevemente | |
antes de permanecer encendidas. Pero, el rebote de interruptor podría ser un | |
problema en un programa de botón de software porque la alta velocidad de | |
funcionamiento de un microcontrolador le permite ver cada cierre de contacto | |
como un evento nuevo y separado. Imagina si un botón de encendido configurado | |
como un botón de alternancia rebotara y cada pulsación tuviera entre 1 y 4 | |
cierres de contacto. El dispositivo no podría encenderse o apagarse de | |
manera confiable. | |
Para determinar si los pulsadores de tu circuito exhiben rebote de interruptor, | |
crea un programa que cuente el número de veces que se cierran los | |
contactos de un pulsador y luego muestre el |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment