TFT ILI9341 con Shield 2.4 me funciona en UNO pero no en MEGA. [+SOLUCIONADO]

Hola, soy nuevo en el foro y por supuesto me he leído las normas de buenas prácticas para postear. :slight_smile:

Me compré este TFT2.4 240x320 v1.0 ILI9341: http://www.ebay.es/itm/Pantalla-LCD-TFT-2-4-Display-Touch-240x320-Arduino-UNO-Mega-2560-con-lector-SD/222596281648?ssPageName=STRK%3AMEBIDX%3AIT&_trksid=p2057872.m2749.l2649

Cuando ví que lo mejor era comprarse una shield, me compré esta: http://www.ebay.es/itm/Adaptador-TFT-LCD-2-4-shield-UNO-R3-expansion-board-SD-Adapter-Arduino-P0004/201592529190?ssPageName=STRK%3AMEBIDX%3AIT&_trksid=p2057872.m2749.l2649

Invertí horas y horas y días enteros buscando librerías y nada me funcionaba. Si os lelgo a decir el número de horas no me creeríais. He llegado a instalar toda clase de librerías, retocando configuraciones, etc.

El caso es que por fin aqui encontré este código que me funciona en mi Arduino Uno, pero NO ME FUNCIONA en el MEGA 2560. Ambos Arduinos son compatibles con el chip CH340.

/*================================================================
This demo code shows how to use the touch screen in TFT01
The LCD connection is the same as that in “8 Bit Pant Demo“
 
by Elecfreaks
================================================================*/
 
#define LCD_RS   19         
#define LCD_WR   18     
#define LCD_CS   17       
#define LCD_REST 16

#define DCLK     15
#define DIN      14 
#define CS       8  
#define DOUT     9
//#define IRQ      8    

unsigned int TP_X,TP_Y;    
unsigned int TouchCount=0;
 int  pacy=0;
 
 
 
void spistar()                                     //SPI Start
{
  digitalWrite(CS,LOW);
  digitalWrite(DCLK,HIGH);
  digitalWrite(DIN,HIGH);
  digitalWrite(DCLK,HIGH);
 
}
//**********************************************************
void WriteCharTo7843(unsigned char num)          //SPI Write Data
{
  unsigned char count=0;
  unsigned char temp;
  unsigned nop;
  temp=num;
  digitalWrite(DCLK,LOW);
  for(count=0;count<8;count++)
  {
    if(temp&0x80)
      digitalWrite(DIN,HIGH);
    else
      digitalWrite(DIN,LOW);
 
    temp=temp<<1; 
 
    digitalWrite(DCLK,LOW);                
    nop++;
    nop++;
    digitalWrite(DCLK,HIGH);
    nop++;
    nop++;
  }
}
 
//**********************************************************
unsigned int ReadFromCharFrom7843()             //SPI Read Data
{ 
  unsigned nop;
  unsigned char count=0;
  unsigned int Num=0;
  for(count=0;count<12;count++)
  {
    Num<<=1;
    digitalWrite(DCLK,HIGH);//DCLK=1; _nop_();_nop_();_nop_();                
    nop++;
    digitalWrite(DCLK,LOW);//DCLK=0; _nop_();_nop_();_nop_();
    nop++;
    if(digitalRead(DOUT)) Num++;
  }
  return(Num);
}
 
 
 
void LCD_Writ_Bus(char VH,char VL)   
{   
  PORTD = VH;
  digitalWrite(LCD_WR,LOW);
  digitalWrite(LCD_WR,HIGH);
  PORTD = VL;
  digitalWrite(LCD_WR,LOW);
  digitalWrite(LCD_WR,HIGH);
}
 
 
void LCD_Write_COM(char VH,char VL)  
{   
  digitalWrite(LCD_RS,LOW);
  LCD_Writ_Bus(VH,VL);
}
 
 
void LCD_Write_DATA(char VH,char VL)    
{
  digitalWrite(LCD_RS,HIGH);
  LCD_Writ_Bus(VH,VL);
}
 
