Na primeira parte vimos como é a interface com o controlador do display. E a detecção de toque? Esta parte não é tratada pelo controlador, porém utiliza alguns pinos em comum com ele. Quais pinos e como implementar a detecção de toque deu um pouco de trabalho.
De forma resumida, quando realizamos um toque, é feito o contato entre duas linhas resistivas ortogonais (em formato de cruz). Dois pino estão ligados ao extremo da linha X e dois pinos estão ligados ao extremo da linha Y. Para conseguirmos detectar a posição do toque é preciso que pelo menos um extremo de cada linha esteja ligado a uma entrada analógica:
- Detectar se temos um toque: colocamos em nível baixo os dois extremos de uma linha (por exemplo X), ligamos uma ponta da outra linha à alimentação via um pullup (basta configurar este pino como entrada com pullup) e examinamos a tensão na outra ponta. Se tiver toque, a tensão será próxima de zero (devido ao contato com a linha aterrada), caso contrário será alguma tensão positiva (devido ao pullup).
- Determinar a posição no eixo X: Colocamos uma ponta do Y em nível alto e a outra em nível baixo e medimos a tensão na ponta do X ligada à entrada analógica.
- Determinar a posição no eixo Y: Colocamos uma ponta do X em nível alto e a outra em nível baixo e medimos a tensão na ponta do Y ligada à entrada analógica.
Como descobrir quais os pinos usados? Basta desconectar o shield do Arduino e usar um multímetro para medir a resistência entre os pinos analógicos e os demais. A maioria das combinações vai ser indicada pelo multímetro como "aberto" (sem conexão). Dois pares vão indicar resistência, são os extremos das linhas. No meu caso foram (6, A1) e (7, A8). Você pode fazer um teste colocando o multímetro para medir a resistência entre uma ponta de uma linha e uma ponta da outra: sem toque fica em aberto, com toque resulta numa resistência que muda conforme onde você toca.
O programa abaixo mostra a detecção de toque e a determinação da posição:
// Conexões do display
const int lcdRST = A4;
const int lcdCS = A3;
const int lcdRS = A2;
const int lcdWR = A1;
const int lcdRD = A0;
const int lcdDATA[] = {8, 9, 2, 3, 4, 5, 6, 7 };
// Conexões do sensor de toque
const int touchY1 = A1;
const int touchY2 = 7;
const int touchX1 = A2;
const int touchX2 = 6;
// Iniciação
void setup() {
// Inicia o controlador do display
// (para ter certeza que não vai interferir)
for (int i = 0; i < 8; i++) {
pinMode(lcdDATA[i], INPUT);
}
pinMode(lcdRST, OUTPUT);
digitalWrite (lcdRST, HIGH);
delay(10);
digitalWrite (lcdRST, LOW);
delay(10);
digitalWrite (lcdRST, HIGH);
delay(10);
pinMode(lcdCS, OUTPUT);
digitalWrite (lcdCS, HIGH);
pinMode(lcdRS, OUTPUT);
digitalWrite (lcdRS, HIGH);
pinMode(lcdRD, OUTPUT);
digitalWrite (lcdRD, HIGH);
pinMode(lcdWR, OUTPUT);
digitalWrite (lcdWR, HIGH);
// Inicia a serial
Serial.begin(115200);
}
// Laço perpétuo
void loop() {
static int maxX = 0, maxY = 0;
static int minX = 1024, minY = 1024;
int x, y;
if (temToque()) {
// Lê a posição
x = toqueX();
y = toqueY();
// Atualiza mínimo e máximo
if (x < minX) {
minX = x;
}
if (x > maxX) {
maxX = x;
}
if (y < minY) {
minY = y;
}
if (y > maxY) {
maxY = y;
}
// Mostra o resultado
Serial.print ("X = ");
Serial.print (x);
Serial.print (" [");
Serial.print (minX);
Serial.print (":");
Serial.print (maxX);
Serial.print ("] Y = ");
Serial.print (y);
Serial.print (" [");
Serial.print (minY);
Serial.print (":");
Serial.print (maxY);
Serial.println ("]");
}
delay (1000);
}
// Verifica se tem toque
bool temToque() {
pinMode (touchY1, INPUT);
pinMode (touchY2, INPUT_PULLUP);
pinMode (touchX1, OUTPUT);
pinMode (touchX2, OUTPUT);
digitalWrite (touchX1, LOW);
digitalWrite (touchX2, LOW);
delay(5);
Serial.print ("Teste de toque: ");
Serial.println (analogRead(touchY1));
return analogRead(touchY1) < 30;
}
// Le a coordenada X do toque (sem escala)
int toqueX() {
pinMode (touchX1, OUTPUT);
pinMode (touchX2, OUTPUT);
pinMode (touchY1, INPUT);
pinMode (touchY2, INPUT);
digitalWrite (touchX1, LOW);
digitalWrite (touchX2, HIGH);
delay(1);
int soma = 0;
for (int i = 0; i < 5; i++) {
soma += analogRead(touchY1);
}
return soma/5;
}
// Le a coordenada Y do toque (sem escala)
int toqueY() {
pinMode (touchX1, INPUT);
pinMode (touchX2, INPUT);
pinMode (touchY1, OUTPUT);
pinMode (touchY2, OUTPUT);
digitalWrite (touchY1, LOW);
digitalWrite (touchY2, HIGH);
delay(1);
int soma = 0;
for (int i = 0; i < 5; i++) {
soma += analogRead(touchX1);
}
return soma/5;
}
Experimentando um pouco você vai ver que a variação da leitura fica apenas numa parte da faixa de 0 a 1023 do ADC. Você precisa fazer um processo de calibração para determinar os valores para os limites (pode variar de display para display); os valores intermediários são deduzidos supondo que a resistência varia linearmente.
Partes das informações aqui eu peguei em https://www.hackster.io/calogerus/arduino-uno-2-4-tft-lcd-display-shield-touch-panel-ili9341-576b1b. Notar que o display deste artigo tem a detecção de toque ligada em pinos diferentes.


Nenhum comentário:
Postar um comentário