Closed ricmm71 closed 2 years ago
Hola de nuevo @ricmm7. He mirado por encima las librerías del XPT2046 y no he visto nada al respecto sobre lo del shifting de bits (ya digo que no he mirado mucho), pero igualmente, he probado tu código y funciona bien. Me parece que has hecho un análisis extensivo del problema y has dado con una solución. He tenido que quitar las calibraciones preestablecidas que metía ya en configuración para la ET4 y la ET5 ya que no iban a servir de nada. Al no tener una ET5 no puedo obtenerlas así que lo dejo sin ello y que la gente calibre la primera vez que encienda, que es como lo están haciendo supongo si lo descargan y compilan desde la rama de marlin. Mis dudas son. Este código serviría con cualquier tamaño de tft y configuración del XPT? La librería es genérica y he estado mirando y no se ha tocado desde que la subieron por primera vez.
Hola, David: Sólo modifiqué la lectura en bruto de las medidas, getRawData(), y el método que devuelve un punto completo, getRawPoint(). Y aunque son independientes del tamaño de la pantalla asociada o de su orientación, al devolver valores diferentes hay que ajustar los valores predeterminados usados en la configuración.
Como referencia para revisar la lectura de los valores en bruto se puede consultar la librería de Paul Stoffregen en https://github.com/ThingPulse/XPT2046_Touchscreen , que parece ser una de las más usadas o mencionadas al menos. En ella se usa una transferencia SPI de 16 bits y el resultado se desplaza 3 bits a la derecha, lo que equivale a la corrección que propuse. En las especificaciones del XPT2046 se muestra que las transferencias SPI con datos de las lecturas van en grupos de 7 bits y 5 bits (bus de 8 bits), para un total de 12 bits, no de 8+4 según implicaría el código original. Los valores obtenidos antes y después de la corrección también lo confirman.
(Nota: en la librería de Stoffregen se leen las muestras del XPT2046 a razón de una cada 16 ciclos de reloj SPI, tras la primera, porque se van solapando varias lecturas consecutivas; en la de Marlin, una cada 24 ciclos porque se usa una transacción SPI por lectura.)
Correcto @ricmm71. Muchas gracias por la aclaración y por tu aporte.
Muchas gracias a ti, David!!
Description
La lectura de los valores en bruto del XPT2046 que se realiza en XPT2046::getRawData() parece que es incorrecta: se realiza en dos lecturas SPI, tomando 8 bits de la primera y 4 de la segunda. Pero según la hoja de especificaciones del chip y de otras librerías que hay por ahí, se debn coger 7 bits de la primera lectura y los 5 restantes de la segunda (lecturas SPI que devuelvan 8 bits).
Esta es la causa de que los valores usados en la calibración no pasen de 1500, cuando siendo el chip de 12 bits deberían estar cercanos a 4000. También da lugar a que el uso de la pantalla sea muy poco precisa.
No sólo el error de la lectura en bruto es errónea, sino que el tratamiento para eliminar valores transitorios y ruido es casi inexistente y poco acertado, ya que leer tres veces seguidas el sensor nada más tocarlo va a dar lugar a tres malas lecturas. Se debería hacer un procesamiento más avanzado (debouncing + filtering). Para probar que el funcionamiento de la pantalla puede ser mucho mejor que el actual, he probado un código que guarda un buffer de muestras y toma la media de las muestras comprendidas en un intervalo de tiempo alejado de los extremos. La implementación no es muy limpia, pero me parece que el funcionamiento de la pantalla táctil mejora mucho.
Steps to Reproduce
Para reproducirlo hay que añadir trazas al código cuando se haga la lectura, trazando los valores leídos para las corrdenadas X y limitando las trazas por tiempo (para no saturar el terminal; no he conservado el código...).
Obtuve estos valores (primer valor, a; segundo valor b): a0 113 b0 120 a1 113 b1 88 a2 113 b2 72 a0 113 b0 24 a1 113 b1 64 a2 113 b2 16 a0 113 b0 168 a1 112 b1 216 a2 112 b2 216 a0 112 b0 88 a1 112 b1 80 a2 112 b2 80 a0 110 b0 248 a1 111 b1 80 a2 111 b2 80 a0 14 b0 112 a1 14 b1 152 a2 14 b2 152 a0 14 b0 88 a1 14 b1 128 a2 14 b2 144
Observándolos en binario se ve claramanete que las primeras lecturas no pasan de 7 bits (7 bits efectivos de 8) y que las segundas tienes los 3 primeros bits a cero (8-3=5 bits efectivos). Por eso hay que desplazar la primera lectura 5 bits a la izquierda y no 4, y descartar los 3 de la dercha de la segunda.
Additional Information
El código erróneo en "Marlin/src/HAL/STM32/tft/xpt2046.cpp": data[i] = (IO() << 4) | (IO() >> 4);
Debería ser: data[i] = (IO() << 5) | (IO() >> 3);
Se adjunta comprimido el fichero xpt2046.cpp con los cambios sugeridos. Con estos cambios los valores de calibración cambian como es de esperar (en mi Anet ET4+): Touch screen calibration completed TOUCH_CALIBRATION_X -5925 TOUCH_CALIBRATION_Y 4446 TOUCH_OFFSET_X 336 TOUCH_OFFSET_Y -17 TOUCH_ORIENTATION TOUCH_PORTRAIT
xpt2046.zip