banner

Arduino e Display Touch Screen



Quer fazer menus mais personalizados? E melhores interfaces homem/máquina? Para tais projetos você pode utilizar um Arduino e um Display Touch Screen. Gostou da ideia? Então, acompanhe o vídeo de hoje, no qual vou te mostrar uma montagem com um Arduino Mega e um Display Touch Screen. Você vai ver como fazer os desenhos que desejar na tela e ainda como determinar a região desta tela a ser tocada para ativar um determinado comando. Destaco que optei por utilizar o Arduino Mega em função da quantidade de pinos que ele possui.


Então, hoje, vou te apresentar o display Touch Screen, suas funções gráficas e como pegar o ponto do toque na tela. Vamos também criar um exemplo contendo todos os elementos, como posicionamento, escrita, desenho de formas, cores e toque.

Arduino Mega 2560




TFT LCD Shield 2.4”

Este display que usamos no nosso projeto tem uma particularidade interessante: possui um cartão SD. No entanto, como fazer gravação e leitura neste será mostrado em um outro vídeo, que ainda pretendo produzir. Nesta aula de hoje o objetivo é tratar especificamente sobre as características gráficas e de touch screen deste display.




Características:

  • Dimensão tela: 2,4 polegadas
  • Slot para cartão MicroSD
  • Cor LCD: 65K
  • Controlador: ILI9325
  • Resolução: 240 x 320
  • Touchscreen: 4 fios resistivos touchscreen
  • Interface: 8 bit dados, mais 4 linhas de controle
  • Tensão de operação: 3,3-5V
  • Dimensões: 71 x 52 x 7mm



Bibliotecas

Adicione as bibliotecas:
Clique nos links e faça os downloads das bibliotecas.
Descompacte o arquivo e cole na pasta de bibliotecas da IDE do arduino.
C:/Program Files (x86)/Arduino/libraries


Observação:
Antes de iniciarmos o nosso programa, vamos fazer algo importante: a calibração do TOUCH.
Utilizando um programa simples para pegar os pontos de toque no display, guarde o valor dos pontos (x,y) em cada uma das extremidades (destacados em amarelo na figura abaixo). Esses valores são importantes para mapear o touch aos pontos gráficos na tela.



#include <TouchScreen.h>
//Portas de leitura das coordenadas do touchvoid
#define YP A1 // Y+ is on Analog1 
#define XM A2 // X- is on Analog2 
#define YM 7 // Y- is on Digital7 
#define XP 6 // X+ is on Digital6 
//objeto para manipulacao dos eventos de toque na tela 
TouchScreen ts = TouchScreen(XP, YP, XM, YM);

void setup() {
       Serial.begin(9600);
}

void loop() {
     TSPoint touchPoint = ts.getPoint();//pega o touch 
     (x,y,z=pressao)
     Serial.print("X: "); Serial.println(touchPoint.x);
     Serial.print("Y: "); Serial.println(touchPoint.y);
     delay(1000);
}



Funções
Agora vamos dar uma olhada em algumas funções gráficas que as bibliotecas nos oferecem.

1.       drawPixel
A função drawPixel é responsável por pintar um único ponto na tela no ponto dado.

void drawPixel(int16_t x, int16_t y, uint16_t color)

2.       drawLine
A função drawLine é responsável por desenhar uma linha a partir de dois pontos.

void drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color);

3.       drawFastVLine
A função drawFastVLine é responsável por desenhar uma linha vertical a partir de um ponto e uma altura.

void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color);

4.       drawFastHLine
A função drawFastHLine é responsável por desenhar uma linha horizontal a partir de um ponto e uma largura.

void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color);

5.       drawRect
A função drawRect é responsável por desenhar um retângulo na tela, passando um ponto de origem, sua altura e largura.

void drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);

6.       fillRect
A função fillRect é a mesma que drawRect, porém, o retângulo será preenchido com a cor dada.

void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);

7.       drawRoundRect
A função drawRoundRect é a mesma que drawRect, porém, o retângulo terá as bordas arredondadas.

void drawRoundRect(int16_t x0, int16_t y0, int16_t w, int16_t h,int16_t radius, uint16_t color);

8.       fillRoundRect
A função fillRoundRect é a mesma que drawRoundRect, porém, o retângulo será preenchido com a cor dada.

void fillRoundRect(int16_t x0, int16_t y0, int16_t w, int16_t h,int16_t radius, uint16_t color);

9.       drawTriangle
A função drawTriangle é responsável por desenhar um triângulo na tela, passando o ponto dos 3 vértices.

void drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color);

10.   fillTriangle
A função fillTriangle é a mesma que drawTriangle, porém, o triângulo será preenchido com a cor dada.

void fillTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color);

11.   drawCircle
A função drawCircle é responsável por desenhar um círculo a partir de um ponto origem e um raio.

void drawCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color);

12.   fillCircle
A função fillCircle é a mesma que drawCircle, porém, o círculo será preenchido com a cor dada.

void fillCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color)

13.   fillScreen
A função fillScreen é responsável por preencher a tela de uma única cor.

void fillScreen(uint16_t color);

14.   setCursor
A função setCursor é responsável por posicionar o cursor para escrita em um ponto dado.

void setCursor(int16_t x, int16_t y);

15.   setTextColor
A função setTextColor é responsável por atribuir uma cor ao texto que será escrito. Temos duas maneiras de utilizá-la:

void setTextColor(uint16_t c); //configura a cor apenas da escrita
void setTextColor(uint16_t c, uint16_t bg); //configura a cor da escrita e a cor do fundo

16.   setTextSize
A função setTextSize é responsável por atribuir um tamanho para o texto que será escrito.

void setTextSize(uint8_t s);

17.   setTextWrap
A função setTextWrap é responsável por quebrar a linha caso chega ao limite da tela.

void setTextWrap(boolean w);

18.   setRotation
A função setRotation é responsável por rotacionar a tela (landscape, portrait).

void setRotation(uint8_t r); //0 (padrão),1,2,3


Exemplo


Criaremos um programa no qual utilizaremos a maior parte dos recursos que o display nos proporciona.
Vamos escrever algumas strings em diferentes tamanhos, criar três figuras geométricas e pegar o evento de toque sobre elas, a cada vez que tocarmos em uma das figuras, teremos o feedback do nome da figura logo abaixo delas.


Bibliotecas

Primeiramente vamos definir as bibliotecas que utilizaremos.

#include <SWTFT.h> //responsável pela parte gráfica
#include <TouchScreen.h> //responsável por pegar os toques na tela
#include <SPI.h> //comunicação com o display
#include <Wire.h> //comunicação com o display
#include "math.h" //calcular potencia


Defines

Definiremos algumas macros para os pinos e valores importantes que utilizaremos.

//Portas de leitura das coordenadas do touch
#define YP A1 // Y+
#define XM A2 // X- 
#define YM 7  // Y-  
#define XP 6  // X+   
//valores encontrados através da calibração do touch
//faça um código simples para imprimir os valores (x,y) a cada toque
//então encontre os valores nas extremidades max/min (x,y)
#define TS_MINX 130 
#define TS_MINY 80 
#define TS_MAXX 900
#define TS_MAXY 900
//tamanho dos textos
#define TEXT_SIZE_L 3
#define TEXT_SIZE_M 2
#define TEXT_SIZE_S 1 
//posicionamento dos textos de feedback
#define FEEDBACK_LABEL_X 10
#define FEEDBACK_LABEL_Y 200
#define FEEDBACK_TOUCH_X 120
#define FEEDBACK_TOUCH_Y 200 
//valores para detectar a pressão do toque
#define MINPRESSURE 10
#define MAXPRESSURE 1000


Prosseguimos com a definição de algumas macros.

//Associa o nome das cores aos valores correspondentes
#define BLACK  0x0000
#define RED    0xF800
#define GREEN  0x07E0
#define CYAN   0x07FF
#define YELLOW 0xFFE0
#define WHITE  0xFFFF

//dados de criação do circulo
const int circle_radius = 30;
const int circle_x = 240;
const int circle_y = 125;

//objeto para manipulacao dos eventos de toque na tela 
TouchScreen ts = TouchScreen(XP, YP, XM, YM); 
//objeto para manipulacao da parte grafica
SWTFT tft;


Setup

No setup, vamos inicializar nosso objeto de controle gráfico e fazer as primeiras configurações.

void setup() {
   Serial.begin(9600); 
   //reseta o objeto da lib grafica
   tft.reset();
   //inicializa objeto controlador da lib grafica
   tft.begin();
   delay(500);
   //rotaciona a tela para landscape
   tft.setRotation(1);
   //pinta a tela toda de preto
   tft.fillScreen(BLACK);
   //chama a função para iniciar nossas configurações
   initialSettings();
}


Loop

No loop, vamos pegar o ponto no qual tocamos a tela e verificamos se o toque ocorreu em uma das figuras.

void loop() {
   TSPoint touchPoint = ts.getPoint();//pega o touch (x,y,z=pressao) 
   pinMode(XM, OUTPUT);
   pinMode(YP, OUTPUT);
   //mapeia o ponto de touch para o (x,y) grafico
   // o fato de termos rotacionado a tela para landscape implica no X receber o mapeamento de Y 
   TSPoint p;
   p.x = map(touchPoint.y, TS_MINY, TS_MAXY, 0, 320);
   p.y = map(touchPoint.x, TS_MINX, TS_MAXX, 240, 0);
    //verifica se a pressão no toque foi suficiente 
   if (touchPoint.z > MINPRESSURE && touchPoint.z < MAXPRESSURE) {
      //verifica se tocou no retangulo
      if(pointInRect(p)) {
         writeShape("Rect");
      }
      //verifica se tocou no triangulo
      else if(pointInsideTriangle(TSPoint(110,150,0), TSPoint(150,100,0), TSPoint(190,150,0), p)) {
         writeShape("Triangle");
      }
      //verifica se tocou no circulo
      else if(pointInCircle(p)) {
         writeShape("Circle");
      }
   } 
}


Verificação se tocamos no círculo

Nesta etapa tratamos da inicialização de tela e definimos as cores dos textos a serem exibidos no display.

/*
Desenha na tela os elementos
*/
void initialSettings()
{
   tft.setTextColor(WHITE);
   tft.setTextSize(TEXT_SIZE_S);
   tft.println("ACESSE");

   tft.setTextColor(YELLOW);
   tft.setTextSize(TEXT_SIZE_M);
   tft.println("MEU BLOG");

   tft.setTextColor(GREEN);
   tft.setTextSize(TEXT_SIZE_L);
   tft.println("FERNANDOK.COM");

   createRect();
   createTriangle();
   createCircle();

   tft.setCursor(FEEDBACK_LABEL_X, FEEDBACK_LABEL_Y);
   tft.setTextColor(CYAN);
   tft.setTextSize(TEXT_SIZE_L);
   tft.println("SHAPE: ");
}



Funções de criação das formas geométricas

Criamos um retângulo, um triângulo e um círculo com as origens que determinarmos.

//cria um retangulo com origem (x,y) = (10,100)
//width = 80 e height = 50
void createRect()
{
   tft.fillRect(10, 100, 80, 50, RED);
   tft.drawRect(10, 100, 80, 50, WHITE);
}

//cria um triangulo com os vertices:
//A = (110,150) ; B = (150,100) ; C = (190,150)
void createTriangle()
{
   tft.fillTriangle(110, 150, 150, 100, 190, 150, YELLOW);
   tft.drawTriangle(110, 150, 150, 100, 190, 150, WHITE); 
}

//cria um circulo com origem no ponto (x,y) = (240,125) e raio = 30
void createCircle()
{
   tft.fillCircle(240, 125, 30, GREEN);
   tft.drawCircle(240, 125, 30, WHITE);
}


Verificação se tocamos no retângulo

Esta função verifica se o ponto está dentro do retângulo.

//Função que verifica se o ponto está dentro do retângulo
bool pointInRect(TSPoint p)
{
   //max/min X do retangulo
   if( p.x >= 10 && p.x <= 90) {
      //max/min Y do retangulo 
      if( p.y <= 150 && p.y >= 100)
      {
         return true;
      }
   }
   return false;
}




Verificação se tocamos no círculo

O mesmo em relação ao círculo.

//distancia entre pontos D = raiz( (xb-xa)^2 + (yb-ya)^2 )
//vefifica se o ponto está dentro do circulo
//se a distancia do ponto pra origem do circulo for menor ou igual ao raio, ele está dentro
bool pointInCircle(TSPoint p)
{
   float distance = sqrt( pow(p.x - circle_x,2) + pow(p.y - circle_y,2));
   if(distance <= circle_radius)
   {
        return true;
   }
   return false;
}



