Creando un menú con botones para tu microcontrolador

En este tutorial construimos un menú con un total de 4 botones y 1 pantalla LCD para que tu microcontrolador controle un programa en ejecución.

En este tutorial construimos un menú con un total de 4 botones y 1 pantalla LCD para que tu microcontrolador Arduino, ESP8266 o ESP32 controle un programa en ejecución.

El artículo se divide en dos partes:

  1. El cableado del microcontrolador, los botones y la pantalla LCD para crear un menú.
  2. Crear el script del programa para controlar variables predefinidas como una temperatura.

Cómo crear un menú con botones para un microcontrolador

Se me ocurrió la idea de un menú cuando planifiqué un nuevo proyecto de controlador de temperatura para mi ahumador. Pensé que sería genial no solo mostrar la temperatura actual de múltiples sondas de temperatura en la pantalla LCD, sino también darme una descripción general de la temperatura objetivo seleccionada para la carne. Esto es importante porque los diferentes tipos de carne tienen diferentes temperaturas objetivo.

También puede transferir mi ejemplo al área de la casa inteligente. Por ejemplo, también puede tener un menú para mostrar la temperatura y la humedad de diferentes habitaciones en su hogar, con cada pantalla en la pantalla mostrando estadísticas de una habitación. Y si la humedad excede un umbral preestablecido, que se puede configurar con el menú, obtienes una alarma en tu teléfono.

En este tutorial, usamos un menú con 4 botones:

Función de color del botón

La izquierdaAzulMuestra la pantalla del menú anterior.
Hacia abajoRojoDisminuir el valor de la pantalla del menú
En altoVerdeIncrementar el valor de la pantalla del menú
A la derechaAmarilloMuestra la siguiente pantalla de menú.

La siguiente imagen muestra los botones en una maqueta para este tutorial. En un proyecto real, soldaría los botones en una placa de circuito con forma de plus.

Botones de menú

Cableado entre botones y microcontrolador para crear un menú

La siguiente tabla le brinda una descripción general de todos los componentes y partes que utilicé para este tutorial. Recibo comisiones por compras realizadas a través de los enlaces de esta tabla.

Arduino NanoAmazonAliExpress
Arduino Pro MiniAmazonAliExpress
Arduino UnoAmazonAliExpress
Arduino MegaAmazonAliExpress
ESP32 ESP-WROOM-32AmazonAliExpress
ESP8266 NodeMCUAmazonAliExpress
ESP8266 WeMos D1 MiniAmazonAliExpress
Kit de botonesAmazonAliexpress
Pantalla LCD de 20×4AmazonAliexpress
Pantalla LCD 16×2AmazonAliexpress

Para este proyecto estoy usando diferentes placas Arduino. Pero puede usar cualquier microcontrolador que desee, como ESP8266 o ESP32. El siguiente bosquejo fritzing muestra la conexión entre las placas Arduino, los 4 botones y la pantalla LCD.

Estoy usando una pantalla LCD de 20 × 4 con comunicación L2C. Si también está interesado en las pantallas LCD en general, le recomiendo que consulte mi tutorial sobre pantallas LCD.

  • Arduino Nano
  • Arduino Pro Mini
  • Arduino Uno
  • Arduino Mega

Arduino Nano

Menú con botones Arduino Nano

Para obtener más información sobre Arduino Nano, visite el tutorial de Arduino Nano.

Arduino Pro Mini

Menú con botones Arduino Pro Mini

Arduino Uno

Menú con botones de Arduino Uno

Para obtener más información sobre Arduino Uno, visite el tutorial de Arduino Uno.

Arduino Mega

Menú con Mega Botones Arduino

Para obtener más información sobre Arduino Mega, visite el tutorial de Arduino Mega.

La pantalla LCD está conectada a través de la interfaz I2C a las placas Arduino para la comunicación y transmisión de datos entre el microcontrolador y la pantalla LCD. Usamos el pin de 5V para la potencia de la pantalla.

Los cuatro botones diferentes están conectados a un pin digital en la placa Arduino. En mi caso, estoy usando los pines de E / S digitales 5 a 8 para la conexión. Si está utilizando otros pines digitales, asegúrese de cambiar también el código del programa.

No utilizo resistencias para la conexión a los botones. En su lugar, utilizo la resistencia pull-up interna de la placa Arduino. La función del pull-up interno es la siguiente: Si no se presiona el botón, la resistencia de pull-up interna se conecta a 5V. Por lo tanto, Arduino reporta ALTO. Sin embargo, si presionamos el botón, el pin Arduino se tira a tierra y señala BAJO. Necesitamos recordar esto más adelante en la parte de programación de este tutorial.

