bclose

Panel táctil y TFTs

Probando el touch screen

Objetivos

 

 
    • Probar el panel táctil o (touch screen)de un display TFT de 3.2”.
    • Ver los comandos básicos para determinar la posición.
    • Aprender a usar algunos sliders y botones.

 

 

Material requerido.

Version R3  Arduino UNO o MEGA.

Display 3.2" de 320x240 color
 3.2” TFT color de Seed Studio con touch panel De 320×240 pixels.

 

Las pantallas táctiles

 

En la sesión anterior estuvimos jugando con los gráficos en una pantalla TFT de 3.2” y dejamos pendiente probar el panel táctil que incorporan de serie, para ver que tal resultado dá y hasta qué punto pueden ser prácticas para el manejo en unas pantallas de relativo pequeño tamaño.

No tenía muy claro que la precisión fuera suficiente para permitirnos hacer aplicaciones prácticas basadas en el panel táctil, así que me puse a hacer pruebas para salir de dudas y tengo que decir que el resultado ha sido de lo más satisfactorio.

La precisión con la que el panel reconoce la presión, especialmente de un stylus o similar, es magnífico y nos permite usarlo en programas que no necesitan botones,  deslizadores o pontenciómetros adicionales, sino que podemos usar con confianza la característica táctil de estos paneles.

Así que pensando, pensando, se me ocurrió ampliar el programa anterior de dibujo de las figuras de Lissajous, añadiendo un panel táctil que nos permitan configurar los tres parámetros de entrada: n, p y fase.

Bastaría con dibujar tres deslizadores para proporcionar el valor de los parámetros de 1 a 9 para los valores de n y p, y de 0 a 360º para el ángulo de fase.

Además vamos a precisar de un botón de OK y otro de Cancel para devolver los valores al programa de dibujo, lo que nos presenta un problema interesante para trabajárnoslo.

Necesitaremos también, algún modo de presentar valores numéricos en la pantalla para saber que valores vamos adoptando, lo que nos va a permitir hacer un repaso general a todas las primitivas disponibles en las librerías de SeedStudio.

Así que vamos directamente al lio que vamos a tener trabajo.

 

Descripciones varias

 

En la última sesión se me olvidó incluir una descripción de los pines que utiliza este Shield TFT, por lo que es buen momento para corregir este descuido:

pines requeridos

Como este display utiliza el bus SPI para comunicarse con Arduino, reserva los pines correspondientes para el control, además del digital pin D4 para el control del lector de tarjetas SD y el D5 para el Chip select del display.

Para leer el panel táctil se reserva los pines analógicos del A0 al A3. El manual describe que el panel táctil se parece a un conjunto de 4 resistencias como estas:

resistencias equivalentes
resistencias equivalentes

Cuando tocamos la pantalla aparece una nueva resistencia, como R touch, de modo que leyendo la tensión de las 4 resistencias podemos calcular la posición en la que se ha tocado la pantalla.

La verdad es que no entiendo nada, pero como usando las librerías proporcionadas por SeedStudio, da lo mismo que no lo entienda, podemos usarlas tranquilamente.

Y según el manual la unión de los pines es más o menos así:

  • Arduino A0 a Y-
  • Arduino A1 a X-
  • Arduino A2 a Y+
  • Arduino A3 a X+

 

Programando el panel táctil

 

Para empezar necesitamos la librería táctil Seeed_TFT_v2.0.zip, además de la librería Touch_Screen_Driver-master  y de la SPI, por lo que necesitamos algunos includes al principio de nuestro programa:

#include <SeeedTouchScreen.h>
#include <TFTv2.h>
#include <SPI.h>

TouchScreen ts = TouchScreen(XP, YP, XM, YM); //init TouchScreen port pins

La última línea, crea una instancia de touch screen llamada ts para que podamos leer el panel y necesitamos inicializarla mediante:

Tft.TFTinit();  //init TFT library

Ya dijimos que necesitamos tres deslizadores p, n y fase para el programa además de dos botones para OK y Cancel. Vamos a dibujar todo esto con una función llamada initPlot:

void initPlot()
   {   Tft.fillRectangle(30, 24, 40, 250, GRAY1);      // Slider 1
       Tft.fillRectangle(30, 24, 40, 22*P+50, BLUE);   // PLot Status Slider 1
       Tft.fillRectangle(90, 24, 40, 250, GRAY1);      // Slider 2
       Tft.fillRectangle(90, 24, 40, 22*N+50, BLUE);   // PLot Status Slider 2
       Tft.fillRectangle(150, 24, 40, 250, GRAY1);     // Fase
       Tft.fillRectangle(150, 24, 40, 280*F/360 +50, BLUE);
 
       Tft.fillRectangle(0, 24, 22,110, GREEN);
       Tft.fillRectangle(0,162, 22,110, RED);
   }