Verificação se tocamos no triângulo

A mesma verificação em relação ao ponto também ocorre dentro do triângulo.

// Função que verifica se o ponto p esta dentro do triangulo ABC
// Se estiver dentro retorna TRUE senão retorna FALSE
bool pointInsideTriangle(TSPoint a, TSPoint b, TSPoint c, TSPoint p){
   float ABC = triangleArea(a, b, c);
   float ACP = triangleArea(a, c, p);
   float ABP = triangleArea(a, b, p);
   float CPB = triangleArea(c, p, b);

   if(ABC == ACP+ABP+CPB){
 return true;
   }
   return false;
}




// Função que calcula a area de um triangulo com base nos pontos x,y
float triangleArea(TSPoint a, TSPoint b, TSPoint c){
 return fabs(((b.x - a.x)*(c.y - a.y) - (c.x - a.x) * (b.y - a.y))/2);
}





Função para imprimir o nome do objeto tocado

Aqui escrevemos na tela o nome da figura geométrica que for tocada.

//escreve na tela o nome da figura geométrica que foi tocada
void writeShape(String shape)
{
   tft.fillRect(FEEDBACK_TOUCH_X, FEEDBACK_TOUCH_Y, 170, 30, BLACK);
   tft.setCursor(FEEDBACK_TOUCH_X, FEEDBACK_TOUCH_Y);
   tft.setTextSize(TEXT_SIZE_G);
   tft.setTextColor(WHITE);
   tft.println(shape); 
}




Faça o download dos arquivos:



9 comentários:

  1. //ESP..ero 32 vezes mais que os outros que minha mensagem seja a vencedora.
    /**************************************************************************
    * MENSAGEM TABELA ASKII
    **************************************************************************/
    void setup(){

    int msgASK [22] = {81,117,101,114,111,32,103,97,110,104,97,114,32,117,109,32,69,83,80,51,50,33};
    char msg [22] = {""};

    void loop(){
    for(cont=0; cont<22;cont++) {
    msg[cont] = FuncConverteAskToChar(msgASK[cont]);
    lcd.print (msg[cont]);
    }
    }
    }

    ResponderExcluir
  2. Quero ligar esse display num NodeMCU-32S.
    Alguém pode me ajudar com a pinagem?
    Obrigado!

    ResponderExcluir
    Respostas
    1. Olá, Gilberto. Caso não tenha conseguido ligar o ESP32 nesse display, tenho um código recém postado que é justamente pra essa ocasião. Qualquer coisa deixe um comentário que eu respondo lá mesmo.
      https://gist.github.com/danliberato/22c3fa69d4b01209e68e5f6b32b05294

      Excluir
  3. Gostaria de ligar este display (TFT shield do Arduino ) no ESP32, usando as funções de toque inclusive.
    Como ficaria as ligações ? É possível ?

    ResponderExcluir
  4. Olá, Eu Estou Tendo O Seguinte Problema.
    'TEXT_SIZE_G' was not declared in this scope

    tft.setTextSize(TEXT_SIZE_G);
    exit status 1
    'TEXT_SIZE_G' was not declared in this scope

    ResponderExcluir
  5. Olá,

    Coloco as bibliotecas nos locais indicados, mas meu display só liga os LED's da tela. Alguém tem alguma sugestão?

    ResponderExcluir
    Respostas
    1. Estou com estes Erros:

      Biblioteca inválida encontrada em C:\Program Files (x86)\Arduino\libraries\Adafruit-GFX-Library-master: no headers files (.h) found in C:\Program Files (x86)\Arduino\libraries\Adafruit-GFX-Library-master

      Biblioteca inválida encontrada em C:\Program Files (x86)\Arduino\libraries\SWTFT-Shield: no headers files (.h) found in C:\Program Files (x86)\Arduino\libraries\SWTFT-Shield

      Biblioteca inválida encontrada em C:\Program Files (x86)\Arduino\libraries\Touch-Screen-Library-master: no headers files (.h) found in C:\Program Files (x86)\Arduino\libraries\Touch-Screen-Library-master

      Excluir
  6. (x,y,z=pressao) esse trecho dá erro, não sei se alguém teve o mesmo problema.

    ResponderExcluir

Tecnologia do Blogger.