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

Dependents:   touch LCD_Grapher Mandelbrot Tactile ... more

touch_tft.cpp

Committer:
dreschpe
Date:
2011-09-04
Revision:
2:ef7972c29c0e
Parent:
1:1745fdf054b5

File content as of revision 2:ef7972c29c0e:

/* 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_x, pos_y;
    point p;

    cls();
    line(0,3,6,3,White);
    line(3,0,3,6,White);

    // get the center of the screen
    pos_x = columns() / 2 - 3;
    pos_x = pos_x * font[1];
    pos_y = (rows() / 2) - 1;
    pos_y = pos_y * font[2];

    locate(pos_x,pos_y);
    printf("press cross");
    locate(pos_x,pos_y + font[2]);
    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_x,pos_y);
    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_x,pos_y);
    printf("press cross");
    locate(pos_x,pos_y + font[2]);
    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_x, pos_y);
    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 = width();
    p.y = (a_point.y - y_off) / pp_ty;
    if (p.y > height()) p.y = height();
    return (p);
}

bool touch_tft::is_touched(point a) {
    if (a.x > threshold & a.y > threshold) return(true);
    else return(false);
}