Aquí tenéis una foto con el resultado:

Dibujando controles

Los 3 deslizadores son de fondo gris, pero en la foto aparecen como azul oscuro y el nivel delos mismos se marca en azul. Además en rojo el botón cancel y en verde el OK.

La parte básica de leer el panel táctil son estas líneas:

Point p = ts.getPoint();
p.x = map(p.x, TS_MINX, TS_MAXX, 0, 240);   //mapear lecturas en coordenadas X,Y
p.y = map(p.y, TS_MINY, TS_MAXY, 0, 320);

Creamos un objeto tipo Point que tiene dos valores p.x y p.y que corresponden a los valores de x e y del punto tocado. Recordad que con la alimentación de Arduino a nuestra derecha, el punto (0,0) queda en la esquina inferior derecha, pero con la y en la horizontal y la x en vertical para que no sea demasiado fácil.

Y para que al principio sepamos donde estamos pulsando, conviene que hagamos una función que nos informe sw donde tocamos:

void referencias(int x, int y)
   {   Tft.fillRectangle(0, 294, 240, 30, BLACK);      // Borra valores de x e y
       Tft.drawString("x = ",0,300,2,RED);             // Plot x
       Tft.drawNumber( x, 48, 300,2 , RED) ;
 
       Tft.drawString("y = ",150,300,2,RED);           // Plot y
       Tft.drawNumber( y, 200, 300,2 , RED) ;
   }

Con lo que veréis que los valores de x e y bailan lo suyo.

Panel TFT

Aquí os dejo una copia inicial del programa que ha dibujado esta imagen Prog_45_2 y que os servirá para mostrar las coordenadas del punto en el que se pulsa.

Lo siguiente que vamos a necesitar es alguna manera de saber que estamos tocando dentro de uno de los deslizadores o botones para moverlos o activarlos. Lo llamaremos SenseControl:

void SenseControl(int x, int y)
   {  if ( (x>20 && x< 65) && ( y>15 && y<270))    // Slider 1
            P = map( y,15,270,1,10);

      if ( (x>90 && x< 133) && ( y>15 && y<270))    // Slider 2
            N = map( y,15,270,1,10);

      if ( (x>145 && x< 195) && ( y>15 && y<270))    // Slider 3
         {  F = map( y,15,270,-3,360);
            if (F <0 ) F = 0 ;
         }

     if ( x<24)
          if ( y>16 && y <130)               // Boton verde OK
               Serial.println("OK");
          else if ( y>150 && y <270)         // Boton rojo cancel
               Serial.println("CANCEL");
   }

Donde mapeamos los valores correspondientes a n y p  y entre 0 y 10, y hasta 360º para la fase.

Esta función comprueba que los puntos donde tocamos queden dentro del recuadro correspondiente (poco más o menos) y mapea una variable P,N o F a valore de 1 a9 o de 0 a 360º en función de la altura del deslizador que se toca.

Y ya solo nos falta el loop:

void loop()
   {   Point p = ts.getPoint();
       p.x = map(p.x, TS_MINX, TS_MAXX, 0, 240);  // mapear las lecturas 
       p.y = map(p.y, TS_MINY, TS_MAXY, 0, 320);
       referencias(p.x, p.y) ; delay(200);

       SenseControl(p.x, p.y) ;
       if ( P0 != P )
         {  Tft.fillRectangle(30, 24, 40, 250, GRAY1);      // Slider 1
            Tft.fillRectangle(30, 24, 40, 22*P+50, BLUE);   // PLot Status Slider 1
            plotVal();
         }
       else if ( N0 != N )
         {  Tft.fillRectangle(90, 24, 40, 250, GRAY1);     // Slider 2
            Tft.fillRectangle(90, 24, 40, 22*N+50, BLUE);  // PLot Status Slider 2
            plotVal();
         }
       else if (F != F0)
         {  Tft.fillRectangle(150, 24, 40, 250, GRAY1);     // Fase
            Tft.fillRectangle(150, 24, 40, 250*F/360 , BLUE);
            plotVal();
         }
       N0 = N ; P0 = P ; F0 = F ;
}

Cuando detectamos que al tocar en los distintos rectángulos los valores de P,N o F cambian, redibujamos el fondo gris y la parte en azul, para mostrar el avance del deslizador.

Me encantaría escribir OK y Cancel en los botones Verde y Rojo, pero no parece haber modo de girar las letras.

