Mostrar en TFT arduino una gráfica de un Array

Hola buenas a todos!

Tengo un problema, tengo una pantalla TFT ili9488, la he configurado con menús e incluso he puesto una imagen. Para mostrar texto o una gráfica con una fórmula no tengo problema, tampoco con el táctil.
Pero acabo de sacar con Matlab un array de datos de una grafica ¿cómo puedo realizar para que me dibuje la gráfica con esos puntos? :-[

Gracias y un saludo .

La tarea es sencilla, sin embargo no es cualquier cosa.

El array de datos bidimensional puesto en pantalla para que sea coherente con la forma en la que podemos ver las gráficas normalmente, debe considerar que el origen de coordenadas (0,0) de la pantalla está ubicado en la esquina superior izquierda y no es equivalente al origen (0,0) del array de datos.

El eje X presenta un desarrollo de valores similares (incremento con dirección de izquierda-derecha), siempre y cuando se tomen las medidas de escalado previamente, para que el valor máximo en X, quede dentro del marco de píxeles de la pantalla.

Adicionalmente al escalado, hay que considerar que el eje Y está invertido (incremento con dirección superior-inferior). Para adecuarlo a una gráfica normal, se debe establecer un límite máximo de píxeles vertical, al que se deben restar uno a uno los datos del eje Y del array bidimensional.

La forma más sencilla para graficar consiste en dibujar un punto por cada dato del array. El trazo de líneas entre puntos es algo más complejo pero es relativamente fácil de conseguir; si quieres desplazar la gráfica en tiempo real, como digamos la adquisición de datos de un sensor en función del tiempo, la complejidad se incrementa.

Aquí las herramientas de dibujo de la librería son lo más importante, claro y la velocidad de tu MCU, no cualquier pantalla es capaz de realizar esta tarea. Ayuda bastante que el chip de la pantalla posea recursos gráficos adicionales accesibles desde el MCU.


Arduino IDE: 1.9.0-beta
MCU: STM32F746IGT6 (Core746I, cortex M7@216MHz) TFT: Riverdi FT813 5"
Librería: gameduino 2 modificada para STM32 (GD2UB)

Sketch

#include <GD2UB.h>

Bitmap title, xaxis, yaxis;

//Marco para graficar
//int PX0=40, PY0=50, PXMAX=450, PYMAX=280, PYBase=275;
//int PX0=40, PY0=50, PXMAX=PX0+410, PYMAX=PY0+230, PYBase= PY0+225;
int PX0=50, PY0=50, PXMAX=PX0+410, PYMAX=PY0+230, PYBase= PY0+225;

void setup()
{
  GD.begin();

  title.fromtext(30, "Graph test");
  xaxis.fromtext(28, "X axis");
  yaxis.fromtext(28, "Y axis");
}

void loop()
{
  GD.ClearColorRGB(0x000030);
  GD.Clear();

  GD.ColorRGB(0xffffff);
  title.draw(PXMAX/2, PY0-20);
  yaxis.draw(PX0-20, PYMAX/2, DEGREES(270));
  xaxis.draw(PXMAX/2, PYMAX+20);

  MarcoG();
  GD.ColorRGB(0x50ff00); GD.Begin(LINE_STRIP);    GD.LineWidth(24);  Trace();
  GD.ColorRGB(0xffffff); GD.Begin(POINTS);      GD.PointSize(4*16);  Trace();  //TraceRandom();

  GD.swap();
}

void MarcoG()
{
  GD.Begin(LINES);
  GD.Vertex2f(PX0*16, PY0*16);    GD.Vertex2f(PX0*16, PYMAX*16);
  GD.Vertex2f(PX0*16, PYMAX*16);  GD.Vertex2f(PXMAX*16, PYMAX*16);
}

void TraceRandom()
{
  for (float x = PX0+10; x < (PXMAX-10); x += 20) {
    float y = PYBase - ((0.001*x*(x+GD.random(50))));
    GD.Vertex2f(x*16, y*16);
  }  
}

void Trace()
{
  for (float x = PX0+10; x < (PXMAX-10); x += 20) {
    float y = PYBase - ((0.001*x*(x)));
    GD.Vertex2f(x*16, y*16);
  }  
}

Luego de la intro, ¿qué pantalla, librería y MCU quieres usar?

@FT81Xmania team

Solo que la librería te permita colorear pixeles individuales. La cantidad de muestras (datos) corresponde al eje X, por lo tanto, deber caber en la resolución horizontal de la pantalla. De ser mayor que esta, tendrás que "escalar" el gráfico mediante la omisión de algunos datos.

El valor de esos datos debe ser proporcional a la resolución vertical (eje Y). Para eso perfectamente se puede recurrir a map para un escalamiento lineal; pero también se deben saber los valores extremos (mínimo y máximo).

Estoy usando una pantalla ILI9488 de 3,5" de mcufriend, librerías UTFT y URTouch y estoy trabajando con un arduino Mega 2560.

Con Matlab tengo la lista de puntos, pero el array como hago que me dibuje la gráfica. Con un
const short y_data[] = {...} podría almacenar los valores del eje y, pero dibujarlo en pantalla...

:confused: :confused:

El array de puntos se puede introducir

  1. Creando dos vectores manualmente (muy laborioso)
  2. Leyendo el array desde un archivo en una memoria SD (me declaro neófito en el tema)
  3. Ajustar el array en una ecuación de tendencia (usas un programa como excel y luego gráficas en tu tft)

El punto 3 también lo puedes conseguir usando algún sistema de aproximación como mínimos cuadrados, exponencial o logarítmico por ejemplo. Este método creo que sería el más rápido para el arreglo que tienes.

UTFT es muy voluminosa, demanda casi toda la capacidad de procesamiento de tu MCU, la opción 3 sería la más eficiente para esa librería

Hace un tiempo experimenté con una ILI9325C con UTFT

Luego descubrí las pantallas FT8XX, y ya no fué lo mismo

Gracias!!!

Probaré con la opción 3, a ver si consigo realizar la gráfica.

No olvides subir el resultado de tu experimento, compartiendo algunas fotos, siempre es refrescante ver los progresos de los demás y se aprenden cosas nuevas.

Intenta primero dibujando la ecuación de ajuste con puntos, es la instrucción gráfica más sencilla de UTFT

for (float DatoX = 40; DatoX < (460); DatoX += 20) 
{
  float DatoY = 275 - ((0.001*DatoX*(DatoX)));
  myGLCD.drawPixel(DatoX, DatoY);
}

La ecuación del ejemplo es: y=0.001x2
límites:
40<x<460
y<275 (restamos de 275 cada valor obtenido en y, con esto conseguimos invertir el plano del TFT para que coincida con el cuadrante positivo del plano cartesiano xy)

275 es un valor arbitrario, corresponde a la base de la gráfica; puede ser el límite del eje Y de tu pantalla, me parece que es 320.

PD: ahora que lo veo con más calma, se puede recurrir al análisis dimensional para obtener una ecuación de correlación, en caso de que no conseguir la ecuación de ajuste por los métodos tradicionales.

He probado haciendo un coseno con fórmula y es sencillo:

void COS(){

  for ( long  i = 0 ; i<478 ; i++)
    {  
       lcd.drawPixel(i,159+(cos(((i*1.13)*3.14)/180)*95));
      
     }
}

Ahora estoy probando a intentar hacerlo con un array y los datos obtenidos en Matlab.

Es buena solución integrar la función en la instrucción para dibujar los puntos, simplifica el sketch. Solo cuida el orden de los paréntesis en la fórmula, a veces falta uno que otro y saltan errores como conejos.

Hice los ajustes necesarios en el ejemplo

Usé la gráfica y=AsinBx. Se pueden modificar las constantes A y B, mediante los botones táctiles, como resultado la gráfica cambia en tiempo real.

Acá el sketch:

#include <GD2UB.h>
Bitmap title, xaxis, yaxis, Gtipo1E, Gtipo1, Gtipo2E, Gtipo2, Gtipo3E, Gtipo3, Gtipo4E, Gtipo4;

int graph=1;
int A=100;
int B=2;

//Marco para graficar
int PX0=50, PY0=50, PXMAX=PX0+410, PYMAX=PY0+230, PYBase= PY0+225;

void setup()
{
  GD.begin();

  title.fromtext(30, "Graph test");
  xaxis.fromtext(28, "X axis");
  yaxis.fromtext(28, "Y axis");
  Gtipo1E.fromtext(26, "                2");  Gtipo1.fromtext(28, "y = 0.001x");
  Gtipo2E.fromtext(26, "                2");  Gtipo2.fromtext(28, "y = 0.5x");
  Gtipo3E.fromtext(26, "                          2");  Gtipo3.fromtext(28, "y = 0.5x-0.0008x");
  Gtipo4E.fromtext(26, "                          2");  Gtipo4.fromtext(28, "y = AsinBx");
}

void loop()
{
  GD.ClearColorRGB(0x000030);
  GD.Clear();  GD.get_inputs();

  GD.ColorRGB(0xffffff);
  title.draw(PXMAX/2, PY0-20);
  yaxis.draw(PX0-20, PYMAX/2, DEGREES(270));
  xaxis.draw(PXMAX/2, PYMAX+20);

  GD.Tag(1);  Gtipo1E.draw(130+20, 90-25+PYMAX+20);   Gtipo1.draw(100+20, 100-30+PYMAX+20);  GD.Tag(255);
  GD.Tag(2);                                       Gtipo2.draw(88+20, 100+PYMAX+20);      GD.Tag(255);
  GD.Tag(3);  Gtipo3E.draw(175+20, 100+25+PYMAX+20);  Gtipo3.draw(130+20, 100+30+PYMAX+20);  GD.Tag(255);
  GD.Tag(4);                                       Gtipo4.draw(100+20, 100+60+PYMAX+20);  GD.Tag(255);

  MarcoG();

  if(graph==1){
  GD.ColorRGB(0x50ff00); GD.Begin(LINE_STRIP);    GD.LineWidth(24);  Trace1();
  GD.ColorRGB(0xffffff); GD.Begin(POINTS);      GD.PointSize(4*16);  Trace1Random();}

  if(graph==2){
  GD.ColorRGB(0x50ff00); GD.Begin(LINE_STRIP);    GD.LineWidth(24);  Trace2();
  GD.ColorRGB(0xffffff); GD.Begin(POINTS);      GD.PointSize(4*16);  Trace2();}

  if(graph==3){
  GD.ColorRGB(0x50ff00); GD.Begin(LINE_STRIP);    GD.LineWidth(24);  Trace3();
  GD.ColorRGB(0xffffff); GD.Begin(POINTS);      GD.PointSize(4*16);  Trace3();}

  if(graph==4){
    GD.ColorRGB(0x50ff00); GD.Begin(LINE_STRIP);    GD.LineWidth(24);  SIN();
    GD.ColorRGB(0xffffff); GD.Begin(POINTS);      GD.PointSize(1*16);  SIN();
    GD.cmd_fgcolor(0x005000);
    GD.Tag(5);  GD.cmd_button(500, 250, 120, 60, 29, 0,  "B-");  GD.Tag(255);
    GD.Tag(6);  GD.cmd_button(660, 250, 120, 60, 29, 0,  "B+");  GD.Tag(255);
    GD.Tag(7);  GD.cmd_button(580, 170, 120, 60, 29, 0,  "A+");  GD.Tag(255);
    GD.Tag(8);  GD.cmd_button(580, 330, 120, 60, 29, 0,  "A-");  GD.Tag(255);

    if (GD.inputs.tag==5)
    {
      B=B-1;
      if(B<=1){B=1;}      
    }

    if (GD.inputs.tag==6)
    {
      B=B+1;
      if(B>=10){B=10;}
    }

    if (GD.inputs.tag==7)
    {
      A=A+10;
      if(A>=150){A=150;}
    }

    if (GD.inputs.tag==8)
    {
      A=A-10;
      if(A<=50){A=50;}
    }    
    
   }

  if (GD.inputs.tag==1)
    {
      graph=1;
    }

  if (GD.inputs.tag==2)
    {
      graph=2;
    }

  if (GD.inputs.tag==3)
    {
      graph=3;
    }

  if (GD.inputs.tag==4)
    {
      graph=4;
    }        

  GD.swap();
}

void Trace1()
{
  for (float x = PX0+10; x < (PXMAX-10); x += 20) {
    float y = PYBase - ((0.001*x*(x)));
    GD.Vertex2f(x*16, y*16);
  }  
}

void Trace1Random()
{
  for (float x = PX0+10; x < (PXMAX-10); x += 20) {
    float y = PYBase - ((0.001*x*(x+random(-30,30))));
    GD.Vertex2f(x*16, y*16);
  }  
}

void Trace2()
{
  for (float x = PX0+10; x < (PXMAX-10); x += 20) {
    float y = PYBase - ((0.5*x));
    GD.Vertex2f(x*16, y*16);
  }  
}

void Trace3()
{
  for (float x = PX0+10; x < (PXMAX-10); x += 20) {
    float y = PYBase - ((0.5*x)-0.0008*x*x);
    GD.Vertex2f(x*16, y*16);
  }  
}

void SIN(){
  for ( long  i = 0 ; i<=359 ; i++)
    {  
       GD.Vertex2f((i+PX0)*16, (PYBase-(A*sin((B*i*PI)/180)))*16);
     }
}

void MarcoG()
{
  GD.Begin(LINES);
  GD.Vertex2f(PX0*16, PY0*16);    GD.Vertex2f(PX0*16, (PYMAX+170)*16);
  GD.Vertex2f(PX0*16, (PYMAX-4)*16);  GD.Vertex2f(PXMAX*16, (PYMAX-4)*16);
}

TFTLCDCyg:
Solo cuida el orden de los paréntesis en la fórmula, a veces falta uno que otro y saltan errores como conejos.

Es verdad. Y cojer los conejos en el campo cuando saltan va ser muy dificil cojerlos, esto lo tengo asumido.
El problema es que el chico yoymi se equivocó de LCD, y eso pasa por no buscar otros LCD´s tipo FT8xx ... :slight_smile:

Saludos amigo ligthcalamar

¿Qué tal funciona el ejemplo en las FT81X de HotMCU?, ojalá subas algunas fotos, tengo curiosidad con el tema del tamaño de los pixeles en aquellas pantallas que has conseguido hacer funcionar.

Ajusté el ejemplo para sin, cos y tan

#include <GD2UB.h>

Bitmap title, xaxis, yaxis, Gtipo1E, Gtipo1, Gtipo2E, Gtipo2, Gtipo3E, Gtipo3, Gtipo4E, Gtipo4, Gtipo5E, Gtipo5, Gtipo6E, Gtipo6;

int graph=1;
int A=50, AC=50, AT=50;
int B=2, BC=2, BT=2;

//Marco para graficar
int PX0=50, PY0=50, PXMAX=450-PX0, PYMAX=PY0+230, PYBase= PY0+225;

void setup()
{
  GD.begin();

  title.fromtext(30, "Graph test");
  xaxis.fromtext(28, "X axis");
  yaxis.fromtext(28, "Y axis");
  Gtipo1E.fromtext(26, "                2");  Gtipo1.fromtext(28, "y = 0.001x");
  Gtipo2E.fromtext(26, "                2");  Gtipo2.fromtext(28, "y = 0.5x");
  Gtipo3E.fromtext(26, "                          2");  Gtipo3.fromtext(28, "y = 0.5x-0.0008x");
  Gtipo4E.fromtext(26, "                          2");  Gtipo4.fromtext(28, "y = AsinBx");
  Gtipo5E.fromtext(26, "                          2");  Gtipo5.fromtext(28, "y = AcosBx");
  Gtipo6E.fromtext(26, "                          2");  Gtipo6.fromtext(28, "y = AtanBx");
}

void loop()
{
  GD.ClearColorRGB(0x000010);
  GD.Clear();  GD.get_inputs();

  GD.ColorRGB(0xffffff);
  title.draw(PXMAX/2, PY0-20);
  yaxis.draw(PX0-20, PYMAX, DEGREES(270));
  xaxis.draw(PXMAX/2, PYMAX+20);

  GD.Tag(1);  Gtipo1E.draw(130+20, 90-25+PYMAX+20);   Gtipo1.draw(100+20, 100-30+PYMAX+20);  GD.Tag(255);
  GD.Tag(2);                                          Gtipo2.draw(88+20, 100+PYMAX+20);      GD.Tag(255);
  GD.Tag(3);  Gtipo3E.draw(175+20, 100+25+PYMAX+20);  Gtipo3.draw(130+20, 100+30+PYMAX+20);  GD.Tag(255);
  GD.Tag(4);                                          Gtipo4.draw(100+20, 100+60+PYMAX+20);  GD.Tag(255);
  GD.Tag(5);                                          Gtipo5.draw(320+20, 100+60+PYMAX+20);  GD.Tag(255);
  GD.Tag(6);                                          Gtipo6.draw(520+20, 100+60+PYMAX+20);  GD.Tag(255);

  MarcoG();

  if(graph==1){
  GD.ColorRGB(0x50ff00); GD.Begin(LINE_STRIP);    GD.LineWidth(24);  Trace1();
  GD.ColorRGB(0xffffff); GD.Begin(POINTS);      GD.PointSize(4*16);  Trace1Random();}

  if(graph==2){
  GD.ColorRGB(0x50ff00); GD.Begin(LINE_STRIP);    GD.LineWidth(24);  Trace2();
  GD.ColorRGB(0xffffff); GD.Begin(POINTS);      GD.PointSize(4*16);  Trace2();}

  if(graph==3){
  GD.ColorRGB(0x50ff00); GD.Begin(LINE_STRIP);    GD.LineWidth(24);  Trace3();
  GD.ColorRGB(0xffffff); GD.Begin(POINTS);      GD.PointSize(4*16);  Trace3();}

  if(graph==4){
    GD.ColorRGB(0x50ff00); GD.Begin(LINE_STRIP);    GD.LineWidth(24);  SIN();
    GD.ColorRGB(0xffffff); GD.Begin(POINTS);      GD.PointSize(1*16);  SIN();

    GD.cmd_fgcolor(0x000050);
    GD.Tag(11);  GD.cmd_button(500, 250, 120, 60, 29, 0,  "B-");  GD.Tag(255);
    GD.Tag(12);  GD.cmd_button(660, 250, 120, 60, 29, 0,  "B+");  GD.Tag(255);
    GD.Tag(13);  GD.cmd_button(580, 170, 120, 60, 29, 0,  "A+");  GD.Tag(255);
    GD.Tag(14);  GD.cmd_button(580, 330, 120, 60, 29, 0,  "A-");  GD.Tag(255);

    if (GD.inputs.tag==11)
    {
      B=B-1;
      if(B<=1){B=1;}      
    }

    if (GD.inputs.tag==12)
    {
      B=B+1;
      if(B>=18){B=18;}
    }

    if (GD.inputs.tag==13)
    {
      A=A+10;
      if(A>=150){A=150;}
    }

    if (GD.inputs.tag==14)
    {
      A=A-10;
      if(A<=50){A=50;}
    }    
    
   }


  if(graph==5){
    GD.get_inputs();
    GD.ColorRGB(0x50ff00); GD.Begin(LINE_STRIP);    GD.LineWidth(24);  COS();
    GD.ColorRGB(0xffffff); GD.Begin(POINTS);      GD.PointSize(1*16);  COS();
    
    GD.cmd_fgcolor(0x005000);
    GD.Tag(15);  GD.cmd_button(500, 250, 120, 60, 29, 0,  "B-");  GD.Tag(255);
    GD.Tag(16);  GD.cmd_button(660, 250, 120, 60, 29, 0,  "B+");  GD.Tag(255);
    GD.Tag(17);  GD.cmd_button(580, 170, 120, 60, 29, 0,  "A+");  GD.Tag(255);
    GD.Tag(18);  GD.cmd_button(580, 330, 120, 60, 29, 0,  "A-");  GD.Tag(255);

    if (GD.inputs.tag==15)
    {
      BC=BC-1;
      if(BC<=1){BC=1;}      
    }

    if (GD.inputs.tag==16)
    {
      BC=BC+1;
      if(BC>=18){BC=18;}
    }

    if (GD.inputs.tag==17)
    {
      AC=AC+10;
      if(AC>=150){AC=150;}
    }

    if (GD.inputs.tag==18)
    {
      AC=AC-10;
      if(AC<=50){AC=50;}
    }    
    
   }


  if(graph==6){
    GD.get_inputs();
    //GD.ColorRGB(0x50ff00); GD.Begin(LINE_STRIP);    GD.LineWidth(24);  TAN();
    GD.ColorRGB(0x50ffff); GD.Begin(POINTS);      GD.PointSize(1*16);  TAN();
    
    GD.cmd_fgcolor(0x500000);
    GD.Tag(19);  GD.cmd_button(500, 250, 120, 60, 29, 0,  "B-");  GD.Tag(255);
    GD.Tag(20);  GD.cmd_button(660, 250, 120, 60, 29, 0,  "B+");  GD.Tag(255);
    GD.Tag(21);  GD.cmd_button(580, 170, 120, 60, 29, 0,  "A+");  GD.Tag(255);
    GD.Tag(22);  GD.cmd_button(580, 330, 120, 60, 29, 0,  "A-");  GD.Tag(255);

    if (GD.inputs.tag==19)
    {
      BT=BT-1;
      if(BT<=1){BT=1;}      
    }

    if (GD.inputs.tag==20)
    {
      BT=BT+1;
      if(BT>=18){BT=18;}
    }

    if (GD.inputs.tag==21)
    {
      AT=AT+10;
      if(AT>=150){AT=150;}
    }

    if (GD.inputs.tag==22)
    {
      AT=AT-10;
      if(AT<=50){AT=50;}
    }    
    
   }
   

  if (GD.inputs.tag==1)
    {
      graph=1;
    }

  if (GD.inputs.tag==2)
    {
      graph=2;
    }

  if (GD.inputs.tag==3)
    {
      graph=3;
    }

  if (GD.inputs.tag==4)
    {
      graph=4;
    }        

   if (GD.inputs.tag==5)
   {
      graph=5;
    }

   if (GD.inputs.tag==6)
   {
      graph=6;
    }            

  GD.swap();
}

void Trace1()
{
  for (float x = 0; x < (PXMAX-10); x += 20) {
    float y = PYBase - ((0.001*x*(x)));
    GD.Vertex2f((x+PX0)*16, y*16);
  }  
}

void Trace1Random()
{
  for (float x = 0; x < (PXMAX-10); x += 20) {
    float y = PYBase - ((0.001*x*(x+random(-30,30))));
    GD.Vertex2f((x+PX0)*16, y*16);
  }  
}

void Trace2()
{
  for (float x = 0; x < (PXMAX-10); x += 20) {
    float y = PYBase - ((0.5*x));
    GD.Vertex2f((x+PX0)*16, y*16);
  }  
}

void Trace3()
{
  for (float x = 0; x < (PXMAX-10); x += 20) {
    float y = PYBase - ((0.5*x)-0.0008*x*x);
    GD.Vertex2f((x+PX0)*16, y*16);
  }  
}

void SIN(){
  for ( long  i = 0 ; i<=359 ; i++)
    {  
       GD.Vertex2f((i+PX0)*16, (PYBase-(A*sin((B*i*PI)/180)))*16);
     }
}

void COS(){
  for ( long  j = 0 ; j<=359 ; j++)
    {  
       GD.Vertex2f((j+PX0)*16, (PYBase-(AC*cos((BC*j*PI)/180)))*16);
     }
}

void TAN(){
  for ( long  j = 0 ; j<=359 ; j++)
    {  
       GD.Vertex2f((j+PX0)*16, (PYBase-(AT*tan((BT*j*PI)/180)))*16);
     }
}

void MarcoG()
{
  GD.Begin(LINES);
  GD.Vertex2f(PX0*16, PY0*16);    GD.Vertex2f(PX0*16, (PYMAX+170)*16);
  GD.Vertex2f(PX0*16, (PYMAX-4)*16);  GD.Vertex2f((PXMAX+PX0)*16, (PYMAX-4)*16);
}

Jajajaja la TFT que me han dejado, no la he elegido. Si los paréntesis, llaves y demás los tengo controlados para no liarla.

Sigo con el Array a ver como me puede salir.

Vamos que presentar un array es similar a barrer una señal en i obteniendo su f(i) donde f es una función.
Dime cual es el problema ahora?
Tu array tendra N puntos, asi que esos N puntos deben comprimirse en el desplazamiento X o bien ajusta la captura de puntos a esa dimensión posible.

:frowning: :frowning: :frowning: Pues estoy bastante perdido...

const short  y_data[] = {
939, 940, 941, 942, 944, 945, 946, 947, 951, 956, 
962, 967, 973, 978, 983, 989, 994, 1000, 1005, 1015, 
1024, 1034, 1043, 1053, 1062, 1075, 1087, 1100, 1112, 1121, 
1126, 1131, 1136, 1141, 1146, 1151, 1156, 1164, 1172, 1179, 
1187, 1194, 1202, 1209, 1216, 1222, 1229, 1235, 1241, 1248, 
1254, 1260, 1264, 1268, 1271, 1275, 1279, 1283, 1287, 1286, 
1284, 1281, 1279, 1276, 1274, 1271, 1268, 1266, 1263, 1261, 
1258, 1256, 1253, 1251, 1246, 1242, 1237, 1232, 1227, 1222, 
1218, 1215, 1211, 1207, 1203, 1199, 1195, 1191, 1184, 1178, 
1171, 1165, 1159, 1152, 1146, 1141, 1136, 1130, 1125, 1120, 
1115, 1110, 1103, 1096, 1088, 1080, 1073, 1065, 1057, 1049, 
1040, 1030, 1021, 1012, 1004, 995, 987, 982, 978, 974}

Tengo el array con 120 datos, para mostrar los datos en forma de gráfica en pantalla, pero no le veo
forma. He estado intentando con un for tomando los valores y luego lcd.drawPixel() para que dibuje pero nada...

Cómo no le ves la forma?
Esta linea te lo dice

for ( long  i = 0 ; i<478 ; i++)

478 datos a barrer.

Tu array tiene 120 datos de modo que tendras que espaciarlos o mostrarlos de modo mas comprimido
de 0 a 119

algo asi, cambia COS() por array() u otro nombre

void array(){

  for ( long  i = 0 ; i<sizeof(y_data[i]) ; i++)    {  // reemplacé 478 x sizeof(y_data[]) = 120
       lcd.drawPixel(i, y_data[i]);
      
  }
}

mas alla de sizeof() era simple poner 120 y ya lo tenias resuelto.

Poniendo el for de esa forma ya he realizado pruebas, y no me dibuja nada, estoy probando a poner de otra forma el array.
:confused: :confused: :frowning: :frowning:

Ahhh no me di cuenta, tus valores superaran el rango y
Wait

void array(){
  float min, max = 0;
  int cant_datos = sizeof(y_data[]);
  min = 10000.0;       // arbitrario
  max = 0.0;

  for (int i=0; i<cant_datos; i++) {  // reemplacé 478 x sizeof(y_data[]) = 120
      if (y_data[i] < min)
          min = y_data[i];
      if (y_data[i] > max)
          max = y_data[i];
  }

  for ( int  i = 0 ; i<cant_datos; i++)    {  // reemplacé 478 x sizeof(y_data[]) = 120
       lcd.drawPixel(i, (y_data[i]-min)/(max-min)*320.0);
  }
}

Si lo grafica al revéz restale 320 - lo que he puesto

lcd.drawPixel(i, 320.0-(y_data[i]-min)/(max-min)*320.0);

Puse 320 porque TFTLCDCyg lo menciona como posible resolución vertical.
Ajusta o definelo con un #define YRES 320 por ejemplo

:frowning: :frowning:
Estoy utilizando tu idea y me sale fallito


unificado:714: error: expected primary-expression before ']' token

int cant_datos = sizeof(y_data[]);

^

exit status 1
expected primary-expression before ']' token


void array2(){
  float min = 0;
  float max = 0;
  int cant_datos = sizeof(y_data[]);
  min = 10000.0;
  max = 0.0;
  for ( long  i = 0 ; i<sizeof(y_data[i]) ; i++)    {  
      if (y_data[i] < min)
          min = y_data[i];
      if (y_data[i] > max)
          max = y_data[i];
  }
  for ( int  i = 0 ; i<cant_datos; i++)    {  
       lcd.drawPixel(i, (y_data[i]-min)/(max-min)*320.0);
  }

Corrige por esto

Has modificado cosas sigue como la escribí, acabo de compilarla y esta bien

cambia tu definición de los valores del array de const short a const int y_data[]

void array(){
  float min, max = 0;
  int cant_datos = sizeof(y_data)/sizeof(int); // esto estaba mal
  min = 10000.0;       // arbitrario
  max = 0.0;

  for (int i=0; i<cant_datos; i++) {  // reemplacé 478 x sizeof(y_data[]) = 120
      if (y_data[i] < min)
          min = y_data[i];
      if (y_data[i] > max)
          max = y_data[i];
  }

  for ( int  i = 0 ; i<cant_datos; i++)    {  // reemplacé 478 x sizeof(y_data[]) = 120
       Serial.println((y_data[i]-min)/(max-min)*320.0);
  }
}

Estuve experimentando con el array que has colocado y le he dado una mirada lo que ha comentado surbyte, resulta que no es tan complicado usar arrays como asumí en mi primer comentario.

Para graficar correctamente, dentro de la pantalla, la clave es la inversión de valores, ya que el plano de coordenadas de la pantalla se encuentra invertido en el eje y. Lo ideal es usar un valor base dentro del rango del eje y de la pantalla. En el ejemplo que he tratado de armar de acuerdo a sus comentarios

Posteriormente, debemos considerar el escalado de los datos, esto es, convertirlos en un valor de píxeles que puedas mostrar dentro de tu pantalla. Me parece que tus datos pueden tener una escala 1:10, esto es, puedes dividir cada dato entre 10, ya que todos los valores superan el rango vertical de la pantalla. El valor de cada dato en el eje y puede ser calculado como:

y_data[j]/10

Por tanto la función para graficar quedaría así (para la librería modificada de gameduino 2):

void GArray(){
  for ( long  j = 0 ; j<=119 ; j++)
    {  
       GD.Vertex2f(j*16, (PYBase-(y_data[j]/10))*16);
     }
}

En el caso particular del array que nos compartes, si graficamos el eje x como 1 vs 1, pensando en una escala imaginaria de 0 a 119 (que es el número de puntos del array para el eje x), podríamos dibujar la gráfica en tan solo 119 pixeles, quedaría algo así:

Podemos aumentar la separación entre valores del eje x, adicionando una variable que sume el espaciado. Esto lo podemos conseguir agregando un valor constante entre cada punto x, el factor de separación sería algo así:

esp*j

La función para trazado quedaría:

void GArray(){
 for ( long  j = 0 ; j<=119 ; j++)
   {  
      GD.Vertex2f((j+PX0+esp*j)*16, (PYBase-(y_data[j]/10))*16);
    }
}

Con esp=2, el resultado en pantalla es:

Con lo que pude aprender respecto a los arrays de valores y con lo que han revisado hasta ahora (gracias por la clase), respondiendo a tu pregunta inicial, en los arrays unidimensionales, los datos del vector corresponden al eje y. Los datos del eje x los puedes establecer considerando las prestaciones de la pantalla.