Script de programa para crear un menú multipantalla

Ahora vamos a sumergirnos en el programa Arduino. Este script es un poco más complicado porque la parte difícil no es la conexión entre la pantalla, los botones y el microcontrolador, sino el script para crear la lógica del menú. Pero que no cunda el pánico, repasamos el guión paso a paso y describo cada pequeño detalle.

#include "LiquidCrystal_I2C.h"
LiquidCrystal_I2C lcd(0x27, 16, 4);

const int buttonPinLeft = 5;
const int buttonPinDown = 6;
const int buttonPinUp = 7;
const int buttonPinRight = 8;

int buttonStateLeft = 0; 
int buttonStateDown = 0;
int buttonStateUp = 0;
int buttonStateRight = 0;


const int numOfScreens = 4;
int currentScreen = 0;
String screens[numOfScreens][2] = {{"Value_1","Unit_1"}, {"Value_2", "Unit_2"}, {"Value_3","Unit_3"}, {"Value_4","Unit_4"}};
int parameters[numOfScreens] = {0, 10, 50, 100};


void setup() {
  Serial.begin(9600);
  lcd.init();   // initializing the LCD
  lcd.backlight(); // Enable or Turn On the backlight

  pinMode(buttonPinLeft, INPUT_PULLUP);
  pinMode(buttonPinDown, INPUT_PULLUP);
  pinMode(buttonPinUp, INPUT_PULLUP);
  pinMode(buttonPinRight, INPUT_PULLUP);

  lcd.clear();
  lcd.setCursor(4,1);
  lcd.print("THIS IS THE");
  lcd.setCursor(3,2);
  lcd.print("MENU TUTORIAL");
  delay(5000);
  lcd.clear();
}

void loop() {
  buttonStateLeft = digitalRead(buttonPinLeft);
  buttonStateDown = digitalRead(buttonPinDown);
  buttonStateUp = digitalRead(buttonPinUp);
  buttonStateRight = digitalRead(buttonPinRight);
  
  if(buttonStateLeft == LOW){
    lcd.clear();
    if (currentScreen == 0) {
      currentScreen = numOfScreens-1;
    } else {
      currentScreen--;
    }
}
  
  else if (buttonStateDown == LOW){
    lcd.clear();
    parameters[currentScreen]--;
}
    
  else if (buttonStateUp == LOW){
    lcd.clear();
    parameters[currentScreen]++;
}

  else if (buttonStateRight == LOW){
    lcd.clear();
    if (currentScreen == numOfScreens-1) {
      currentScreen = 0;
    } else {
      currentScreen++;
    }
}
  
  printScreen();
  delay(200);
}


void printScreen() {
  if (currentScreen == 3) {
    lcd.setCursor(0,0);
    lcd.print(screens[0][0]);
    lcd.print(": ");
    lcd.print(parameters[0]);
    lcd.print(" ");
    lcd.print(screens[0][1]);

    lcd.setCursor(0,1);
    lcd.print(screens[1][0]);
    lcd.print(": ");
    lcd.print(parameters[1]);
    lcd.print(" ");
    lcd.print(screens[1][1]);

    lcd.setCursor(0,2);
    lcd.print(screens[2][0]);
    lcd.print(": ");
    lcd.print(parameters[2]);
    lcd.print(" ");
    lcd.print(screens[2][1]);

    lcd.setCursor(0,3);
    lcd.print(screens[3][0]);
    lcd.print(": ");
    lcd.print(parameters[3]);
    lcd.print(" ");
    lcd.print(screens[3][1]);
  }
  else {
    lcd.setCursor(0,0);
    lcd.print("MENU TOTORIAL");
    lcd.setCursor(0,2);
    lcd.print(screens[currentScreen][0]);
    lcd.setCursor(0,3);
    lcd.print(parameters[currentScreen]);
    lcd.print(" ");
    lcd.print(screens[currentScreen][1]);
  }
}

Primero, importamos la biblioteca necesaria para la comunicación LCD I2C y creamos un objeto LiquidCrystal_I2C. El objeto tiene un total de tres variables:

  • Dirección hexadecimal I2C: 0x27
    En mi caso, la pantalla LCD del menú I2C está conectada a la dirección hexadecimal 0x27. Esta es la dirección predeterminada para esta pantalla. O puede probar el script con la misma dirección, puede encontrar la dirección I2C Hex con un escáner de direcciones I2C Hex. Puede encontrar el script y la descripción del escáner de direcciones hexadecimales I2C en este artículo.
  • Dígitos seguidos: 20 y número de líneas: 4
    En mi caso, estoy usando una pantalla LCD de 20 × 4. Si estás usando una pantalla de 16 × 2, debes cambiar el código porque estamos usando más de 2 líneas de la pantalla.

Si no sabe cómo instalar la biblioteca LiquidCrystal_I2C, encontrará un tutorial paso a paso en este artículo.

Ahora definimos un total de 4 variables diferentes con el número de pin para saber en qué señal los diferentes botones envían su estado al Arduino. Por ejemplo, el botón de abajo está conectado al pin 6.

Las variables buttonState almacenan el estado actual del botón. Al comienzo del script, los botones tienen el estado 0. Si se presiona un botón, obtiene el estado 1. Con este estado, sabemos más adelante en el script qué botón se ha presionado y puede desencadenar la reacción.

Una vez que nos preocupamos por los botones, llegamos a las pantallas. La primera variable define el número de pantallas que queremos mostrar. En este caso, queremos crear 4 pantallas. La segunda variable define la pantalla que se muestra al inicio del programa. Definimos la pantalla 0. Y aquí está el primer obstáculo, porque ahora estamos creando una matriz bidimensional. En cada una de las 4 pantallas queremos registrar 2 variables. Las 2 variables son un valor y una unidad y pueden ser temperatura y kelvin. La variable de pantalla actual es 0 porque accedemos al primer elemento de una matriz en Arduino con 0 y no 1.

La siguiente tabla muestra la matriz bidimensional.

0 1

numOfScreens0Valor_1 = 0Unidad 1
1Valor_2 = 10Unidad 2
2Valor_3 = 50Unidad 3
3Valor_4 = 100Unidad 4

La última variable que declaramos es una matriz que almacena el valor actual de la pantalla. Como tenemos 4 pantallas en total, almacenamos 4 valores que se pueden aumentar o disminuir.

Una vez definidas todas las variables nos encargamos de la función de configuración que solo funcionará una vez cuando se inicie el microcontrolador. Primero establecemos la velocidad en baudios en 9600, lo que significa que podemos ver los valores en el monitor en serie con una velocidad de datos de 9600 bits por segundo. Por tanto, la velocidad de transmisión definida en la función de configuración y en el monitor serie debe ser síncrona.
Después de configurar la velocidad en baudios, inicializamos la pantalla LCD y encendemos la luz de fondo.
Luego inicializamos los 4 botones con sus pines y activamos la resistencia pull-up interna para que no necesitemos una resistencia extra para nuestro circuito.

Para la función de configuración, queremos escribir un texto breve en las pantallas. Primero limpiamos la pantalla complete y coloque el cursor en la segunda línea del número 4. Aquí imprimimos la primera parte del texto. Luego colocamos el cursor en la siguiente línea y como la segunda parte de la prueba es más larga, colocamos el cursor en el número de 3 dígitos e imprimimos la segunda parte del texto. El texto se muestra durante 5 segundos y después de este tiempo se borra la pantalla.

Ahora entramos en la función de ciclo completo que, por supuesto, se procesa una y otra vez. Las primeras 4 líneas de la función de bucle se utilizan para leer el estado actual de los botones. Si se presiona un botón, la variable buttonState es BAJA y reaccionamos a continuación con la reacción de acuerdo con el botón presionado y luego ejecutamos la función printScreen que se explicará en la siguiente sección de este tutorial de menú.
Primero discutimos las declaraciones buttonStateLeft y buttonStateRight. Ingresamos el primero si se presiona el botón y despejamos la pantalla para mostrar la nueva pantalla sin la información anterior. Pour le bouton gauche, nous diminuons le pointeur pour afficher l’écran avant, mais lorsque le pointeur est déjà sur le premier écran (currentScreen == 0), nous voulons afficher le dernier écran pour obtenir une rotation sans fin que vous connaissez depuis votre teléfono móvil. Para el botón derecho, queremos mostrar la siguiente pantalla. Es por eso que estamos aumentando la variable currentScreen. Si llegamos a la última pantalla, también mostramos la primera pantalla para obtener la funcionalidad de un bucle sin fin en las pantallas.
Ahora queremos discutir qué sucede si presionamos el botón hacia arriba o hacia abajo. Primero limpiamos la pantalla, luego aumentamos o disminuimos el valor de la pantalla actual. La matriz correspondiente que definimos anteriormente almacena los valores de los cambios. Por lo tanto, para cada pantalla podemos cambiar el valor.

