El Matouch 1.28″ ToolSet_Controller es una placa de desarrollo compacta ESP32-S3 con muchas características. Cuenta con una pantalla táctil RGB redonda de 1,28 pulgadas con un anillo codificador rotatorio, Wi-Fi, Bluetooth 5.0 y retroalimentación háptica por vibración. También incluye un RTC, ranura para tarjeta micro-SD y conectores para I²C, UART, SPI y GPIO.
En esta guía de inicio aprenderás cómo configurar la placa para programarla con el Arduino IDE. Dos ejemplos de código te mostrarán cómo usar la pantalla, la pantalla táctil, el codificador rotatorio y el motor para la retroalimentación háptica.
Vamos a empezar …
Partes necesarias
Necesitarás una placa Matouch 1.28″ ToolSet_Controller de Makerfabs y un cable USB-C para programar la placa y probar los ejemplos de código.

Matouch 1.28″ ToolSet_Controller

Cable USB C
Makerguides is a participant in affiliate advertising programs designed to provide a means for sites to earn advertising fees by linking to Amazon, AliExpress, Elecrow, and other sites. As an Affiliate we may earn from qualifying purchases.
El Matouch 1.28″ ToolSet_Controller
El Matouch 1.28″ ToolSet_Controller está potenciado por el microcontrolador ESP32-S3, que cuenta con procesamiento de doble núcleo junto con conectividad Wi-Fi y Bluetooth 5.0. En su centro hay una pantalla IPS RGB redonda de 1,28 pulgadas con una resolución de 240 por 240 píxeles. La pantalla soporta toque capacitivo para una interacción precisa. Alrededor de la pantalla hay un anillo codificador rotatorio con función de botón pulsador, que permite una entrada intuitiva como desplazamiento, ajuste de volumen o navegación por menús.

Componentes del Matouch 1.28″ ToolSet_Controller
Además de la pantalla y el control rotatorio, la placa integra un motor de vibración háptica que proporciona retroalimentación táctil. Un reloj en tiempo real (RTC) asegura una medición precisa del tiempo incluso cuando el dispositivo está en modo de suspensión profunda. Para almacenamiento local de datos, la ranura para tarjeta micro-SD facilita el registro de información o almacenamiento de medios.

La placa mide 60 por 60 milímetros. Este diseño compacto y cuadrado facilita su integración en controladores portátiles, herramientas de escritorio e interfaces de usuario. La expansión está soportada mediante conectores accesibles para pines I²C, UART, SPI y GPIO, que permiten el uso de sensores externos, actuadores u otros módulos. La alimentación se gestiona mediante un sistema a bordo que soporta tanto USB Tipo-C como operación con batería externa, pero sin circuito de carga.
Pinout del Matouch 1.28″ ToolSet_Controller
La imagen a continuación muestra el pinout del Matouch 1.28″ ToolSet_Controller. Hay 15 pines GPIO y pines de alimentación de 5V o 3.3V disponibles:

El Matouch 1.28″ ToolSet_Controller es ideal para proyectos que necesitan una interfaz pequeña pero capaz. Aplicaciones típicas incluyen un controlador multimedia de escritorio para ajustar volumen o cambiar pistas, un panel de control para hogar inteligente o una herramienta de configuración de dispositivos.
Especificaciones técnicas
La tabla a continuación resume las especificaciones técnicas de la placa.
| Especificación | Detalles |
|---|---|
| Microcontrolador | ESP32-S3 de doble núcleo, Xtensa LX7 |
| Conectividad inalámbrica | Wi-Fi 802.11 b/g/n, Bluetooth 5.0 |
| Pantalla | IPS RGB redonda de 1.28″, 240 × 240 píxeles, táctil capacitiva |
| Entrada rotatoria | Anillo codificador rotatorio con botón pulsador |
| Vibración | Motor háptico |
| Almacenamiento | Ranura para tarjeta micro-SD |
| Reloj | Reloj en tiempo real (RTC) |
| Expansión | I²C, UART, SPI, GPIO |
| Alimentación | USB Tipo-C, batería externa |
| Dimensiones | 60 × 60 mm |
| Soporte open-source | Arduino IDE, proyectos de ejemplo en GitHub |
Finalmente, puedes encontrar los esquemas del Matouch 1.28″ ToolSet_Controller en el siguiente enlace:
Instalación del Core ESP32
Si este es tu primer proyecto con una placa de la serie ESP32, necesitarás instalar primero el core ESP32. Si ya tienes placas ESP32 instaladas en tu Arduino IDE, puedes saltarte esta sección.
Comienza abriendo el diálogo de Preferencias seleccionando “Preferences…” en el menú “File”. Esto abrirá el diálogo de Preferencias que se muestra a continuación.
En la pestaña Settings encontrarás un cuadro de edición en la parte inferior del diálogo etiquetado “Additional boards manager URLs“:

En este campo copia la siguiente URL:
https://espressif.github.io/arduino-esp32/package_esp32_dev_index.json
Esto permitirá que el Arduino IDE sepa dónde encontrar las librerías core del ESP32. A continuación instalaremos las placas ESP32 usando el Gestor de Placas.
Abre el Gestor de Placas vía «Tools -> Boards -> Board Manager». Verás el Gestor de Placas en la barra lateral izquierda. Escribe «ESP32» en el campo de búsqueda en la parte superior y deberías ver dos tipos de placas ESP32; las «Arduino ESP32 Boards» y las placas «esp32 de Espressif». Queremos las librerías «esp32 de Espressif». Haz clic en el botón INSTALL y espera hasta que la descarga e instalación se completen.

Selección de placa
Finalmente necesitamos seleccionar una placa ESP32. En el caso del Matouch 1.28″ ToolSet_Controller, elegimos el módulo genérico «ESP32S3 Dev Module». Para ello, haz clic en el menú desplegable y luego en «Select other board and port…»:

Esto abrirá un diálogo donde puedes escribir «esp32s3 dev» en la barra de búsqueda. Verás la placa «ESP32S3 Dev Module» bajo Boards. Haz clic en ella y en el puerto COM para activarla y luego haz clic en OK:

Ten en cuenta que debes conectar la placa mediante el cable USB a tu ordenador antes de poder seleccionar un puerto COM.
Instalar librería Adafruit GFX
Una vez que tienes el código ESP32 instalado, el siguiente paso es instalar la Arduino_GFX librería de moononournation, que usaremos para dibujar en la pantalla Matouch 1.28″. Abre el LIBRARY MANAGER, escribe «GFX Library for Arduino» en la barra de búsqueda, encuentra la «GFX Library for Arduino» de Moon y haz clic en el botón INSTALL:

Ahora todo está listo para escribir y ejecutar código en el Matouch 1.28″ ToolSet_Controller.
Código para Encoder, Motor y Pantalla
En este primer sketch aprenderás a usar la pantalla, el encoder y el motor para la retroalimentación háptica.

Usaremos el anillo del encoder para cambiar el brillo de la pantalla entre 1% y 100% y mostraremos el valor de brillo en la pantalla. Una breve vibración indicará si el anillo se gira demasiado (<1%, >100%). Finalmente, pulsar el botón del encoder alternará la pantalla encendida o apagada. La foto a continuación muestra la pantalla apagada, con brillo al 4% y al 100%:

Echa un vistazo rápido al código completo primero y luego discutiremos sus detalles:
#include <Arduino_GFX_Library.h>
#define TFT_BLK 45
#define TFT_RES 21
#define TFT_CS 1
#define TFT_MOSI 2
#define TFT_MISO -1
#define TFT_SCLK 42
#define TFT_DC 46
#define ENCODER_BTN 17
#define ENCODER_CLK 48
#define ENCODER_DT 47
#define MOTOR_PIN 41
int brightness = 50;
bool btn_display = true;
int enc_state = 0;
int old_state = -1;
bool has_changed = true;
Arduino_ESP32SPI *bus = new Arduino_ESP32SPI(TFT_DC, TFT_CS, TFT_SCLK,
TFT_MOSI, TFT_MISO, HSPI, true);
Arduino_GFX *gfx = new Arduino_GC9A01(bus, TFT_RES, 0 /* rotation */, true /* IPS */);
void encoder_irq() {
enc_state = digitalRead(ENCODER_CLK);
if (enc_state != old_state) {
brightness = digitalRead(ENCODER_DT) == enc_state ? brightness + 1 : brightness - 1;
}
old_state = enc_state;
has_changed = true;
}
void button_irq() {
btn_display = !btn_display;
has_changed = true;
}
void draw_text() {
gfx->setTextSize(2);
gfx->setCursor(60, 55);
gfx->println(F("Makerguides"));
}
void limit_brightness() {
if (brightness > 100 || brightness < 0) {
digitalWrite(MOTOR_PIN, HIGH);
delay(50);
digitalWrite(MOTOR_PIN, LOW);
}
brightness = constrain(brightness, 0, 100);
}
void update_brightness() {
gfx->fillRect(65, 95, 120, 65, WHITE);
gfx->setTextSize(6);
gfx->setCursor(65, 100);
gfx->printf("%3d", brightness);
int b = map(brightness, 0, 100, 1, 255);
analogWrite(TFT_BLK, btn_display ? b : 0);
}
void init_display() {
gfx->begin();
gfx->fillScreen(WHITE);
gfx->setTextColor(BLACK);
}
void init_pins() {
pinMode(TFT_BLK, OUTPUT);
digitalWrite(TFT_BLK, HIGH);
pinMode(MOTOR_PIN, OUTPUT);
pinMode(ENCODER_BTN, INPUT);
pinMode(ENCODER_CLK, INPUT);
pinMode(ENCODER_DT, INPUT);
attachInterrupt(ENCODER_CLK, encoder_irq, CHANGE);
attachInterrupt(ENCODER_BTN, button_irq, FALLING);
}
void setup(void) {
Serial.begin(115200);
init_pins();
init_display();
draw_text();
}
void loop() {
if (has_changed) {
has_changed = false;
limit_brightness();
update_brightness();
}
}
Importaciones
El programa comienza incluyendo la librería gráfica para la pantalla redonda GC9A01. Este encabezado incluye los controladores de pantalla, constantes de color como WHITE, BLACK, o RED, y primitivas de dibujo.
#include <Arduino_GFX_Library.h>
Constantes de Pines y Hardware
Constantes nombradas asignan etiquetas significativas a los pines GPIO del ESP32. Definen el pin PWM para la retroiluminación TFT, reset, chip-select, pines SPI, datos/comando de pantalla, el botón pulsador del codificador rotatorio y dos canales de cuadratura, y el pin de control del motor de vibración. Definirlos aquí una vez hace el resto del código más legible.
#define TFT_BLK 45 #define TFT_RES 21 #define TFT_CS 1 #define TFT_MOSI 2 #define TFT_MISO -1 #define TFT_SCLK 42 #define TFT_DC 46 #define ENCODER_BTN 17 #define ENCODER_CLK 48 #define ENCODER_DT 47 #define MOTOR_PIN 41
Variables de Estado Global
Algunas variables globales guardan el brillo actual, estado de encendido/apagado de la pantalla, el nivel lógico más reciente del encoder y su valor previo, y una bandera “dirty” que indica al bucle principal cuando algo cambió debido a una interrupción. El brillo inicial es 50%, la pantalla comienza activada, y old_state se inicializa con un valor imposible (-1) para que la primera lectura del encoder se considere un cambio.
int brightness = 50; bool btn_display = true; int enc_state = 0; int old_state = -1; bool has_changed = true;
Objetos de Bus y Driver de Pantalla
Dos objetos configuran la pantalla. Arduino_ESP32SPI configura el bus SPI y los pines de control para el TFT. El constructor selecciona los pines DC, CS, SCLK, MOSI y MISO, el periférico HSPI y habilita DMA para transferencias más rápidas. Arduino_GC9A01 es el driver específico para el panel redondo de 1.28″; recibe el objeto del bus SPI, el pin de reset, rotación y bandera IPS. El objeto resultante gfx expone métodos de dibujo usados en todo el sketch.
Arduino_ESP32SPI *bus = new Arduino_ESP32SPI(TFT_DC, TFT_CS, TFT_SCLK,
TFT_MOSI, TFT_MISO, HSPI, true);
Arduino_GFX *gfx = new Arduino_GC9A01(bus, TFT_RES, 0 /* rotation */, true /* IPS */);
Rutina de Servicio de Interrupción: encoder_irq
Esta ISR se ejecuta cada vez que cambia la línea CLK del encoder. Lee el nivel actual de CLK y lo compara con el anterior. Si hubo una transición, mira la línea DT para determinar la dirección: cuando DT es igual al nuevo nivel de CLK, el brillo incrementa, de lo contrario decrementa. Luego recuerda el nuevo estado y marca la UI como cambiada para que el bucle principal pueda redibujar y aplicar el nuevo brillo. Usar una ISR hace que el encoder sea sensible sin esperar activamente en loop().
void encoder_irq() {
enc_state = digitalRead(ENCODER_CLK);
if (enc_state != old_state) {
brightness = digitalRead(ENCODER_DT) == enc_state ? brightness + 1 : brightness - 1;
}
old_state = enc_state;
has_changed = true;
}
Rutina de Servicio de Interrupción: button_irq
Esta ISR alterna si la pantalla debe estar encendida. Cada flanco de bajada en el botón pulsador del encoder invierte btn_display y marca que hubo un cambio para que el bucle principal actualice la pantalla y la retroiluminación.
void button_irq() {
btn_display = !btn_display;
has_changed = true;
}
Ayudante de Dibujo: draw_text
Este ayudante coloca una etiqueta fija “Makerguides” cerca de la parte superior de la pantalla redonda. Establece un tamaño de texto pequeño, mueve el cursor e imprime la cadena desde memoria flash (F() macro).
void draw_text() {
gfx->setTextSize(2);
gfx->setCursor(60, 55);
gfx->println(F("Makerguides"));
}
Ayudante Lógico: limit_brightness
Esta función aplica el rango válido de brillo y señala hápticamente cuando el usuario intenta ir más allá. Si el valor actual está fuera de [0, 100], activa brevemente el motor de vibración para indicar el límite, luego ajusta el valor al rango usando constrain. La retroalimentación del motor solo se activa cuando se detecta una condición fuera de rango, así que los topes “vibran” pero los pasos normales no.
void limit_brightness() {
if (brightness > 100 || brightness < 0) {
digitalWrite(MOTOR_PIN, HIGH);
delay(50);
digitalWrite(MOTOR_PIN, LOW);
}
brightness = constrain(brightness, 0, 100);
}
Actualización de UI y Retroiluminación: update_brightness
Esta función refresca la lectura numérica en pantalla y aplica el nuevo nivel PWM de retroiluminación. Primero pinta un rectángulo blanco sobre el número anterior para borrarlo limpiamente, establece un tamaño de texto mayor, posiciona el cursor e imprime el brillo como un valor de tres dígitos alineado a la derecha. Luego mapea 0–100% al rango PWM 1–255 y escribe ese ciclo de trabajo al pin de retroiluminación. Si la pantalla ha sido apagada con el botón pulsador, fuerza el ciclo de trabajo a cero para apagar la retroiluminación sin cambiar el valor almacenado de brillo.
void update_brightness() {
gfx->fillRect(65, 95, 120, 65, WHITE);
gfx->setTextSize(6);
gfx->setCursor(65, 100);
gfx->printf("%3d", brightness);
int b = map(brightness, 0, 100, 1, 255);
analogWrite(TFT_BLK, btn_display ? b : 0);
}
Inicialización de Pantalla: init_display
Al iniciar, se inicializa el driver de pantalla, se limpia la pantalla a blanco y se establece el color de texto predeterminado a negro. Estos pasos garantizan un estado conocido antes de renderizar cualquier elemento de UI.
void init_display() {
gfx->begin();
gfx->fillScreen(WHITE);
gfx->setTextColor(BLACK);
}
Inicialización de Pines y Cableado de Interrupciones: init_pins
Aquí se configuran todos los modos GPIO. El pin de retroiluminación se establece como salida y se pone en alto inicialmente para que el panel sea visible durante el arranque. El pin del motor se configura como salida. Los pines del botón pulsador del encoder, CLK y DT son entradas. Nota que el encoder tiene resistencias pull-up internas de 10K, por lo que INPUT_PULLUP no es necesario aquí (aunque aparece en algunos ejemplos).

Finalmente, se adjuntan interrupciones de hardware: el CLK del encoder usa CHANGE para capturar flancos de subida y bajada para máxima resolución, mientras que el botón usa FALLING para activarse una vez por pulsación. Esta configuración mantiene el bucle principal simple y sensible.
void init_pins() {
pinMode(TFT_BLK, OUTPUT);
digitalWrite(TFT_BLK, HIGH);
pinMode(MOTOR_PIN, OUTPUT);
pinMode(ENCODER_BTN, INPUT);
pinMode(ENCODER_CLK, INPUT);
pinMode(ENCODER_DT, INPUT);
attachInterrupt(ENCODER_CLK, encoder_irq, CHANGE);
attachInterrupt(ENCODER_BTN, button_irq, FALLING);
}
Setup
La función setup() inicializa el puerto serial para depuración, configura pines e interrupciones, prepara la pantalla y dibuja la etiqueta estática. Después de setup(), el dispositivo está listo para responder a movimientos del encoder y pulsaciones del botón.
void setup(void) {
Serial.begin(115200);
init_pins();
init_display();
draw_text();
}
Bucle Principal
El loop() es intencionadamente mínimo. Solo reacciona cuando una ISR ha marcado has_changed. Cuando esa bandera está activa, la limpia, aplica límites de brillo con retroalimentación háptica si es necesario, y actualiza tanto el número en pantalla como el PWM de retroiluminación. Este patrón evita redibujos y escrituras PWM innecesarias, manteniendo la UI ágil y eficiente en consumo.
void loop() {
if (has_changed) {
has_changed = false;
limit_brightness();
update_brightness();
}
}
Cómo el Encoder Controla el Brillo y la Retroalimentación Háptica
El encoder proporciona dos señales de onda cuadrada, CLK y DT, cuya fase relativa indica dirección. En cada transición de CLK, la ISR compara DT con el nuevo nivel de CLK para decidir si sumar o restar uno a brightness. Cuando el usuario gira más allá de los extremos, limit_brightness() activa el motor de vibración por 50 milisegundos y ajusta el valor para que se mantenga dentro de [0, 100]. El valor numérico en pantalla siempre refleja el número ajustado, mientras que el brillo visible real proviene del PWM en TFT_BLK, que se establece al ciclo de trabajo mapeado o a cero cuando el botón pulsador ha apagado la pantalla.
Código para Pantalla Táctil
En este siguiente ejemplo de código aprenderás a usar la pantalla táctil. Escribiremos el texto «Touch» en el centro de la pantalla y dibujaremos un círculo negro donde se toque la pantalla. La foto a continuación muestra la pantalla del controlador antes y después de algunos eventos táctiles:

Como antes, te sugiero echar un vistazo rápido al código completo antes de discutir los detalles:
#include <Wire.h>
#include <Arduino_GFX_Library.h>
#define TFT_BLK 45
#define TFT_RES 21
#define TFT_CS 1
#define TFT_MOSI 2
#define TFT_MISO -1
#define TFT_SCLK 42
#define TFT_DC 46
#define TOUCH_INT 40
#define TOUCH_SDA 38
#define TOUCH_SCL 39
#define TOUCH_RST 18
#define MOTOR_PIN 41
Arduino_ESP32SPI *bus = new Arduino_ESP32SPI(TFT_DC, TFT_CS, TFT_SCLK,
TFT_MOSI, TFT_MISO, HSPI, true);
Arduino_GFX *gfx = new Arduino_GC9A01(bus, TFT_RES, 0 /* rotation */, true /* IPS */);
int read_touch(int *x, int *y) {
byte data_raw[7];
i2c_read(0x15, 0x02, data_raw, 7);
int event = data_raw[1] >> 6;
if (event == 2) {
*x = (int)data_raw[2] + (int)(data_raw[1] & 0x0f) * 256;
*y = (int)data_raw[4] + (int)(data_raw[3] & 0x0f) * 256;
return 1;
}
return 0;
}
int i2c_read(uint16_t addr, uint8_t reg_addr, uint8_t *reg_data, uint32_t length) {
Wire.beginTransmission(addr);
Wire.write(reg_addr);
if (Wire.endTransmission(true))
return -1;
Wire.requestFrom(addr, length, true);
for (int i = 0; i < length; i++) {
*reg_data++ = Wire.read();
}
return 0;
}
void init_pins() {
pinMode(TFT_BLK, OUTPUT);
digitalWrite(TFT_BLK, HIGH);
Wire.begin(TOUCH_SDA, TOUCH_SCL);
pinMode(MOTOR_PIN, OUTPUT);
}
void init_display() {
gfx->begin();
gfx->fillScreen(WHITE);
gfx->setTextColor(BLACK);
gfx->setTextSize(3);
gfx->setCursor(80, 105);
gfx->print(F("Touch"));
}
void setup(void) {
Serial.begin(115200);
init_pins();
init_display();
}
void loop() {
static int x, y;
if (read_touch(&x, &y) == 1) {
gfx->fillCircle(x, y, 5, BLACK);
digitalWrite(MOTOR_PIN, HIGH);
delay(20);
digitalWrite(MOTOR_PIN, LOW);
}
}
Importaciones
El programa incluye la librería I²C para comunicarse con el controlador táctil y la misma librería gráfica que viste antes para dibujar en la pantalla circular GC9A01. La librería Wire proporciona begin, beginTransmission, write, endTransmission, y requestFrom para acceso a nivel de registro I²C, mientras que Arduino_GFX_Library.h incluye el driver de pantalla, primitivas de dibujo y constantes de color que usaste antes.
#include <Wire.h> #include <Arduino_GFX_Library.h>
Constantes de Pines y Hardware
Los pines de pantalla reflejan el sketch anterior e identifican la retroiluminación, reset, chip-select SPI y líneas de bus, y el pin D/C. Constantes adicionales definen la interrupción del controlador táctil, SDA, SCL y pines de reset. El pin del motor nuevamente controla el motor de vibración háptica. En este sketch la interrupción táctil y las líneas de reset están definidas por completitud, pero solo se usan las líneas I²C.
#define TFT_BLK 45 #define TFT_RES 21 #define TFT_CS 1 #define TFT_MOSI 2 #define TFT_MISO -1 #define TFT_SCLK 42 #define TFT_DC 46 #define TOUCH_INT 40 #define TOUCH_SDA 38 #define TOUCH_SCL 39 #define TOUCH_RST 18 #define MOTOR_PIN 41
Objetos de Bus y Driver de Pantalla
La configuración de pantalla sigue el mismo patrón que antes. Un objeto Arduino_ESP32SPI conecta el periférico HSPI del ESP32 con los pines elegidos y DMA habilitado, y un objeto Arduino_GC9A01 controla el panel IPS redondo de 1.28″. El objeto resultante gfx expone la misma API de dibujo que ya usaste.
Arduino_ESP32SPI *bus = new Arduino_ESP32SPI(TFT_DC, TFT_CS, TFT_SCLK,
TFT_MOSI, TFT_MISO, HSPI, true);
Arduino_GFX *gfx = new Arduino_GC9A01(bus, TFT_RES, 0 /* rotation */, true /* IPS */);
Lector Táctil: read_touch
Esta función consulta el controlador táctil vía I²C, analiza un paquete y devuelve las coordenadas táctiles mediante parámetros puntero. Primero lee siete bytes comenzando en el registro 0x02 del dispositivo con dirección 0x15. El controlador codifica un “evento” en los dos bits superiores del byte alto de X; desplazando seis bits se obtiene ese código de evento.
Solo cuando el evento es igual a 2 la función trata el paquete como un contacto válido y calcula las coordenadas. La posición X se forma tomando el byte bajo y sumando los cuatro bits bajos del byte alto multiplicados por 256, reconstruyendo una coordenada típica de 12 bits; Y se decodifica igual desde sus bytes alto y bajo.
Cuando se decodifica un toque válido, la función almacena x y y mediante los punteros y devuelve 1. Para cualquier otro evento devuelve 0.
int read_touch(int *x, int *y) {
byte data_raw[7];
i2c_read(0x15, 0x02, data_raw, 7);
int event = data_raw[1] >> 6;
if (event == 2) {
*x = (int)data_raw[2] + (int)(data_raw[1] & 0x0f) * 256;
*y = (int)data_raw[4] + (int)(data_raw[3] & 0x0f) * 256;
return 1;
}
return 0;
}
Ayudante I²C: i2c_read
Este ayudante realiza una transacción común de “escribir registro, luego leer datos”. Comienza una transmisión a la dirección de 7 bits, escribe la dirección del registro y verifica endTransmission. Un resultado distinto de cero indica error y devuelve -1. Luego solicita el número especificado de bytes y los extrae de Wire.read() al buffer del llamador, devolviendo finalmente 0 para éxito. Esta es la pieza de bajo nivel que read_touch usa para obtener el paquete táctil.
int i2c_read(uint16_t addr, uint8_t reg_addr, uint8_t *reg_data, uint32_t length) {
Wire.beginTransmission(addr);
Wire.write(reg_addr);
if (Wire.endTransmission(true))
return -1;
Wire.requestFrom(addr, length, true);
for (int i = 0; i < length; i++) {
*reg_data++ = Wire.read();
}
return 0;
}
Inicialización de Pines y Bus: init_pins
La configuración GPIO refleja el sketch anterior para la retroiluminación y motor. El pin de retroiluminación se configura como salida y se pone en alto para que la pantalla sea visible inmediatamente. El pin del motor se configura como salida listo para pulsos hápticos. El bus I²C se inicia en los pines SDA y SCL especificados usando Wire.begin(TOUCH_SDA, TOUCH_SCL), que selecciona los pines alternativos del ESP32 definidos para el controlador táctil. No se adjunta interrupción táctil aquí; este sketch opta por sondeo simple.
void init_pins() {
pinMode(TFT_BLK, OUTPUT);
digitalWrite(TFT_BLK, HIGH);
Wire.begin(TOUCH_SDA, TOUCH_SCL);
pinMode(MOTOR_PIN, OUTPUT);
}
Inicialización de Pantalla: init_display
El arranque de pantalla sigue los mismos pasos que viste antes. Se inicia el driver gfx, se limpia la pantalla a blanco y se establece el color de texto a negro. Se dibuja una etiqueta amigable “Touch” en el centro usando un tamaño de texto mayor para indicar la interacción esperada. La macro F() mantiene el literal en memoria flash.
void init_display() {
gfx->begin();
gfx->fillScreen(WHITE);
gfx->setTextColor(BLACK);
gfx->setTextSize(3);
gfx->setCursor(80, 105);
gfx->print(F("Touch"));
}
Setup
El inicio es similar en estructura al sketch anterior. Se abre el puerto serial para depuración, se inicializan pines y el bus I²C, y se prepara y etiqueta la pantalla. Después de que setup retorna, el dispositivo está listo para sondear toques y dibujar la retroalimentación.
void setup(void) {
Serial.begin(115200);
init_pins();
init_display();
}
Bucle
El bucle principal sondea continuamente el controlador táctil y reacciona inmediatamente cuando se reporta un contacto válido. Las variables x y y se declaran static para que su almacenamiento persista entre iteraciones, permitiendo que read_touch escriba mediante los punteros.
Cuando read_touch devuelve 1, se dibuja un círculo negro relleno de radio cinco píxeles en las coordenadas reportadas para marcar el toque. Un pulso corto de 20 milisegundos activa el motor de vibración para proporcionar confirmación háptica del toque.
void loop() {
static int x, y;
if (read_touch(&x, &y) == 1) {
gfx->fillCircle(x, y, 5, BLACK);
digitalWrite(MOTOR_PIN, HIGH);
delay(20);
digitalWrite(MOTOR_PIN, LOW);
}
}
Cómo se Relaciona Esto con el Sketch Anterior
La creación de la pantalla, inicialización, API de dibujo y control del motor siguen los mismos patrones que ya usaste. En lugar de interrupciones del encoder y una bandera has_changed, este sketch sondea el controlador táctil vía I²C y activa la retroalimentación háptica en cada contacto válido en lugar de en un tope de brillo.
La retroiluminación simplemente se habilita y no se modula por PWM, porque aquí no hay estado de brillo. Los pines de interrupción táctil y reset están definidos pero no se usan; añadir una interrupción externa en TOUCH_INT podría permitir dormir entre toques, mientras que usar TOUCH_RST podría realizar un reset hardware del IC táctil si fuera necesario.
Conclusiones
En este tutorial aprendiste cómo empezar con el Matouch 1.28″ ToolSet_Controller. Los dos ejemplos de código sobre la pantalla, la pantalla táctil, el codificador rotatorio y la retroalimentación háptica deberían facilitarte arrancar tu propio proyecto.
No discutimos Wi-Fi, Bluetooth 5.0, la tarjeta SD ni el soporte RTC en este tutorial. Pero puedes encontrar ejemplos en Makerfabs’s Github repo for the Matouch display. Si quieres aprender más sobre codificadores rotatorios, echa un vistazo a nuestro tutorial How To Interface A Quadrature Rotary Encoder.
La base cuadrada del Matouch 1.28″ ToolSet_Controller puede ser un poco grande para algunas aplicaciones. Si buscas una pantalla similar con codificador rotatorio pero base redonda, mira el CrowPanel 1.28inch-HMI ESP32 Rotary Display. Y si solo necesitas una pantalla redonda (sin el anillo codificador rotatorio), el tutorial Digital Clock on CrowPanel 1.28″ Round Display puede ser útil.
De lo contrario, no dudes en dejar cualquier pregunta en la sección de comentarios.
¡Feliz bricolaje! 😉

