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:



Um comentário:

  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

Tecnologia do Blogger.