La función printScreen tiene muchas líneas pero es bastante simple y directa. Primero comprobamos si estamos en la última pantalla número 3. Si es así, queremos mostrar cada número y cada unidad fila por fila. Por lo tanto, colocamos el cursor en la primera línea e imprimimos el nombre del número, el número y la unidad. Hacemos esto línea por línea cambiando el cursor.
Si no estamos en la última pantalla, queremos mostrar el título “MENÚ TOTORIAL” en la primera línea y usar las dos últimas líneas para mostrar el nombre del número, número y unidad.

Sé que estos tutoriales pueden ser un poco secos, pero en el siguiente video puedes ver el menú de botones en acción. Me ves pasar por todas las pantallas y cambiar los valores. Siempre que se cambia un valor, también se almacena y no se sobrescribe a partir de los valores iniciales.

En este tutorial, te mostré cómo crear un menú básico con 4 botones, una pantalla LCD y un Arduino Nano. Por supuesto, estos son los básicos, pero a partir de ahí puedes crear tu propio menú y soluciones aún más complejas. Si tiene problemas para crear su menú o tiene preguntas generales sobre este tutorial, no dude en utilizar la sección de comentarios a continuación para hacer sus preguntas. Les respondo lo antes posible.


4 comentarios en «Creando un menú con botones para tu microcontrolador»

  1. Hola, ¿Cómo hacer para que en la pantalla aparezcas únicamente «MENU TUTORIAL», y (Value_1 0 Unit_1) pase a la otra pantalla y también cómo podría agregar un submenu en algunas de ellas?.

    Saludos…

    Responder
    • Para hacer que en la pantalla aparezca únicamente «MENU TUTORIAL», una opción podría ser crear una variable booleana que indique si se está mostrando el menú principal o un submenú. Al inicio, se configuraría esta variable como verdadera para indicar que se está mostrando el menú principal.

      Luego, en el código que se encarga de mostrar la pantalla, se podría hacer uso de esta variable para determinar qué información se muestra. Por ejemplo:

      if (mostrandoMenuPrincipal) {
      // Mostrar "MENU TUTORIAL" en la pantalla
      } else {
      // Mostrar el contenido del submenú
      }

      Para pasar a la otra pantalla, se podría hacer uso de una función que cambie el valor de la variable booleana y actualice la información que se muestra en la pantalla. Por ejemplo:

      void mostrarSubmenu() {
      mostrandoMenuPrincipal = false;
      // Actualizar la información de la pantalla para mostrar el submenú
      }

      Para agregar un submenú en algunas de las pantallas, se podría hacer uso de la misma técnica descrita anteriormente. Simplemente se necesitaría crear una nueva variable booleana que indique si se está mostrando un submenú en particular y modificar el código que muestra la pantalla de acuerdo a ese valor.

      Es importante tener en cuenta que la forma en que se implemente esto dependerá del microcontrolador que estés utilizando y de la librería gráfica que estés empleando. Por lo tanto, es posible que sea necesario adaptar esta solución a las características específicas de tu proyecto.

      Responder
  2. Buenas tardes amino no sé nada de Arduino me gustaría que me alludaras con una ide para bajar y subir las pwm y que se me muestre en la pantalla tengo una LCD 16×2 con i2c

    Responder
    • Para controlar las señales PWM y mostrar la información en una pantalla LCD con controlador I2C, puedes seguir los siguientes pasos:

      1. Conecta la pantalla LCD con el controlador I2C a tu microcontrolador. Asegúrate de que tengas los componentes necesarios, como resistencias de pull-up para el bus I2C.
      2. Configura el microcontrolador para generar señales PWM. Esto puede variar dependiendo del microcontrolador que estés usando, pero en general necesitarás configurar el canal PWM, el período y el ciclo de trabajo.
      3. En tu programa, crea un bucle que lea un valor de entrada, lo procese y lo utilice para ajustar el ciclo de trabajo de la señal PWM. Por ejemplo, puedes leer un valor de un potenciómetro y usarlo para ajustar la intensidad de un LED conectado al canal PWM.
      4. Utiliza la librería de control de pantalla LCD con controlador I2C para escribir en la pantalla el valor actual del ciclo de trabajo de la señal PWM. Asegúrate de configurar la pantalla para mostrar el número con el formato adecuado (por ejemplo, como un porcentaje).

      Espero que esta información te sea útil. Si tienes alguna duda o necesitas más detalles, no dudes en preguntar.

      Responder

Deja un comentario