void Lcd_Write_Com_Data(int com,int val)		   //发送数据命令
{
    LCD_Write_COM(com>>8,com);
    LCD_Write_DATA(val>>8,val);
}
 
void Address_set(unsigned int x1,unsigned int y1,unsigned int x2,unsigned int y2)
{
  LCD_Write_COM(0x00,0x46);LCD_Write_DATA(x2,x1);	  
  LCD_Write_COM(0x00,0x47);LCD_Write_DATA(y2>>8,y2);  
  LCD_Write_COM(0x00,0x48);LCD_Write_DATA(y1>>8,y1);
  LCD_Write_COM(0x00,0x20);LCD_Write_DATA(x1>>8,x1);	  
  LCD_Write_COM(0x00,0x21);LCD_Write_DATA(y1>>8,y1); 
  LCD_Write_COM(0x00,0x22);		         				 
}
 
void LCD_Init(void)
{
 
  digitalWrite(LCD_REST,HIGH);
  delay(5); 
  digitalWrite(LCD_REST,LOW);
  delay(5);
  digitalWrite(LCD_REST,HIGH);
  delay(5);
 
  digitalWrite(LCD_CS,LOW);  
        Lcd_Write_Com_Data(0x11,0x2004);		
        Lcd_Write_Com_Data(0x13,0xCC00);		
        Lcd_Write_Com_Data(0x15,0x2600);	
	Lcd_Write_Com_Data(0x14,0x252A);			
	Lcd_Write_Com_Data(0x12,0x0033);		
	Lcd_Write_Com_Data(0x13,0xCC04);		
	delay(1); 
	Lcd_Write_Com_Data(0x13,0xCC06);		
	delay(1); 
	Lcd_Write_Com_Data(0x13,0xCC4F);		
	delay(1); 
	Lcd_Write_Com_Data(0x13,0x674F);
	Lcd_Write_Com_Data(0x11,0x2003);
	delay(1); 	
	Lcd_Write_Com_Data(0x30,0x2609);		
	Lcd_Write_Com_Data(0x31,0x242C);		
	Lcd_Write_Com_Data(0x32,0x1F23);		
	Lcd_Write_Com_Data(0x33,0x2425);		
	Lcd_Write_Com_Data(0x34,0x2226);		
	Lcd_Write_Com_Data(0x35,0x2523);		
	Lcd_Write_Com_Data(0x36,0x1C1A);		
	Lcd_Write_Com_Data(0x37,0x131D);		
	Lcd_Write_Com_Data(0x38,0x0B11);		
	Lcd_Write_Com_Data(0x39,0x1210);		
	Lcd_Write_Com_Data(0x3A,0x1315);		
	Lcd_Write_Com_Data(0x3B,0x3619);		
	Lcd_Write_Com_Data(0x3C,0x0D00);		
	Lcd_Write_Com_Data(0x3D,0x000D);		
	Lcd_Write_Com_Data(0x16,0x0007);		
	Lcd_Write_Com_Data(0x02,0x0013);		
	Lcd_Write_Com_Data(0x03,0x0003);		
	Lcd_Write_Com_Data(0x01,0x0127);		
	delay(1); 
	Lcd_Write_Com_Data(0x08,0x0303);		
	Lcd_Write_Com_Data(0x0A,0x000B);		
	Lcd_Write_Com_Data(0x0B,0x0003);   
	Lcd_Write_Com_Data(0x0C,0x0000);   
	Lcd_Write_Com_Data(0x41,0x0000);    
	Lcd_Write_Com_Data(0x50,0x0000);   
	Lcd_Write_Com_Data(0x60,0x0005);    
        Lcd_Write_Com_Data(0x70,0x000B);    
	Lcd_Write_Com_Data(0x71,0x0000);    
	Lcd_Write_Com_Data(0x78,0x0000);    
	Lcd_Write_Com_Data(0x7A,0x0000);   
	Lcd_Write_Com_Data(0x79,0x0007);		
	Lcd_Write_Com_Data(0x07,0x0051);   
	delay(1); 	
	Lcd_Write_Com_Data(0x07,0x0053);		
	Lcd_Write_Com_Data(0x79,0x0000);
 
	LCD_Write_COM(0x00,0x22);
  digitalWrite(LCD_CS,HIGH);  
 
}
 
