Componentes · 5 min de lectura

Cómo usar un módulo joystick: leer los ejes X-Y y el botón con Arduino

¿Cómo funciona un módulo joystick analógico (KY-023)? Pines VRx, VRy y SW, conexión con Arduino, zona muerta y calibración, detección de direcciones, control de un servo con joystick y código para ESP32 y Pico.

Un módulo joystick es la versión para Arduino de las palancas de los mandos de videoconsola. Al mover la palanca a izquierda-derecha y adelante-atrás, da su posición en dos ejes, y al presionarla hacia abajo se activa un botón interno. Es el elemento de entrada más práctico para mandos de coches robot, soportes de cámara pan-tilt, juegos en matrices LED y menús de pantalla. El modelo más común también se conoce como KY-023.

Módulo joystick analógico KY-023
Módulo joystick analógico: lleva dos potenciómetros para los dos ejes y un botón que se activa al presionar la palanca; tiene 5 pines: GND, +5V, VRx, VRy y SW.

¿Cómo funciona un módulo joystick?

Bajo la palanca hay dos potenciómetros de 10 kΩ colocados en ángulo recto: uno detecta el movimiento en el eje X y el otro en el eje Y. Cada potenciómetro funciona como un divisor de tensión; con la palanca centrada, su cursor da unos 2,5 V y analogRead() lee unos 512. Al llevar la palanca a un extremo, el valor se acerca a 0; al otro, a 1023. Si presionas la palanca hacia abajo, un pequeño botón une el pin SW con GND.

Posición de la palancaVRx (X)VRy (Y)
Centro (suelta)~512~512
Todo a la izquierda~0~512
Todo a la derecha~1023~512
Todo arriba~512~0
Todo abajo~512~1023

Qué dirección da 0 y cuál da 1023 depende de cómo sujetes el módulo. Si con los pines hacia ti las direcciones no coinciden con esta tabla, no pasa nada: en el código puedes invertir un eje restando el valor de 1023.

Pines y conexión del joystick

PinFunciónArduino UnoESP32Raspberry Pi Pico
GNDTierraGNDGNDGND
+5VAlimentación5V3V33V3
VRxEje X (analógico)A0GPIO 34GP26
VRyEje Y (analógico)A1GPIO 35GP27
SWBotón (a GND al pulsar)D2GPIO 25GP15
En el ESP32 y la Pico alimenta el módulo desde el pin 3V3, no desde 5V; aunque el pin se llame «+5V», el módulo funciona sin problemas a 3,3 V. Si lo alimentas a 5 V, a los pines analógicos les llegarán más de 3,3 V y la placa puede estropearse. En el ESP32 no uses los pines 34–39 para SW; no tienen resistencia pull-up interna.

Leer el joystick con Arduino

El código siguiente lee los dos ejes y el botón y los muestra en el Monitor Serie. Como el botón se une a GND al pulsarlo y la mayoría de los módulos no llevan resistencia pull-up, el pin SW debe configurarse como INPUT_PULLUP; así se lee HIGH cuando está suelto y LOW cuando está pulsado.

Arduino (C++)
1const int X_PIN = A0;
2const int Y_PIN = A1;
3const int SW_PIN = 2;
4
5void setup() {
6  pinMode(SW_PIN, INPUT_PULLUP);   // basınca LOW / LOW when pressed
7  Serial.begin(9600);
8}
9
10void loop() {
11  int x = analogRead(X_PIN);       // 0–1023, ortada ~512 / ~512 at center
12  int y = analogRead(Y_PIN);
13  bool pressed = digitalRead(SW_PIN) == LOW;
14
15  Serial.print("X: ");  Serial.print(x);
16  Serial.print("  Y: "); Serial.print(y);
17  Serial.print("  Buton / button: ");
18  Serial.println(pressed ? "basılı / pressed" : "-");
19  delay(100);
20}
Si abres el Serial Plotter (trazador serie), verás los dos ejes en el mismo gráfico. Observar cómo cambian las dos líneas al girar la palanca despacio es la forma más rápida de entender la dirección de cada eje.

Zona muerta y calibración

En la práctica, con la palanca suelta el valor no es exactamente 512: marca algo como 495 o 525 y oscila unas unidades. Si no lo corriges, tu coche robot avanza solo o el servo tiembla aunque no toques el joystick. La solución tiene dos pasos: medir y guardar el valor central al arrancar (calibración) e ignorar las pequeñas desviaciones cerca del centro (zona muerta). La función siguiente convierte cada eje en un valor limpio de -100 a +100 con el centro exactamente en 0:

Arduino (C++)
1int centerX, centerY;
2const int DEAD_ZONE = 40;
3
4int readAxis(int pin, int center) {
5  int v = analogRead(pin) - center;
6  if (abs(v) < DEAD_ZONE) return 0;                              // ölü bölge / dead zone
7  if (v > 0) return map(v, DEAD_ZONE, 1023 - center, 0, 100);    // sağ ya da aşağı / right or down
8  return map(v, -center, -DEAD_ZONE, -100, 0);                   // sol ya da yukarı / left or up
9}
10
11void setup() {
12  Serial.begin(9600);
13  centerX = analogRead(A0);   // açılışta joystick'e dokunma / don't touch it at startup
14  centerY = analogRead(A1);
15}
16
17void loop() {
18  Serial.print(readAxis(A0, centerX));
19  Serial.print(", ");
20  Serial.println(readAxis(A1, centerY));
21  delay(50);
22}

