Jon Freeman / Touch_tft
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers touch_tft.cpp Source File

touch_tft.cpp

00001 /* mbed library for resistive touch pads
00002  * uses 4 pins - 2 IO and 2 Analog
00003 
00004  * c 2011 Peter Drescher - DC2PD
00005  *
00006  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00007  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00008  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00009  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00010  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00011  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00012  * THE SOFTWARE.
00013  */
00014 
00015 
00016 #include "touch_tft.h"
00017 #include "mbed.h"
00018 
00019 #define threshold 0x2000  // threshold to detect pressed 
00020 
00021 touch_tft::touch_tft(PinName xp, PinName xm, PinName yp, PinName ym,
00022                      PinName mosi, PinName miso, PinName sclk, PinName cs, PinName reset,const char* name):
00023         _xp(xp),_xm(xm),_yp(yp),_ym(ym),_ax(xp),_ay(yp),
00024         SPI_TFT(mosi,miso,sclk,cs,reset,name) {
00025     xa = xp;
00026     ya = yp;
00027 
00028 }
00029 
00030 point touch_tft::get_touch() {
00031     unsigned short x1 = 0,x2 = 0, y1 = 0, y2 = 0;
00032     unsigned int s1 = 0,s2 = 0,d1 , d2;
00033     point p;
00034 
00035     do {
00036         // read y voltage
00037         _xp.output();
00038         _xm.output();
00039         switch (orientation) {
00040             case(0):
00041             case(3):
00042                 _xp = 1;
00043                 _xm = 0;
00044                 break;
00045             case(1):
00046             case(2):
00047                 _xp = 0;
00048                 _xm = 1;
00049                 break;
00050         }
00051         _ym.input();        // y- have to be passive
00052         AnalogIn Ay(ya);    // we have to call the constructor to switch to analog mode
00053         wait_us(10);
00054 //        y1 = Ay.read_u16(); // get y voltage
00055         NVIC_DisableIRQ(TIMER3_IRQn);  
00056         y1 = Ay.read_u16(); // get y voltage
00057         NVIC_EnableIRQ(TIMER3_IRQn);
00058         d1 = (y1 > y2)? (y1-y2) : (y2-y1);
00059         if (((y1 < 8000) && (d1 < 2000)) || ((y1 > 8000) && (d1 < 150))) s1 ++;
00060         else {
00061             if (s1 > 0) s1 --;
00062         }
00063         y2 = y1;
00064         // debug
00065         //locate(1,7);
00066         //printf("d: %4d y: %5d s1: %4d",d1,y1,s1);
00067 
00068         // read x voltage
00069         _yp.output();
00070         _ym.output();
00071         switch (orientation) {
00072             case(0):
00073             case(1):
00074                 _yp = 1;
00075                 _ym = 0;
00076                 break;
00077             case(2):
00078             case(3):
00079                 _yp = 0;
00080                 _ym = 1;
00081                 break;
00082         }
00083         _xm.input();        // x- have to be passive
00084         AnalogIn Ax(xa);    // we have to call the constructor to switch to analog mode
00085         wait_us(10);
00086 //        x1 = Ax.read_u16(); // get x voltage
00087         NVIC_DisableIRQ(TIMER3_IRQn);  
00088         x1 = Ax.read_u16(); // get x voltage
00089         NVIC_EnableIRQ(TIMER3_IRQn);
00090         d2 = (x1 > x2)? (x1-x2) : (x2-x1);
00091         if (((x1 < 8000) && (d2 < 2000)) || ((x1 > 8000) && (d2 < 150))) s2 ++;
00092         else {
00093             if (s2 > 0) s2 --;
00094         }
00095         x2 = x1;
00096         // debug
00097         //locate(1,8);
00098         //printf("d: %4d x: %5d s2: %4d",d2,x1,s2);
00099 
00100     } while (s1 < 3 || s2 < 3); // read until we have three samples close together
00101     switch (orientation) {
00102         case(0):
00103         case(2):
00104             p.y = (x1+x2) / 2;  // average of two sample
00105             p.x = (y1+y2) / 2;
00106             break;
00107         case(1):
00108         case(3):
00109             p.x = (x1+x2) / 2;  // average of two sample
00110             p.y = (y1+y2) / 2;
00111             break;
00112     }
00113     return(p);
00114 }
00115 
00116 void touch_tft::calibrate(void) {   // Swap names of calibrate and noncalibrate
00117 //    locate  (60,60);
00118 //    printf("x_off %d, y_off %d", x_off, y_off);
00119 //    locate  (60,80);
00120 //    printf("pp_tx %d, pp_ty %d", pp_tx, pp_ty);
00121     x_off = 9344;
00122     y_off = 9105;
00123     pp_tx = 145;
00124     pp_ty = 194;
00125 }
00126 
00127 void touch_tft::noncalibrate(void) {
00128     int i;
00129     int a = 0,b = 0,c = 0, d = 0;
00130     int pos_x, pos_y;
00131     point p;
00132 
00133     cls();
00134     line(0,3,6,3,White);
00135     line(3,0,3,6,White);
00136 
00137     // get the center of the screen
00138     pos_x = columns() / 2 - 3;
00139     pos_x = pos_x * font[1];
00140     pos_y = (rows() / 2) - 1;
00141     pos_y = pos_y * font[2];
00142 
00143     locate(pos_x,pos_y);
00144     printf("press cross");
00145     locate(pos_x,pos_y + font[2]);
00146     printf("to calibrate");
00147     for (i=0; i<5; i++) {
00148         do {
00149             p = get_touch();
00150         } while (p.x < 0x2000 | p.y < 0x2000);  // wait for touch
00151         a += p.x;
00152         b += p.y;
00153     }
00154     a = a / 5;
00155     b = b / 5;
00156     locate(pos_x,pos_y);
00157     printf("OK         ");
00158     do {
00159         p = get_touch();
00160     } while (p.y > 0x2000 | p.x > 0x2000); // wait for no touch
00161 
00162     cls();
00163     line(width() -5, height() - 8,width() - 5,height() -1,White);   // paint cross
00164     line(width() - 8,height() - 5,width() - 1,height() - 5,White);
00165     locate(pos_x,pos_y);
00166     printf("press cross");
00167     locate(pos_x,pos_y + font[2]);
00168     printf("to calibrate");
00169     for (i=0; i<5; i++) {
00170         do {
00171             p  = get_touch();
00172         } while (p.y < 0x2000 | p.x < 0x2000);  // wait for touch
00173         c+= p.x;
00174         d+= p.y;
00175     }
00176     c = c / 5;
00177     d = d / 5;
00178 
00179     locate(pos_x, pos_y);
00180     printf("OK         ");
00181     do {
00182         p = get_touch();
00183     } while (p.y > 0x2000 | p.x > 0x2000); // wait for no touch
00184 
00185     x_off = a;
00186     y_off = b;
00187 
00188     i = c-a;  // delta x
00189     pp_tx = i / (width() - 6);
00190 
00191     i = d-b;  // delta y
00192     pp_ty = i / (height() - 6);
00193 
00194 //    locate  (60,60);
00195 //    printf("x_off %d, y_off %d", x_off, y_off);
00196 //    locate  (60,80);
00197 //    printf("pp_tx %d, pp_ty %d", pp_tx, pp_ty);
00198 //    wait    (15);
00199 
00200 //    cls();
00201 }
00202 
00203 
00204 point touch_tft::to_pixel(point a_point) {
00205     point p;
00206 
00207     p.x = (a_point.x - x_off) / pp_tx;
00208     if (p.x > width()) p.x = width();
00209     p.y = (a_point.y - y_off) / pp_ty;
00210     if (p.y > height()) p.y = height();
00211     return (p);
00212 }
00213 
00214 bool touch_tft::is_touched(point a) {
00215     if (a.x > threshold & a.y > threshold) return(true);
00216     else return(false);
00217 }