Aquí tenéis el programa completo Prog_45_1

 

Uniendo el panel táctil y el que dibuja las curvas

 

El programa anterior mueve los valores de los deslizadores directamente desde el loop principal lo que no nos conviene nada para unirlo con el programa de ploteo de las curvas de Lissajous que vimos en la sesión anterior, por lo que vamos a tener que tocarlo un poquito (Pero poco).

No vamos a usar ninguna idea nueva y se trata solo de adaptar ambos programas para que se mezclen sin hacer grumos.

 
  •  Lo que va a generar más de un problemilla, porque no sé si os habéis dado cuenta que hemos cambiado la referencia de origen en ambos programas.

 

Para ello he mezclado un par de las funciones anteriores  procesControl() y senseControl() en una única función , lo que básicamente procesa todo el tema del panel de control y los deslizadores, desde una bucle while, del que solo se sale cuando pulsamos el botón de OK (Devuelve true) o de CANCEL (Que devuelve false). Por lo demás es exactamente lo mismo de antes:

bool procesControl()
   { 
      initPlot() ;
      while (true)
        {   Point p = ts.getPoint();
            p.x = map(p.x, TS_MINX, TS_MAXX, 0, 240);       /
            p.y = map(p.y, TS_MINY, TS_MAXY, 0, 320);
           referencias(p.x, p.y) ; delay(200);   

           int x = p.x ; int y = p.y ;
           if ( (x>20 && x< 65) && ( y>15 && y<270))    // Slider 1
                 P = map( y,15,270,1,10);
          
           if ( (x>90 && x< 133) && ( y>15 && y<270))    // Slider 2
                 N = map( y,15,270,1,10);

          if ( (x>145 && x< 195) && ( y>15 && y<270))    // Slider 3
              {  F = map( y,15,270,-3,360);
                 if (F <0 ) F = 0 ;
              }

         if ( x<24)
            if ( y>16 && y <130)               // Boton verde OK
                 return(true);
            else if ( y>150 && y <270)         // Boton rojo cancel
                 return(false);

         if ( P0 != P )
           { 
              Tft.fillRectangle(30, 24, 40, 250, GRAY1);      // Slider 1
              Tft.fillRectangle(30, 24, 40, 22*P+50, BLUE);   // PLot Status Slider 
              plotVal();
           }
         else if ( N0 != N )
            { Tft.fillRectangle(90, 24, 40, 250, GRAY1);     // Slider 2
              Tft.fillRectangle(90, 24, 40, 22*N+50, BLUE);  // PLot Status Slider 2
              plotVal();
            }
         else if (F != F0)
            { Tft.fillRectangle(150, 24, 40, 250, GRAY1);     // Fase
              Tft.fillRectangle(150, 24, 40, 250*F/360 , BLUE);
              plotVal();
            }
         N0 = N ; P0 = P ; F0 = F ;
      }
   }

Además he ampliado el loop principal que dibuja las curvas, para que pueda saltar a la función de proceso de los controles:

void loop()
   { for ( long  i = 0 ; i <= 360 ; i++)
       {   float y = 160 + cos( p * i * k + fase) * 120 ;
           float x = 120 + sin( n * i * k + fase) * 110 ;
           if (inicio)
             { x0 = x ; y0 = y ;
               inicio = false ;
             }
           Tft.drawLine(x0,y0,x,y, CYAN);
           x0 = x ; y0 = y ;
       }
     // ………………………………………………………..
     Ref() ;
     Point q = ts.getPoint();
     q.x = map(q.x, TS_MINX, TS_MAXX, 0, 240);
     q.y = map(q.y, TS_MINY, TS_MAXY, 0, 320);
     int x = q.x ; int y = q.y ;

     //referencias(p.x, p.y) ; delay(200);
     if ( x<120 )
       {  Tft.fillRectangle(0, 0, 240, 320, BLACK);      // Borra display
          if ( procesControl()) ; // SI OK
              { Tft.fillRectangle(0, 0, 240, 320, BLACK);      // Borra display
                n = N ;
                p = P ;
                fase = F * 2 * PI / 360 ;
              }
       }
   }

Fíjate que no hay diferencia en la función que plotea las curvas, pero le hemos añadido más código tras la línea de puntos, que, básicamente, comprueba si se toca la pantalla para de x<120, o sea la parte inferior con la alimentación de Arduino a la derecha.

Si es así, lanza procesControl () para que modifiques los parámetros y a la vuelta asigna los valores de n, p y fase a los que traemos de nuevos y redibuja la curva. No hay más.

 
  • Hay alguna que otra cosa más como adaptar tipos de algunas variables para que coincidan, modificar que no imprima el valor de la fase en radianes, que no hay quién lo entienda y en su lugar plotee el valor en grados y cosillas parecidas de ajuste.
  • Como cuando empecé con el dibujo de las curvas no tenía aun en mente, el tema del touch screen, hay cosas a posteriori que he tenido que encajar un poco a martillazos para que encajen.
  • Así que convendría pulir un poco el programa reescribiéndolo desde el principio para dejarlo presentable y poderlo enseñar, pero creo que voy a dejároslo a vosotros. Si alguno se anima lo publicamos aquí para la posteridad.

 

Aquí tenéis el programa Prog_45_9 (Si, me temo que ha habido varias versiones) y un mini video mostrando el uso del conjunto.

 

 

Resumen de la sesión

 

 

    • Hemos jugado con el panel táctil para ver que funciona bastante bien y que nos permite evitar añadir  potenciómetros y deslizadores adicionales para el control de nuestra aplicación.
    • Vimos que ha sido bastante sencillo definir zonas activas como botones y deslizadores a nuestro proyecto.
    • Y a pesar de la improvisación de la mezcla hemos sido capaces de combinar los dos programas previos en una aplicación única que nos permite modificar las curvas de Lissajous mediante 3 deslizadores y dos botones.

 
 

 

 

