Algunos consejos para usar TFT´s

Las correcciones funcionan muy bien, es posible utilizar la memoria de 64 Gb y la de 128 Gb, tanto en el teensy 4 como en el teensy 4.1.

En el teensy 4.1, el lector SDIO o de 4 bits viene instalado en la propia placa del MCU. En el caso del teensy 4, hay que soldar algún elemento extra en la parte inferior del PCB, ya sea un grupo de hilos delgados o bien algún PCB extra. En mi caso opté por utilizar algunos hilos y soldarlos en un adaptador microSD-SD

La solución funciona, sin embargo, hay que cuidar de no mover demasiado el adaptador, ya que alguno de los hilos o se puede desoldar o se puede dañar. Una alternativa consiste en localizar algún lector microSD comercial, quizás con algún mecanismo de retención de la tarjeta de memoria.

Tengo en mente un lector que coindice con el orden del pinout del teensy 4, sin embargo el espaciado de los puntos de soldadura es de 2 mm

Localicé un lector microSD con conexionado directo, sin resistencias intermedias, lo que lo convierte en un excelente complemento de 3.3V para el teensy 4, además coincide pin a pin con el cabezal inferior SDIO del PCB del teensy.

Adicionalmente, pude localizar un adaptador de 2 mm a 2.54 mm, para poder usarlo en un cabezal normal.

Para armar el adaptador 2-2.54 mm se puede usar una tira de pines macho, usando los pasadores individuales para soldarlos en la microSD y luego en la cara posterior del PCB-adaptador.

Finalmente, para el pinout de 2.54 mm, soldamos una tira de pines macho normal.

Me agrada bastante como ha quedado el módulo, es mas robusto y creo que tendrá buen desempeño con las pantallas FT1x/BT81x.

PD: por cierto hace unas semanas pedí a directamente a Riverdi, una pantalla EVE4 de 5", con el chip BT817. Hubo que esperar un mes aproximadamente, ya que el TFT se construye sobre pedido. Por fin ha llegado el jueves, hubo que pagar algún complemento por gastos de importación, pero ya lo tenía considerado.

Riverdi 6 Riverdi 7

Terminaré de instalar el lector microSD y seguiré con las correcciones en la librería para conseguir que funcione con microSD de mas de 32 Gb.

Seguiré con los datos de la tabla de registros específicos para esta pantalla y conseguir el constructor correcto dentro de la librería, pero para eso, hay que revisar a detalle el datasheet de la pantalla RVT50HQBNWC00-B.

Me gustaría afinar el detector de tipo de pantalla de la librería por puerto serie al iniciar el TFT; ya que por el momento, solo da números básicos como 0 para FT800/FT801 y 1 para FT813; creo que puedo conseguir leer el registro de inicio, para que muestre el chip correcto en hexadecimal: 13 para FT813 o 17 para FT817 por ejemplo.

He conseguido hacer funcionar la pantalla en la placa teensy 4. Hay varios aspectos a considerar dentro de la librería.

En esta cuarta familia de chips EVE, el pin PD debe ir conectado al MCU, recuerdo que el buen ligthcalamar encontró que las pantallas de HOTMCU necesitan de ese pin para poder resetearse correctamente tanto al subir algún sketch como al conectar el MCU a la fuente de alimentación.

El pin PD puede ir conectado a algún pin digital que tenga capacidades PWM; usé el pin 24 en el teensy 4.

Antes de iniciar la pantalla, debe implementarse una secuencia "power on reset" por software, antes aplicar cualquier otra instrucción de llamado al chip de la pantalla. La secuencia se implementó en el archivo wiring.h

pinMode(POR_PIN, OUTPUT);
digitalWrite(POR_PIN, HIGH);    
delay(100);
digitalWrite(POR_PIN, LOW);     //           |
delay(100);                     //           |
digitalWrite(POR_PIN, HIGH);    //           |
delay(100);

