The Matouch 1.28″ ToolSet_Controller è una scheda di sviluppo compatta ESP32-S3 con molte funzionalità. Dispone di un touchscreen RGB rotondo da 1,28 pollici con anello encoder rotativo, Wi-Fi, Bluetooth 5.0 e feedback aptico tramite vibrazione. Sono presenti anche un RTC, uno slot per schede micro-SD e connettori per I²C, UART, SPI e GPIO.
In questa guida introduttiva imparerai come configurare la scheda per la programmazione con Arduino IDE. Due esempi di codice ti mostreranno come utilizzare il display, il touchscreen, l’encoder rotativo e il motore per il feedback aptico.
Iniziamo…
Componenti necessari
Ti serviranno una scheda Matouch 1.28″ ToolSet_Controller di Makerfabs e un cavo USB-C per programmare la scheda e provare gli esempi di codice.

Matouch 1.28″ ToolSet_Controller

Cavo 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.
Il Matouch 1.28″ ToolSet_Controller
Il Matouch 1.28″ ToolSet_Controller è alimentato dal microcontrollore ESP32-S3, che offre un processore dual-core insieme a connettività Wi-Fi e Bluetooth 5.0. Al centro c’è un display RGB IPS rotondo da 1,28 pollici con risoluzione 240×240 pixel. Il display supporta il tocco capacitivo per un’interazione precisa. Intorno al display c’è un anello encoder rotativo con funzione di pulsante integrato, che consente input intuitivi come lo scorrimento, la regolazione del volume o la navigazione nei menu.

Componenti del Matouch 1.28″ ToolSet_Controller
Oltre al display e al controllo rotativo, la scheda integra un motore di vibrazione aptica che fornisce feedback tattile. Un orologio in tempo reale (RTC) garantisce una misurazione precisa del tempo anche in modalità deep sleep. Per l’archiviazione locale, lo slot per schede micro-SD facilita il logging di informazioni o l’archiviazione di media.

La scheda misura 60×60 millimetri. Questo design compatto e quadrato la rende facile da integrare in controller portatili, strumenti da scrivania e interfacce utente. L’espansione è supportata tramite connettori accessibili per I²C, UART, SPI e pin GPIO, che permettono l’uso di sensori esterni, attuatori o altri moduli. L’alimentazione è gestita da un sistema onboard che supporta sia USB Type-C sia batterie esterne, ma senza circuito di ricarica.
Pinout del Matouch 1.28″ ToolSet_Controller
L’immagine seguente mostra il pinout del Matouch 1.28″ ToolSet_Controller. Sono disponibili 15 pin GPIO e pin di alimentazione a 5V o 3,3V:

Il Matouch 1.28″ ToolSet_Controller è ideale per progetti che richiedono un’interfaccia piccola ma potente. Applicazioni tipiche includono un controller multimediale da scrivania per regolare il volume o cambiare traccia, un pannello di controllo per smart home o uno strumento di configurazione dispositivi.
Specifiche tecniche
La tabella seguente riassume le specifiche tecniche della scheda.
| Specifiche | Dettagli |
|---|---|
| Microcontrollore | ESP32-S3 dual-core, Xtensa LX7 |
| Wireless | Wi-Fi 802.11 b/g/n, Bluetooth 5.0 |
| Display | IPS RGB rotondo da 1,28″, 240 × 240 pixel, touch capacitivo |
| Input rotativo | Anello encoder rotativo con pulsante integrato |
| Vibrazione | Motore aptico |
| Archiviazione | Slot per scheda micro-SD |
| Orologio | Orologio in tempo reale (RTC) |
| Espansione | I²C, UART, SPI, GPIO |
| Alimentazione | USB Type-C, batteria esterna |
| Dimensioni | 60 × 60 mm |
| Supporto open-source | Arduino IDE, progetti di esempio su GitHub |
Infine, puoi trovare lo schema elettrico del Matouch 1.28″ ToolSet_Controller al seguente link:
Installazione del Core ESP32
Se è il tuo primo progetto con una scheda della serie ESP32, devi prima installare il core ESP32. Se le schede ESP32 sono già installate nel tuo Arduino IDE, puoi saltare questa sezione.
Inizia aprendo la finestra Preferenze selezionando “Preferences…” dal menu “File”. Si aprirà la finestra Preferenze mostrata qui sotto.
Nella scheda Settings troverai una casella di testo in fondo alla finestra etichettata “Additional boards manager URLs“:

In questo campo incolla il seguente URL:
https://espressif.github.io/arduino-esp32/package_esp32_dev_index.json
Questo permetterà all’Arduino IDE di sapere dove trovare le librerie core ESP32. Successivamente installeremo le schede ESP32 tramite il Boards Manager.
Apri il Boards Manager tramite “Tools -> Boards -> Board Manager”. Vedrai il Boards Manager apparire nella barra laterale sinistra. Digita “ESP32” nel campo di ricerca in alto e dovresti vedere due tipi di schede ESP32; le “Arduino ESP32 Boards” e le schede “esp32 di Espressif”. Noi vogliamo le “esp32 libraries di Espressif”. Clicca sul pulsante INSTALL e attendi che il download e l’installazione siano completati.

Selezione della scheda
Infine dobbiamo selezionare una scheda ESP32. Nel caso del Matouch 1.28″ ToolSet_Controller, scegliamo il generico “ESP32S3 Dev Module”. Per farlo, clicca sul menu a tendina e poi su “Select other board and port…”:

Si aprirà una finestra di dialogo dove puoi digitare “esp32s3 dev” nella barra di ricerca. Vedrai la scheda “ESP32S3 Dev Module” sotto Boards. Cliccaci sopra, seleziona la porta COM per attivarla e poi clicca OK:

Nota che devi collegare la scheda al computer tramite cavo USB prima di poter selezionare una porta COM.
Installazione della libreria Adafruit GFX
Una volta installato il core ESP32, il passo successivo è installare la Arduino_GFX library di moononournation, che useremo per disegnare sul display Matouch 1.28″. Apri il LIBRARY MANAGER, digita “GFX Library for Arduino” nella barra di ricerca, trova la “GFX Library for Arduino” di Moon e clicca sul pulsante INSTALL:

Ora tutto è pronto per scrivere ed eseguire codice sul Matouch 1.28″ ToolSet_Controller.
Codice per Encoder, Motore e Display
In questo primo sketch imparerai come usare il display, l’encoder e il motore per il feedback aptico.

Useremo l’anello encoder per cambiare la luminosità del display tra 1% e 100% e mostreremo il valore di luminosità sul display. Una breve vibrazione segnalerà se l’anello viene ruotato oltre i limiti (<1%, >100%). Infine, premendo il pulsante dell’encoder si accenderà o spegnerà il display. La foto sotto mostra il display spento, con luminosità al 4% e al 100%:

Dai prima un’occhiata veloce al codice completo e poi ne discuteremo i dettagli:
#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();
}
}
Importazioni
Il programma inizia includendo la libreria grafica per il display rotondo GC9A01. Questa libreria include i driver del display, costanti di colore come WHITE, BLACK, o RED, e primitive di disegno.
#include <Arduino_GFX_Library.h>
Costanti per pin e hardware
Costanti nominate associano etichette significative ai pin GPIO dell’ESP32. Definiscono il pin PWM per il backlight TFT, reset, chip-select, pin SPI, dati/comando display, il pulsante dell’encoder rotativo e i due canali quadrature, e il pin di controllo del motore di vibrazione. Definirli qui rende il codice più leggibile.
#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
Variabili di stato globali
Alcune variabili globali tengono la luminosità corrente, lo stato acceso/spento del display, il livello logico più recente dell’encoder e il valore precedente, e un flag “dirty” che indica al loop principale quando qualcosa è cambiato a causa di un interrupt. La luminosità iniziale è 50%, il display parte acceso, e old_state è inizializzato a un valore impossibile (-1) così la prima lettura dell’encoder sarà vista come un cambiamento.
int brightness = 50; bool btn_display = true; int enc_state = 0; int old_state = -1; bool has_changed = true;
Oggetti bus display e driver
Due oggetti configurano il display. Arduino_ESP32SPI configura il bus SPI e i pin di controllo per il TFT. Il costruttore seleziona i pin DC, CS, SCLK, MOSI e MISO, sceglie la periferica HSPI e abilita DMA per trasferimenti più veloci. Arduino_GC9A01 è il driver specifico per il pannello rotondo da 1,28″; riceve l’oggetto bus SPI, il pin reset, la rotazione e il flag IPS. L’oggetto risultante gfx espone i metodi di disegno usati in tutto lo 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 */);
Routine di servizio interrupt: encoder_irq
Questa ISR viene eseguita ogni volta che cambia la linea CLK dell’encoder. Legge il livello CLK corrente e lo confronta con il precedente. Se c’è stata una transizione, controlla la linea DT per determinare la direzione: quando DT è uguale al nuovo livello CLK la luminosità aumenta, altrimenti diminuisce. Ricorda il nuovo stato e segna l’interfaccia come cambiata così il loop principale può ridisegnare e applicare la nuova luminosità. Usare un ISR rende l’encoder reattivo senza dover attendere attivamente in 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;
}
Routine di servizio interrupt: button_irq
Questo ISR commuta lo stato acceso/spento del display. Ogni fronte di discesa sul pulsante dell’encoder inverte btn_display e segnala che è avvenuto un cambiamento così il loop principale aggiornerà schermo e retroilluminazione.
void button_irq() {
btn_display = !btn_display;
has_changed = true;
}
Helper per il disegno: draw_text
Questo helper posiziona un’etichetta fissa “Makerguides” vicino alla parte superiore del display rotondo. Imposta una dimensione testo piccola, sposta il cursore e stampa la stringa dalla memoria flash (F() macro).
void draw_text() {
gfx->setTextSize(2);
gfx->setCursor(60, 55);
gfx->println(F("Makerguides"));
}
Helper logico: limit_brightness
Questa funzione applica il range valido per la luminosità e segnala apticamente quando l’utente tenta di superarlo. Se il valore corrente è fuori dall’intervallo [0, 100], attiva brevemente il motore di vibrazione per indicare il limite, poi limita il valore usando constrain. Il feedback del motore si attiva solo quando si rileva una condizione fuori range, quindi gli stop finali “vibrano” ma i passaggi normali no.
void limit_brightness() {
if (brightness > 100 || brightness < 0) {
digitalWrite(MOTOR_PIN, HIGH);
delay(50);
digitalWrite(MOTOR_PIN, LOW);
}
brightness = constrain(brightness, 0, 100);
}
Aggiornamento UI e retroilluminazione: update_brightness
Questa funzione aggiorna la lettura numerica sullo schermo e applica il nuovo livello PWM al backlight. Prima dipinge un rettangolo bianco sopra il numero precedente per cancellarlo, imposta una dimensione testo più grande, posiziona il cursore e stampa la luminosità come valore a tre cifre allineato a destra. Poi mappa 0–100% nell’intervallo PWM 1–255 e scrive quel duty cycle sul pin del backlight. Se il display è stato spento con il pulsante, forza il duty cycle a zero per spegnere il backlight senza modificare il valore di luminosità memorizzato.
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);
}
Inizializzazione display: init_display
All’avvio, il driver del display viene inizializzato, lo schermo viene pulito con bianco e il colore testo predefinito impostato su nero. Questi passaggi garantiscono uno stato di disegno noto prima di renderizzare gli elementi UI.
void init_display() {
gfx->begin();
gfx->fillScreen(WHITE);
gfx->setTextColor(BLACK);
}
Inizializzazione pin e collegamento interrupt: init_pins
Qui vengono configurate tutte le modalità GPIO. Il pin del backlight è impostato come output e inizialmente portato alto così il pannello è visibile all’avvio. Il pin del motore è output. I pin pulsante, CLK e DT dell’encoder sono input. Nota che l’encoder ha resistenze di pull-up interne da 10K, quindi INPUT_PULLUP non è necessario qui (anche se appare in alcuni esempi).

