Algunos consejos para usar TFT´s

Nuevamente me he dado a la tarea de modificar la librería para gameduino 23X de James Bowman. Esta librería está diseñada para funcionar en placas AVR, arduino due , algunas STM32, ESP32, ESP8266 y en las placas teensy.

No obstante su gran valor, creo que merece impulsar la parte multimedia apoyándola de la librería SdFat beta de Greiman. Con la gran ayuda que en su momento me bridó mi hermano Tomas con su trabajo en placas STM32, con la colaboración de Javier y del amigo de oriente nopnop2002, luego de varias semanas de prueba y error, aislando las optimizaciones de la librería GD23ZUTX, decidí aventurarme a modificar directamente la última versión de la librería de James, para que funcione exclusivamente con las placas teensy que tienen lector SDIO (3.5, 3.6 y 4.1) o que pueden incorporar un lector externo microSD con estas características (teensy 4).

La idea es poder agregar fácilmente pantallas de las familias FT81x o BT81x, con ajustes mínimos. No ha sido tarea fácil conjuntarlo todo, ya que se debe rastrear los cambios uno por uno, descartando aquellas instrucciones que aplican para otras plataformas y que no intervienen en las rutinas de interés.

Lo fundamental de la librería SdFat-beta es el llamado al lector SDIO, para ello hay que distribuir correctamente estas instrucciones, de lo contrario no funcionarán.

SdFat32 SD
SD.begin(SdioConfig(FIFO_SDIO))
File32 r o File2 archivo

Gracias a Javier conseguimos la codificación correcta para que dos instrucciones fundamentales: load y safeload, puedan cargar en pantalla los archivos de assets o de imágenes, mediante SdFat, que en la experimentación actual, funcionan correctamente para SdFat-beta

Originalmente esas dos funciones trabajan con la librería SD. La versión para SdFat es esta:

byte GDClass::load(const char *filename, FUNC_POINTER progress)
{
//SdFat beta V2
   File32 archivo;
   archivo = SD.open(filename);
//SdFat beta V2
  return (loadSdFat(archivo, progress)); 
}
byte GDClass::loadSdFat(File32& archivo, FUNC_POINTER progress)
{
  int offset=0;
  int offsetFT;
  int bytesDisponibles;
  int wbn;
  GD.__end();
   if (archivo) {
   int tamArchivo=archivo.available();
   while( offset < tamArchivo)
    {
        uint16_t m = ( (archivo.available() > TAM_BUFFER_SD) ? TAM_BUFFER_SD : archivo.available());
        archivo.read(buf,m);
        offsetFT=0;
        bytesDisponibles=m;
        while (offsetFT < m) 
        {
           uint16_t n = ( (bytesDisponibles > TAM_BUFFER_FT) ? TAM_BUFFER_FT : bytesDisponibles);
           wbn = (n + 3) & ~3;   // force 32-bit alignment
           GD.resume();
           if (progress)
           (*progress)((offset+offsetFT), tamArchivo);
            #ifdef DUMMY_GDCOPYRAM
             memcpy (FTbuf, buf+offsetFT, wbn );
            #else
              GD.copyram((buf+offsetFT), wbn);
             #endif              
             offsetFT+=n;
             bytesDisponibles-=n;
             GDTR.stop();
        }
        offset+=m;         
    }	
    GD.resume();

    #ifdef TEENSYDUINO
      SPI.endTransaction();
    #endif
    return 1;
  }
  GD.resume();
     #ifdef TEENSYDUINO
       SPI.endTransaction();
     #endif
     return 0;
}

Se agregaron un par de instrucciones de finalización de comunicación SPI para cesar el llamado al lector SDIO, ya que después de cargado el archivo en la GRAM de la pantalla, ya no es necesario que el bus esté activo, al dejarlo activo, salta una pantalla de error que no necesariamente tiene que ver con la ausencia o error en el archivo de imagen jpg o arreglo de assets. Aplica también para la reproducción de archivos de audio.

Las familias FT81x o BT81x, soportan la reproducción de archivos avi con audio. Gracias a nopnop2002, ajustó la rutina MoviePlayer para cargar videos desde un lector externo en placas STM32 como la Blue Pill STM32F103

Tocaba entonces unir loadsdfat, con MoviePlayer para que ambas puedan usar la librería SdFat-beta dentro de la librería modificada gameduino 23X y para complicar más las cosas, en las placas teensy 4 o 4.1.

La clase MoviePlayer adaptada por nopnop2002 es:

class MoviePlayer
{
  uint32_t mf_size, mf_base, wp;
  //Reader r;
  File r;
  void loadsector() {
    byte buf[512];
    GD.__end();
    //r.readsector(buf);
    int32_t c = r.curPosition();
    int32_t p = r.peek();
//Serial.print("curPosition=" + String(c));
//Serial.print(" peek=" + String(p));
    int n = r.read(buf,512);
//Serial.println(" n=" + String(n));
    GD.resume();
    GD.wr_n(mf_base + wp, buf, 512);
    wp = (wp + 512) & (mf_size - 1);
//Serial.println("wp=" + String(wp));
  }

public:
  int begin(const char *filename) {
Serial.println("MoviePlayer begin filanem=" + String(filename));
    if (ft8xx_model == 0) GD.alert("FT800 is not support MoviePlayer");
    mf_size = 0x40000UL;
    mf_base = 0x100000UL - mf_size;
    GD.__end();
    //if (!r.openfile(filename)) {
    if (!r.open(filename)) {
      Serial.println("MoviePlayer open failed");
      return 0;
    }
Serial.println("MoviePlayer open ok");
    GD.resume();

    wp = 0;
    while (wp < (mf_size - 512)) {
      loadsector();
    }
Serial.println("MoviePlayer loadsector ok");

    GD.cmd_mediafifo(mf_base, mf_size);
Serial.println("MoviePlayer mediafifo ok");
Serial.print("REG_MEDIAFIFO_WRITE=");
Serial.println(REG_MEDIAFIFO_WRITE,HEX);
    GD.cmd_regwrite(REG_MEDIAFIFO_WRITE, wp);
    GD.finish();

    return 1;
  }
  int service() {
    //if (r.eof()) {
    if (r.peek() == -1) {
      return 0;
    } else {
      //byte buf[512];

      uint32_t fullness = (wp - GD.rd32(REG_MEDIAFIFO_READ)) & (mf_size - 1);
      while (fullness < (mf_size - 512)) {
        loadsector();
        fullness += 512;
        GD.wr32(REG_MEDIAFIFO_WRITE, wp);
      }
      return 1;
    }
  }
  void play() {
Serial.println("MoviePlayer play start");
    GD.cmd_playvideo(OPT_MEDIAFIFO | OPT_FULLSCREEN);
    GD.flush();
    while (service())
      ;
    GD.cmd_memcpy(0, 0, 4);
    GD.finish();
Serial.println("MoviePlayer play end");
  }
};

Tanto MoviePlayer como loadsdfat, se reacondicionaron para funcionar con SdFat-beta, considerando las instrucciones base.

Tras varias semanas de prueba y error, finalmente conviven todas ellas en la librería modificada GDTeensy4X. El objetivo secundario consistió en aislar las posibles fuentes de ruido en la señal de audio de los videos.

Tres de ellas son relevantes y obligaron a modificar la rutina GD.begin(), parece que contribuyen a reducir el ruido de fondo:

Suprimir la activación del bus SPI para cualquier lector externo
Habilitar el llamado al lector SDIO antes de activar los registros de la pantalla
Modificar la rutina GD.begin() para activar el registro de la pantalla REG_PCLK, hasta el primer llamado a GD.swap()

La rutina GD.begin() quedó de esta forma:

void GDClass::begin(uint8_t options, int cs) {

 GDTR.begin0();
 byte external_crystal = 0;
 SD.begin(SdioConfig(FIFO_SDIO));

 begin1:
 GDTR.begin1();
  
  #if(SizeFT813==51)
   GD.wr32(REG_PCLK, 2);
  #endif
  #if(SizeFT813==35)
   GD.wr32(REG_PCLK, 6);//5
  #endif

  ClearColorRGB(0x000000);
  Clear();
  swap();
  finish();

Esta es la fracción original presente en la libreria para gameduino:

void GDClass::begin(uint8_t options, int cs, int sdcs) {
#if defined(ARDUINO) || defined(ESP8266) || defined(ESP32) || defined(SPIDRIVER)
  GDTR.begin0(cs);
  if (STORAGE && (options & GD_STORAGE))
    SD.begin(sdcs);
#endif

  byte external_crystal = 0;
begin1:
  GDTR.begin1();

  Clear();
  swap();
  finish();

He podido conectar tres pantallas FT813:

  • 3.5" NHD en la teensy 4.1
  • 5" Riverdi en la teensy 4
  • 4.3" NHD en la teensy 3.6

Todas funcionan correctamente con las modificaciones en la librería y lo mas importante con apenas ruido de fondo.

PD: la instrucción SdFat32 SD debe ir en el encabezado del archivo ccp, inmediatamente después del llamado a la libreria SdFat

Ya con la librería avanzada, y para continuar con mas pruebas sobre su comportamiento, me aventuré a darle un vistazo a la librería arduinoFFT, compilé algunos ejemplos con el teensy 4, para mi sorpresa no saltaron errores graves, solo algunas advertencias. La versión de la librería es:

02/10/18 v1.4

Revisando en la red vi este proyecto, me pareció que podía usarlo como base, ya que explica muy bien el uso de la librería y de dónde salen los valores de frontera que se deben usar para las diferentes bandas en el análisis FFT. Está enfocado a ESP32 y leds direccionables, pero no fue complicado aislar las rutinas principales para explorar su funcionamiento en la pantalla FT813 de 5".
Luego de depurar algunas líneas, por fin veo una FFT en la pantalla…


PD: ya es algo tarde, mas adelante subiré algunos comentarios, adjunto el sketch.

GD_FFT-24.zip (67.1 KB)

Al cabo de varios años de experimentar con la familia de pantallas EVE-X (FT800, FT81X, BT81X), me he percatado que presentan un detalle que no se refiere en algún documento técnico: la persistencia de imagen luego de mantener pixeles estáticos durante períodos muy prolongados.

Una solución simple es que los pixeles se puedan refrescar mediante un barrido frecuente. Esta es la rutina de protección que parece soluciona ese detalle:

int XProtector=0, velXProtector=1, color;
void Protector01()
{
 XProtector=XProtector+velXProtector;
 if(XProtector>=GD.w)
   {
    velXProtector=-1; 
    color = color + 1;
    if (color>=3){color=0;}
   }
 if(XProtector<=0)
   {
    velXProtector=1;
    color = color + 1;
    if (color>=3){color=0;}
   }
 GD.SaveContext();
   if (color==0)
    {
     GD.ColorRGB(0xff0000);
    }
   if (color==1)
    {
     GD.ColorRGB(0x00ff00);
    }
   if (color==2)
    {
     GD.ColorRGB(0x0000ff);
    }
   //sprintf(TXP,"color = %d", color); GD.cmd_text(GD.w-41, 5, 20, 0, TXP);    
   GD.LineWidth(0.3 * 16);
   GD.Begin(LINES);
   GD.Vertex2f((XProtector)*16,(0)*16);  GD.Vertex2f((XProtector)*16,(GD.h)*16);
 GD.RestoreContext();
}

Dibuja una línea vertical de apenas 5/16 de espesor, al llegar a un extremo cambia de canal de color y regresa hacia el otro extremo, la secuencia es R-G-B, de esta forma se evita la aparición de imágenes persistentes de fondo. Dadas sus características no interfiere con el funcionamiento del programa que se esté ejecutando en primer plano, sugiero que esta rutina se agregue al final, para que el 100% de pixeles reciba esa actualización frecuente.

Librería arduinoFFT en teensy 4.x

La matriz de vectores que se puede obtener del procesamiento de una señal de audio mediante rutinas FFT tiene dos características:

  1. Actualización muy rápida. 40000 Hz no es una cifra muy alta para los estándares de frecuencia que podemos encontrar en algún MCU comercial para arduino: 16 MHz, 150 MHz , 216 Mhz o 600 MHz.

  2. Cantidad de datos a presentar. “40,000 ciclos en un segundo”, no es algo menor, es un mundo de datos que se deben manejar para dibujar algo en el TFT. Le podemos complicar la vida al MCU si queremos monitorear digamos 16 bandas o mejor aún 24 bandas. Veamos que sucedería en el TFT con este último número: 24 bandas.

Cada banda la podemos traducir en una barra vertical que bien podría ser de 1 pixel de ancho por digamos 34 pixeles de altura (usando la función map podemos conseguir esta conversión). Veamos los números:

1 x 34 x 24 = 34 x 24 pixeles = 816 pixeles

Realmente siguen sin ser muchos números, para un TFT normal de 320 x 240 = 76,800 pixeles o bien 800 x 480 = 384,000 pixeles.

Ahora bien, recordemos la tasa de adquisición de datos promedio es de 40 kHz. En un segundo, el TFT debe conseguirlo y permitirnos procesar esa información en algo visible. ¿Dije un pixel de ancho?, vamos que esa es una línea diminuta. Para algo con mejor visibilidad, pensemos que cada barra tendrá 5 pixeles de ancho por 150 pixeles de alto

Para manejar esa cantidad de pixeles, es mejor obtener vector que nos permita dibujar 24 barras de 5 x 150 pixeles, con una determinada separación (PitchX), algo así como:

int YhB = 150;
int PitchB = 5, PitchX = 5;
#define NUM_BANDS   24

int xbase = (320-(NUM_BANDS*PitchB + (NUM_BANDS-1)*PitchX))/2;
int ybase = (240+(YhB))/2;

void BarrasTFT()
{
  for (int j = 0; j < 24; j++) 
     {
      tft.fillRect(xbase + j*PitchX + j*PitchB, ybase-YhB, PitchB, YhB, ILI9341_YELLOW);
     }
}


Es decir: 5 x 150 x 24 =18,000 pixeles

El siguiente paso es conseguir que las barras verticales tengan movilidad y sean capaces de representar los datos en forma porcentual. Podemos aproximar esta situación con el movimiento de dos barras, una inferior representará el dato actual y la superior el complemento de ese porcentaje.

El ancho de frecuencias que vamos a monitorear en este ejemplo va de 80 Hz a 14k Hz, repartidos en 24 bandas.

    //24 bands, 14kHz top band
      if (i<=2 )            bandValues[0]  += (int)vReal[i];  // 80
      if (i>=2   && i<=3  ) bandValues[1]  += (int)vReal[i];  // 100
      if (i>=3   && i<=4  ) bandValues[2]  += (int)vReal[i];  // 125
      if (i>=4   && i<=5  ) bandValues[3]  += (int)vReal[i];  // 157
      if (i>=5   && i<=6  ) bandValues[4]  += (int)vReal[i];  // 196
      if (i>=6   && i<=7  ) bandValues[5]  += (int)vReal[i];  // 246
      if (i>=7  &&  i<=9  ) bandValues[6]  += (int)vReal[i];  // 308
      if (i>=8  && i<=11  ) bandValues[7]  += (int)vReal[i];  // 385
      if (i>=11  && i<=14 ) bandValues[8]  += (int)vReal[i];  // 482
      if (i>=14  && i<=17 ) bandValues[9]  += (int)vReal[i];  // 604
      if (i>=17  && i<=22 ) bandValues[10] += (int)vReal[i];  // 756
      if (i>=22  && i<=27 ) bandValues[11] += (int)vReal[i];  // 946
      if (i>=27  && i<=34 ) bandValues[12] += (int)vReal[i];  // 1184
      if (i>=34  && i<=43 ) bandValues[13] += (int)vReal[i];  // 1482
      if (i>=43  && i<=53 ) bandValues[14] += (int)vReal[i];  // 1855
      if (i>=53  && i<=67 ) bandValues[15] += (int)vReal[i];  // 2322
      if (i>=67  && i<=84 ) bandValues[16] += (int)vReal[i];  // 2907
      if (i>=84  && i<=105) bandValues[17] += (int)vReal[i];  // 3639
      if (i>=105 && i<=131) bandValues[18] += (int)vReal[i];  // 4555
      if (i>=131 && i<=164) bandValues[19] += (int)vReal[i];  // 5702
      if (i>=164 && i<=206) bandValues[20] += (int)vReal[i];  // 7138
      if (i>=206 && i<=258) bandValues[21] += (int)vReal[i];  // 8935
      if (i>=258 && i<=322) bandValues[22] += (int)vReal[i];  // 11184
      if (i>=322          ) bandValues[23] += (int)vReal[i];  // 14000

El hilo con la señal de audio podemos conectarlo a algún pin Ax, en este caso escogí el pin 16 que equivale a A2 en el teensy 4. La señal proviene del canal derecho de la tarjeta de audio de la PC.

La función que nos permite dibujar las “barras animadas” del analizador de espectro quedó así:

void BarrasTFT()
{
  for (int j = 0; j < 24; j++) 
     {
      tft.fillRect(xbase + j*PitchX + j*PitchB, ybase-Datos[j], PitchB, Datos[j], ILI9341_GREEN); //inferior
      tft.fillRect(xbase + j*PitchX + j*PitchB, ybase-TOP, PitchB, TOP-Datos[j], ILI9341_RED);    //superior
     }
}

Agregué la rutina con la librería arduinoFFT, para poder convertir correctamente los datos en valores porcentuales y ver su comportamiento real en el TFT.

Mantener el equivalente a una tasa de refresco, se puede conseguir con la instrucción millis o micros. Luego del procesamiento FFT, podemos llamar a la función que dibuja las barras de esta forma:

  unsigned long currentMillis0 = millis();
  if(currentMillis0 - previousMillis0 > 42)
  {
    previousMillis0 = currentMillis0;
    BarrasTFT();
  }

MCU: Teensy 4
TFT: ILI9341 2.8"
Librerías: ILI9341_t3, JPGDEC, SD, SPI, arduinoFFT

Adjunto el skecth.

ILI9341_t3_T4x_FFT.zip (37 KB)

Muy tentador tu trabajo @TFTLCDCyg, se presentan a diario situaciones donde un analisis FFT es muy importante. A tener en cuenta.

Desde hace varios años he estado tratando de graficar una FFT en la pantalla FT813. Me dijeron alguna vez que no se podía por la limitación de las funciones que permiten realizar dibujos y menos aún en una pantalla controlable con la librería GFX como la ILI9341.

Al principio esa idea la asumí como verdadera, luego de profundizar en el funcionamiento de las primitivas, caigo en cuenta que solo se tiene que escribir las líneas de código en el orden correcto. Luego salen al mercado placas teensy 4.x que se agregan al ecosistema de arduino, con frecuencias mas allá de 240 Mhz, que en verdad que facilitan aun mas los cálculos.

Los accidentes pasan y solo nos queda aprender de ellos. Hace un par de meses por descuido conecté al revés los pines de la fuente de alimentación que me permitían conectar la pantalla NHD de 5" en el teensy 3.6. Apenas uní los pines a los conectores de la retroiluminación de la pantalla con los de la fuente de 5V y solo vi salir un hilo blanco humo de la parte posterior de la pantalla de 5"...

Lamentablemente la pantalla no da señales de vida...

Luego de volver a ahorrar meticulosamente algunos pesos por semana, y de esperar que los amigos de Mouser tuviesen la pantalla en stock, por fin pude hacerme de una segunda pantalla NHD de 5". El envío salió de DFW Airport, TX, USA el 30/03/21 y llegó al terruño hoy 01/04/21 a las 16:19 hrs.

|500x372

|500x372

|500x372

|500x372

Toca cuidarla y poner mas atención

Buenas:

¿Cómo se llama esta pantalla para Arduino que se muestra en este vídeo?

Ver vídeo.

Lo comento porque estoy buscando una buena pantalla para textos tipo LCD 20x4, que este se me queda ya corto. Se que hay uno de 40x4 pero sigue siendo corto para mi. |500x147

Estaba buscando una LCD de 40x8 pero veo que no existe, ya tendría que irme a los GLCD que son gráficos.

Saludos.

Esa pantalla es un shield TFT para arduino UNO o MEGA como la que muestran en este tutorial

Tal vez un LCD gráfico 128x64 px te podría ayudar, busca que tenga el controlador ST7920, se puede controlar con el puerto SPI, así que ocuparás pocos hilos

Me imagino que te refieres a este. |433x500

https://thesolaruniverse.wordpress.com/2017/08/11/an-128x64-graphic-lcd-display-with-st7920-controller-for-the-arduino-displaying-temperature-and-relative-humidity/

https://rduinostar.com/documentacion/datasheets/lcd-st7920-hj12864zw/

Librería. https://code.google.com/archive/p/u8glib/

La verdad que no quiero pagar 40 €urazos por esta GLCD. Que cara para lo que es, más caro que usar un movil viejo de Android y hacer mi propia interfaz.

;)

Existen algunos LCD gráficos que podrían reciclarse de celulares algo viejitos, por ejemplo NOKIA 3310/5110/5120/5125. El LCD es este:


La resolución es de 84x48 pixeles, lógica de 5V, quizás podrías tener a la mano algún celular de esos, recortar el PCB donde viene el LCD. Es posible que algún proveedor cercano tenga el LCD entre sus artículos, ya lo venden listo para conectar en un arduino como el UNO o el MEGA

Lo tengo en cuenta, no se si todavía los venden pero este tengo que ver cuanto caracteres cabe en una línea. Porque si es menor que el de 20x4 como que no.

Aquí un ejemplo de este LD que nombras.

Ver vídeo.

Saludos.

No todos los TFT son caros hay opciones bastante accesibles con mejores prestaciones:

La opción táctil del ST7735 es la mas pequeña que he visto en pantallas de 1.8", puedes conectarla por SPI, opera con lógica de 3.3V, con algunos divisores de voltaje en las líneas de control SPI puedes conectarla en una arduino UNO

Módulo de pantalla LCD TFT LCD de 1,8 pulgadas, SPI puerto serial, módulo TFT a color, 8/10/12 Pines, 1,8 pulgadas|Accesorios y partes de impresoras 3D| - AliExpress

ST7735 prueba

Tienes estas otras opciones: Pantalla TFT de 0,96/1,3/1,44 pulgadas IPS 7P SPI HD 65K Color módulo LCD ST7735 conducir IC 80*160 (no OLED) para Arduino|Módulos de LCD| - AliExpress

Varios tamaños a seleccionar: Pantalla TFT a Color de 1,44/1,8/2,0/2,2/2,4 pulgadas Unidad de módulo de pantalla LCD ST7735 ILI9225 ILI9341 interfaz SPI 2,8x128 128 240x320|Módulos de LCD| - AliExpress

Es posible actualizar la librería básica de adafruit (Adafruit_PCD8544) para que funcione con las placas teensy 3.x y 4.x

|500x377

Estas líneas deben estar dentro de la función begin, en el archivo .ccp para el IDE de arduino compile sin errores y cargue el skecht en la placa teensy 4, por ejemplo:

    // Set software SPI ports and masks.
    clkport     = (unsigned char*)portOutputRegister(digitalPinToPort(_sclk));
    clkpinmask  = digitalPinToBitMask(_sclk);
    mosiport    = (unsigned char*)portOutputRegister(digitalPinToPort(_din));
    mosipinmask = digitalPinToBitMask(_din);

Pues si, estos parece muy buenos y baratos. Si me interesa que tenga más de 4 líneas y más de 20 caracteres, que es lo que estoy buscando, aunque sea un GLCD, da igual, usaré por ahora caracteres.

Tengo el Teensy++ 2.0, en su moomento hice un tutorial básico en PDF que peudes ver.

Ver tutorial Teensy++ 2.0

Eso si, ahora estoy con Arduino.

Voy a indagar a ver si estos LCD los puedo usar en Arduino UNO.

Saludos.

Acá hay un tutorial para conectar esta pantalla en un arduino UNO

Muchas gracias. :D :D :D :D :D :D :D :D

Ahora conseguir ese LCD y hacer los primeros pinitos con ella.

Eso si, dejo claro que compraré junto conel LCD 40x4 que nunca lo he manipulado, jajajajjaja. El 16x2 y 20x4 lo tengo a la orden del día.

A probar que no quede.

Saludos.

Desde hace varios años he estado buscando una pantalla que tenga un buen desempeño en el entorno arduino. Han pasado por la mesa de trabajo pantallas con chips diversos: ILI9325, ILI9340, ILI9341, ST7735, PCD8544, SSD1351, SSD1306 y algunas otras mas especializadas como Nextion y SmartGPU. Como saben he dado con pantallas con chips EVE2 y hasta el momento me han dado muy buenos resultados.

Hoy conseguí una memoria microSD de 64 Gb, en específico: Kingston CANVAS Select Plus 1-V10. Al usarla con la librería actual GDT4Xv134 la pantalla NHDFT813-3.5" ¡dio un pantallazo azul!, a pesar de estar adaptada para funcionar con la librería SdFat beta V2.

Revisando a fondo la librería y estudiando un poco mas en relación a estas memorias microSD de gran capacidad, caí en cuenta que éstas memorias no se pueden formatear en Fat32, se deben formatear únicamente en exFAT.

La versión tradicional de SdFat solo soporta Fat32 lo que nos limita a usar memorias microSD del tipo SDHC de entre 4 Gb como mínimo y un máximo 32 Gb. En la práctica, la librería GD23ZUTX, puede trabajar con microSD de 16 Gb y a duras penas con 32 Gb.

La librería SdFat actual de Greiman ya tiene soporte para memorias exFAT. La modificación de la libreria para gameduino 23X en la que estoy trabajando actualmente, la reduje para ser solo compatible con placas como la teensy 4, 4.1, 3.6 y 3.5. La idea es poder usar el lector en modo de 4 bits (SDIO) y así aprovechar la máxima velocidad posible de las tarjetas microSD. Utilicé la libreria SdFat beta para administrar el contenido multimedia en la pantallas EVE2.

Teniendo esto en mente, los ajustes permiten usar tarjetas tipo SDHC, ya que la libreria está codificada para archivos Fat32, pero no para exFAT. Greiman agrupa estos diferentes tipos de archivo en lo que denomina como SDFAT_FILE_TYPE:

1 es para FAT16/FAT32
2 es para exFAT
3 es para FAT16/FAT32 y exFAT

Cada tipo está asociado a una definición de sistema de archivos:

1 File32
2 ExFile
3 FsFile

Finalmente, la definición del llamado de la tarjeta microSD es diferente:

1 SdFat32
2 SdExFat
3 SdFs

La librería fue adaptada para el tipo 1, es por ello que da error al usar la memoria microSD de 64Gb. Hay que adaptarla al tipo 3, para que puedan usarse memorias tipo SDHC y tipo exFAT. En resumen hay que agregar los argumentos siguientes, donde corresponda:

SdFs 
FsFile, FsFile&

Hoy haré los ajustes y mañana probaré el resultado, a cruzar los dedos para poder usar memorias microSD de 64 Gb y muy probablemente de 128 Gb!

Luego de varias pruebas me di cuenta que uno de los hilos del cableado del lector microSD instalado en el teensy 4 estaba desoldado, vaya, por eso me daba errores de lectura.

Los ajustes funcionan muy bien y la librería es capaz de reconocer tanto tarjetas formateadas en FAT32 como en exFAT. La memoria microSD de 64 Gb la puede reconocer sin problemas. Está en camino una memoria de 128 Gb ya veremos como se comporta, esperemos que se repitan los resultados.

Existen un par de errores que me gustaría explorar. La libreria GD23ZUTX no tiene errores cuando se combinan en una misma displaylist botones e imágenes de fondo, sin embargo puede reproducir correctamente archivos de audio.

En el caso de la versión GDT4Xv134, las imagenes de fondo y botones van muy bien, sin embargo la reproducción de archivos de audio tiene retrasos aleatorios.

Cabe señalar que con los recientes ajustes es posible subir imágenes jpg de hasta 800x600 px, el máximo teórico que puede manejar el chip FT813; esto pesar que la pantalla de 5" que tengo en el banco de pruebas, tiene una resolución de 800x480 px.

La versión del TFT de 5" con chip BT817Q que viene en camino, tiene un límite teórico de 1024x600 y 1280x800 px!!!. Ya veremos si es posible proyectar en el TFT imágenes con ese tamaño