Detectar direcciones: arriba, abajo, izquierda, derecha

En juegos y menús muchas veces solo necesitas la dirección, no la posición exacta. Comparando los valores con dos umbrales conviertes el joystick en una cruceta de cuatro direcciones. Para moverse por un menú conviene que cada empujón cuente como un solo paso, por eso el código usa una breve espera o no acepta un paso nuevo hasta que la palanca vuelve al centro.

Arduino (C++)
1void loop() {
2  int x = analogRead(A0);
3  int y = analogRead(A1);
4  if (x < 300)      Serial.println("Sol / left");
5  else if (x > 700) Serial.println("Sağ / right");
6  else if (y < 300) Serial.println("Yukarı / up");
7  else if (y > 700) Serial.println("Aşağı / down");
8  delay(150);
9}

Controlar un servomotor con el joystick

Convirtiendo un eje del joystick a 0–180 grados puedes mover un servo a mano; con dos ejes y dos servos montas un soporte pan-tilt que gira una cámara a izquierda-derecha y arriba-abajo. Para la conexión del servo y los avisos de alimentación, mira ¿Qué es un servomotor?

Arduino (C++)
1#include <Servo.h>
2
3Servo panServo;
4
5void setup() {
6  panServo.attach(9);
7}
8
9void loop() {
10  int x = analogRead(A0);
11  int angle = map(x, 0, 1023, 0, 180);   // joystick → açı / joystick → angle
12  panServo.write(angle);
13  delay(15);
14}

Joystick con el ESP32 y la Raspberry Pi Pico

El ADC del ESP32 es de 12 bits y da valores de 0 a 4095, pero como no es lineal, el centro suele salir en torno a 1800–1950 en lugar de 2048. Por eso la calibración anterior es todavía más importante en el ESP32. Si vas a usar Wi-Fi, conecta los ejes a pines ADC1 (GPIO 32–39). En la Pico las entradas analógicas son GP26–GP28 y read_u16() devuelve valores de 0 a 65535:

MicroPython
1from machine import ADC, Pin
2import time
3
4x_axis = ADC(26)                        # GP26 → VRx
5y_axis = ADC(27)                        # GP27 → VRy
6button = Pin(15, Pin.IN, Pin.PULL_UP)   # SW, basınca 0 / 0 when pressed
7
8while True:
9    x = x_axis.read_u16()               # 0–65535, ortada ~32768 / ~32768 at center
10    y = y_axis.read_u16()
11    print(x, y, "BASILI / PRESSED" if button.value() == 0 else "")
12    time.sleep(0.1)

Ideas de proyectos con joystick

  • Mando para coche robot: conecta el joystick a una placa emisora y envía órdenes al coche por nRF24L01 o Bluetooth.
  • Cámara pan-tilt: orienta una cámara en cualquier dirección con dos servos y un joystick.
  • Serpiente en una matriz LED: guía la serpiente por una matriz de 8x8 con el joystick.
  • Menú en pantalla: recorre las opciones con arriba y abajo y elige con el botón; para la pantalla, mira Cómo usar una pantalla LCD I2C.
  • Selector de color: controla un LED RGB eligiendo el color con el eje X y el brillo con el eje Y.
  • Ratón de ordenador: convierte el joystick en un ratón USB de verdad con un Arduino Leonardo o un Pro Micro.

Errores comunes y cómo solucionarlos

  • El botón parece pulsado sin estarlo: el pin SW no está en INPUT_PULLUP; el pin queda al aire y lee valores aleatorios.
  • En reposo no marca 512 y oscila: es normal; calibra al arrancar y añade una zona muerta.
  • Los ejes están invertidos o cambiados: depende de la orientación del módulo; resta el valor de 1023 o intercambia los cables de VRx y VRy.
  • En el ESP32 el centro no es 2048: el ADC del ESP32 no es lineal; mide el centro al arrancar y calcula a partir de él.
  • El servo tiembla o el Arduino se reinicia: el servo sobrecarga los 5 V del Arduino; aliméntalo con una fuente de 5 V aparte y une las tierras.

Un joystick no es más que dos potenciómetros y un botón, así que ¿Qué es un potenciómetro? y Cómo conectar un pulsador a Arduino refuerzan lo que has aprendido aquí. En la app BlueGrays encontrarás proyectos de control de LED y servo con joystick y un juego de la serpiente en matriz LED, con esquemas y código.

Preguntas frecuentes

¿Para qué sirven los pines del módulo joystick?

GND y +5V son los pines de alimentación. VRx y VRy dan la posición en los ejes X e Y como tensión analógica y van a pines analógicos. SW es la salida del botón, que se une a GND al presionar la palanca, y va a un pin digital configurado como INPUT_PULLUP.

¿Por qué mi joystick no marca exactamente 512 en el centro?

