Modified copy of Peter Dresche lib using fewer analogue pins for touch panel
Revision 0:ab6e91032412, committed 2012-08-11
- Comitter:
- JonFreeman
- Date:
- Sat Aug 11 15:30:10 2012 +0000
- Commit message:
- [mbed] converted /energy_saver/Touch_tft
Changed in this revision
touch_tft.cpp | Show annotated file Show diff for this revision Revisions of this file |
touch_tft.h | Show annotated file Show diff for this revision Revisions of this file |
diff -r 000000000000 -r ab6e91032412 touch_tft.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/touch_tft.cpp Sat Aug 11 15:30:10 2012 +0000 @@ -0,0 +1,217 @@ +/* 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 + NVIC_DisableIRQ(TIMER3_IRQn); + y1 = Ay.read_u16(); // get y voltage + NVIC_EnableIRQ(TIMER3_IRQn); + 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 + NVIC_DisableIRQ(TIMER3_IRQn); + x1 = Ax.read_u16(); // get x voltage + NVIC_EnableIRQ(TIMER3_IRQn); + 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) { // Swap names of calibrate and noncalibrate +// locate (60,60); +// printf("x_off %d, y_off %d", x_off, y_off); +// locate (60,80); +// printf("pp_tx %d, pp_ty %d", pp_tx, pp_ty); + x_off = 9344; + y_off = 9105; + pp_tx = 145; + pp_ty = 194; +} + +void touch_tft::noncalibrate(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 + + 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); + +// locate (60,60); +// printf("x_off %d, y_off %d", x_off, y_off); +// locate (60,80); +// printf("pp_tx %d, pp_ty %d", pp_tx, pp_ty); +// wait (15); + +// cls(); +} + + +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); +}
diff -r 000000000000 -r ab6e91032412 touch_tft.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/touch_tft.h Sat Aug 11 15:30:10 2012 +0000 @@ -0,0 +1,124 @@ +/* mbed library for touchscreen connected to 4 mbed pins + * derive from SPI_TFT lib + * Copyright (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. + */ + +#ifndef MBED_TOUCH_H +#define MBED_TOUCH_H + +#include "mbed.h" +#include "SPI_TFT.h" + +struct point{ + unsigned short x; + unsigned short y; + }; + + +/** touchscreen control class, based on SPI_TFT + * + * Example: + * @code + * + * #include "mbed.h" + * #include "SPI_TFT.h" + * #include "Arial12x12.h" + * #include "Arial28x28.h" + * #include "touch_tft.h" + * // the TFT is connected to SPI pin 5-7 + * // the touch is connected to 19,20,16,17 + * + * touch_tft tt(p19,p20,p16,p17,p5, p6, p7, p8, p15,"TFT"); // x+,x-,y+,y-,mosi, miso, sclk, cs, reset + * + * int main() { + * point p; + * + * tt.claim(stdout); // send stdout to the TFT display + * tt.background(Black); // set background to black + * tt.foreground(White); // set chars to white + * tt.cls(); // clear the screen + * tt.set_font((unsigned char*) Arial12x12); // select the font + * tt.set_orientation(1); + * + * tt.calibrate(); // calibrate the touch + * while (1) { + * p = tt.get_touch(); // read analog pos. + * if (tt.is_touched(p)) { // test if touched + * p = tt.to_pixel(p); // convert to pixel pos + * tt.fillcircle(p.x,p.y,3,Blue); // print a blue dot on the screen + * } + * } + * @endcode + */ +class touch_tft : public SPI_TFT{ +public: + /** create a TFT with touch object connected to the pins: + * + * @param pin xp resistiv touch x+ + * @param pin xm resistiv touch x- + * @param pin yp resistiv touch y+ + * @param pin ym resistiv touch y- + * @param mosi,miso,sclk SPI connection to TFT + * @param cs pin connected to CS of display + * @param reset pin connected to RESET of display + * based on my SPI_TFT lib + */ + touch_tft(PinName xp, PinName xm, PinName yp, PinName ym,PinName mosi, PinName miso, PinName sclk, PinName cs, PinName reset,const char* name ="TFT"); + + /** calibrate the touch display + * + * User is asked to touch on two points on the screen + */ + void calibrate(void); + void noncalibrate(void); + + /** read x and y analog samples + * + * @returns point(x,y) + */ + point get_touch(void); + + /** calculate coord on screen + * + * @param a_point point(analog x, analog y) + * @returns point(pixel x, pixel y) + * + */ + point to_pixel(point a_point); + + /** test if screen is touched + * + * @param point analog x,y + * @returns true is touched + * + */ + bool is_touched(point a); + +protected: + DigitalInOut _xp; + DigitalInOut _xm; + DigitalInOut _yp; + DigitalInOut _ym; + AnalogIn _ax; + AnalogIn _ay; + PinName xa; + PinName ya; + + + unsigned short x_a,y_a; + unsigned short x_off,y_off; + unsigned short pp_tx,pp_ty; + + + + }; + +#endif \ No newline at end of file