Schermo sempre bianco TFT LCD Capacitivo ILI9341 Adafruit

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.

Nella seconda foto, nella parte centrale, si vedono dei pad con la scritta "close for SPI", ma non sembrano chiusi. E' così?

Ciao, Ale.

Ciao,
Intanto grazie mille per la risposta ed il tuo aiuto.
Effettivamente non avevo fatto caso a questo.
Però avevo provato a cablarli connettendoli a pin digitali con la combinazione im0 basso e gli altri alti come nella tabella della nota tecnica.
Dove per SPI a 4 cavi e 8 bit riporta quella combinazione.
Però ora mi viene il dubbio di cosa voglia dire “chiusi”.
Scusa l’ignoranza, per chiusi intendi o secondo te viene inteso che vanno messi a massa?
O cortocircuitati tra loro?
O altro?

Grazie per il tuo tempo!

Pierpaolo.

In genere devi mettere una goccia di stagno che unisca i 2 pad, chiudendo così il contatto (quella specie di freccia). Non è detto che sia risolutivo, ma la scritta quello dice...

Ciao, Ale.

Adafruit documenta sempre molto bene i suoi prodotti .... perché NON leggete la documentazione? :roll_eyes:

E' ben descritto cosa bisogna fare!!!

Guglielmo

P.S.: In particolare quel display lavora o parallelo 8 bit o SPI e in QUESTO paragrafo spiega cpme farlo funzionare in SPI.

In realtà è stato risolutivo, ti ringrazio per l'aiuto!

Giusto "pur parlè", è strano però che imponendo IM0 = LOW e gli altri IM1,2,3 = HIGH (come da tabella nella nota tecnica) non si ottenga lo stesso risultato.
Nella documentazione in effetti è riportato che saldare quei 3 pad tra loro equivale a connettere IM1,2,3 a livello di tensione 3.3 V. Anche collegarli al pin denominato "3Vo", che però esplicitamente non ha protezione da sovratensione e quindi nemmeno lo toccavo.
Probabilmente sono dei pin open collector quindi si più imporre "esternamente" il livello logico 0 ma non 1, a meno di non chiudere fisicamente il circuito (per l'appunto saldandoli).

Ancora un grazie per il tuo tempo.

Saluti,
Pierpaolo.

Genitilissimo,

mi scusi non so perchè mi ero perso il suo messaggio.
La ringrazio per aver condiviso la pagina web dedicata al dispositivo.
Effettivamente partendo dalla pagina shop relativa allo schermo, tra i link non avevo notato questo:

che sostanzialmente è quello che ha condiviso lei (suddiviso in sezioni per ogni url).
Ammetto di essere spesso negligente, ma effettivamente è la prima volta che compro da Adafruit e non avevo proprio notato una sezione del sito "Learn".
Ci farò certamente più attenzione, anche per evitare post inutili su questo forum.

La ringrazio per il suo tempo e per l'aiuto!

Saluti,
Pierpaolo.

PS: condivido giusto una riflessione.

è strano però che imponendo IM0 = LOW e gli altri IM1,2,3 = HIGH (come da tabella nella nota tecnica) non si ottenga lo stesso risultato.
Nella documentazione in effetti è riportato che saldare quei 3 pad tra loro equivale a connettere IM1,2,3 a livello di tensione 3.3 V. Anche collegarli al pin denominato "3Vo", che però esplicitamente non ha protezione da sovratensione e quindi nemmeno lo toccavo.
Probabilmente sono dei pin open collector quindi si più imporre "esternamente" il livello logico 0 ma non 1, a meno di non chiudere fisicamente il circuito (per l'appunto saldandoli).

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.