Merge branch 'tfry-git-work/xpt2046'
This commit is contained in:
commit
1c48f1aaa7
|
@ -8,72 +8,89 @@
|
||||||
#include "Arduino.h"
|
#include "Arduino.h"
|
||||||
#include "XPT2046_touch.h"
|
#include "XPT2046_touch.h"
|
||||||
|
|
||||||
|
XPT2046_touch::XPT2046_touch(uint8_t _cs_pin, SPIClass _spiChan) : cs_pin(_cs_pin), my_SPI(_spiChan){
|
||||||
|
setOversampling();
|
||||||
|
setThreshold();
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************/
|
void XPT2046_touch::begin(){
|
||||||
XPT2046_touch::XPT2046_touch(uint8_t _cs_pin, SPIClass _spiChan) : cs_pin(_cs_pin), my_SPI(_spiChan){
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************/
|
|
||||||
|
|
||||||
void XPT2046_touch::begin(){
|
|
||||||
pinMode(cs_pin, OUTPUT);
|
pinMode(cs_pin, OUTPUT);
|
||||||
digitalWrite(cs_pin, HIGH);
|
digitalWrite(cs_pin, HIGH);
|
||||||
my_SPI.begin();
|
my_SPI.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t XPT2046_touch::gatherSamples(uint8_t command) {
|
||||||
|
uint32_t sample_sum = 0;
|
||||||
|
uint16_t samples[MAX_OVERSAMPLING];
|
||||||
|
|
||||||
|
my_SPI.transfer16(command); // discard first reading after switching MUX
|
||||||
|
for (int i = 0; i < oversampling; ++i) {
|
||||||
|
samples[i] = my_SPI.transfer16(command);
|
||||||
|
sample_sum += samples[i];
|
||||||
|
}
|
||||||
|
int32_t avg = sample_sum / oversampling;
|
||||||
|
if (oversampling < 3) {
|
||||||
|
return avg >> 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************/
|
// occasionally, we get a reading that is a _far_ outlier.
|
||||||
|
// checking for, and removing those improves quality a lot.
|
||||||
|
uint8_t n = oversampling;
|
||||||
|
for (int i = 0; i < oversampling; ++i) {
|
||||||
|
if (abs(avg - samples[i]) > 80) { // NOTE: data is left shifted by 3 at this point. I.e. the test is for 10+ pixels deviation from average
|
||||||
|
sample_sum -= samples[i];
|
||||||
|
--n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (n < 2) return avg >> 3;
|
||||||
|
else return (sample_sum / n) >> 3;
|
||||||
|
}
|
||||||
|
|
||||||
boolean XPT2046_touch::read_XY(uint16_t *xy){
|
TS_Point XPT2046_touch::getPoint() {
|
||||||
int z1, z2, tmpH, tmpL;
|
uint16_t z1, z2;
|
||||||
|
|
||||||
|
my_SPI.beginTransaction(SPISettings(2000000, MSBFIRST, SPI_MODE0)); // max clock freq for XPT2046
|
||||||
digitalWrite(cs_pin, LOW);
|
digitalWrite(cs_pin, LOW);
|
||||||
|
TS_Point ret;
|
||||||
|
|
||||||
//Check if touch screen is pressed.
|
//Check if touch screen is pressed.
|
||||||
SPI.transfer(B10110011); // Z1
|
my_SPI.transfer(B10110011); // trigger Z1 reading
|
||||||
delay(10);
|
z1 = my_SPI.transfer16(B11000011) >> 3; // read Z1, and trigger Z2 reading
|
||||||
tmpH = (my_SPI.transfer(0) << 5);
|
z2 = my_SPI.transfer16(B10010011) >> 3; // read Z2, and trigger Y reading
|
||||||
tmpL = (my_SPI.transfer(0) >> 3);
|
ret.z = z1 + 4095 - z2;
|
||||||
z1 = tmpH | tmpL;
|
|
||||||
|
|
||||||
SPI.transfer(B11000011); // Z2
|
if(ret.z >= threshold){ //If the touch screen is pressed, read the X,Y coordinates from XPT2046.
|
||||||
delay(10);
|
ret.x = gatherSamples(B10010011);
|
||||||
tmpH = (my_SPI.transfer(0) << 5);
|
ret.y = gatherSamples(B11010011);
|
||||||
tmpL = (my_SPI.transfer(0) >> 3);
|
} else {
|
||||||
z2 = tmpH | tmpL;
|
ret.z = 0;
|
||||||
|
|
||||||
if((z2 - z1) < Z_THRESHOLD){ //If the touch screen is pressed, read the X,Y coordinates from XPT2046.
|
|
||||||
my_SPI.transfer(B11010011); // X
|
|
||||||
delay(10);
|
|
||||||
tmpH = (my_SPI.transfer(0) << 5);
|
|
||||||
tmpL = (my_SPI.transfer(0) >> 3);
|
|
||||||
xy[0] = tmpH | tmpL;
|
|
||||||
|
|
||||||
my_SPI.transfer(B10010011); // Y
|
|
||||||
delay(10);
|
|
||||||
tmpH = (my_SPI.transfer(0) << 5);
|
|
||||||
tmpL = (my_SPI.transfer(0) >> 3);
|
|
||||||
xy[1] = tmpH | tmpL;
|
|
||||||
digitalWrite(cs_pin, HIGH);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
digitalWrite(cs_pin, HIGH);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
my_SPI.transfer(B00000000); // enter power saving (and IRQ enable)
|
||||||
|
|
||||||
/****************************************************************************/
|
digitalWrite(cs_pin, HIGH);
|
||||||
void XPT2046_touch::setButtonsNumber(byte columnButtons, byte rowButtons ){
|
my_SPI.endTransaction();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean XPT2046_touch::read_XY(uint16_t *xy) {
|
||||||
|
TS_Point p = getPoint();
|
||||||
|
xy[0] = p.x;
|
||||||
|
xy[1] = p.y;
|
||||||
|
return p.z > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////// Buttons ////////////////
|
||||||
|
void XPT2046_touch::setButtonsNumber(byte columnButtons, byte rowButtons ){
|
||||||
_rowButtons = rowButtons;
|
_rowButtons = rowButtons;
|
||||||
_columnButtons = columnButtons;
|
_columnButtons = columnButtons;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************/
|
uint8_t XPT2046_touch::getButtonNumber(){
|
||||||
uint8_t XPT2046_touch::getButtonNumber(){
|
|
||||||
uint16_t xy[2];
|
uint16_t xy[2];
|
||||||
uint8_t tmp, buttonNum;
|
uint8_t tmp, buttonNum;
|
||||||
int div;
|
int div;
|
||||||
|
|
||||||
if(read_XY(xy)){
|
if(read_XY(xy)){
|
||||||
|
|
||||||
div = (X_MAX + X_MIN) / (_columnButtons + 1);
|
div = (X_MAX + X_MIN) / (_columnButtons + 1);
|
||||||
buttonNum = ((xy[1] / div));
|
buttonNum = ((xy[1] / div));
|
||||||
|
|
||||||
|
@ -84,5 +101,4 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0; //Touch screen is not pressed.
|
return 0; //Touch screen is not pressed.
|
||||||
}
|
}
|
||||||
/****************************************************************************/
|
|
||||||
|
|
|
@ -11,7 +11,8 @@
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <SPI.h>
|
#include <SPI.h>
|
||||||
|
|
||||||
#define Z_THRESHOLD 3000
|
#define Z_THRESHOLD 3500 // Note: reversed for backwards compatiblity: 4095-x
|
||||||
|
#define MAX_OVERSAMPLING 32
|
||||||
|
|
||||||
// Pre-defined touch screen calibration for using the 2.4" ILI9341 LCD
|
// Pre-defined touch screen calibration for using the 2.4" ILI9341 LCD
|
||||||
#define X_MIN 830
|
#define X_MIN 830
|
||||||
|
@ -19,23 +20,54 @@
|
||||||
#define Y_MIN 550
|
#define Y_MIN 550
|
||||||
#define Y_MAX 3550
|
#define Y_MAX 3550
|
||||||
|
|
||||||
|
|
||||||
|
class TS_Point {
|
||||||
|
public:
|
||||||
|
TS_Point(void) : x(0), y(0), z(0) {}
|
||||||
|
TS_Point(int16_t x, int16_t y, int16_t z) : x(x), y(y), z(z) {}
|
||||||
|
bool operator==(TS_Point p) { return ((p.x == x) && (p.y == y) && (p.z == z)); }
|
||||||
|
bool operator!=(TS_Point p) { return ((p.x != x) || (p.y != y) || (p.z != z)); }
|
||||||
|
int16_t x, y, z;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
class XPT2046_touch {
|
||||||
class XPT2046_touch{
|
|
||||||
private:
|
private:
|
||||||
uint8_t cs_pin;
|
uint8_t cs_pin;
|
||||||
SPIClass my_SPI;
|
SPIClass my_SPI;
|
||||||
uint8_t _rowButtons = 1;
|
uint8_t _rowButtons = 1;
|
||||||
uint8_t _columnButtons = 1;
|
uint8_t _columnButtons = 1;
|
||||||
|
uint8_t oversampling;
|
||||||
|
uint16_t threshold;
|
||||||
|
uint16_t gatherSamples(uint8_t command);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
XPT2046_touch(uint8_t _cs_pin, SPIClass _spiChan); //Contructor.
|
/** c'tor. Note that no IRQ pin is supported, here. You can easily do that yourself:
|
||||||
|
* \code if(digitalRead(irq_pin)) {
|
||||||
|
* // no press: skip
|
||||||
|
* } else {
|
||||||
|
* // _may_ be touched, but not necessarily reach the threshold
|
||||||
|
* TS_Point p = ts.getPoint();
|
||||||
|
* if (p.z > 0) {
|
||||||
|
* // do something
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* \endcode */
|
||||||
|
XPT2046_touch(uint8_t _cs_pin, SPIClass _spiChan); //Contructor
|
||||||
void begin();
|
void begin();
|
||||||
void setButtonsNumber(byte rowButtons, byte columnButtons);
|
void setButtonsNumber(byte rowButtons, byte columnButtons);
|
||||||
|
/** Number of samples to average per point 0..32 */
|
||||||
|
void setOversampling(uint8_t num_readings = 7) {
|
||||||
|
oversampling = max(1, min(num_readings, MAX_OVERSAMPLING));
|
||||||
|
}
|
||||||
|
void setThreshold(uint16_t threshold = 4095 - Z_THRESHOLD) {
|
||||||
|
XPT2046_touch::threshold = threshold;
|
||||||
|
}
|
||||||
uint8_t getButtonNumber();
|
uint8_t getButtonNumber();
|
||||||
boolean read_XY(uint16_t *xy);
|
boolean read_XY(uint16_t *xy);
|
||||||
|
TS_Point getPoint();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue