PlatformIO package of the Teensy core framework compatible with GCC 10 & C++20
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

TouchScreen.cpp 5.5KB

3 yıl önce
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. // Touch screen library with X Y and Z (pressure) readings as well
  2. // as oversampling to avoid 'bouncing'
  3. // (c) ladyada / adafruit
  4. // Code under MIT License
  5. #include "Arduino.h"
  6. #include "pins_arduino.h"
  7. #ifdef __AVR
  8. #include <avr/pgmspace.h>
  9. #elif defined(ESP8266)
  10. #include <pgmspace.h>
  11. #endif
  12. #include "TouchScreen.h"
  13. // increase or decrease the touchscreen oversampling. This is a little different than you make think:
  14. // 1 is no oversampling, whatever data we get is immediately returned
  15. // 2 is double-sampling and we only return valid data if both points are the same
  16. // 3+ uses insert sort to get the median value.
  17. // We found 2 is precise yet not too slow so we suggest sticking with it!
  18. #define NUMSAMPLES 2
  19. TSPoint::TSPoint(void) {
  20. x = y = 0;
  21. }
  22. TSPoint::TSPoint(int16_t x0, int16_t y0, int16_t z0) {
  23. x = x0;
  24. y = y0;
  25. z = z0;
  26. }
  27. bool TSPoint::operator==(TSPoint p1) {
  28. return ((p1.x == x) && (p1.y == y) && (p1.z == z));
  29. }
  30. bool TSPoint::operator!=(TSPoint p1) {
  31. return ((p1.x != x) || (p1.y != y) || (p1.z != z));
  32. }
  33. #if (NUMSAMPLES > 2)
  34. static void insert_sort(int array[], uint8_t size) {
  35. uint8_t j;
  36. int save;
  37. for (int i = 1; i < size; i++) {
  38. save = array[i];
  39. for (j = i; j >= 1 && save < array[j - 1]; j--)
  40. array[j] = array[j - 1];
  41. array[j] = save;
  42. }
  43. }
  44. #endif
  45. TSPoint TouchScreen::getPoint(void) {
  46. int x, y, z;
  47. int samples[NUMSAMPLES];
  48. uint8_t i, valid;
  49. valid = 1;
  50. pinMode(_yp, INPUT);
  51. pinMode(_ym, INPUT);
  52. pinMode(_xp, OUTPUT);
  53. pinMode(_xm, OUTPUT);
  54. #if defined (USE_FAST_PINIO)
  55. *xp_port |= xp_pin;
  56. *xm_port &= ~xm_pin;
  57. #else
  58. digitalWrite(_xp, HIGH);
  59. digitalWrite(_xm, LOW);
  60. #endif
  61. #ifdef __arm__
  62. delayMicroseconds(20); // Fast ARM chips need to allow voltages to settle
  63. #endif
  64. for (i=0; i<NUMSAMPLES; i++) {
  65. samples[i] = analogRead(_yp);
  66. }
  67. #if NUMSAMPLES > 2
  68. insert_sort(samples, NUMSAMPLES);
  69. #endif
  70. #if NUMSAMPLES == 2
  71. // Allow small amount of measurement noise, because capacitive
  72. // coupling to a TFT display's signals can induce some noise.
  73. if (samples[0] - samples[1] < -4 || samples[0] - samples[1] > 4) {
  74. valid = 0;
  75. } else {
  76. samples[1] = (samples[0] + samples[1]) >> 1; // average 2 samples
  77. }
  78. #endif
  79. x = (1023-samples[NUMSAMPLES/2]);
  80. pinMode(_xp, INPUT);
  81. pinMode(_xm, INPUT);
  82. pinMode(_yp, OUTPUT);
  83. pinMode(_ym, OUTPUT);
  84. #if defined (USE_FAST_PINIO)
  85. *ym_port &= ~ym_pin;
  86. *yp_port |= yp_pin;
  87. #else
  88. digitalWrite(_ym, LOW);
  89. digitalWrite(_yp, HIGH);
  90. #endif
  91. #ifdef __arm__
  92. delayMicroseconds(20); // Fast ARM chips need to allow voltages to settle
  93. #endif
  94. for (i=0; i<NUMSAMPLES; i++) {
  95. samples[i] = analogRead(_xm);
  96. }
  97. #if NUMSAMPLES > 2
  98. insert_sort(samples, NUMSAMPLES);
  99. #endif
  100. #if NUMSAMPLES == 2
  101. // Allow small amount of measurement noise, because capacitive
  102. // coupling to a TFT display's signals can induce some noise.
  103. if (samples[0] - samples[1] < -4 || samples[0] - samples[1] > 4) {
  104. valid = 0;
  105. } else {
  106. samples[1] = (samples[0] + samples[1]) >> 1; // average 2 samples
  107. }
  108. #endif
  109. y = (1023-samples[NUMSAMPLES/2]);
  110. // Set X+ to ground
  111. // Set Y- to VCC
  112. // Hi-Z X- and Y+
  113. pinMode(_xp, OUTPUT);
  114. pinMode(_yp, INPUT);
  115. #if defined (USE_FAST_PINIO)
  116. *xp_port &= ~xp_pin;
  117. *ym_port |= ym_pin;
  118. #else
  119. digitalWrite(_xp, LOW);
  120. digitalWrite(_ym, HIGH);
  121. #endif
  122. int z1 = analogRead(_xm);
  123. int z2 = analogRead(_yp);
  124. if (_rxplate != 0) {
  125. // now read the x
  126. float rtouch;
  127. rtouch = z2;
  128. rtouch /= z1;
  129. rtouch -= 1;
  130. rtouch *= x;
  131. rtouch *= _rxplate;
  132. rtouch /= 1024;
  133. z = rtouch;
  134. } else {
  135. z = (1023-(z2-z1));
  136. }
  137. if (! valid) {
  138. z = 0;
  139. }
  140. return TSPoint(x, y, z);
  141. }
  142. TouchScreen::TouchScreen(uint8_t xp, uint8_t yp, uint8_t xm, uint8_t ym,
  143. uint16_t rxplate=0) {
  144. _yp = yp;
  145. _xm = xm;
  146. _ym = ym;
  147. _xp = xp;
  148. _rxplate = rxplate;
  149. #if defined (USE_FAST_PINIO)
  150. xp_port = portOutputRegister(digitalPinToPort(_xp));
  151. yp_port = portOutputRegister(digitalPinToPort(_yp));
  152. xm_port = portOutputRegister(digitalPinToPort(_xm));
  153. ym_port = portOutputRegister(digitalPinToPort(_ym));
  154. xp_pin = digitalPinToBitMask(_xp);
  155. yp_pin = digitalPinToBitMask(_yp);
  156. xm_pin = digitalPinToBitMask(_xm);
  157. ym_pin = digitalPinToBitMask(_ym);
  158. #endif
  159. pressureThreshhold = 10;
  160. }
  161. int TouchScreen::readTouchX(void) {
  162. pinMode(_yp, INPUT);
  163. pinMode(_ym, INPUT);
  164. digitalWrite(_yp, LOW);
  165. digitalWrite(_ym, LOW);
  166. pinMode(_xp, OUTPUT);
  167. digitalWrite(_xp, HIGH);
  168. pinMode(_xm, OUTPUT);
  169. digitalWrite(_xm, LOW);
  170. return (1023-analogRead(_yp));
  171. }
  172. int TouchScreen::readTouchY(void) {
  173. pinMode(_xp, INPUT);
  174. pinMode(_xm, INPUT);
  175. digitalWrite(_xp, LOW);
  176. digitalWrite(_xm, LOW);
  177. pinMode(_yp, OUTPUT);
  178. digitalWrite(_yp, HIGH);
  179. pinMode(_ym, OUTPUT);
  180. digitalWrite(_ym, LOW);
  181. return (1023-analogRead(_xm));
  182. }
  183. uint16_t TouchScreen::pressure(void) {
  184. // Set X+ to ground
  185. pinMode(_xp, OUTPUT);
  186. digitalWrite(_xp, LOW);
  187. // Set Y- to VCC
  188. pinMode(_ym, OUTPUT);
  189. digitalWrite(_ym, HIGH);
  190. // Hi-Z X- and Y+
  191. digitalWrite(_xm, LOW);
  192. pinMode(_xm, INPUT);
  193. digitalWrite(_yp, LOW);
  194. pinMode(_yp, INPUT);
  195. int z1 = analogRead(_xm);
  196. int z2 = analogRead(_yp);
  197. if (_rxplate != 0) {
  198. // now read the x
  199. float rtouch;
  200. rtouch = z2;
  201. rtouch /= z1;
  202. rtouch -= 1;
  203. rtouch *= readTouchX();
  204. rtouch *= _rxplate;
  205. rtouch /= 1024;
  206. return rtouch;
  207. } else {
  208. return (1023-(z2-z1));
  209. }
  210. }