Salve a tutti,
come da titolo del post, mi sto imbattendo in qualche problema nell'utilizzare lo schermo capacitivo da 2.8 pollici della Adafruit modello ILI9341, quello come nel link qui sotto:
ho visto che ci sono parecchi post al riguardo, ma "purtroppo" molti riguardano la versione rossa del dispositivo (da quello che ho capito potrebbe essere una versione più vecchia), che anche se viene dichiarato lo stesso "codice modello", in realtà è abbastanza differente, già solo nell'organizzazione e nome dei pin (cosa che a me onestamente mette un po difficoltà nel correlare eventuali soluzioni per il mio caso).
Allego il codice che sto usando attualmente, in cui uso queste librerie:
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
#include <Adafruit_FT6206.h>
scaricate tramite il manager delle librerie del nuovo IDE (io ho la versione 2.3.4 oltre al vecchio IDE Legacy 1.8.19).
da quello che ho capito con Adafruit_ILI9341.h si gestisce il display (nel senso di cambiamento colori ed effetti grafici) mentre con Adafruit_FT6206.h si gestisce il touch.
I metodi associati all'istanza:
Adafruit_FT6206 ctp = Adafruit_FT6206();
non mi danno alcun problema, infatti la seguente serie di metodi:
TS_Point p = ctp.getPoint();
int16_t screenX = map(p.y, 0, 240, 0, tft.width());
int16_t screenY = map(p.x, 0, 320, 0, tft.height());
fanno stampare a video la posizione corrente del dito sullo schermo in modo direi corretto. Ho fatto dei check sui 4 angoli e nel centro dello schermo vedendo che effettivamente screeX e screenY sono coerenti.
Il problema è la parte grafica, per cui chiedo aiuto!
Il codice completo è il seguente:
/*************************************************************
* Esempio base per Display ILI9341 e Touch FT6206
* (Adafruit 2.8" TFT Breakout #2090) su Arduino UNO R3
*
* Collegamenti (riassunto):
* Display:
* - VIN -> 5V
* - GND -> GND
* - CLK -> 13
* - MISO -> 12
* - MOSI -> 11
* - CS -> 10
* - D/C -> 9
* - RST -> 8
* Touch (FT6206):
* - SDA (touch) -> A4 (Arduino)
* - SCL (touch) -> A5 (Arduino)
* - INT (o CCS) -> 4 (Arduino)
*
*************************************************************/
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
#include <Adafruit_FT6206.h>
#include "Adafruit_TFTLCD.h"
#include <Adafruit_SPITFT.h>
// Definizioni pin SPI per il display
#define TFT_CS 10 // Chip Select display
#define TFT_DC 9 // Data/Command display
#define TFT_RST 8 // -1 se RST è cablato internamente
#define TOUCH_INT 4
/*#define im0 7
#define im1 6
#define im2 5
#define im3 4*/
// Istanza display ILI9341
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
// Touch capacitivo FT6206 (I2C su A4/A5)
Adafruit_FT6206 ctp = Adafruit_FT6206();
// Vettore di colori da ciclare a ogni tocco (se vuoi riattivare la funzione)
uint16_t colorList[] = {
ILI9341_BLACK,
ILI9341_BLUE,
ILI9341_RED,
ILI9341_GREEN,
ILI9341_CYAN,
ILI9341_MAGENTA,
ILI9341_YELLOW,
ILI9341_WHITE
};
uint8_t currentColorIndex = 0;
void setup() {
Serial.begin(115200);
Serial.println("Avvio setup...");
SPI.begin();
/*pinMode(im0, OUTPUT);
pinMode(im1, OUTPUT);
pinMode(im2, OUTPUT);
pinMode(im3, OUTPUT);
digitalWrite(im0, LOW);
digitalWrite(im1, HIGH);
digitalWrite(im2, HIGH);
digitalWrite(im3, HIGH);*/
tft.begin(10000000);
Serial.println("Display inizializzato!");
delay(1000);
Serial.println("Mando il display in sleep (SLPIN)...");
tft.writeCommand(ILI9341_SLPIN);
delay(5000);
tft.writeCommand(ILI9341_SLPOUT);
delay(120);
tft.writeCommand(ILI9341_DISPON);
uint8_t x = tft.readcommand8(ILI9341_RDMODE);
Serial.print("Display Power Mode: 0x"); Serial.println(x, HEX);
x = tft.readcommand8(ILI9341_RDMADCTL);
Serial.print("MADCTL Mode: 0x"); Serial.println(x, HEX);
x = tft.readcommand8(ILI9341_RDPIXFMT);
Serial.print("Pixel Format: 0x"); Serial.println(x, HEX);
x = tft.readcommand8(ILI9341_RDIMGFMT);
Serial.print("Image Format: 0x"); Serial.println(x, HEX);
x = tft.readcommand8(ILI9341_RDSELFDIAG);
Serial.print("Self Diagnostic: 0x"); Serial.println(x, HEX);
Serial.println(F("Done!"));
tft.setRotation(0);
tft.setCursor(0, 0);
tft.setTextColor(ILI9341_BLACK);
tft.setTextSize(2);
tft.println("Test ILI9341 + FT6206");
Serial.println("Display inizializzato!");
if (!ctp.begin(40)) {
Serial.println("Touch FT6206 non rilevato. Controlla collegamenti!");
while(1) { delay(1000); }
}
Serial.println("Touch inizializzato correttamente!");
tft.println("Touch OK! Prova a toccare...");
}
void loop() {
if (ctp.touched()) {
TS_Point p = ctp.getPoint();
int16_t screenX = map(p.y, 0, 240, 0, tft.width());
int16_t screenY = map(p.x, 0, 320, 0, tft.height());
Serial.print("Tocco a x=");
Serial.print(screenX);
Serial.print(", y=");
Serial.println(screenY);
tft.fillCircle(screenX, screenY, 4, ILI9341_RED);
tft.fillScreen(colorList[currentColorIndex]);
currentColorIndex++;
if (currentColorIndex >= (sizeof(colorList) / sizeof(colorList[0]))) {
currentColorIndex = 0;
}
}
// Piccola attesa
delay(50);
}
Ho allegato un "servizio fotografico" relativo al cablaggio che sto usando (spero sia utile).
Riassumendo:
Display:
- VIN -> 5V
- GND -> GND
- CLK -> 13
- MISO -> 12
- MOSI -> 11
- CS -> 10
- D/C -> 9
- RST -> 8
Touch (FT6206):
- SDA (touch) -> A4 (Arduino)
- SCL (touch) -> A5 (Arduino)
- INT (o CCS) -> 4 (Arduino)
attualmente ho fatto l'aggiunta dei partitori resistivi nei collegamenti tra i pin digitali di arduino ed i pin dello schermo. Ho letto in diversi post che lo schermo è progettato con logica digitale a 3.3 V mentre il GPIO di arduino a 5V, ma anche senza ho gli stessi problemi.
I partitori sono fatti con resistenza da 5kOhm (poco meno) e da 10kOhm.
Ho letto che potrebbe essere in modalità SLEEP, ed in qualche posto qualcuno ha suggerito di usare i seguenti comandi, ma onestamente con o senza non cambia proprio nulla...
tft.writeCommand(ILI9341_SLPOUT);
delay(120);
tft.writeCommand(ILI9341_DISPON);
Per quanto riguarda la seguente parte di codice, in cui "verifica lo stato" del display:
uint8_t x = tft.readcommand8(ILI9341_RDMODE);
Serial.print("Display Power Mode: 0x"); Serial.println(x, HEX);
x = tft.readcommand8(ILI9341_RDMADCTL);
Serial.print("MADCTL Mode: 0x"); Serial.println(x, HEX);
x = tft.readcommand8(ILI9341_RDPIXFMT);
Serial.print("Pixel Format: 0x"); Serial.println(x, HEX);
x = tft.readcommand8(ILI9341_RDIMGFMT);
Serial.print("Image Format: 0x"); Serial.println(x, HEX);
x = tft.readcommand8(ILI9341_RDSELFDIAG);
Serial.print("Self Diagnostic: 0x"); Serial.println(x, HEX);
in realtà ho notato che cablare anche i pin IM0,IM1,IM2 e IM3 è un aspetto fondamentale nei messaggi di diagnostica. In particolare se non vengono cablati, per ogni campo stampato a seguito di comando readcommand8() si ha 0x0 come valore di risposta. Invece se segue ciò che viene riportato nella seguente guida tecnica:
cioè che per impostare la modalità SPI a 4 cavi su 8 bit è necessario imporre IM0 = LOW e gli altri IM1..3=HIGH, allora la stampa a video cambia nel seguente modo:
ILI9341 Test!
Display Power Mode: 0x94
MADCTL Mode: 0x48
Pixel Format: 0x5
Image Format: 0x80
Self Diagnostic: 0xC0
non so perchè a volte Self Diagnostic: 0x00...
Attualmente sto anche alimentando Arduino Uno R3 con alimentatore da 12V/2A (della serie "non si sa mai") senza cambiamenti ovviamente.
Nota a margine, ho usato sia Arduino Uno R3 originale che la scheda di valutazione della AZ-delivery, ma direi che questo aspetto è abbastanza irrilevante, visto che ci ho usato altri shield come il CAN-shield (che usa SPI in ogni caso) senza problemi. Ho un arduino R4 minima a disposizione, fosse mai un problema di risorse computazionali (?).
Rimango in attesa di feedback e Vi ringrazio dell'attenzione.
Cordialmente,
Pierpaolo.