void Pant(char VH,char VL)
{
  int i,j;
  digitalWrite(LCD_CS,LOW); 
  Address_set(0,0,240,320);
  for(i=0;i<=320;i++)
  {
    for (j=0;j<=240;j++)
    {
      LCD_Write_DATA(VH,VL);
    }
  }
  digitalWrite(LCD_CS,HIGH);  
}
 
 
void AD7843(void)              
{
  digitalWrite(CS,LOW);                    
  WriteCharTo7843(0x90);        
  digitalWrite(DCLK,HIGH);
  digitalWrite(DCLK,LOW); 
  TP_Y=ReadFromCharFrom7843();
  WriteCharTo7843(0xD0);      
  digitalWrite(DCLK,HIGH);
  digitalWrite(DCLK,LOW);
  TP_X=ReadFromCharFrom7843();
  digitalWrite(CS,HIGH);
}
 
 
 
 
void setup()
{
 
  unsigned char p;
  int i,j,k;
  for(p=0;p<20;p++)
  {
    pinMode(p,OUTPUT);
  }
  pinMode(DOUT,INPUT);
//  pinMode(IRQ,INPUT);
 
  LCD_Init();  
  Pant(0x00,0x00);   
}
 
void loop()
{  TouchCount++; 
  unsigned char flag;
  unsigned char ss[6];	
  unsigned int lx,ly;
   spistar();  
  if(TouchCount==200)
  {
      pacy=random(0, 7);  
      TouchCount=0;
  }

//  while(digitalRead(IRQ)==0)
//  {  	
      digitalWrite(LCD_CS,LOW); 
      AD7843();
      lx=240-((TP_X-220)/16);
      ly=320-((TP_Y-400)/11);
      Address_set(lx,ly,lx+2,ly+2);
      switch(pacy)
                                {
                                  case 0: for(int i=0; i<5; i++)  LCD_Write_DATA(0xF8,0x00);  break;   //Red
                                  case 1: for(int i=0; i<5; i++)  LCD_Write_DATA(0xFF,0xE0);  break;   //Yellow
                                  case 2: for(int i=0; i<5; i++)  LCD_Write_DATA(0xFF,0xFF);  break;   //White 
                                  case 3: for(int i=0; i<5; i++)  LCD_Write_DATA(0x05,0x1F);  break;   //Blue
                                  case 4: for(int i=0; i<5; i++)  LCD_Write_DATA(0x00,0x1F);  break;   //Blue-2
                                  case 5: for(int i=0; i<5; i++)  LCD_Write_DATA(0xF8,0x1F);  break;   //Magenta
                                  case 6: for(int i=0; i<5; i++)  LCD_Write_DATA(0x07,0xE0);  break;   //Green
                                  case 7: for(int i=0; i<5; i++)  LCD_Write_DATA(0x7F,0xFF);  break;   //Cyan
                                  defoult:for(int i=0; i<5; i++)  LCD_Write_DATA(0x00,0x00);  break;   //Black
                                }
      digitalWrite(LCD_CS,HIGH); 
//    }
}

El código lo encontré aquí. micro:bit Accessories Store | ELECFREAKS

¿alguien puede darme una pista? Gracias!

Eso es porque el shield funciona solo para arduino UNO. Ese shield lo que hace es activar el TFT en modo de 8 bits (la mitad de las señales de control del TFT), ya que el UNO no tiene suficientes pines para conectarlo a 16 bits.

