segunda-feira, 16 de janeiro de 2017

Display 2.4" TFT LCD Touch Screen - Arduino Uno

Depois de um tempinho sem postar, aproveitei as férias para atualizar o blog, e hoje trago um tutorial para resolver os problemas de quem não conseguiu usar satisfatoriamente esse display, que apesar de odiado por muitos, tem funcionado muito bem aqui nos testes.

Antes de começar, vou citar alguns detalhes:

Baixe as bibliotecas:
https://github.com/marcelocella204/Display-2.4-TFT-LCD-Touch-Screen

Modelo utilizado:


Vale a pena comprar? Sim. Pelo menos por enquanto está bem estável o touch screen,  e apenas para exibir informações simples, como texto e barras, melhor ainda. Eu diria que pra utilizar num produto final, que seja vendido, não é interessante usar o touch, pois ele não fica "perfeito", mas para estudo e protótipos é nota 10.

Para uso do touch recomendo o toque com a ponta do dedos, mas pra calibrar recomento o uso da caneta stylus que acompanha o display.

Alguns tutoriais recomendam o uso de material isolante entre o conector USB do arduino UNO e o shield, pois pode haver curto, o meu não foi preciso, verifique com cuidado se é o seu caso.

Rotação da tela: existem 4 direções ( de 0 a 3), caso você mude a rotação, será necessário adaptar o código. No exemplo estou usando a posição 1.
No caso do touch, é possível fazer uma adaptação automática da rotação usando a função map, porém, para deixar o touch mais simples e preciso, não utilizei essa função, sendo assim será necessário adaptação do código.


 Vamos ao primeiro código de teste, apenas exibindo informações básicas:


// Code provided by Smoke And Wires
// http://www.smokeandwires.co.nz
// This code has been taken from the Adafruit TFT Library and modified
// by us for use with our TFT Shields / Modules
// For original code / licensing please refer to
// https://github.com/adafruit/TFTLCD-Library
//código adaptado e comentado por Marcelo Cella para o blog http://viciadosemarduino.blogspot.com.br/ com o apoio de
//http://sttamp.com/loja
#include <Adafruit_GFX.h> // Core graphics library
#include "SWTFT.h" // Hardware-specific library
// 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 //use este site para gerar mais cores http://www.barth-dev.de/online/rgb565-color-picker/
#define BLUE 0x001F
#define RED 0xF800
#define GREEN 0x07E0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define WHITE 0xFFFF
#define PINK 0xE0F9
#define GREY 0x630C
SWTFT tft;
// If using the shield, all control and data lines are fixed, and
// a simpler declaration can optionally be used:
// SWTFT tft;
void setup(void) {
Serial.begin(9600); // inicial comunicação serial
Serial.println(F("TFT LCD test"));
tft.reset(); // reinicia o display
uint16_t identifier = tft.readID(); // identificador do chip do seu display
Serial.print(F("LCD driver chip: "));
Serial.println(identifier, HEX);
tft.begin(identifier);
Serial.println(F("Benchmark Time (microseconds)"));
Serial.print(F("Screen fill "));
delay(500);
Serial.println(F("Done!"));
delay(500);
tft.setRotation(1); // seleciona rotação 1 (porta usb voltada para a esquerda)
tft.fillScreen(BLUE); // preenche a tela inteira com uma cor
tft.drawRect(0, 0, 320, 240, YELLOW); // desnha uma borda na tela
tft.drawRect(1, 1, 318, 238, YELLOW); // desenha mais uma linha de borda
tft.drawRect(10, 135, 300, 15, YELLOW); //desenha a barra em branco/estrutura: Coluna inicial, linha inicial, comprimento, altura
tft.setCursor(30, 30); //define ponto inicial para o próximo texto/ estrutura: coluna e linha, 320x240 max
tft.setTextColor(WHITE); // define cor para o próximo texto
tft.setTextSize(3);// define o tamanho para o próximo texto
tft.println("Hello World!");
tft.setTextSize(2);
tft.setCursor(10, 190);
tft.print(F("LCD driver chip: "));
tft.println(identifier, HEX);
}
void loop(void) {
for (int x = 0; x < 300; x++) { // exemplo de exibição de números
tft.setCursor(30, 100); // primeiro exibimos o "texto", fundo azul com letras verdes
tft.setTextColor(GREEN);
tft.setTextSize(3);
tft.println(x);
delay (200);
tft.setCursor(30, 100); // depois exibimos novamente com "texto" e fundo azul
tft.setTextColor(BLUE); // ou seja, exibimos e apagamos para poder fazer o renew de forma simples
tft.setTextSize(3);
tft.println(x);
tft.drawRect(10, 135, x, 15, YELLOW); // preenche a barra de acordo com o valor de x
}
tft.fillRect(11, 136, 298, 13, BLUE); // apagamos a barra para o próximo loop do for
}
Resultado:



Teste de touch screen:

// Code provided by Smoke And Wires
// http://www.smokeandwires.co.nz
// This code has been taken from the Adafruit TFT Library and modified
// by us for use with our TFT Shields / Modules
// For original code / licensing please refer to
// https://github.com/adafruit/TFTLCD-Library
//código adaptado e comentado por Marcelo Cella para o blog http://viciadosemarduino.blogspot.com.br/ com o apoio de
//http://sttamp.com/loja
#include <Adafruit_GFX.h> // Core graphics library
#include "SWTFT.h" // Hardware-specific library
#include "TouchScreen.h"
#define YP A2 // must be an analog pin, use "An" notation!
#define XM A3 // must be an analog pin, use "An" notation!
#define YM 8 // can be a digital pin
#define XP 9 // can be a digital pin
// For better pressure precision, we need to know the resistance
// between X+ and X- Use any multimeter to read it
// For the one we're using, its 300 ohms across the X plate
// No meu caso, o resistor de 200 ohms funciona melhor
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 200);
// 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 //use este site para gerar mais cores http://www.barth-dev.de/online/rgb565-color-picker/
#define BLUE 0x001F
#define RED 0xF800
#define GREEN 0x07E0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define WHITE 0xFFFF
#define PINK 0xE0F9
#define GREY 0x630C
SWTFT tft;
int button_1 = 1; // criamos 3 botoes na tela inicial
int button_2 = 1;
int button_3 = 1;
int ledteste = 13; // criamos uma saída para teste (led onboard do arduino)
void setup(void) {
pinMode (ledteste, OUTPUT);
Serial.begin(9600);
Serial.println(F("TFT LCD test")); // fazemos novamente a verificação do CI
tft.reset();
uint16_t identifier = tft.readID();
Serial.print(F("LCD driver chip: "));
Serial.println(identifier, HEX);
tft.begin(identifier);
Serial.println(F("Benchmark Time (microseconds)"));
Serial.print(F("Screen fill "));
delay(50);
Serial.println(F("Done!"));
delay(50);
tft.setRotation(1);
tft.fillScreen(GREY);
tft.drawRect(15, 15, 70, 70, WHITE);// Coluna inicial, linha inicial, comprimento, altura
tft.drawRect(115, 15, 70, 70, WHITE);// Coluna inicial, linha inicial, comprimento, altura
tft.drawRect(215, 15, 70, 70, WHITE);// Coluna inicial, linha inicial, comprimento, altura
tft.setTextColor(YELLOW);
tft.setTextSize(3);
tft.setCursor(42, 42);//COLUNA, LINHA
tft.println("1");
tft.setCursor(145, 42);//COLUNA, LINHA
tft.println("2");
tft.setCursor(240, 42);//COLUNA, LINHA
tft.println("3");
}
void loop(void) {
TSPoint p = ts.getPoint(); //função que verifica posição do toque
pinMode(XM, OUTPUT); // define x+, x-, y+ e y- (conextores do touch)
digitalWrite(XM, LOW);
pinMode(YP, OUTPUT);
digitalWrite(YP, HIGH);
pinMode(YM, OUTPUT);
digitalWrite(YM, LOW);
pinMode(XP, OUTPUT);
digitalWrite(XP, HIGH);
// analisa se houve pressão suficiente para ser considerado um toque
if (p.z > ts.pressureThreshhold) { // we have some minimum pressure we consider 'valid'// pressure of 0 means no pressing!
Serial.print("X = ");
Serial.print(p.x);
Serial.print("\tY = ");
Serial.print(p.y);
Serial.print("\tPressure = ");
Serial.println(p.z);
delay (50);
if (p.x >= 755 && p.x <= 940 && p.y <= 460) { // analisa se a area tocada corresponde ao boatão 1
button_1 ++; // botão 1 recebe mais um
button_1 = button_1 % 2; // testa se botão 1 é impar ou par
if (!button_1) {// se for diferente de 0
button_1_on(); // botão 1 = on
digitalWrite (ledteste, HIGH); // ascende led onboard
}
else {// se for = 0
button_1_off(); // boatão 1 desliga
digitalWrite (ledteste, LOW);
}
}
if (p.x >= 530 && p.x <= 700 && p.y <= 460) {// analisa se a area tocada corresponde ao boatão 2
button_2 ++;
button_2 = button_2 % 2;
if (!button_2) {
button_2_on();
//insira aqui as açoes para o botão 2
}
else {
button_2_off();
//insira aqui as açoes para o botão 2
}
}
if (p.x >= 285 && p.x <= 470 && p.y <= 460) { // analisa se a area tocada corresponde ao boatão 3
button_3 ++;
button_3 = button_3 % 2;
if (!button_3) {
button_3_on();
//insira aqui as açoes para o botão 3
}
else {
button_3_off();
//insira aqui as açoes para o botão 3
}
}
tft.fillRect(255, 175, 50, 50, GREY);// primeiro "apagamos" a região onde serão exibidos ultimos toques
tft.setTextColor(YELLOW);
tft.setTextSize(2);
tft.setCursor(10, 175);//COLUNA, LINHA
tft.println ("Last Touch Point x:");
tft.setCursor(255, 175);//COLUNA, LINHA
tft.println(p.x); // reexibindo posição do ultimo toque em x
tft.setCursor(10, 202);//COLUNA, LINHA
tft.println ("Last Touch Point y:");
tft.setCursor(255, 202);//COLUNA, LINHA
tft.println(p.y); // reexibindo posição do ultimo toque em y
}
}
void button_1_on () { //criamos uma função que "ascende" o botão 1
tft.fillRect(15, 15, 70, 70, GREEN);// desenha botão verde escrito on
tft.setTextColor(BLACK);
tft.setTextSize(3);
tft.setCursor(36, 42);
tft.println("ON");
return;
}
void button_1_off () {//criamos uma função que "apaga" o botão 1
tft.fillRect(15, 15, 70, 70, GREY);// apaga o verde
tft.drawRect(15, 15, 70, 70, WHITE);// desenha botão preto com bordas brancas (off)
tft.setTextColor(GREEN);
tft.setTextSize(3);
tft.setCursor(42, 42);
tft.println("1");
return;
}
void button_2_on () {
tft.fillRect(115, 15, 70, 70, GREEN);// Coluna inicial, linha inicial, comprimento, altura
tft.setTextColor(BLACK);
tft.setTextSize(3);
tft.setCursor(136, 42);
tft.println("ON");
return;
}
void button_2_off () {
tft.fillRect(115, 15, 70, 70, GREY);// Coluna inicial, linha inicial, comprimento, altura
tft.drawRect(115, 15, 70, 70, WHITE);// Coluna inicial, linha inicial, comprimento, altura
tft.setTextColor(YELLOW);
tft.setTextSize(3);
tft.setCursor(140, 42);
tft.println("2");
return;
}
void button_3_on () {
tft.fillRect(215, 15, 70, 70, GREEN);// Coluna inicial, linha inicial, comprimento, altura
tft.setTextColor(BLACK);
tft.setTextSize(3);
tft.setCursor(236, 42);
tft.println("ON");
return;
}
void button_3_off () {
tft.fillRect(215, 15, 70, 70, GREY);// Coluna inicial, linha inicial, comprimento, altura
tft.drawRect(215, 15, 70, 70, WHITE);// Coluna inicial, linha inicial, comprimento, altura
tft.setTextColor(YELLOW);
tft.setTextSize(3);
tft.setCursor(240, 42);
tft.println("3");
return;
}
resultado:

Teste de performance:

6 comentários:

  1. Este comentário foi removido pelo autor.

    ResponderExcluir
  2. Respostas
    1. o texto ou a tela toda? na horizontal ou na vertical? valeu

      Excluir
  3. Ola...rodei o programa dos botões, a imagem aparece mas o touch não funciona....na compilação apareceram algumas msgs como: "In file included from c:\program files (x86)\arduino\hardware\tools\avr\avr\include\avr\iom2560.h:38:0," ...sabe o que poderia ser?
    Obrigado pela ajuda!

    ResponderExcluir
  4. amigo o meu aparece a tela toda invertida tem ideia de como posso mudar isso ?

    ResponderExcluir
  5. O meu também aparece espelhado. Mas dos participantes acima ninguém é capaz de dizer porquê......

    ResponderExcluir