LIB for resistiv touchscreen connected to 4 mbed pins Use SPI_TFT lib

Dependents:   touch LCD_Grapher Mandelbrot Tactile ... more

Revision:
0:d78b00f167cb
Child:
1:1745fdf054b5
diff -r 000000000000 -r d78b00f167cb touch_tft.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/touch_tft.cpp	Thu Jul 14 21:02:43 2011 +0000
@@ -0,0 +1,188 @@
+/* mbed library for resistive touch pads
+ * uses 4 pins - 2 IO and 2 Analog
+
+ * c 2011 Peter Drescher - DC2PD
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+
+#include "touch_tft.h"
+#include "mbed.h"
+
+#define threshold 0x2000  // threshold to detect pressed 
+
+touch_tft::touch_tft(PinName xp, PinName xm, PinName yp, PinName ym,
+                     PinName mosi, PinName miso, PinName sclk, PinName cs, PinName reset,const char* name):
+        _xp(xp),_xm(xm),_yp(yp),_ym(ym),_ax(xp),_ay(yp),
+        SPI_TFT(mosi,miso,sclk,cs,reset,name) {
+    xa = xp;
+    ya = yp;
+
+}
+
+point touch_tft::get_touch() {
+    unsigned short x1 = 0,x2 = 0, y1 = 0, y2 = 0;
+    unsigned int s1 = 0,s2 = 0,d1 , d2;
+    point p;
+
+    do {
+        // read y voltage
+        _xp.output();
+        _xm.output();
+        switch (orientation) {
+            case(0):
+            case(3):
+                _xp = 1;
+                _xm = 0;
+                break;
+            case(1):
+            case(2):
+                _xp = 0;
+                _xm = 1;
+                break;
+        }
+        _ym.input();        // y- have to be passive
+        AnalogIn Ay(ya);    // we have to call the constructor to switch to analog mode
+        wait_us(10);
+        y1 = Ay.read_u16(); // get y voltage
+        d1 = (y1 > y2)? (y1-y2) : (y2-y1);
+        if (((y1 < 8000) && (d1 < 2000)) || ((y1 > 8000) && (d1 < 150))) s1 ++;
+        else {
+            if (s1 > 0) s1 --;
+        }
+        y2 = y1;
+        // debug
+        //locate(1,7);
+        //printf("d: %4d y: %5d s1: %4d",d1,y1,s1);
+
+        // read x voltage
+        _yp.output();
+        _ym.output();
+        switch (orientation) {
+            case(0):
+            case(1):
+                _yp = 1;
+                _ym = 0;
+                break;
+            case(2):
+            case(3):
+                _yp = 0;
+                _ym = 1;
+                break;
+        }
+        _xm.input();        // x- have to be passive
+        AnalogIn Ax(xa);    // we have to call the constructor to switch to analog mode
+        wait_us(10);
+        x1 = Ax.read_u16(); // get x voltage
+        d2 = (x1 > x2)? (x1-x2) : (x2-x1);
+        if (((x1 < 8000) && (d2 < 2000)) || ((x1 > 8000) && (d2 < 150))) s2 ++;
+        else {
+            if (s2 > 0) s2 --;
+        }
+        x2 = x1;
+        // debug
+        //locate(1,8);
+        //printf("d: %4d x: %5d s2: %4d",d2,x1,s2);
+
+    } while (s1 < 3 || s2 < 3); // read until we have three samples close together
+    switch (orientation) {
+        case(0):
+        case(2):
+            p.y = (x1+x2) / 2;  // average of two sample
+            p.x = (y1+y2) / 2;
+            break;
+        case(1):
+        case(3):
+            p.x = (x1+x2) / 2;  // average of two sample
+            p.y = (y1+y2) / 2;
+            break;
+    }
+    return(p);
+}
+
+void touch_tft::calibrate(void) {
+    int i;
+    int a = 0,b = 0,c = 0, d = 0;
+    int pos;
+    point p;
+
+    cls();
+    line(0,3,6,3,White);
+    line(3,0,3,6,White);
+    pos = columns() / 2 - 5;
+    locate(pos,5);
+    printf("press cross");
+    locate(pos,6);
+    printf("to calibrate");
+    for (i=0; i<5; i++) {
+        do {
+            p = get_touch();
+        } while (p.x < 0x2000 | p.y < 0x2000);  // wait for touch
+        a += p.x;
+        b += p.y;
+    }
+    a = a / 5;
+    b = b / 5;
+    locate(pos,5);
+    printf("OK         ");
+    do {
+        p = get_touch();
+    } while (p.y > 0x2000 | p.x > 0x2000); // wait for no touch
+
+    cls();
+    line(width() -5, height() - 8,width() - 5,height() -1,White);   // paint cross
+    line(width() - 8,height() - 5,width() - 1,height() - 5,White);
+    locate(pos,5);
+    printf("press cross");
+    locate(pos,6);
+    printf("to calibrate");
+    for (i=0; i<5; i++) {
+        do {
+            p  = get_touch();
+        } while (p.y < 0x2000 | p.x < 0x2000);  // wait for touch
+        c+= p.x;
+        d+= p.y;
+    }
+    c = c / 5;
+    d = d / 5;
+
+    locate(pos,5);
+    printf("OK         ");
+    do {
+        p = get_touch();
+    } while (p.y > 0x2000 | p.x > 0x2000); // wait for no touch
+
+    cls();
+
+    x_off = a;
+    y_off = b;
+
+    i = c-a;  // delta x
+    pp_tx = i / (width() - 6);
+
+    i = d-b;  // delta y
+    pp_ty = i / (height() - 6);
+}
+
+
+point touch_tft::to_pixel(point a_point) {
+    point p;
+
+    p.x = (a_point.x - x_off) / pp_tx;
+    if(p.x > width()) p.x = 0;
+    p.y = (a_point.y - y_off) / pp_ty;
+    if(p.y > height()) p.y = 0; 
+    return (p);
+}
+
+bool is_touched(point a){
+  if (a.x > threshold & a.y > threshold) return(true);
+  else return(false);
+}