Librería gameduino 2 modificada para pantallas FT81X

Desde hace algunos meses GD3 estaba dejando olvidadas a placas como el arduino UNO o el arduino NANO.

El tema volvió a la mesa gracias a algunas pruebas que está haciendo lightcalamar. El hecho de que la librería use casi toda la memoria, solo por la inclusión de un par de imágenes en la calibración o en el pantallazo de error, no me parece justo.

Al principio optamos por tener GD2 y GD3 por separado. Esa situación fue resultado de una falta de conocimiento personal de la modificación de la librería. Con el paso del tiempo y con muchas pruebas e infinidad de errores, hoy por fin tenemos una librería que puede usarse para FT81X como para FT80X, con tan solo manipular algunos "#defines" en el archivo GD23L.h

Librería GD23L

La versión es lo mas ligera posible. Funciona tanto para placas teensy 3.X como arduino UNO, Due, MEGA o NANO. Las pruebas se realizaron en el IDE 1.80.

Link: GD23L

#define CS               10 //10 Riverdi-shield   8  gameduino2
#define SD_PIN            5 // 5 Riverdi-shield   9  gameduino2

#define TFT_FT81X_ENABLE  1   //            FT81x
#define ORIENTACION       0   //0, 1, 2, 3, FT81X 

#define PROTO             0   //0 FT80x alternatives, 1 gameduino2
#define ROTACION          0   //0,  1       FT80x

Cuando establecemos:

TFT_FT81X_ENABLE   1

Los parámetros de frecuencia y de configuración de las pantallas FT81X, se seleccionan de forma automática

Esta linea:

#define ORIENTACION       0   //0, 1, 2, 3, FT81X

Permite establecer la orientación que deseamos en la pantalla

PROTO y ROTACION solo funcionan cuando:

TFT_FT81X_ENABLE   0

Esto permite establecer que la pantalla que está conectada al MCU, es una pantalla de la familia FT80X. Nuevamente los parámetros de frecuencia, orientación y manejo de colores (instrucción PROTO) se establecen de forma automática, sin interaccionar con los parámetros de la familia FT81X.

Hay pocos ejemplos, no obstante se pueden usar los que hemos tratado a lo largo del post para GD2 o GD3; siempre y cuando no superen el espacio de memoria de programación. En una subsecuente revisión trataré de incluir algunos más e insertaré la función para imprimir números decimales.

Ésta versión inicial solo cuenta con los ajustes para FT813, trataré de incluir los correspondientes a FT810, FT811 y FT812.

Resta obtener la versión para SDIO (Teensy 3.5/3.6). No prometo una versión con imágenes en la calibración o en el pantallazo de error; pero, intentaré ver que tanto se incrementa el uso de memoria de programación.

PD: por cierto faltan los parámetros de configuración para las pantallas de HotMCU.

Pues si! Tienes mucha razón y claro q ese grano de arena aporta mucho, en lo personal me Ayuda un montón. Aunq mi proyecto no sería tan complejo, me gusta la idea de poder trabajar con la librerías de GDx por su mayor capacidad de recursos.

Ok.