Los potenciómetros y la mecánica no son perfectos; en reposo el valor suele quedarse entre 490 y 530 y oscila unas unidades. Medir y guardar el valor central al arrancar y usar una zona muerta de ±30–50 resuelve el problema.

¿Por qué el pin SW cambia al azar entre LOW y HIGH?

La mayoría de los módulos joystick no tienen resistencia pull-up para el botón, así que el pin queda al aire como si no estuviera conectado. Activa la pull-up interna del Arduino con pinMode(SW_PIN, INPUT_PULLUP) y leerás HIGH suelto y LOW pulsado.

¿Cuántos servos puedo controlar con un joystick?

Un joystick tiene dos ejes, así que controla dos servos de forma independiente, ideal para una cámara pan-tilt. Para más servos añades un segundo joystick; los 6 pines analógicos del Arduino Uno alcanzan para hasta tres joysticks.

¿Puedo usar el joystick como mando inalámbrico?

Sí. Conecta el joystick a un Arduino y envía sus valores a otra placa con un módulo de radio nRF24L01, un módulo Bluetooth HC-05 o ESP-NOW entre dos ESP32. La mayoría de los proyectos de coches robot y radiocontrol se hacen así.

¿El módulo joystick funciona con el ESP32 y la Raspberry Pi Pico?

Sí, pero debes alimentarlo desde el pin 3V3. Los valores van de 0 a 4095 en el ESP32 y de 0 a 65535 en la Pico. En el ESP32 usa pines ADC1 (GPIO 32–39), que funcionan con el Wi-Fi activado, y calibra el centro al arrancar.

Ver todos los proyectos
Control Led con Joystick
#59Intermedio
Premium

Control Led con Joystick

Proyecto de control que enciende LEDs en 4 direcciones diferentes según los valores de los ejes X e Y del módulo joystick. Enseña la lectura analógica del joystick y la lógica de detección de direcció

4.7(50)
66
Servocontrol con joystick
#60Intermedio
Premium

Servocontrol con joystick

Proyecto Pan-tilt que controla independientemente dos servomotores en los ejes X e Y con módulo joystick. Enseña la lógica de integración joystick-servo y seguimiento de posición.

4.7(42)
58
Serpiente de píxeles Matriz 8x8
#88Avanzado
Premium

Serpiente de píxeles Matriz 8x8

Juego de serpiente por hardware basado en Arduino desarrollado utilizando una matriz de LEDs 8x8 WS2812B NeoPixel y un joystick analógico. Incluye un algoritmo dinámico de velocidad y controles matemá

4.7(39)
57
Matriz Snake 16x16
#89Avanzado
Premium

Matriz Snake 16x16

Se trata de un puerto de hardware extendido de 256 píxeles del clásico juego de la serpiente que se ejecuta en una matriz de 16x16 WS2812B NeoPixel. En este proyecto, que se controla mediante Arduino

4.8(52)
67
Servomotor ESP32 (control mediante potenciómetro)
#118Intermedio
Premium

Servomotor ESP32 (control mediante potenciómetro)

En este proyecto controlamos un servomotor SG90 mediante un potenciómetro. Ajustamos el ángulo del servo asignando el valor analógico leído en el potenciómetro al rango de 0 a 180 grados. Gracias a la biblioteca ESP32Servo, cualquier GPIO del ESP32 puede generar una señal PWM. Este es un método de control básico para brazos robóticos, cardanes de cámara y mecanismos de puertas automáticas.

4.3(29)
42
Juego Pong - SSD1306
#86Intermedio
Premium

Juego Pong - SSD1306

El clásico juego Pong construido con Arduino y una pantalla OLED SSD1306, equipado con un oponente autónomo de inteligencia artificial (CPU) que sigue instantáneamente los movimientos de la bola y rea

4.5(47)
65
OLED T-Rex Run: Arduino Dinosaurio Juego 🦖
#87Avanzado
Premium

OLED T-Rex Run: Arduino Dinosaurio Juego 🦖

¡Llevamos el legendario juego de dinosaurios "Sin Internet" al hardware! Convierte la emoción de los juegos retro en una miniconsola física con este proyecto que hemos desarrollado utilizando Arduino,

4.7(33)
53
Juego Arduino LCD Runner
#98Intermedio
Premium

Juego Arduino LCD Runner

Juego endless runner de desplazamiento lateral que se ejecuta en una pantalla LCD de 6x2 caracteres. El héroe corre automáticamente, el jugador salta los obstáculos pulsando el botón. Aparecen obstáculos aleatorios en las filas superior e inferior. El zumbador pasivo reproduce la melodía de apertura, el sonido de salto, el sonido de celebración de 50 puntos y la melodía de fin de partida. La pantalla de inicio "BlueGrays - Arduino Projects" se muestra al arrancar. La puntuación se actualiza inst

4.7(31)
53

Aprende a leer los dos potenciómetros y el botón de un joystick, corregir la deriva del centro con una zona muerta, detectar direcciones y controlar un servomotor con el joystick.

Cómo usar un módulo joystick: leer los ejes X-Y y el botón con Arduino | BlueGrays