Luego, hay que fijar los parámetros de control específicos de la pantalla relacionados con la sincronización y relojes horizontal y vertical. De acuerdo con el datasheet del TFT. Los mejores parámetros de ajuste que han funcionado, son:

    GD.wr32(REG_HSIZE, 800);  //      Thd       visible horizontal line length 
    GD.wr32(REG_VSIZE, 480);  //      Tvd       number of visible lines 

    GD.wr32(REG_HCYCLE, 816); //808 816 896  816 Th        One Horizontal Line length (visible/invisible)
    GD.wr32(REG_HOFFSET, 8);  //4   8   48   8   Thb       HS Blanking            
    GD.wr32(REG_HSYNC0, 8);   //4   8   48   8   Thfp      HS front porch         
    GD.wr32(REG_HSYNC1, 4);   //2   4   8    4   Thpw/Thw  HS pulse width         
	
    GD.wr32(REG_VCYCLE, 496);  //488 496 504  504 Tv        VS period time         
    GD.wr32(REG_VOFFSET, 8);  //4   8   12   12   Tvb       VS Blanking            
    GD.wr32(REG_VSYNC0, 8);   //4   8   12   12   Tvfp      VS front porch         
    GD.wr32(REG_VSYNC1, 4);    //2   4   8    8   Tvpw/Tvw  VS pulse width         

    GD.wr32(REG_PCLK, 2);             //2, 1, 0       1:REG_PCLK_FREQ
	GD.wr32(REG_PCLK_FREQ, 0);        //0   
	GD.wr32(REG_PCLK_2X, 0);          //0,1
    GD.wr32(REG_SWIZZLE, 0);          //0 1  3
    GD.wr32(REG_PCLK_POL, 1);         //1, 0
    GD.wr32(REG_CSPREAD, 1);          //1,0
    GD.wr32(REG_DITHER, 1);           //1, 0

La frecuencia del bus SPI-1, la he fijado en 36 MHz. La frecuencia de la pantalla puede establecerse hasta 72 MHz, las pruebas que he realizado han dado como frecuencia óptima 64 MHz, es decir un 88.88% de la frecuencia máxima. Al acercar ese parámetro al máximo teórico la pantalla sigue respondiendo, pero el audio se acelera al reproducir video.

Finalmente, hay que leer varias veces el registro 0x0c0000, antes de iniciar el TFT, dentro del archivo wiring.h. Originalmente la libreria establece un valor de 0 para pantallas FT800/801, 1 para FT813, siguiendo esa premisa, correspondería el valor 2 para BT815/BT816 y el valor 3 sería para BT817/BT818.

Al almacenar la lectura sucesiva del valor del registro 0x0c0000 antes de subir las frecuencias de sincronización, es posible obtener el valor hexadecimal equivalente para cada familia de pantallas 0 para FT800, 1 para FT801, 13 para FT813, 15 para BT815 o 17 para BT817

    // So that FT800,801      FT810-3   FT815,6      FT817
    // model       0            1         2             3
    switch (__rd16(0x0c0000) >> 8) {
    case 0x00:
    case 0x01: ft8xx_model = 0;  BT8XX = __rd16(0x0c0000) >> 8; break;
    case 0x10: ft8xx_model = 1;  BT8XX = __rd16(0x0c0000) >> 8; break;
    case 0x11: ft8xx_model = 1;  BT8XX = __rd16(0x0c0000) >> 8; break;
    case 0x12: ft8xx_model = 1;  BT8XX = __rd16(0x0c0000) >> 8; break;
    case 0x13: ft8xx_model = 1;  BT8XX = __rd16(0x0c0000) >> 8; break;
    case 0x15: ft8xx_model = 2;  BT8XX = __rd16(0x0c0000) >> 8; break;
    case 0x16: ft8xx_model = 2;  BT8XX = __rd16(0x0c0000) >> 8; break;
	case 0x17: ft8xx_model = 3;  BT8XX = __rd16(0x0c0000) >> 8; break;
    default:   ft8xx_model = 3;  BT8XX = __rd16(0x0c0000) >> 8; break;

El monitor serie da este resultado de detección, reporta correctamente la familia del chip del TFT, la velocidad del bus SPI, dimensiones en pixeles y frecuencia del reloj del TFT:

Los leds de retroiluminación dan un tono cálido, posiblemente el tipo de chip no tiene tonos fríos por completo.

Tras algún tiempo de mantener la pantalla conectada al teensy 4, para verificar la estabilidad de la conexión del lector SDIO, manteniendo la pantalla en el bus SPI-1, por fin he podido afinar algunos detalles.

Para asegurar la estabilidad del panel táctil, es necesario instalar resistencias de 10K en modo pullup en las líneas MISO, MOSI y SCK. Sin ellas, las entradas táctiles se activan de forma aleatoria sin tocarlas. Este comportamiento ya lo había notado en las primeras placas Nucleo STM32 que se utilizaron para conectar pantallas FT813: F429ZI-DISCO1, M4DEMO (F407) y Core7XX (F746).

Con estas tres resistencias en el bus SPI1, la pantalla funciona sin problemas. Verificaré el funcionamiento de la microSD de 128 Gb, para comprobar si los ajustes para exFat, que sugiere la libreria SdFat beta2, pueden servir para usar este tipo de memorias de gran capacidad.

GDT4Xv134: librería para gameduino 23x compatible con SdFat

Aunque hay algunos puntos por revisar, creo la librería ya es operativa en la mayoría de funciones principales o widgets. Acá está el repositorio:

https://github.com/FT81xMania/GDT4Xv134

MCU: teensy 4, teensy 4.1, teensy 3.6 y probablemente teensy 3.5
TFT: las pantallas en las que me ha sido posible experimentar la librería son:
EVE: Riverdi FT801
EVE2: Riverdi: FT813 5", 7", NHD: 3.5", 4.3", 5" y 7", MO: FT813 5" (por configurar el panel táctil)
EVE3: MO: BT815 5" (inestable), 38G (por configurar el panel táctil)
EVE4: Riverdi: BT817 5"

Para el manejo de elementos multimedia (arreglos de celdas, assets, jpg, png y avi (EVE2, 3 y 4) , se puede utilizar la librería SdFat en su versión mas reciente; accediendo al lector SDIO de cada una de las placas T3x o T4x. Salvo en el teensy 4, por lo que no es necesario instalar un lector microSD.

Sigue en proceso de revisión.

En los ratos libres he podido probar el funcionamiento de la librería en una pantalla NHD de 3.5" con chip FT813. Funciona según lo esperado, las primeras pruebas las hice sin el GPS instalado, ni el DS3231. En esta oportunidad, ambos dispositivos ya están conectados al teensy 4.1... y ¡voalá!, el arreglo funciona:

Se producen algunas observaciones de compilación, pero ninguna que impida la carga del sketch en el teensy 4.1

IDE arduino: 1.8.16
Teensyduino: 1.55
SdFat: 2.0.5-beta.1, 2.1.0

Sigo afinando detalles con la pantalla BT817, hay dos registros que me llaman la atención: cmd_testcard y cmd_logo, que no están presentes en los chips FT81x. Las habilitaré en la libreria para saber su función.

Pantalla NHD FT813 3.5" en STM32F411CE

Aunque esta placa lleva un tiempo en el mercado, recientemente la descubrí mirando en el portal de ventas del fabricante; y me quiero aventurar para explorar si es que es posible darla de alta como variante en el núcleo alternativo para el IDE de arduino creada por Danieleff ( danieleff/STM32GENERIC: Generic implementation of Arduino for STM32 boards (github.com)).

He utilizado las placas STM2F103C8, F429I-DISCO, Nucleo F767ZI, M4DEMO, M3DEMO, Core7XXI, entre otras, en este core alterno para STM32 y funcionan muy bien.

Uno de los atractivos de la F411CE es su tamaño, idéntico al de la F103C8, la frecuencia de operación y principalmente, que puede recibir algún overclock para llevarla de 100 MHz hasta 150 MHz, es probable que la funcionalidad en el bus USB se vea afectada, sin embargo creo que podría ser la base de un reproductor de video compacto, ya que la usaré en algún dispositivo portátil que no dependerá de la PC

Están por llegar algunas placas perforadas de 8x12 cm, mientras tanto encontré algunas tiras de pines de 2 cm de largo, para poder instalarlos en el PCB de la F411.

Intentaré crear la variante, siguiendo la siguiente estrategia:

  1. Copiar la carpeta de la variante con chip similar a la F411CE, y ubicarla en la ruta de variantes del Core alterno: C:\arduino-1.8.16\hardware\STM32GENERIC_danielefF\STM32\variants. La variante que mas se acerca a la 411CE, es la variante Nucleo_F411RE

  2. Cambiar el nombre de la carpeta, en este caso la designaré con el nombre BLACK_F411CE

  3. En la carpeta recién creada hay tres archivos, ajustaremos el archivo variant.h para que coincida con el pinout de la F411CE, ya que no todos los pines del chip están disponibles físicamente.

Con una inspección visual del PCB de la F411CE, podemos establecer cual es el pinout disponible y procedemos a reflejarlo en el archivo variant.h. Cabe señalar que el pin del led para esta placa es PC13.

También podemos ir a la ruta:
C:\arduino-1.8.16\hardware\STM32GENERIC_danielefF\STM32\system\STM32F4\stm32_chip

y localizar el archivo de definiciones que corresponde al chip de la placa, en este caso stm32_STM32F411CE.h y copiar la definición de pines, en variant.h:

#define VARIANT_PIN_LIST_DEFAULT \

Guardamos el archivo para conservar los cambios.

El contenido del archivo varian.h será entonces:

#ifndef VARIANT_H
#define VARIANT_H

#define LED_BUILTIN PC13

#define MOSI PA7
#define MISO PA6
#define SCK PA5
#define SS PA4

#define SDA PB9
#define SCL PB8

#define VARIANT_PIN_LIST \
   PIN(A,0), \
   PIN(A,1), \
   PIN(A,2), \
   PIN(A,3), \
   PIN(A,4), \
   PIN(A,5), \
   PIN(A,6), \
   PIN(A,7), \
   PIN(A,8), \
   PIN(A,9), \
   PIN(A,10), \
   PIN(A,11), \
   PIN(A,12), \
   PIN(A,15), \
   PIN(B,0), \
   PIN(B,1), \
   PIN(B,3), \
   PIN(B,4), \
   PIN(B,5), \
   PIN(B,6), \
   PIN(B,7), \
   PIN(B,8), \
   PIN(B,9), \
   PIN(B,10), \
   PIN(B,11), \
   PIN(B,12), \
   PIN(B,13), \
   PIN(B,14), \
   PIN(B,15), \
   PIN(C,13), \
   PIN(C,14), \
   PIN(C,15), 
#endif

Con ayuda del STM32CubeMX, he podido explorar algunos posibles números para obtener un overclock en el chip; mediante prueba y error se han verificado algunas opciones. El archivo variant.c: tiene lo necesario para conseguir este experimento. Ha quedado de esta forma:

#include "stm32_build_defines.h"
#include "stm32_def.h"

extern void SystemClock_Config(void) {
  RCC_OscInitTypeDef RCC_OscInitStruct;
  RCC_ClkInitTypeDef RCC_ClkInitStruct;

  __HAL_RCC_PWR_CLK_ENABLE();

  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 16; //25-96MHz  20-120MHz  24-100MHz    16-150MHz  Menor a 16 no responde
  RCC_OscInitStruct.PLL.PLLN = 192;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 4;
  
  HAL_RCC_OscConfig(&RCC_OscInitStruct);


  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  
  HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3);

   HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}

Con PLLM en 16, es posible conseguir una frecuencia de 150 MHz.

Finalmente, debemos agregar algunas líneas al final del archivo boards.txt, ubicado en la ruta:
C:\arduino-1.8.16\hardware\STM32GENERIC_danielefF\STM32

Para poder dar de alta la nueva variante en el listado de placas del core alterno. Las líneas que he agregado son:

################################################################################
# BLACK_F411CE board

BLACK_F411CE.name=BLACK_F411CE

BLACK_F411CE.upload.maximum_size=524288
BLACK_F411CE.upload.maximum_data_size=131072

BLACK_F411CE.build.core=arduino
BLACK_F411CE.build.board=BLACK_F411CE

BLACK_F411CE.build.mcu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard
BLACK_F411CE.build.series=STM32F4
BLACK_F411CE.build.variant=BLACK_F411CE
BLACK_F411CE.build.extra_flags=-DSTM32F411CE
BLACK_F411CE.build.f_cpu=150000000L

BLACK_F411CE.upload.protocol=STLink
BLACK_F411CE.upload.tool=stlink_upload

BLACK_F411CE.menu.upload_method.STLinkMethod=STLink
BLACK_F411CE.menu.upload_method.STLinkMethod.upload.protocol=STLink
BLACK_F411CE.menu.upload_method.STLinkMethod.upload.tool=stlink_upload

BLACK_F411CE.menu.usb.SerialUSB=Serial [Virtual COM port]
BLACK_F411CE.menu.usb.SerialUSB.build.extra_flags_usb=-DMENU_USB_SERIAL

BLACK_F411CE.menu.serial.SerialUSB=SerialUSB
BLACK_F411CE.menu.serial.SerialUSB.build.extra_flags_serial=-DMENU_SERIAL=SerialUSB
BLACK_F411CE.menu.serial.SerialUART1=SerialUART1 [PA9/PA10]
BLACK_F411CE.menu.serial.SerialUART1.build.extra_flags_serial=-DMENU_SERIAL=SerialUART1

Al reiniciar el IDE de arduino, ya podemos localizar la variante que hemos creado

Probando el funcionamiento de la variante recién creada:

void setup()
{
  pinMode(PC0, OUTPUT);   //blue
}

void loop()
{
    digitalWrite(PC0, LOW); // led on
    delay(100);
    digitalWrite(PC0, HIGH);// led off
    delay(100);    
}

Ahora toca cablear la pantalla NHD-FT813 de 3.5"

Instalé el cableado en el PCB para que las uniones sean mas duraderas y no interfieran con las pruebas

VCC  (3.3V) y GND
SCK         PA5
MISO        PA6
MOSI        PA7
CS          PA4
Audio pin:  9 (TFT)
BL VCC      3.3V/5V
BL GND      GND

Ahora si la prueba de funcionamiento con el logo del chip FT813

Y nuevamente el test de saludo de toda la vida

Esta pantalla puede reproducir videos avi con audio por lo que de una vez instalé un jack de montaje superficial de 3.5.

Modifiqué la libreria GD23ZUTX para que pueda funcionar con la libreria SdFat más reciente, con la idea de que se puedan utilizar memorias SD de mas de 32 Gb.

El chip FT813 puede soportar imágenes jpg de 800x600 px; aunque la pantalla NHD de 3.5" tiene un tamaño nominal de 320x240 px, en teoría pueden subirse a la GRAM ese tipo de imágenes.

En el proyecto del GPS, los mapas que me gustaría subir son de por lo menos 800 px de largo por 400 pixeles de alto, ya que así los puedo convertir con el editor de imágenes, la idea es que cada mapa cargado en la GRAM pueda desplazarse, considerando el centro de la pantalla como el punto de referencia principal, al llegar al límite de coordenadas del mapa en pantalla, se cargará el siguiente mapa, permitiendo un mapeo de fondo continuo. Este es un ejemplo de los mapas que se podrán visualizar en el GPS:

La lectura del GPS puede realizarse en tiempo real, sin afectar la carga de imágenes en la pantalla.

He estado trabajando en el transcurso de la semana en el código que podrá permitir centrar el mapa, respecto al centro del TFT, considerando las coordenadas del GPS. Acá una muestra del resultado:

El GPS es un ublox 7, equipado con una antena externa, para mejorar la adquisición de las coordenadas. Está conectado en los pines PA2 (TX2, a RX-GPS), PA3 (RX2, a TX-GPS), del puerto USART2.

La libreria de comunicación entre la F411CE y el GPS, es una variante de la nmea (http://nmea.sourceforge.net, versión estable 0.5.3), corregida por el amigo RndMnkIII. Estoy preparando el repositorio github para compartir la libreria con los ajustes para STM32. En sus experimentos logró ajustar algunas funciones para poder estimar las coordenadas UTM y en grados decimales. Para que las conversiones funcionen correctamente es necesario utilizar la unidad de punto flotante de la placa STM32, definiendo las variables principales como double.

Adjunto el ejemplo que permite procesar las lecturas provenientes del GPS, también funciona en la placa Core7XXI (STM32F746IG)

CORE7XXI_nmealib_GPS_cadenas.zip (7.1 KB)

Pantalla ST7735 con panel táctil en F411CE

Es posible conectar otro tipo de pantallas con chips como el ST7735 en la variante F411CE, utilizando las librerías mas recientes de adafruit. Con lo aprendido en la librería GD23ZUTX, creo que es posible utilizar la librería SdFat V2 para el manejo de archivos de imagen.

Bueno lo primero, el TFT ST7735 que vamos a instalar es este:

El pinout del TFT lo vamos a conectar de esta forma:

ST7735_wiring

Para evitar algún fallo, sugiero conectar cada unión con hilos individuales soldados entre un cabezal hembra de 6 pines dobles y a cada pin del zócalo del MCU.

PCB1 PCB2

Estas son las líneas para el encabezado de configuración:

#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library for ST7735
#include <SPI.h>

#define TFT_CS        PA4//10
#define TFT_RST       PA0//8
#define TFT_DC        PA1//9

Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);

¡Funciona!

PCB3

La pantalla y el panel táctil están conectados al bus SPI 1. Podemos utilizar la librería XPT2046_Touchscreen, comentando las líneas que llaman a la función attachInterrupt, dentro del archivo ccp. La forma de usar esa función en STM32 es diferente a como se utiliza en ARM o AVR. No obstante, creo que aun podemos usar sin problemas esta librería sin recurrir al uso de interrupciones.

El lector externo está ya conectado en el bus SPI2, así que podemos aprovecharlo para ver si funciona para cargar imágenes bmp en la memoria de la F411CE. Podemos partir de las líneas que se utilizaron en GD23ZUTX, agregándolas en el encabezado

#include <SdFat.h>
#define SD_CS    PB12
#define SetSDSpeed  36
static SPIClass SPI_2(SPI2, PB15, PB14, PB13);
#define SD_CONFIG SdSpiConfig(SD_CS, DEDICATED_SPI, SD_SCK_MHZ(SetSDSpeed), &SPI_2)
SdFs SD;

En el setup, podemos iniciar el lector externo con esta línea:

SD.begin(SD_CONFIG);

En la red hay varias modificaciones de la función bmpDraw, que dependiendo de las modificaciones en la librería Adafruit_GFX utilizan ya sea writeRect o pushColor o alguna combinación entre ellas y alguna matriz para almacenar los patrones de colores RGB. La función pushColor se quedó solo como un comentario en la libreria GFX:

// displays supporting setAddrWindow() and pushColors()), but haven't
// implemented this yet.

En la versión mas reciente de la librería GFX, podemos usar writeRect, ya que es la que está definida, con ella podemos intentar leer las líneas del archivo de imagen para reconstruirla en la memoria de la pantalla, quizás no obtengamos una buena velocidad pero es posible que las optimizaciones de la librería SdFat V2 nos den un impulso extra.

Adjunto el ejemplo para poder verificar el funcionamiento del TFT-ST7735, el panel touch XPT2046 y el lector externo.

F411CE_ST7735_Test.zip (207.3 KB)

El panel táctil también funciona y la carga de imágenes, usando la writeRect dentro de bmpDraw, tal parece que si funciona!!!

Para poder inicializar el TFT, el panel táctil y el lector microSD el encabezado y el setup quedó así:

#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library for ST7735
#include <SPI.h>
#include <SdFat.h>
#include <XPT2046_Touchscreen.h>

#define CS_PIN  PA2  //touch

#define TFT_CS        PA4//10
#define TFT_RST       PA0//8
#define TFT_DC        PA1//9

XPT2046_Touchscreen ts(CS_PIN);
#define TIRQ_PIN  PA3//2

Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);