En el transcurso de la semana actualizaré el repositorio.
Quedando mas o menos de esta forma;

  • GD2_HOTMCU (Arduino MEGA)
  • GD3_HOTMCU (Arduino MEGA)
  • GD23L_HOTMCU (Arduino NANO y UNO

De esta forma prefiero qeu convivan las 3 librerías para las pantallas HOTMCU.

@juanjqh, si te inclinas hacia las pantallas de HOTMCU y quieres usar Teensy, te aconsejo la versión 3.5, porque la versión 3,6 no es tolerante a pins de 5v. Si vas a usar Arduino UNO o mega no hay problema.

El enunciado.

BOMBAZO al canto para pantallas FT81X

Este mensaje trata de obtener múltiples ASSETS con lo cual podemos superar la barrera del Mega de RAM de las pantallas FT81X (y posiblemente en creces también las pobre FT80X). Hoy he realizado un simple test y funciona correctamente.
Que es lo que funciona?

Por ejemplo podemos tener 4 MEGAS de RAM (o mas... indefinido por la flash de nuestra placa ARV o ARM) para estas FT81X ... pero si solo admiten 1 MEGA de RAM ?... si pero hay una técnica que lo hace viable. Voy a resumir y escribir lo mas preciso posible.

Hace meses atrás concretamente antes de Navidad del año 2016 leí este mensaje en Foro de James de como se podría leer en la microSD múltiples ASSETS convertidos y me puse manos en la obra y como es obvio, ni me llegó a compilar por errores, y estos eran debidos, hoy me dí cuenta por la falta de no presentar correctamente las definiciones de las imágenes convertidas a través de la herramienta gd2asset para windows. Este es uno de los errores que cometí. Bueno yo no, la tools no puede mas en el sistema de las ventanas.

Mensajes míos atrás, he escrito que existe otra herramienta (Gd3asset) en mi repositorio del cual está modificado por mi y listo para compilar en Linux(documentación adjuntada en el mismo) el cual es totalmente operacional sea para FT81x o FT80x da igual, las limitaciones la pondrá el chip de su sistema.

Vamos al caso y porque se puede usar superiormente en las FT81x mas alla del mega de RAM.

Supongamos que nos hemos leído mi proyecto MDC v1.0 y aparte que fué escrito en FT800(480x272 pixels) y hace unas semanas lo estoy exportando a FT810(800x480 pixels) la realidad he encontrado, aun subiendo el tamaño de los iconos del proyecto y siempre observando el "limite" del MEGA que da la RAM de FT810, he realizado maravillas ... y hoy leí sin querer el mensaje de James;

Right, if you manually edit the LOAD_ASSETS() macro in each file - e.g. to LOAD_ASSETS_1(), LOAD_ASSETS_2() etc. then you can load each set in turn using the appropriate macro.

Each set of assets will load at address 0, overwriting the previously loaded set.

If you're displaying existing assets and you load new assets, then the overwrite will be visible. This may not be what you want, so to prevent the glitching you can show a loading message:

GD.Clear()
GD.cmd_text(240, 136, 31, OPT_CENTER, "Loading...");
GD.swap();
LOAD_ASSETS_1();

Esto, hoy me dio una idea, porque no usar esta técnica? En la cita se dice que al cargar un assets nuevo se sobrescribe el anterior cargado ... esto quiere decir lo que es una memoria RAM, es volátil. Revisé la posibilidad de unas funciones para borrar la RAM Gráfica de las FT8XX sin resultado en la documentación de FTDI (la del fabricante, vamos). Después la lógica, una RAM solo se escribe y si deseas sobrescribir en un "tiempo" determinado es realizar una nueva escritura desde el inicio ... Si señor así reza la técnica.

Escribo un simple ejemplo;

void radio() {
  LOAD_ASSETS_1();
    GD.BitmapHandle(RADIOA_HANDLE);          
    GD.BitmapLayout(ARGB4, 2 * 450, 450);
}

....

....

....

void gps() {
  LOAD_ASSETS_2();
    GD.BitmapHandle(GPS_HANDLE);          
    GD.BitmapLayout(ARGB4, 2 * 150, 150);
}

y así mas. Se define en cada función, los iconos, imágenes convertidas, pero esto si importante, en cada función no puede superar el MEGA de RAM, pero ya si nos vamos a otra función la segunda "machaca" a la primera y así infinito ... Aquí una DEMO de todo lo escrito

En pocas palabras, en mi proyecto, tengo que "resubir" los logotipos del Radio de FM de mi proyecto (actualmente 64x64 a 150x150) podré inclusive en el apartado del radio poner iconos de mayor tamaño, en mi GPS poner iconos por ejemplo de unas antenas en "movimiento" ... etc ... vuelta a empezar.

Adjunto mi código actual de mi proyecto.

Exportando las imágenes png (transparentes) en formato ARGB4, son de una calidad infinita y muy buenas, esto sí en mi T35 (Teensy 3.5) ahora sí que voy a quizás a exportar el proyecto definitivamente, simplemente por velocidad, que ya la experimenté en su día con el ejemplo "Hello Wold" ...

GD_MDC_B12a_FT810-170510a.zip (33.4 KB)

Buenas.
He realizado mas pruebas y todo es correcto.

He podido realizar ASSETS inclusive con fuentes personalizadas en cada "pantallazo" o función, una autentica maravilla el camino que está tomando estas técnicas hacía pantallas FT8XX.

Las transiciones son muy aceptables, llegado el caso que estoy usando Arduino modelo MEGA.

En mi trabajo he reparado amplificadores de alta gama de marcas como; Panasonic, Denon, Harman Kardon etc y lo bueno son los VFD que usan como display por puntos, entonces estoy buscando estas fuentes para poder adaptarlas a mi necesidad de mi MDC (Multi Data Center), por cierto ya va en fase de la v2.0.

Concretamente el superar que la pantalla en mi mensaje anterior tengamos múltiples ASSET_LOADx, es sin lugar a dudas lo mejor que le han podido pasar a estas, y como escribí hasta las pobres FT800 ...

Pondré en breve algunas capturas.

He aquí un tipo de fuente VFD

Aportazo mi estimado, eso significa que cada pantalla individualmente, puede usar toda la memoria gráfica disponible. Gracias.

Si tienes salidas a 10 pantallas diferentes, con la técnica que has usado potencialmente dispones 10 megas de memoria gráfica!!!

Sin olvidar que tienes a la mano la posibilidad de arreglos en forma de celdas mas grandes. En verdad que ese gd3asset tiene mucho que dar. Me viene a la mente el trabajo que tratamos de sacar adelante con los iconos de las emisoras de radio que tienes en el proyecto en un solo asset, al parecer has superado el limite de 16 que tantos dolores de cabeza dio.

PD: aun no he encontrado mi RPi-3, me da que tendré que ahorrar para conseguir otro y meterle mano a Linux para sacarle provecho a GD3asset.

Es totalmente impresionante esta nueva forma de exprimir la RAM de las FT8xx. Y decirte que globalmente la flash del MCU no se "infla" es decir ni espacio, ni variables, todo queda en la microSD. digamos que es otra forma de "carga" de imágenes desde la microSD, sin usar el cmd_loadimage()

He usado no obstante la técnica de los sprites donde un fichero, por ejemplo mis logotipos del Radio, son de 120x120 pixels y van 10 osea 120x1200 pixels por 3 y sin problemas. Convertidos en ARGB4, una máxima calidad y eso que estuve meses atrás de como convertir todo el sistema en un solo mega de RAM, ZAS !!! Adiós !!!

Solo puedo decirte amigo mio TFTLCDCyg, cuando vi que funcionaba, hasta unas lagrimas salieron de mis ojos y posiblemente ha sido la alegría mas grande que estas "caprichosas y cabronas" de pantallas me han dado.

Hace dos semanas recibí mis flamantes 2 FT810 y 1 FT811 de HotMCU, estas van a tener una buena vida y por que no decir usar la misma técnica en FT80x? con 256K de RAM se hacen muchas cosas ... tu bien lo sabes ... :slight_smile:

Otra cosa que he investigado una vez incluido el fichero en el inicio de la hoja por ejemplo;

#include "logos.h"

En este mismo se puede incluir todos los .h que usaremos de "todas" las pantallas. Ejemplo;

#define LOAD_ASSETS_3()  GD.safeload("fontad7.gd2");
#define FONTAD7_HANDLE 0
#define FONTAD7_WIDTH 22
#define FONTAD7_HEIGHT 32
#define FONTAD7_CELLS 96
// #define ASSETS_END 33940UL
static const shape_t FONTAD7_SHAPE = {0, 22, 32, 0};


#define LOAD_ASSETS_6()  GD.safeload("radiofm.gd2");
#define RADIOFM_HANDLE 0
#define RADIOFM_WIDTH 100
#define RADIOFM_HEIGHT 200
#define RADIOFM_CELLS 1
// #define ASSETS_END 40000UL
static const shape_t RADIOFM_SHAPE = {0, 100, 200, 0};

#define LOAD_ASSETS_1()  GD.safeload("master.gd2");
#define MASTER_HANDLE 0
#define MASTER_WIDTH 128
#define MASTER_HEIGHT 1280
#define MASTER_CELLS 1
// #define ASSETS_END 327680UL
static const shape_t MASTER_SHAPE = {0, 128, 1280, 0};

#define LOAD_ASSETS_2()  GD.safeload("radioa.gd2");
#define RADIOA_HANDLE 0
#define RADIOA_WIDTH 120
#define RADIOA_HEIGHT 960
#define RADIOA_CELLS 1
#define RADIOB_HANDLE 1
#define RADIOB_WIDTH 120
#define RADIOB_HEIGHT 960
#define RADIOB_CELLS 1
#define RADIOC_HANDLE 2
#define RADIOC_WIDTH 120
#define RADIOC_HEIGHT 960
#define RADIOC_CELLS 1
#define LEDS_HANDLE 3
#define LEDS_WIDTH 32
#define LEDS_HEIGHT 64
#define LEDS_CELLS 1
#define SPEAKER_HANDLE 4
#define SPEAKER_WIDTH 64
#define SPEAKER_HEIGHT 192
#define SPEAKER_CELLS 1
// #define ASSETS_END 707584UL
static const shape_t RADIOA_SHAPE = {0, 120, 960, 0};
static const shape_t RADIOB_SHAPE = {1, 120, 960, 0};
static const shape_t RADIOC_SHAPE = {2, 120, 960, 0};
static const shape_t LEDS_SHAPE = {3, 32, 64, 0};
static const shape_t SPEAKER_SHAPE = {4, 64, 192, 0};

y hay que tener cuidado en los desmarcados;

// #define ASSETS_END 33940UL

o eliminar o desmarcar, porque lo que hace la instrucción es definir donde acaba de escribir en RAM. Al desmarcar o borrar la linea significa que no hay fin de escritura. Esto es muy importante.

Despues de experimentar con cada "pantalla" para imprimir las imágenes de los múltiples assets, he descubierto un bug.

Si definimos el comando;

LOAD_ASSETS_x();

fuera de un "loop", sí la memoria "no se ha limpiado del todo" obtendremos rayas y no concuerda la imagen a representar con la elegida en el comando.

Entonces para que todo vaya correcto, tenemos que posicionar muy bien la forma. He aquí un ejemplo:

void relojes() {

   
      delay(1000); 
      GD.BitmapHandle(CUCUA_HANDLE);           
      GD.BitmapLayout(ARGB4, 2 * 100, 100); 

      GD.BitmapHandle(CUCUB_HANDLE);           
      GD.BitmapLayout(ARGB4, 2 * 210, 350);

      GD.BitmapHandle(CUCUC_HANDLE);           
      GD.BitmapLayout(ARGB4, 2 * 250, 250);                

      do {
      
      // ********* MUY IMPORTANTE **************************
      LOAD_ASSETS_4();       //  <----  AQUI DE CARGA LOS ASSETS
      // **************************************************      
      DateTime now = rtc.now();
      GD.get_inputs();
      GD.ClearColorRGB(BLUEDARK);
      GD.Clear(1, 1, 1);
      
      GD.ColorRGB(WHITE);

      GD.Begin(BITMAPS);    
      GD.SaveContext();
      GD.VertexTranslateX(16*150);
      GD.Vertex2ii(400, 95, 1, 0);
      GD.RestoreContext(); 

      GD.SaveContext();
      GD.VertexTranslateX(16*150);
      GD.Vertex2ii(380, 185, 2, 0);
      GD.RestoreContext(); 

      GD.SaveContext();
      GD.VertexTranslateX(16*150);
      GD.Vertex2ii(350, 75, 0, 0);
      GD.RestoreContext(); 

... ... ...

... ... ... 

      GD.swap();
     }
   while(1);
 }

Donde se incluye las imágenes;

#define LOAD_ASSETS_4()  GD.safeload("relojes.gd2");
#define CUCUA_HANDLE 0
#define CUCUA_WIDTH 100
#define CUCUA_HEIGHT 100
#define CUCUA_CELLS 1
#define CUCUB_HANDLE 1
#define CUCUB_WIDTH 210
#define CUCUB_HEIGHT 350
#define CUCUB_CELLS 1
#define CUCUC_HANDLE 2
#define CUCUC_WIDTH 250
#define CUCUC_HEIGHT 250
#define CUCUC_CELLS 1
// #define ASSETS_END 292000UL
static const shape_t CUCUA_SHAPE = {0, 100, 100, 0};
static const shape_t CUCUB_SHAPE = {1, 210, 350, 0};
static const shape_t CUCUC_SHAPE = {2, 250, 250, 0};

Es decir dentro del "loop" hemos de poner el LOAD_ASSETS_4 si lo ponemos fuera, obtendremos solo rayas
Saludos.!

Esas lineas que ves en la transición de imágenes, ocurren debido a la baja velocidad del MCU, aun en el teensy 3.6@240 Mhz pueden llegar a verse. Se acentúan en FT80X, debido a la velocidad de procesamiento de imágenes que tiene ese chip, aunque el FT81X es 500 a 1000 veces mas rápido en la carga de JPG, debemos considerar que en los assets estamos adicionando el manejo de los slots de memoria para imagenes, que no cuentan con la misma velocidad de procesamiento.

Una técnica que permite eliminar esas distorsiones visuales, es llamando una pantalla intermedia de procesamiento, como en este ejemplo:

Carga de grupos de assets

Merece la pena que un día nos compartas un pequeño manual con el manejo de assets en FT81X. Todo lo que has podido experimentar con ellos, vale un libro XD. Gracias.

Debido a la falta de tiempo por varias circunstancias, creo que se me está olvidando como usar los assets!!!...

PD: ya que tenga la R-Pi3 en las manos le dedicaré un tiempo a liarme con la consola de linux para luego adentrarme en esa gd3asset que has creado, tengo algunos pequeños juegos de video en mente y me vendrá muy bien aprender a crear archivos de sprites: el siguiente nivel con el tema de los assets y solo se consiguen crear en Linux. Por supuesto que subiré los pasos y los códigos.

Aun no he localizado el código del ejemplo que me pediste, no recuerdo como lo llamé en su momento XD, pero ten por seguro que lo encontraré.

TFTLCDCyg:
Esas lineas que ves en la transición de imágenes, ocurren debido a la baja velocidad del MCU, aun en el teensy 3.6@240 Mhz pueden llegar a verse.
Merece la pena que un día nos compartas un pequeño manual con el manejo de assets en FT81X. Todo lo que has podido experimentar con ellos, vale un libro XD. Gracias.

Creo que estriba en la velocidad del MCU, Arduino MEGA da mucho juego pero muy lento. En fin,, por cierto localicé una Teensy 3,2 en china muy barata, unos 12€ y estoy a la espera.

Novedades de hoy 17 de Mayo de 2017

Hoy será un buen día para recordar sin lugar a dudas. Hoy después de 3 días por fin pude compilar la herramienta GD3assets para las pantallas FT81x en Windows. Es decir ya existe tal herramienta pero es una versión privada y si todo es decidir, posiblemente sea publica para todos aquellos que nos leen.

No me gusta adjudicarme nada que no sea mio. Ahora bien si desde las fuentes al autor de las mismas se respeta su "copyright", ademas con su consentimiento y posiblemente al mismo pedirle que lo modificase él creo sería un poco desafortunado. Si las fuentes se dejan "otros" las puedan usar para sus fines, es otra etapa nuevas para usar, si partimos que la shield Gameduino2 esta muerta(no se consique por ningún lado) , pantallas de HotMCU, Riverdi, etc ... porque no pueden usar una herramienta altruista?

Creo que soy el único que la usaba en Linux (así lo hice publico), por la facilidad de compilar un ejecutable, sin embargo sé de los dolores de cabeza que puede producir, entrar en un sistema desconocido, (aunque para mi sencillo) desde las fuentes originales he tenido que combatir con Python en windows y ha sido una batalla ganada.

Bien sabes TFTLCDCyg que ya no uso Windows, sin embargo me gustan los retos, casi dos noches con pesadillas de "errores" y después de empezar desde cero, ya que el ejecutable de GD2Asset esta originalmente escrito para compilar en Linux y no Windows. Toda una aventura ...

Una contribución mas a estas grandes y cabronas ( :slight_smile: :slight_smile: :slight_smile: ) de pantallas.

P.D. No voy a olvidar a Javier, la persona que condujo parte del código a modificar superando las barrera de los 256KBytes, desde estas lineas un saludo si nos lee!
P.D.2 Amigo TFTLCDCyg no desistes con la RB pi3, sin embargo la puedes poner en su cajón. :wink:

El hecho es que GD2 se quedó a la espera de algunas modificaciones y con las desveladas de los tres, hemos llegado hasta este punto. He podido ver en todo este tiempo, que varios entusiastas la han tomado como base, pero no se han aventurado a lo que se ha conseguido acá.

GD3 merece llamarse así, tanto como GD3ASSET debe tener su lugar. En cuanto disponga de un tiempo abriré un post en aquel foro, que por supuesto llevaré el nombre de los tres involucrados en este proyecto que parecía muy ambicioso, y que poco a poco nos ha llevado a este punto.

Lo mas probable es que hayan sido los costos del hardware para ensamblar el gameduino3, sin olvidar alguno que otro hecho de la vida real; que a todos nos afecta en un momento dado.

Debo darles las gracias: ligthcalamar y RndMnkIII, por embarcarse en un hobby algo extraño, lleno de desveladas y que parece que nos ha enganchado a mas de uno.

Un primer ejemplo con GD3ASSET:

30 iconos de 64 x 64, con la famosa imagen aquella como fondo...

TFTLCDCyg:
El hecho es que GD2 se quedó a la espera de algunas modificaciones y con las desveladas de los tres, hemos llegado hasta este punto. He podido ver en todo este tiempo, que varios entusiastas la han tomado como base, pero no se han aventurado a lo que se ha conseguido acá.

GD3 merece llamarse así, tanto como GD3ASSET debe tener su lugar. En cuanto disponga de un tiempo abriré un post en aquel foro, que por supuesto llevaré el nombre de los tres involucrados en este proyecto que parecía muy ambicioso, y que poco a poco nos ha llevado a este punto.

Opino igual que tu amigo mio TFTLCDCyg, lo que se ha conseguido aquí no tiene precio, no tiene quizás un premio, sin embargo, y yo soy de aquellas personas, ya me conoces, lo mejor que me pasó en un año y algo fue conoceros a los dos, osea tu y RndMnkIII, algo desaparecido por cierto su nuevo trabajo actual, pero volverá a darnos sorpresas estoy muy seguro.

Nuestro precio a sido, robar días, horas a nuestras familias, depositar en nuestra cuenta y comprar pantallas, artilugios etc ... sin ningún tipo de subvención y que contar mas !!!

No me da envidia lo que mucho sabe como es nuestro amigo James Bowman al contrario gracias a él se sabe infinidad de "acertijos" ... y como no las gracias a él obviamente.

Gracias a él, por dejar las fuentes he podido modificar a mi antojo, y a ti te funcioné a día de hoy, y ten la seguridad que ha sido mas por manía mía o llamarle antojo propio, pero sé que leyendo el foro de James, muchos con son los que tienen el problema de convertir los Assets con Python.

Después de dos días de algunas "pesadillas" y (esto que conmigo lo tenía solucionado en Linux) y sea factible en Windows a día de hoy, la verdad que doy por enterrado éstas, me alegro muy, pero que muy mucho. Y como bien dices, si tu ya eres feliz, hagamos a los demás lo sean también.

A todo esto, quizás en un futuro, (dependiendo de nuestro hobby, claro está) se podría modificar el apartado por ejemplo de generar los ficheros dentro de los script que localicé y tienen una resolución de FT800 (480x272) esto se puede modificar comprimiendo con zlib a Python en 800x480 y dejar mas espacio para RAM. De esto sé un poco como desarrollarlo, y mas cosas. El tema de modificar el fichero .gd2 está "casado" con la librería y esto entonces es otro trabajo mas, Se puede hacer, una salida .gd3 como ficheros, pero es un poco laborioso. Bastantes cosas se pueden modificar ya sabiendo que cada "pantalla" es un MegaByte!!!

Saludos.

Bueno pues tratando de retomar las notas de escuela, directo me fui con el tema de las fuentes y una primer excepción:

Creo que es pedirle demasiado a la herramienta en el entorno de Windows. ¿Crees que es posible solventar esa falla?

PD: no pasa nada si no es factible, no me escaparé de aprender el manejo de la consola de Linux, para poder darte una mano; ya viene en camino una segunda R-Pi3. Tengo mucha curiosidad.

Es un problema de las fuentes usadas por Python con el modulo PIL en Windows. En Linux no da este problema.
Este es el código usado.

def load_ttf(self, name, ttfname, size, format):
        font = ImageFont.truetype(ttfname, size)
        sizes = [font.getsize(chr(c)) for c in range(32, 128)]
        fw = max([w for (w, _) in sizes])
        fh = max([h for (_, h) in sizes])
        # print fw, fh
        alle = {}

He encontrado esta posible solución modificando el modulo PIL, python - How I can load a font file with PIL.ImageFont.truetype without specifying the absolute path? - Stack Overflow

y el repositorio: Included linux font directory in truetype by aeroaks · Pull Request #682 · python-pillow/Pillow · GitHub
Le echaré un vistazo a ver que se puede hacer.

Jejeje tenías razón... he estado algo ocupado con GD3ASSET y tratando de arreglar la PC, que en días pasados se fastidió la fuente y se llevó consigo el disco del sistema operativo y otro más de respaldo... estoy tratando de recuperar lo mas posible.

FT81X: MSGEQ7 Rolling Graph

Dejo un ejemplo para dibujar gráficas lineales, el cual he podido rescatar de entre los escombros de la anterior PC...

Traza en forma de linea continua, 7 bases de datos; en el ejemplo almacenan 145 datos cada una.
En este arreglo especifico, el máximo posible es de 185 datos, mas allá de este valor el FT813 colapsa debido a que supera el limite de instrucciones que puede presentar en pantalla.

Al reducir el número de bases de datos, la capacidad de almacenamiento se va incrementando, alcanzando hasta 780 datos en el caso de presentar una base.

Este ejercicio, permite ver la capacidad de procesamiento gráfico que tiene el chip FT81X. Hay algo de complicidad con el MCU, por lo que el orden de velocidad quedaría (mayor a menor) T36-Due-MEGA; el UNO que da fuera por el tema de la memoria.

Software:
IDE 181, teensy loader 1.35 beta 2, librería GD23L

Hardware:
Pantalla: Riverdi FT813 5"
MCU: Teensy 3.6@240 MHz
Otros: Riverdi breakout 20, Quad MSGEQ7
Fuente de audio: placa de audio de la PC

Link del sketch

PD: alguna vez alguien me dijo que este tipo de gráficas solo eran viables en STM32... estas pantallas aun tienen sorpresas bajo la chistera... solo falta que salten conejos!

Wow!! que bien esto me da ideas ...

Ahora soy yo el que está atascado. He usado tu ejemplo del GD3_MSGEQ7_Spectrum_analyzer y va bien, pero un problema.

Asi es como me queda una vez modificado;

Para ello he usado los 15 handles de las 15 imagenes y lo que quiero es ponerlas todas en un fichero concretamente lo adjunto ya preparado, sin embargo en la parte del código donde se representa es;

  GD.Vertex2ii(XbaseD+Xdelta*0, 215, map(left[0],0,1024,0,15)); 
  GD.Vertex2ii(XbaseD+Xdelta*2, 215, map(left[1],0,1024,0,15)); 
  GD.Vertex2ii(XbaseD+Xdelta*4, 215, map(left[2],0,1024,0,15));   
  GD.Vertex2ii(XbaseD+Xdelta*6, 215, map(left[3],0,1024,0,15)); 
  GD.Vertex2ii(XbaseD+Xdelta*8, 215, map(left[4],0,1024,0,15));
  GD.Vertex2ii(XbaseD+Xdelta*10, 215, map(left[5],0,1024,0,15));
  GD.Vertex2ii(XbaseD+Xdelta*12, 215, map(left[6],0,1024,0,15)); 
  GD.Vertex2ii(XbaseD+Xdelta*14, 215, map(R[0],0,1024,0,15));
  GD.Vertex2ii(XbaseD+Xdelta*16, 215, map(R[1],0,1024,0,15));  
  
  
  GD.SaveContext();
   GD.VertexTranslateX(16*260);
   GD.Vertex2ii(440-165, 215, map(R[2],0,1024,0,15));      
   GD.Vertex2ii(440-110, 215, map(R[3],0,1024,0,15));    
   GD.Vertex2ii(440-55, 215, map(R[4],0,1024,0,15));
   GD.Vertex2ii(500-60, 215, map(R[5],0,1024,0,15));   
   GD.Vertex2ii(500, 215, map(R[6],0,1024,0,15));   
  GD.RestoreContext();

en donde pone GD.Vertex2ii(440-165, 215, map(R[2],0,1024,0,15 en negrilla significa las imágenes, sin embargo yo las tengo por celdas.

Realice la conversión con;

gd2asset -f barras2.gd2 -o barras2.h sp0.png,format=ARGB4 sp1.png,format=ARGB4 sp2.png,format=ARGB4 sp3.png,format=ARGB4 sp4.png,format=ARGB4 sp5.png,format=ARGB4 sp6.png,format=ARGB4 sp7.png,format=ARGB4 sp8.png,format=ARGB4 sp9.png,format=ARGB4 sp10.png,format=ARGB4 sp11.png,format=ARGB4 sp12.png,format=ARGB4 sp13.png,format=ARGB4 sp14.png,format=ARGB4

para las 15, de este modo no puedo poner mas assets. He realizado un nuevo fichero donde es un asset solo con las 15 imágenes en un solo fichero que adjunto, su peso en RAM es de 230kb y claro quiero todos esos 750kb que me sobran.

Adjunto el código que estoy usando y las imágenes en una sola.

Crees TFTLCDCyg se podria hacer como digo?

GD3_MSGEQ7_170520a.zip (4.68 KB)

SPECTRUM_PNG.zip (68.1 KB)

Suena interesante, pero tenemos una frontera en el formato base del dibujo: hay un límite vertical y horizontal en pixeles que no podemos superar con la herramienta gdxasset.exe.

En este mensaje James lo explica, tal parece que la herramienta para phyton lo puede hacer. No solo dividir de forma vertical, sino que también se puede de forma horizontal.

No debemos dejar de lado aquellas 2048 instrucciones por pantalla del motor EVE/EVE2.

El ejemplo de 2000 sprites de la librería de James, muestra como deben "empaquetarse" las imágenes para el caso de que deseemos presentarlas todas de una vez, pero en esos extremos la velocidad del MCU se torna relevante y las dimensiones de las imágenes también.

Debe existir una forma de "mapear" una imagen de 800x480 (o de 480x272) de tal forma que la carguemos en pantalla una vez, y podamos solo usar fragmentos de la misma. Este aspecto lo he tocado varias veces pero, por falta de tiempo lo he explorado a fondo. No prometo nada, pero puede ser una buena solución gráfica.

Se me ocurre que podamos simplificar todas esas barras en tan solo "6 minibarras": "tres apagadas" y "tres iluminadas", pero no sé si todos los MCU logren soportar la carga de proceso.

Veamos lo que dice el cook-book del FT813 (FT81X_Series_Programmer_Guide)

"...The graphics engine has no frame buffer: it uses dynamic compositing to build up each display line during scan out. Because of this, there is a finite amount of time available to draw each line. This time depends on the scan out parameters (decided by REG_PCLK and REG_HCYCLE) but is never less than 2048 internal clock cycles. FT81X’s internal clock runs at 60MHz.
Some performance limits:
 The display list length must be less than 2048 instructions, because the graphics engine fetches display list commands one per clock.
 The usual performance of rending pixels is 16 pixels per clock
 For some bitmap formats, the drawing rate is 8 pixels per clock. These are TEXT8X8, TEXTVGA and PALETTED4444/565.
 For bilinear filtered pixels, the drawing rate is reduced to ¼ pixel per clock..."

La librería gameduino 2 prioriza placas como la UNO.

Basados en este principio, opté por darle un enfoque diferente a las celdas, ¿por qué llevar a límite al FTXX?, es mejor mantenerlo relajado. Sabemos que gd3asset puede con eso y por lo visto bastante más.

No sé como se comporte el siguiente código en placas AVR, pero en el Teensy 3.6 va muy fluido. Espero te ayude con el proyecto, está diseñado para FT81X. La celda se reduce a 6 dots de 32x18 pixeles. El archivo de imagen no es necesario cargarlo en la SD, pesa apenas 2.55 Kb.

GD23L Analizador MSGEQ7

Ayer por fin, casi he terminado de realizar a toda pantalla FT811 con Arduino MEGA, la representación del Spectrum Audio con 225 led´s ... (código adaptado del ejemplo de TFTLCDCyg, obviamente) y la verdad toda una elegancia.

Nunca me imagine tanta belleza con este ejemplo a estas pantallas.

Aquí el video

También se muestra una gráfica tipo "osciloscopio" donde el pobre Arduino MEGA, por su baja velocidad no alcanza mas, ahora toca probar en Teensy!

Nota muy importante. Cuando realice mi proyecto RadioFM, use 4 MGSEQ7, en este caso solamente 1, sin embargo con otro MSGEQ7 se pueden usar las 14 bandas de audio para diferentes frecuencias, por defecto en la datasheet del integrado se usa un condensador de 33pF, si el segundo MGSEQ7, doblamos esta capacidad es decir 66pF el espectro de frecuencias varía intermediamente donde tendremos desde los 40Hz a 16KHz con 14 filtros. Lo pondré en practica en otros video.

Aplicando algo de trigonometría para dibujar alguno que otro arco...

Velocímetro

Video: Gauge para FT813