(29) Comments

  • Alguien que me pueda decir como ligar interrupciones a un botón en arduino, para poder cambiar entre menus sin importar si existe una acción ejecutándose?

  • // IMPORTANT: Adafruit_TFTLCD LIBRARY MUST BE SPECIFICALLY
    // CONFIGURED FOR EITHER THE TFT SHIELD OR THE BREAKOUT BOARD.
    // SEE RELEVANT COMMENTS IN Adafruit_TFTLCD.h FOR SETUP.

    #include // Core graphics library
    #include // Hardware-specific library

    #define USE_ADAFRUIT_SHIELD_PINOUT //definicion que se ha de imponer al emplear placas DX o similares en que no puede reconocer el controlador.

    // The control pins for the LCD can be assigned to any digital or
    // analog pins…but we’ll use the analog pins as this allows us to
    // double up the pins with the touch screen (see the TFT paint example).
    #define LCD_CS A3 // Chip Select goes to Analog 3
    #define LCD_CD A2 // Command/Data goes to Analog 2
    #define LCD_WR A1 // LCD Write goes to Analog 1
    #define LCD_RD A0 // LCD Read goes to Analog 0

    #define LCD_RESET A4 // Can alternately just connect to Arduino’s reset pin

    // When using the BREAKOUT BOARD only, use these 8 data lines to the LCD:
    // For the Arduino Uno, Duemilanove, Diecimila, etc.:
    // D0 connects to digital pin 8 (Notice these are
    // D1 connects to digital pin 9 NOT in order!)
    // D2 connects to digital pin 2
    // D3 connects to digital pin 3
    // D4 connects to digital pin 4
    // D5 connects to digital pin 5
    // D6 connects to digital pin 6
    // D7 connects to digital pin 7
    // For the Arduino Mega, use digital pins 22 through 29
    // (on the 2-row header at the end of the board).

    // Assign human-readable names to some common 16-bit color values:
    #define BLACK 0x0000
    #define BLUE 0x001F
    #define RED 0xF800
    #define GREEN 0x07E0
    #define CYAN 0x07FF
    #define MAGENTA 0xF81F
    #define YELLOW 0xFFE0
    #define WHITE 0xFFFF

    Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);
    // If using the shield, all control and data lines are fixed, and
    // a simpler declaration can optionally be used:
    // Adafruit_TFTLCD tft;

    #define YP A1 // must be an analog pin, use “An” notation!
    #define XM A2 // must be an analog pin, use “An” notation!
    #define YM 7 // can be a digital pin
    #define XP 6 // can be a digital pin

    void setup(void) {
    Serial.begin(9600);
    Serial.println(F(“TFT LCD test”));

    #ifdef USE_ADAFRUIT_SHIELD_PINOUT
    Serial.println(F(“Using Adafruit 2.8\” TFT Arduino Shield Pinout”));
    #else
    Serial.println(F(“Using Adafruit 2.8\” TFT Breakout Board Pinout”));
    #endif

    Serial.print(“TFT size is “); Serial.print(tft.width()); Serial.print(“x”); Serial.println(tft.height());

    tft.reset();

    uint16_t identifier = tft.readID();

    //************************************ ordenes para placas no identificables “uncknown C0C0”

    if(identifier == 0x9325) {
    Serial.println(F(“Found ILI9325 LCD driver”));
    } else if(identifier == 0x9328) {
    Serial.println(F(“Found ILI9328 LCD driver”));
    } else if(identifier == 0x7575) {
    Serial.println(F(“Found HX8347G LCD driver”));
    } else if(identifier == 0x9341) {
    Serial.println(F(“Found ILI9341 LCD driver”));
    } else if(identifier == 0x8357) {
    Serial.println(F(“Found HX8357D LCD driver”));
    } else {
    Serial.print(F(“Unknown LCD driver chip: “));
    Serial.println(identifier, HEX);
    identifier = 0x9341;
    }
    //************************************** Lo importante es la última orden que, en caso de no identificar microcontrolador, obliga a asumir un ILI9341.
    /*

    if(identifier == 0x9325) {
    Serial.println(F(“Found ILI9325 LCD driver”));
    } else if(identifier == 0x9328) {
    Serial.println(F(“Found ILI9328 LCD driver”));
    } else if(identifier == 0x7575) {
    Serial.println(F(“Found HX8347G LCD driver”));
    } else if(identifier == 0x9341) {
    Serial.println(F(“Found ILI9341 LCD driver”));
    } else if(identifier == 0x8357) {
    Serial.println(F(“Found HX8357D LCD driver”));
    } else {
    Serial.print(F(“Unknown LCD driver chip: “));
    Serial.println(identifier, HEX);

    Serial.println(F(“If using the Adafruit 2.8\” TFT Arduino shield, the line:”));
    Serial.println(F(” #define USE_ADAFRUIT_SHIELD_PINOUT”));
    Serial.println(F(“should appear in the library header (Adafruit_TFT.h).”));
    Serial.println(F(“If using the breakout board, it should NOT be #defined!”));
    Serial.println(F(“Also if using the breakout, double-check that all wiring”));
    Serial.println(F(“matches the tutorial.”));
    return;
    }
    */
    tft.begin(identifier);

    Serial.println(F(“Benchmark Time (microseconds)”));

    Serial.print(F(“Screen fill “));
    Serial.println(testFillScreen());
    delay(500);

    Serial.print(F(“Text “));
    Serial.println(testText());
    delay(3000);

    Serial.print(F(“Lines “));
    Serial.println(testLines(CYAN));
    delay(500);

    Serial.print(F(“Horiz/Vert Lines “));
    Serial.println(testFastLines(RED, BLUE));
    delay(500);

    Serial.print(F(“Rectangles (outline) “));
    Serial.println(testRects(GREEN));
    delay(500);

    Serial.print(F(“Rectangles (filled) “));
    Serial.println(testFilledRects(YELLOW, MAGENTA));
    delay(500);

    Serial.print(F(“Circles (filled) “));
    Serial.println(testFilledCircles(10, MAGENTA));

    Serial.print(F(“Circles (outline) “));
    Serial.println(testCircles(10, WHITE));
    delay(500);

    Serial.print(F(“Triangles (outline) “));
    Serial.println(testTriangles());
    delay(500);

    Serial.print(F(“Triangles (filled) “));
    Serial.println(testFilledTriangles());
    delay(500);

    Serial.print(F(“Rounded rects (outline) “));
    Serial.println(testRoundRects());
    delay(500);

    Serial.print(F(“Rounded rects (filled) “));
    Serial.println(testFilledRoundRects());
    delay(500);

    Serial.println(F(“Done!”));
    }

    void loop(void) {
    for(uint8_t rotation=0; rotation<4; rotation++) {
    tft.setRotation(rotation);
    testText();
    delay(2000);
    }
    }

    unsigned long testFillScreen() {
    unsigned long start = micros();
    tft.fillScreen(BLACK);
    tft.fillScreen(RED);
    tft.fillScreen(GREEN);
    tft.fillScreen(BLUE);
    tft.fillScreen(BLACK);
    return micros() – start;
    }

    unsigned long testText() {
    tft.fillScreen(BLACK);
    unsigned long start = micros();
    tft.setCursor(0, 0);
    tft.setTextColor(WHITE); tft.setTextSize(1);
    tft.println("Hello World!");
    tft.setTextColor(YELLOW); tft.setTextSize(2);
    tft.println(1234.56);
    tft.setTextColor(RED); tft.setTextSize(3);
    tft.println(0xDEADBEEF, HEX);
    tft.println();
    tft.setTextColor(GREEN);
    tft.setTextSize(5);
    tft.println("Groop");
    tft.setTextSize(2);
    tft.println("I implore thee,");
    tft.setTextSize(1);
    tft.println("my foonting turlingdromes.");
    tft.println("And hooptiously drangle me");
    tft.println("with crinkly bindlewurdles,");
    tft.println("Or I will rend thee");
    tft.println("in the gobberwarts");
    tft.println("with my blurglecruncheon,");
    tft.println("see if I don't!");
    return micros() – start;
    }

    unsigned long testLines(uint16_t color) {
    unsigned long start, t;
    int x1, y1, x2, y2,
    w = tft.width(),
    h = tft.height();

    tft.fillScreen(BLACK);

    x1 = y1 = 0;
    y2 = h – 1;
    start = micros();
    for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color);
    x2 = w – 1;
    for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color);
    t = micros() – start; // fillScreen doesn't count against timing

    tft.fillScreen(BLACK);

    x1 = w – 1;
    y1 = 0;
    y2 = h – 1;
    start = micros();
    for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color);
    x2 = 0;
    for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color);
    t += micros() – start;

    tft.fillScreen(BLACK);

    x1 = 0;
    y1 = h – 1;
    y2 = 0;
    start = micros();
    for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color);
    x2 = w – 1;
    for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color);
    t += micros() – start;

    tft.fillScreen(BLACK);

    x1 = w – 1;
    y1 = h – 1;
    y2 = 0;
    start = micros();
    for(x2=0; x2<w; x2+=6) tft.drawLine(x1, y1, x2, y2, color);
    x2 = 0;
    for(y2=0; y2<h; y2+=6) tft.drawLine(x1, y1, x2, y2, color);

    return micros() – start;
    }

    unsigned long testFastLines(uint16_t color1, uint16_t color2) {
    unsigned long start;
    int x, y, w = tft.width(), h = tft.height();

    tft.fillScreen(BLACK);
    start = micros();
    for(y=0; y<h; y+=5) tft.drawFastHLine(0, y, w, color1);
    for(x=0; x<w; x+=5) tft.drawFastVLine(x, 0, h, color2);

    return micros() – start;
    }

    unsigned long testRects(uint16_t color) {
    unsigned long start;
    int n, i, i2,
    cx = tft.width() / 2,
    cy = tft.height() / 2;

    tft.fillScreen(BLACK);
    n = min(tft.width(), tft.height());
    start = micros();
    for(i=2; i0; i-=6) {
    i2 = i / 2;
    start = micros();
    tft.fillRect(cx-i2, cy-i2, i, i, color1);
    t += micros() – start;
    // Outlines are not included in timing results
    tft.drawRect(cx-i2, cy-i2, i, i, color2);
    }

    return t;
    }

    unsigned long testFilledCircles(uint8_t radius, uint16_t color) {
    unsigned long start;
    int x, y, w = tft.width(), h = tft.height(), r2 = radius * 2;

    tft.fillScreen(BLACK);
    start = micros();
    for(x=radius; x<w; x+=r2) {
    for(y=radius; y<h; y+=r2) {
    tft.fillCircle(x, y, radius, color);
    }
    }

    return micros() – start;
    }

    unsigned long testCircles(uint8_t radius, uint16_t color) {
    unsigned long start;
    int x, y, r2 = radius * 2,
    w = tft.width() + radius,
    h = tft.height() + radius;

    // Screen is not cleared for this one — this is
    // intentional and does not affect the reported time.
    start = micros();
    for(x=0; x<w; x+=r2) {
    for(y=0; y<h; y+=r2) {
    tft.drawCircle(x, y, radius, color);
    }
    }

    return micros() – start;
    }

    unsigned long testTriangles() {
    unsigned long start;
    int n, i, cx = tft.width() / 2 – 1,
    cy = tft.height() / 2 – 1;

    tft.fillScreen(BLACK);
    n = min(cx, cy);
    start = micros();
    for(i=0; i10; i-=5) {
    start = micros();
    tft.fillTriangle(cx, cy – i, cx – i, cy + i, cx + i, cy + i,
    tft.color565(0, i, i));
    t += micros() – start;
    tft.drawTriangle(cx, cy – i, cx – i, cy + i, cx + i, cy + i,
    tft.color565(i, i, 0));
    }

    return t;
    }

    unsigned long testRoundRects() {
    unsigned long start;
    int w, i, i2,
    cx = tft.width() / 2 – 1,
    cy = tft.height() / 2 – 1;

    tft.fillScreen(BLACK);
    w = min(tft.width(), tft.height());
    start = micros();
    for(i=0; i20; i-=6) {
    i2 = i / 2;
    tft.fillRoundRect(cx-i2, cy-i2, i, i, i/8, tft.color565(0, i, 0));
    }

    return micros() – start;
    }

  • Hola Admin.
    Me he encontrado con esta página y debo felicitarte por la dedicación y lo que nos has simplificado la faena para aprender paso a paso a controlar nuestros arduino. No había encontrado hasta hoy una página tan ordenada y que permitiese aprender paso a paso a controlar muchos de los sensores y objetos que vienen con los kits de aprendizaje.
    Respecto de los displays tft de 2.8″ con tarjeta SD incorporada y pantalla tactil te comento que he pillado uno de DX y al intentar reconocer el microcontrolador indica que no puede identificarlo (C0C0). Buscando resulta muy útil saber que muchos de los no reconocibles emplean un microcontrolador ILI9341 que funciona con las librerías de adafruit (#include y #include . en el ejemplo que tiene esta librería denominado graphictest solo hay que agregarle dos líneas: definir #define USE_ADAFRUIT_SHIELD_PINOUT en la cabecera y en el proceso a continuación de “uint16_t identifier = tft.readID(); if identifier==….” hay que agregar al final del último else la obligación de que al no poder identificar el microprocesador se asigna el valor identifier = 0x9341;
    } else {
    Serial.print(F(“Unknown LCD driver chip: “));
    Serial.println(identifier, HEX);
    identifier = 0x9341;
    }
    A partir de aquí la pantalla va de maravillas.

    • Hola Pablo y muchas gracias por el aporte. Pues resulta que tengo por aqui varios de estos displays TFT en shield que no he sido capaz de arrancar y me encantaria si me pudieses mandar ese ejemplo corregido que me comentas a ver si soy capaz de sacarlo para adelante jajajaj

      Muchas gracias por todo

  • Buenas Tardes.

    Yo quisiera saber que pantalla táctil me recomendarían, tengo un proyecto en el cual utilizaremos arduino muy probablemente, entonces queremos adaptar la maquina para varios modelos y queremos utilizar la pantalla táctil para poder cargar los programas dependiendo del modelo a correr, y también a la vez tener una ventana donde pueda controlar las salidas manualmente.

    • hola eduardo, pues depende jn poco del tamaño de pantalla que necesiteis y clsas asi. dame un poco las esñeckficaciones ideales y vemos que ñjede encajaros

    • Carlos Diaz

    Buenas. Has usado y armado un programa para manejar una impresora 3D desde la pantalla tactil arduino? Seria muy bueno saber si lo has logrado y como. Yo tengo algunos errores

    • Yo de momento solo he usado la pantalla típica LCD con potenciómetro y pulsador, pero me apunto tu idea para intentarlo cuando pueda. Un saludo.

    • Javier Alemañ

    hola, tengo una pantalla Generic touchscreen with SD markings on TFT panel are “QR4 5265S01 G3/4 TP28017”, que creo que es identica a la de la foto de este artículo, y no hay forma que funcione, siempre se queda en blanco muy iluminado.

    ¿Que puede estar pasando o que e echo mal para que no me funcione el ejemplo de este artículo?

    Saludos y gracias por adelantado.

    • Hola Javier, No creo que hagas nada mal. EL problema con las pantallas TFT que todos hemos pillado en china, es que a pesar de su aspecto el chip interno que de verdad controla el display puede ser casi cualquiera lo que genera una autentica explosioin de posibilidades. Por eso las librerias piden que especifiques cual es tu chip y puede acabar siendo poco menos que imposible identificarlo y menos aun configurar la libreria correctamente.

      Tengo por aqui unos 50 displays de difernetes tipos que no puedo usar porque el chino me los vende pero luego no sabe como manejarles y por eso yo yano compro ningun display que no tenga garantizado su manejo. Los que hay en nuestra tienda estan probados y os pongo a descargar las librerias configuradas porque de otro modo el riesgo de haber comprado un pisapapeles con pinchos es muy alto

  • Hola a todos.
    Tengo una pantalla de TFT LCD 2.4″ con chip ILI9335, pero no he podido conseguir el controlador por ninguna parte. lo mas que he podido hacer es instalar la librería de la SPFD5408 pero toda la pantalla sale al revés como en un espejo. me podrían ayudar con la librería para el 9335 o o la forma de invertir la pantalla.

    • Yojona

    Puedo usarlo con un arduino nano?

    • Seguro que si, pero tendras que estudiar que pines usa y cablearlos

  • Ya he compilado el código y al parecer no da problemas, el detalle me ha surgido cuando conecté la LCD touch y no agarraba. El programa me arrojaba un error a la hora de cargar el código en la tarjeta, algo así de avrdude: stk500_getsync(): not in sync: resp=0x00
    No sé a qué se deba.

    • Hola Erendira, parece mas un problema con la puerta serie y que no ha podido volcar el problema. Asegurate de puedes volcarle el programa sin problemas y luego veremos si el codigo es compatible

    • Eréndira

    Hola, antes que nada felicitaciones, es un muy buen post. Yo tengo una touch screen de 4D systems y la verdad no sé si haya mucha diferencia entre esa y la que tu ocupaste. ¿Será que apliquen los mismos comandos? Gracias de antemano. Un saludo.

    • Hola Erendira,
      No sabria decirte si la de 4d es compatible con esta de seed studio que use yo para el post, pero puedes probarlo y aver que pasa porque no vas a dañar tu pantalla. Para ello bastaria con que la reconozca la libreria y en caso contrario probar con la libreria de adafruit que son las dos tipicas

      En cuanto a los comandos seran similares en una y otra aunque cada una con sus manias claro

    • Gaston

    Hello, i have a question, i have a touch screen with driver HX8352A, how can i make this code work for my touch screen???

    • Hi Gaston,
      All the code in this example is developped with the Seed libraries for this kind of display, so any other supported display should run the code with no problems. But I am affraid I can’t say wether or not is your display supported in that libarary.
      I advice you to check seed TFT main page at :
      https://github.com/Seeed-Studio/TFT_Touch_Shield_V2
      And check for your display, OK?
      Regards

  • En este tema, en el apartado “Programando el panel tactil”
    Has puesto dos veces el mismo fichero
    “Para empezar necesitamos la librería táctil Seeed_TFT_v2.0.zip, además de la librería Seeed_TFT_v2.0.zip y de la SPI, por lo que necesitamos…
    Saludos

    • Hola Pedro Luis,
      Lamento el error y confío en que ya esté corregido. He añadido la librería Touch_Screen_Driver-master, a la pagina para que podáis descargarla.
      Gracias por la indicarmelo y un saludo.

  • cordial saludo, soy nuevo en el tema y me gustaría configurar la pantalla con tres botones y que me genere una señal de salida para encender los leds cuando los pulse cada uno.
    gracias

    • Hola Rles, en esta misma pagina tienes ejemplos de como definir y usar botones tactiles con este panel, que creo te serviran de ayuda en tu necesidad. Si no es asi dimelo y veremos como ayudarte
      Un saludo

    • Cames

    Hola amigo esta super lo que hiciste aun que algo complicado..
    Te escribo por la razón que yo estoy tratando de hacer un botón el cual me active o desactive una salida de 5 v.
    aparte quiero tomar un dato de un sensor para reflejarlo en la pantalla..
    El problema es en el dato del sensor como puedo hacer para que no se sobre ponga y aparte de que no me interrumpa en el loop.
    el botón ya lo tengo listo activando la salida que quiero. Te lo pregunto por que tu asociaste varios void en el tutorial.

    • Un metodo seria que leyeras el sensor dentro del loop, y otro seria que definieras una interrupcion programada cada tanto tiempo para leer el sensor y que desde dentro del loop lo imprimas en el display en la posicion que te convenga
      Un aludo

    • Jose luis rueda

    Muy interesante el tutorial

    Yo quiero hacer un menu tactil , compre el tft touch shield de seed studio
    pero no encontrado un sistema de menu que funcione con el
    Por desgracia no soy un experto en arduino , y aunque encontre este menu http://thecustomgeek.com/2011/06/18/jos-open-source-menu-interface-for-arduino/
    es para alfraduit y no soy capaz de adaptar el codigo
    No se si alguien me puede ayudar a encontrar un codigo para menu con este tft , seeed studio 2,8 v2.0 sld10261p

    Un saludo

    • Hola Jose Luis
      No he probado el TFT de 2.8 de seedstudio, pero la probabilidad de que use la misma libreria que el de 3.2 que he presenrado en el tutorial es muy alta. De ser asi, confio en que el tuto mostrandote como definir zonas activas y botones te seran utiles, y lo unico que debes tener en cuenta es que estas librerias no permiten girar el texto, lo que resulta molesto.
      Bastara con que definas tantas zonas activas como necesites y dettectes la spulsaciones como te describo en el tutorial.

      Por lo demas, adaptar la libreria de adafruit a este display, puede o no ser complñicado, pero siempre seria mas barato, con mucho compraqrte un display de adafruit directamente.

      UN saludo

Give a Reply

WordPress Anti-Spam by WP-SpamShield