Closed rtek1000 closed 5 years ago
A great library for using resistive touch without controller is this, it serves as a basis for comparison:
uint16_t TouchScreen::pressure(void) {
// Set X+ to ground
pinMode(_xp, OUTPUT);
digitalWrite(_xp, LOW);
// Set Y- to VCC
pinMode(_ym, OUTPUT);
digitalWrite(_ym, HIGH);
// Hi-Z X- and Y+
digitalWrite(_xm, LOW);
pinMode(_xm, INPUT);
digitalWrite(_yp, LOW);
pinMode(_yp, INPUT);
int z1 = analogRead(_xm);
int z2 = analogRead(_yp);
if (_rxplate != 0) {
// now read the x
float rtouch;
rtouch = z2;
rtouch /= z1;
rtouch -= 1;
rtouch *= readTouchX();
rtouch *= _rxplate;
#if !defined (__STM32F1__)
rtouch /= 1024;
#else
rtouch /= 4095;
#endif
return rtouch;
} else {
#if !defined (__STM32F1__)
return (1023-(z2-z1));
#else
return (4095-(z2-z1));
#endif
}
}
Thank you.
Example of use of pressure measurement:
// Touch screen library with X Y and Z (pressure) readings as well
// as oversampling to avoid 'bouncing'
// This demo code returns raw readings, public domain
#include <stdint.h>
#include <TouchScreen_STM.h>
// These are the pins for the shield!
#define YP 8 // must be an analog pin
#define XM 9 // must be an analog pin
#define YM 10 // can be a digital pin
#define XP 11 // can be a digital pin
#define MINPRESSURE 10
#define MAXPRESSURE 1000
// For better pressure precision, we need to know the resistance
// between X+ and X- Use any multimeter to read it
// For the one we're using, its 300 ohms across the X plate
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
void setup(void) {
Serial.begin(9600);
}
void loop(void) {
// a point object holds x y and z coordinates
TSPoint p = ts.getPoint();
// we have some minimum pressure we consider 'valid'
// pressure of 0 means no pressing!
if (p.z > MINPRESSURE && p.z < MAXPRESSURE) {
Serial.print("X = "); Serial.print(p.x);
Serial.print("\tY = "); Serial.print(p.y);
Serial.print("\tPressure = "); Serial.println(p.z);
}
}
Hi,
I've adapted a code based on other libraries, if anyone wants to test it, it's attached.
Tested on 7-inch display with SSD1963 + XPT2064, log taken in the modified TFT_Touch_Raw.ino example:
(Now we have pressure ;) )
Raw x, y, z, status = 2909, 1912, 236, pressed Raw x, y, z, status = 0, 4095, 65535, not pressed
Thank you.
Hi,
If someone has a 7-inch screen with SSD1963 + XPT2046, try using this code below:
(This code should work better than the example provided with the display because it should not draw points in a distant place)
/* FILE: TFT_Touch_Example1
DATE: 10/06/14
VERSION: 0.1
ORIGINAL AUTHOR: Andrew Davies
This is an example of how to use the TFT_Touch library. It does not display
anything on the screen!
Open up the Serial Monitor Window from the IDE and set to 38400 baud to see the
information from screen contacts
By using a stylus at the screen extremes or touch zone limits this sketch can be
used to check tha calibration values.
IMPORTANT: The 2.4" screen orientation used for calibration is with the SD Card slot on the left!
The library provides the ability to read the current status of the touch screen.
It does not provide any graphics drawing functions for controlling the TFT screen itself
it is intended for providing touch screen support to any graphics sketches and libraries.
However the library will work standalone as this example sketch will demonstrate.
The example will read the current state of the touch screen and output it to the serial
port as raw X and Y coordinates.
No information will be displayed on the TFT screen itself whilst this example is running.
You may copy, alter and reuse this code in any way you like, but please leave
reference to HobbyComponents.com in your comments if you redistribute this code.
This software may not be used directly for the purpose of selling products that
directly compete with Hobby Components Ltd's own range of products.
THIS SOFTWARE IS PROVIDED "AS IS". HOBBY COMPONENTS MAKES NO WARRANTIES, WHETHER
EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ACCURACY OR LACK OF NEGLIGENCE.
HOBBY COMPONENTS SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR ANY DAMAGES,
INCLUDING, BUT NOT LIMITED TO, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR ANY
REASON WHATSOEVER.
Adapted by Rowboteer 13/5/15
*/
// These are the pins used to interface between the 2046 touch controller and Arduino Mega
#define DOUT 3 /* Data out pin (T_DO) of touch screen */
#define DIN 4 /* Data in pin (T_DIN) of touch screen */
#define DCS 5 /* Chip select pin (T_CS) of touch screen */
#define DCLK 6 /* Clock pin (T_CLK) of touch screen */
//URTouch myTouch(/* tclk */ 6,/* tcs */ 5,/* din */ 4,/* dout */ 3,/* irq */ 2); //byte tclk, byte tcs, byte din, byte dout, byte irq
// These are the default min and maximum values, set to 0 and 4095 to test the screen
#define HMIN 0
#define HMAX 4095
#define VMIN 0
#define VMAX 4095
#define XYSWAP 0 // 0 or 1
// This is the screen size for the raw to coordinate transformation
// width and height specified for landscape orientation
#define HRES 800 /* Default screen resulution for X axis */
#define VRES 480 /* Default screen resulution for Y axis */
#include <TFT_Touch.h> // https://github.com/Bodmer/TFT_Touch
/* Create an instance of the touch screen library */
TFT_Touch touch = TFT_Touch(DCS, DCLK, DIN, DOUT);
#include <UTFT.h>
UTFT myGLCD(SSD1963_800480, 38, 39, 40, 41); //(byte model, int RS, int WR, int CS, int RST, int SER)
extern uint8_t BigFont[];
//word colorlist[] = {VGA_WHITE, VGA_BLACK, VGA_RED, VGA_BLUE, VGA_GREEN, VGA_FUCHSIA, VGA_YELLOW, VGA_AQUA};
unsigned int X_Raw;
unsigned int Y_Raw;
int Z_Raw;
#define MaxPressure 300
#define MinPressure 10
bool isPressed = false;
unsigned int X_Rel;
unsigned int Y_Rel;
int X_MIN = 80;
int Y_MIN = 265;
int X_MAX = 3975;
int Y_MAX = 3975;
void setup()
{
Serial.begin(115200);
touch.setCal(HMIN, HMAX, VMIN, VMAX, HRES, VRES, XYSWAP); // Raw xmin, xmax, ymin, ymax, width, height
touch.setRotation(0);
myGLCD.InitLCD(1);
myGLCD.clrScr();
myGLCD.setFont(BigFont);
myGLCD.setColor(VGA_WHITE);
myGLCD.drawLine(30, 0, 30, 60);
myGLCD.drawLine(0, 30, 60, 30);
myGLCD.drawLine(myGLCD.getDisplayXSize() - 31, 0, myGLCD.getDisplayXSize() - 31, 60);
myGLCD.drawLine(myGLCD.getDisplayXSize() - 1, 30, myGLCD.getDisplayXSize() - 61, 30);
myGLCD.drawLine(myGLCD.getDisplayXSize() - 31, myGLCD.getDisplayYSize() - 1, myGLCD.getDisplayXSize() - 31, myGLCD.getDisplayYSize() - 61);
myGLCD.drawLine(myGLCD.getDisplayXSize() - 1, myGLCD.getDisplayYSize() - 31, myGLCD.getDisplayXSize() - 61, myGLCD.getDisplayYSize() - 31);
myGLCD.drawLine(0, myGLCD.getDisplayYSize() - 31, 60, myGLCD.getDisplayYSize() - 31);
myGLCD.drawLine(30, myGLCD.getDisplayYSize() - 1, 30, myGLCD.getDisplayYSize() - 61);
myGLCD.drawLine((myGLCD.getDisplayXSize() / 2) - 1, (myGLCD.getDisplayYSize() / 2) + 29, (myGLCD.getDisplayXSize() / 2) - 1, (myGLCD.getDisplayYSize() / 2) - 31);
myGLCD.drawLine((myGLCD.getDisplayXSize() / 2) + 29, (myGLCD.getDisplayYSize() / 2) - 1, (myGLCD.getDisplayXSize() / 2) - 31, (myGLCD.getDisplayYSize() / 2) - 1);
}
/* Main program */
void loop()
{
/* Check if the touch screen is currently pressed*/
// Raw and coordinate values are stored within library at this instant
// for later retrieval by GetRaw and GetCoord functions.
// This avoids getting duff values returned
isPressed = touch.Pressed(); //isTouched();
//if (isTouched()) // Note this function updates coordinates stored within library variables
//{
/* Read the current X and Y axis as raw co-ordinates at the last touch time*/
// The values returned were captured when Pressed() was called!
X_Raw = touch.RawX();
Y_Raw = touch.RawY();
Z_Raw = touch.RawZ();
// map(value, fromLow, fromHigh, toLow, toHigh)
X_Rel = map(X_Raw, X_MIN, X_MAX, 0, HRES);
Y_Rel = map(Y_Raw, Y_MIN, Y_MAX, 0, VRES);
if ((Z_Raw < MaxPressure) && (Z_Raw > MinPressure)) {
myGLCD.setColor(VGA_WHITE);
myGLCD.drawPixel(X_Rel, Y_Rel);
}
/* Output the results to the serial port */
Serial.print("Raw x, y, z, Pressed = ");
Serial.print(X_Raw);
Serial.print(",\t");
Serial.print(Y_Raw);
Serial.print(",\t");
Serial.print(Z_Raw);
Serial.print(",\t");
if (isPressed) {
Serial.print("Is Pressed");
} else {
Serial.print("Is not Pressed");
}
Serial.print("; Rel x, y = ");
Serial.print(X_Rel);
Serial.print(",\t");
Serial.println(Y_Rel);
delay(10);
//}
//delay(10);
}
Hi,
Some lighter touches cause error, you need to use pressure measurement too.
Source: https://www.buydisplay.com/download/ic/XPT2046.pdf
Source: https://github.com/PaulStoffregen/XPT2046_Touchscreen