#define SD_CS    PB12

#define SetSDSpeed  36
static SPIClass SPI_2(SPI2, PB15, PB14, PB13);
#define SD_CONFIG SdSpiConfig(SD_CS, DEDICATED_SPI, SD_SCK_MHZ(SetSDSpeed), &SPI_2)
SdFs SD;

int x=0, y=0, Rotacion=3;
char PXY[40];
boolean wastouched = true;
boolean istouched = false;

void setup() {
 SD.begin(SD_CONFIG);
  
 tft.initR(INITR_BLACKTAB);
 tft.setRotation(Rotacion);
 tft.fillScreen(ST77XX_BLACK);

 bmpDraw("tiger.bmp", 0, 0);
  
 ts.begin();
 ts.setRotation(Rotacion);
}

La calibración táctil con esta librería depende de la rotación de la pantalla, debe ser igual a la rotación del panel táctil. Las coordenadas que se obtienen con la librería no pueden usarse directamente para calcular los pares (x,y), ya que son datos de resistencia eléctrica, que varia según el lugar que se presione en el panel táctil.

Los pares (p.x, p.y) deben ser convertidos a (x,y) mediante dos funciones de mapeo que vinculen la superficie de la pantalla con cada resistencia eléctrica.

Para obtener los valores máximo y mínimo en cada dirección, se debe obtener un promedio de los datos obtenidos en cada esquina del panel táctil, luego con ellos podemos usar la función map para poder relacionarla con los pixeles que tiene la pantalla. En este caso las dos funciones de mapeo que he podido conseguir son:

x = map (p.x, 201, 3950, 0, 160);     
y = map (p.y, 3850, 340, 0, 128);   //ST7735 1.8", rotación 1

Con lo aprendido hasta ahora, por fin es posible construir una interfaz para controlar un ventilador PWM, empleando una de las pantallas táctiles FT813, decidí utilizar una placa F411CE, por su tamaño compacto y porque sería mi primer placa STM32 usada en un proyecto para la PC. Usaré el dispositivo para controlar el ventilador lateral del gabinete. En algunas ocasiones ya sea por los días calurosos, el uso de algún juego demandante en la PC o bien alguna sesión de trabajo que implica el procesamiento de videos o una elevada carga de uso del GPU, resulta en que el chipset se calienta demasiado y me gustaría bajarle la temperatura.

El PCB del control lo instalaré en el lateral del gabinete, mas adelante me gustaría diseñar una ventana transparente en el lateral, donde habrá mejor forma de fijar tanto el ventilador como el TFT. La idea es mostrar como es que se puede usar uno de esos TFT en un proyecto.

Acá las piezas

Lo primero es construir un cabezal para sujetar la STM2F4111, permitiéndonos soldar todo el cableado para que luego no haya sorpresas. para ello usaré dos tiras de 40 pines hembra

Recortando los pines sobrantes y puliéndolos un poco con una lima. Así quedó luego de soldar en la cara posterior de la placa perforada

Para sujetar el TFT hay que armar un cabezal de 20 pines, retiramos los pines excedentes con unas pinzas de corte y luego pulimos el lateral del cabezal con una lima

Podemos aprovechar para instalar algunas tiras de pines macho en ángulo recto, que funcionarán como cabezales laterales para conectar los relevadores y algunos hilos de energía, hay que ubicar el cabezal del TFT de tal forma que sea posible instalar y retirar el TFT sin problemas

La pantalla tiene la capacidad de reproducir videos en formato avi con audio, así que podemos agregar un jack de 3.5 mm para poder usar esta característica y darle otro uso a la pantalla en cualquier momento.

Estos zócalos de superficie, viene con un par de centradores en la base, los podemos cortar para fijarlos de mejor forma en el PCB

El PCB del controlador ya va tomando forma

Primero toca conectar las uniones del MCU al TFT.