Infine, gli interrupt hardware sono collegati: l’encoder CLK usa CHANGE per catturare sia fronti di salita che di discesa per massima risoluzione, mentre il pulsante usa FALLING per attivarsi una volta per pressione. Questa configurazione mantiene il loop principale semplice e reattivo.
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 funzione setup() inizializza la seriale per il debug, configura pin e interrupt, prepara il display e disegna l’etichetta statica. Dopo setup(), il dispositivo è pronto a rispondere ai movimenti dell’encoder e alle pressioni del pulsante.
void setup(void) {
Serial.begin(115200);
init_pins();
init_display();
draw_text();
}
Loop principale
Il loop() è volutamente minimale. Reagisce solo quando un ISR ha segnato has_changed. Quando il flag è impostato, lo resetta, applica i limiti di luminosità con feedback aptico se necessario, e aggiorna sia il numero sullo schermo sia il PWM del backlight. Questo schema evita ridisegni e scritture PWM inutili, mantenendo l’interfaccia reattiva ed efficiente.
void loop() {
if (has_changed) {
has_changed = false;
limit_brightness();
update_brightness();
}
}
Come l’encoder controlla luminosità e aptica
L’encoder fornisce due segnali a onda quadra, CLK e DT, la cui fase relativa indica la direzione. Ad ogni transizione di CLK, l’ISR confronta DT con il nuovo livello CLK per decidere se aggiungere o sottrarre uno da brightness. Quando l’utente supera i limiti, limit_brightness() fa vibrare il motore per 50 millisecondi e limita il valore nell’intervallo [0, 100]. Il valore numerico sul display riflette sempre il numero limitato, mentre la luminosità visibile deriva dal PWM su TFT_BLK, che è impostato al duty cycle mappato o a zero quando il pulsante ha spento il display.
Codice per Touch Screen
Nel prossimo esempio di codice imparerai come usare il touchscreen del display. Scriveremo la parola “Touch” al centro del display e disegneremo un cerchio nero dove il display viene toccato. La foto sotto mostra il display del controller prima e dopo alcuni tocchi:

Come prima, ti suggerisco di dare un’occhiata veloce al codice completo prima di discuterne i dettagli:
#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);
}
}
Importazioni
Il programma include la libreria I²C per comunicare con il controller touch e la stessa libreria grafica vista prima per disegnare sul display rotondo GC9A01. La libreria Wire fornisce begin, beginTransmission, write, endTransmission, e requestFrom per l’accesso a basso livello ai registri I²C, mentre Arduino_GFX_Library.h include il driver display, primitive di disegno e costanti colore già usate.
#include <Wire.h> #include <Arduino_GFX_Library.h>
Costanti per pin e hardware
I pin del display sono gli stessi dello sketch precedente e identificano il backlight, reset, chip-select SPI e linee bus, e il pin D/C. Altre costanti definiscono l’interrupt del controller touch, SDA, SCL e pin reset. Il pin motore controlla ancora il motore di vibrazione aptica. In questo sketch le linee di interrupt e reset del touch sono definite per completezza, ma vengono usate solo le linee 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
Oggetti bus display e driver
La configurazione del display segue lo stesso schema di prima. Un oggetto Arduino_ESP32SPI collega la periferica HSPI dell’ESP32 con i pin scelti e DMA abilitato, e un oggetto Arduino_GC9A01 guida il pannello IPS rotondo da 1,28″. L’oggetto risultante gfx espone la stessa API di disegno già usata.
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 */);
Lettore touch: read_touch
Questa funzione interroga il controller touch via I²C, analizza un pacchetto e restituisce le coordinate del tocco tramite parametri puntatore. Legge prima sette byte a partire dal registro 0x02 all’indirizzo dispositivo 0x15. Il controller codifica un “evento” nei due bit più alti del byte alto X; spostando di sei si ottiene il codice evento.
Solo quando l’evento è uguale a 2 la funzione considera il pacchetto come un contatto valido e calcola le coordinate. La posizione X si forma prendendo il byte basso e aggiungendo i quattro bit bassi del byte alto moltiplicati per 256, ricostruendo una coordinata tipica a 12 bit; Y è decodificato allo stesso modo dai suoi byte alto e basso.
Quando viene decodificato un tocco valido, la funzione memorizza x e y tramite i puntatori e restituisce 1. Per ogni altro evento restituisce 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;
}
Helper I²C: i2c_read
Questo helper esegue una comune transazione “scrivi registro, poi leggi dati”. Inizia una trasmissione all’indirizzo a 7 bit, scrive l’indirizzo registro e controlla endTransmission. Un risultato diverso da zero segnala un errore e restituisce -1. Poi richiede il numero specificato di byte e li preleva da Wire.read() nel buffer del chiamante, infine restituisce 0 per successo. Questo è il pezzo a basso livello su cui read_touch si basa per ottenere il pacchetto touch.
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;
}
Inizializzazione pin e bus: init_pins
La configurazione GPIO rispecchia lo sketch precedente per il backlight e il motore. Il pin backlight è impostato come output e portato alto così lo schermo è subito visibile. Il pin motore è configurato come output pronto per impulsi aptici. Il bus I²C è avviato sui pin SDA e SCL specificati usando Wire.begin(TOUCH_SDA, TOUCH_SCL), che seleziona i pin alternativi ESP32 definiti per il controller touch. Qui non è collegato alcun interrupt touch; questo sketch usa il polling semplice.
void init_pins() {
pinMode(TFT_BLK, OUTPUT);
digitalWrite(TFT_BLK, HIGH);
Wire.begin(TOUCH_SDA, TOUCH_SCL);
pinMode(MOTOR_PIN, OUTPUT);
}
Inizializzazione display: init_display
L’avvio del display segue gli stessi passaggi visti prima. Il driver gfx viene avviato, lo schermo pulito con bianco e il colore testo impostato su nero. Una scritta amichevole “Touch” è resa al centro con dimensione testo più grande per indicare l’interazione attesa. La macro F() mantiene il literal in 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
L’avvio è simile nella struttura allo sketch precedente. La porta seriale è aperta per il debug, pin e bus I²C sono inizializzati, e il display preparato e etichettato. Dopo setup, il dispositivo è pronto a interrogare i tocchi e disegnare il feedback.
void setup(void) {
Serial.begin(115200);
init_pins();
init_display();
}
Loop
Il loop principale interroga continuamente il controller touch e reagisce immediatamente quando viene segnalato un contatto valido. Le variabili x e y sono dichiarate static così la loro memoria persiste tra le iterazioni, permettendo a read_touch di scrivere tramite i puntatori.
Quando read_touch restituisce 1, viene disegnato un cerchio nero pieno di raggio cinque pixel alle coordinate segnalate per marcare il tocco. Un breve impulso di 20 millisecondi attiva il motore di vibrazione per fornire conferma aptica del tocco.
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);
}
}
Come questo si collega allo sketch precedente
La creazione del display, l’inizializzazione, l’API di disegno e il controllo motore seguono gli stessi schemi già usati. Invece degli interrupt dell’encoder e del flag has_changed, questo sketch interroga il controller touch via I²C e attiva l’aptica ad ogni contatto valido invece che agli stop di luminosità.
Il backlight è semplicemente acceso e non modulato in PWM, perché qui non c’è uno stato di luminosità. I pin di interrupt e reset touch sono definiti ma non usati; aggiungere un interrupt esterno su TOUCH_INT potrebbe permettere di andare in sleep tra i tocchi, mentre usare TOUCH_RST potrebbe eseguire un reset hardware del controller touch se necessario.
Conclusioni
In questo tutorial hai imparato come iniziare con il Matouch 1.28″ ToolSet_Controller. I due esempi di codice sul display, touchscreen, encoder rotativo e feedback aptico dovrebbero aiutarti a far partire più facilmente il tuo progetto.
Non abbiamo trattato Wi-Fi, Bluetooth 5.0, la scheda SD o il supporto RTC in questo tutorial. Ma puoi trovare esempi su Makerfabs’s Github repo for the Matouch display. Se vuoi approfondire gli encoder rotativi, dai un’occhiata al nostro tutorial How To Interface A Quadrature Rotary Encoder.
La base quadrata del Matouch 1.28″ ToolSet_Controller può essere un po’ grande per alcune applicazioni. Se cerchi un display simile con encoder rotativo ma base rotonda, dai un’occhiata al CrowPanel 1.28inch-HMI ESP32 Rotary Display. E se ti serve solo un display rotondo (senza anello encoder), il tutorial Digital Clock on CrowPanel 1.28″ Round Display potrebbe esserti utile.
Altrimenti, sentiti libero di lasciare domande nella sezione commenti.
Buon divertimento con il tinkering 😉