En MEGA, el shield para TFT debe ser diferente.

PD: cabe la posibilidad de que consigas un arduino MEGA con selector de señal lógica 3.3V-5V, o bien puedes ir directamente por un arduino Due. En estos dos casos puedes conectar directamente la pantalla, ya que de origen se controla con 3.3V

Muchas gracias por tu respuesta. Ya he comprado ese shield que me has puesto en el enlace, y cuando lo reciba, y con suerte a ver si me funcionan las librerías porque ando picando con código pelado todo en un mismo módulo, fabricándome yo los botones con sus eventos de click, etc.

De momento me conformaré conectando el UNO al MEGA mediante I2C, aunque me da que la pantalla irá terriblemente lenta.

¡Saludos!

Verás que resultará muy sencillo activar tu pantalla. La librería que debes usar es la UTFT/URTouch.

Algunas reflexiones al respecto.

Pantalla: SPI, I2C, 8 bits, 16 bits

La pantalla que quieres usar (8/16 bits) permite controlar sistemas sencillos, pero hay que considerar que la velocidad de 16 MHz, no está optimizada, ya que las librerías solo tocan el manejo básico y es frustrante ver las velocidades finales; una pena, ya que con 16 MHz se pueden conseguir interfaces muy rápidas, pero no lo tenemos disponible para arduino.

Pensando en usar el IDE de arduino como plataforma de programación en tiempo real, hay opciones que te permiten mayor soltura en las interfaces, éstas recurren a la comunicación por SPI o por I2C, de esas opciones las mejores velocidades se consiguen con SPI, siendo el mejor chip el ILI9341.

Por I2C las pantallas que recomendaría son las SmartGPU2, tienen como unidad de procesamiento gráfica un STM32F103. Hay otras opciones (mucho más costosas) que requieren de software extra y no se pueden programar en tiempo real con el IDE de arduino.

MCU

Pensando en placas de soporte o MCU compatibles con el IDE de arduino, las mejores prestaciones de velocidad finales se consiguen con la interfaz SPI. Las mejores opciones: teensy 3.6, teensy 3.5, teensy 3.2, STM32F103ZX, STM32F407VX, STM32F407ZX, NodeMECU, arduino Due.

PD: existen otras opciones de pantallas SPI que incluyen su propio procesador gráfico, con resultados impresionantes incluso en placas como el arduino UNO.

De acuerdo, usare esas librerias UTFT/URTouch, y de paso la URButtons. POr cierto el shield que he adqurido es de 3.2"! espero que no haya problemas o me tendre que pillar una TFT de 3.2.

Muy instructivo todo lo que pones. Existe una gran variedad pero puede ser una odisea como me ha pasado a mí. Los fabricantes chinos no se por qué, no cuelgan sus librerías. Otros no advierten que la placa es a 3,3V y que no funcionará en el tradicional UNO y otras, etc.

Nada, que no hay forma. He probado de todo y no va.

Recordemos, dispongo de este TFT.

Montado en el Ardunino MEGA 2560 con la shield que me dijiste que comprara.

La librería UTouch no me va. Igual no estoy declarando bien el modelo y sus pines.

He pensado dar por perdida la TFT y comprarme esta para utilizar con la shield:

https://es.aliexpress.com/store/product/LCD-3-2-inch-TFT-Touch-Screen-Module-Display-Ultra-HD-320-240-ILI9341-Compatible-Punctuality/1326062_32548227874.html?spm=a219c.12010612.0.0.6e3448f0mn4mbJ

Ha pasado bastante tiempo sin que haya usado el shield-TFT para MEGA. Trataré de dar mi opinión, instalando un arreglo similar al que tienes. Pienso que tal vez no estás definiendo correctamente el iniciador de tu pantalla.

El fabricante aclara que está usando otro chip driver:

Now we provide 320x240 TFT01_2.4 LCD module used S6D1121 for driver IC to replace of ILI9325. So new library we have used new driver IC's init code to replace ILI9327 init code in demo and library.

Justo lineas abajo proporciona un link para descargar la versión más reciente de UTFT y por consiguiente de URTouch. No hagas caso de la documentación restante, no tiene que ver con el modelo de tu pantalla. Por cierto debes realizar una calibración de la pantalla táctil para obtener el vector de ajuste en el archivo URTouchCD.h

El iniciador debería hacer referencia a esta línea:

#define S6D1121_16 15

Por tanto, este iniciador debería funcionar con tu pantalla y la versión más reciente de UTFT:

UTFT myGLCD(15, 38, 39, 40, 41);

Hace un tiempo encontré un complemento para UTFT, que permite cargar imágenes RAW desde una tarjeta SD instalada en el lector de la pantalla. Usa la librería SdFat como soporte para la gestión de archivos.

La diseñó ghlawrence2000 un usuario del foro. Acá el repositorio

#include <SPI.h>
// SdFat lib from here :-
// https://github.com/greiman/SdFat/archive/master.zip
#include <SdFat.h>
#include <UTFT.h>
#include <UTFT_SdRaw.h>

#define SD_CHIP_SELECT  53  // SD chip select pin
SdFat sd;

UTFT myGLCD(5, 38, 39, 40, 41);  //ILI9325D_16

UTFT_SdRaw myFiles(&myGLCD);

void setup() {
  sd.begin(SD_CHIP_SELECT, SPI_FULL_SPEED);

  myGLCD.InitLCD();
  myGLCD.clrScr();
}

void loop() {
  char FileRAW[] = "SK45/6oB.raw";  
  myFiles.load(0, 0, 320, 240, FileRAW, 1);

  char FileRAW1[] = "SK45/6oG.raw"; 
  myFiles.load(0, 0, 320, 240, FileRAW1, 1);

  char FileRAW2[] = "SK45/Zipo1a.raw"; 
  myFiles.load(0, 0, 320, 240, FileRAW2, 1);

  char FileRAW3[] = "SK45/u2.raw"; 
  myFiles.load(0, 0, 320, 240, FileRAW3, 1);

  char FileRAW4[] = "SK45/Trees.raw"; 
  myFiles.load(0, 0, 320, 240, FileRAW4, 1);

  char FileRAW5[] = "SK45/tiger.raw"; 
  myFiles.load(0, 0, 320, 240, FileRAW5, 1);

  char FileRAW6[] = "SK45/sun.raw"; 
  myFiles.load(0, 0, 320, 240, FileRAW6, 1);
}

Solo hay que copiar la carpeta descomprimida, en una tarjeta SD.

Los archivos RAW se pueden crear con la herramienta ImageConverter565.exe, incluida en la librería UTFT, puedes usar como base imágenes bmp o jpg.


TFT: ILI9325D, 2.8"

SK45.zip (1.02 MB)

Gracias pero nada, sigue sin ir.

Nótese que mi TFT no es el que aparece en las imágenes que posteas. En el mío pone 2,4"TFT 240*320 sod44pin.

Además, un sketch me reveló que el chip es el ILI9341.

La librería UTFT es la última de la web de Rinky-Dink Electronics.

Espero que mi información te sirva.

Ha pasado tiempo de esto y hoy me ha dado por enredar un poco en este proyecto. He conseguido que me funcione. Es increíble..... Este verano le dediqué un tillón de horas sin resultado... y hoy en menos de 30 min. di con la clave!

La clave es poner el iD 14 del chip (en la librería uTFT.cpp está la lista de chips disponibles). De esta forma, la declaración en cualquier código de ejemplo de arduino queda así:

UTFT myGLCD(14,38,39,40,41);

En fin, dejo aquí la solución porque nunca se sabe si algún forero que utilice el buscador, esto le podría servir.

Gracias, @TFTLCDCyg.