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