/******************************************************************************* * Function Name : LCD_TouchRead( ) * Author : Anilandro * Description : Lectura de puntero sobre pantalla con versión Portrait y Landscape * Input : None * Output : None * Return : * Attention : None *******************************************************************************/ uint8_t LCD_TouchRead(Coordinate * displayLCD){ uint16_t px,py,x,y; int p,f; //char cadena[20]; GetFormat(); /*obtiene valor de formato de pantalla activo*/ p=0; f=0; while(f<30){ getDisplayPoint(&display, Read_Ads7846(), &matrix ) ; /*lee la posición del puntero sobre la pantalla*/ px=display.x; py=display.y; if((PMode2==0)&&(py<400)){x=px,y=py;p=1;break;} if((PMode2==1)&&(px<400)){x=px,y=py;p=1;break;} f++; } if(f>=30){p=0;x=400;y=400;} displayLCD->x = x; displayLCD->y = y; return(p); }
/**************************************************************************//** * @brief Read normalized touchscreen XY position (10bit resolution) * @return Touchscreen position *****************************************************************************/ static POINT getTouchSample( void ) { POINT sample, normalizedSample; sample = getTouchSample10bit(); getDisplayPoint( &normalizedSample, &sample, &calibFactors ); return normalizedSample; }
static void ReadTouchScreenPress(void) { int xDpos; int yDpos; POINT stDisplayPoint; POINT stTouchScreenPoint; do { if(IsTSPress) { IsTSPress = 0; stTouchScreenPoint.x = x_val[0]; stTouchScreenPoint.y = y_val[0]; getDisplayPoint(&stDisplayPoint, &stTouchScreenPoint, &stMatrix); xDpos = stDisplayPoint.x; xDpos = LCD_WIDTH - xDpos; if(xDpos < 0) { xDpos = 0; } if(xDpos > LCD_WIDTH) { xDpos = LCD_WIDTH; } UARTPuts("xDpos=",-1); UARTPutNum(xDpos); yDpos = stDisplayPoint.y; yDpos = LCD_HEIGHT - yDpos; if(yDpos < 0) { yDpos = 0; } if(yDpos > LCD_HEIGHT) { yDpos = LCD_HEIGHT; } UARTPuts("yDpos=",-1); UARTPutNum(yDpos); UARTPuts("\r\n", -1); } } while (1); }
tsTouchError_t tsRead(tsTouchData_t* data) { uint32_t x1, y1; // Assign pressure levels regardless of touch state tsReadZ(&data->z1, &data->z2); data->xraw = 0; data->yraw = 0; data->xlcd = 0; data->ylcd = 0; // Abort if the screen is not being touched (0 levels reported) if (data->z1 < _tsThreshhold) { data->valid = false; return TS_ERROR_NONE; } nopDelay(CFG_TFTLCD_TS_DELAYBETWEENSAMPLES); // Get two X/Y readings and compare results x1 = tsReadX(); y1 = tsReadY(); // X/Y seems to be valid and reading has been confirmed twice data->xraw = x1; data->yraw = y1; // Convert x/y values to pixel location with matrix multiply tsPoint_t location, touch; touch.x = x1; touch.y = y1; getDisplayPoint(&location, &touch, &_tsMatrix); data->xlcd = location.x; data->ylcd = location.y; data->valid = true; return TS_ERROR_NONE; }
/***************************************************************************//** * @brief * Convert ADC readings into XY position * * @param[in] pos * Pointer to position structure ******************************************************************************/ void TOUCH_RecalculatePosition(volatile TOUCH_Pos_TypeDef *pos) { POINT old_pos, new_pos; if (pos->pen) { old_pos.x = pos->adcx; old_pos.y = pos->adcy; if (getDisplayPoint(&new_pos, &old_pos, &calibrationMatrix) == OK) { if (new_pos.x >= 0) pos->x = new_pos.x; else pos->x = 0; if (new_pos.y >= 0) pos->y = new_pos.y; else pos->y = 0; } } else { pos->x = 0; pos->y = 0; } }
/****************************************************************************** * * Description: * Read coordinates from the touch panel. The values (especially z) will * have the value 0 when there are no touch events. * * Params: * [out] x, y, z * * Returns: * None * *****************************************************************************/ void touch_xyz(int32_t *x, int32_t* y, int32_t* z) { int32_t ix, iy, iz = 0; POINT displayPoint, screenSample; //SSP_DATA_SETUP_Type sspCfg; uint8_t pwrDown = PWRDOWN; readAndFilter(&ix, &iy, &iz); //spiTransfer(PWRDOWN); //sspCfg.tx_data = &pwrDown; //sspCfg.rx_data = NULL; //sspCfg.length = 1; CS_ON; //SSP_ReadWrite (SSP_PORT, &sspCfg, SSP_TRANSFER_POLLING); Chip_SSP_WriteFrames_Blocking(SSP_ID, &pwrDown, 1); CS_OFF; *z = iz; if (calibrated) { screenSample.x = ix; screenSample.y = iy; getDisplayPoint( &displayPoint, &screenSample, &(storedCalData.storedMatrix) ) ; *x = displayPoint.x; *y = displayPoint.y; } else { *x = ix; *y = iy; } }
//* Function: Perform DSP //* Description: Performs a number of operations on the camera input //such as thresholding/centroid calc. Then draw squares on the screen //or switch color or brush size, or even clear the screen. Depending //on the number of centroids and their size, a different gesture is //detected and the corresponding action is performed. See below for //more details //* Input: nothing //* Returns: nothing void *perform_DSP(void *args){ static int calibrate = 1; struct Centroid *centroids; static int touch = 0; static int fingerup = 0; struct Centroid last_centroid; POINT point1, point2; while(dsp_running){ //calculate centroids centroids = get_fingers(); //if fingers are touching if (centroids[0].size > 0) { touch = 1; last_centroid = get_biggest_finger(centroids); }else{ //if finger just came off if (touch == 1) fingerup = 1; touch = 0; } //if calibrating if (calibrate) { //black out screen if calbrating struct pixel back_color = COLOR_DARK_GREY; //background color for (int i = 0; i < DATA_LEN; ++i) { //dark grey pixels2[i*RGBA_LEN+RGBA_R] = back_color.r; //set red value pixels2[i*RGBA_LEN+RGBA_G] = back_color.g; //set green value pixels2[i*RGBA_LEN+RGBA_B] = back_color.b; //set blue value pixels2[i*RGBA_LEN+RGBA_A] = SHORT_MAX; //set alpha pixels2[i*4+3] = SHORT_MAX; } //draw calibration point calib_color.x = perfectPoints[calibrate-1].x; calib_color.y = perfectPoints[calibrate-1].y; draw_square(pixels2, DATA_WIDTH, DATA_HEIGHT, calib_color); if (fingerup) { //set actual calibration points to the last finger that touched the display actualPoints[calibrate-1].x = last_centroid.x; actualPoints[calibrate-1].y = last_centroid.y; calibrate++; //increment up to number of calibration points //if done calibration if (calibrate > 3) { //create calibration matrix setCalibrationMatrix(&perfectPoints[0], &actualPoints[0], &calibMatrix); //clear pixels for (int i = 0; i < DATA_LEN * 4; ++i) { pixels2[i] = 0; } //done calibration calibrate = 0; } fingerup = 0; } }else{ if (centroids != NULL) { for (int i = 0; i < 10; ++i) { //if decently sized, draw as a red pixel if (centroids[i].size > 10) { point2.x = centroids[i].x; point2.y = centroids[i].y; getDisplayPoint(&point1, &point2, &calibMatrix); finger_colors[0].x = point1.x; finger_colors[0].y = point1.y; draw_square(pixels2, DATA_WIDTH, DATA_HEIGHT, finger_colors[0]); } } } } } return NULL; }
/********************************************************************** * * Function: main() * * Description: Entry point into console version of sample * program that exercises the calibration * functions. * * Argument(s): argCount - the number of arguments provided * argValue - pointer to the list of char strings * representing the command line arguments. * * Return: void * */ int main( int argCount, char ** argValue ) { int retValue = OK ; MATRIX matrix ; POINT display ; int n ; greeting() ; /* The following call calculates the translation matrix that */ /* results when the three consecutive points in the sample */ /* set are used. Such points are assumed to be properly */ /* spaced within the screen surface. */ /* Note that we call the function twice as we would normally */ /* do within a calibration routine. The first time we call */ /* it using a perfect set of display and screen arguments. */ /* Such a call is made to obtain a calibration matrix that is */ /* just good enough to collect samples to do the real */ /* calibration. */ /* */ /* */ /* */ /* NOTE! NOTE! NOTE! */ /* */ /* setCalibrationMatrix() and getDisplayPoint() will do fine */ /* for you as they are, provided that your digitizer */ /* resolution does not exceed 10 bits (1024 values). Higher */ /* resolutions may cause the integer operations to overflow */ /* and return incorrect values. If you wish to use these */ /* functions with digitizer resolutions of 12 bits (4096 */ /* values) you will either have to a) use 64-bit signed */ /* integer variables and math, or b) judiciously modify the */ /* operations to scale results by a factor of 2 or even 4. */ /* */ setCalibrationMatrix( &perfectDisplaySample[0], &perfectScreenSample[0], &matrix ) ; /* Look at the matrix values when we use a perfect sample set. */ /* The result is a unity matrix. */ printf("\n\nLook at the unity matrix:\n\n" "matrix.An = % 8ld matrix.Bn = % 8ld matrix.Cn = % 8ld\n" "matrix.Dn = % 8ld matrix.En = % 8ld matrix.Fn = % 8ld\n" "matrix.Divider = % 8ld\n", matrix.An,matrix.Bn,matrix.Cn, matrix.Dn,matrix.En,matrix.Fn, matrix.Divider ) ; /* Now is when we need to do the work to collect a real set of */ /* calibration data. */ /* Draw three targets on your display. Drawing one at time is */ /* probably a simpler implementation. These targets should be */ /* widely separated but also avoid the areas too near the */ /* edges where digitizer output tends to become non-linear. */ /* The recommended set of points is (in display resolution */ /* percentages): */ /* */ /* ( 15, 15) */ /* ( 50, 85) */ /* ( 85, 50) */ /* */ /* Each time save the display and screen set (returned by the */ /* digitizer when the user touches each calibration target */ /* into the corresponding array). */ /* Since you normalized your calibration matrix above, you */ /* should be able to use touch screen data as it would be */ /* provided by the digitizer driver. When the matrix equals */ /* unity, getDisplayPoint() returns the same raw input data */ /* as output. */ /* Call the function once more to obtain the calibration */ /* factors you will use until you calibrate again. */ setCalibrationMatrix( &displaySample[0], &screenSample[0], &matrix ) ; /* Let's see the matrix values for no particular reason. */ printf("\n\nThis is the actual calibration matrix that we will use\n" "for all points (until we calibrate again):\n\n" "matrix.An = % 8d matrix.Bn = % 8d matrix.Cn = % 8d\n" "matrix.Dn = % 8d matrix.En = % 8d matrix.Fn = % 8d\n" "matrix.Divider = % 8d\n", matrix.An,matrix.Bn,matrix.Cn, matrix.Dn,matrix.En,matrix.Fn, matrix.Divider ) ; /* Now, lets use the complete set of screen samples to verify */ /* that the calculated calibration matrix does its job as */ /* expected. */ printf("\n\nShow the results of our work:\n\n" " Screen Sample Translated Sample Display Sample\n\n" ) ; /* In a real application, your digitizer driver interrupt */ /* would probably do the following: */ /* 1) collect raw digitizer data, */ /* 2) filter the raw data which would probably contain */ /* position jitter, */ /* 3) filter out repeated values (a touch screen */ /* controller normally continues causing interrupts */ /* and collecting data as long as the user is */ /* pressing on the screen), and */ /* 4) call the function getDisplayPoint() to obtain */ /* the display coordinates that the user meant to */ /* input as he touched the screen. */ /* */ /* This code sample, of course, only uses sample data. So we */ /* simply run through all the available sample points. */ for( n = 0 ; n < MAX_SAMPLES ; ++n ) { getDisplayPoint( &display, &screenSample[n], &matrix ) ; printf(" % 6d,%-6d % 6d,%-6d % 6d,%-6d\n", screenSample[n].x, screenSample[n].y, display.x, display.y, displaySample[n].x, displaySample[n].y ) ; } return( retValue ) ; } // end of main()
void loop() { if (nn < 3) { if (ts.touched()) { TS_Point p = ts.getPoint(); touch[nn].x = p.x/4; touch[nn].y = p.y/4; nn += 1; Serial.print(p.x); Serial.print("/"); Serial.println(p.y); delay(1*1000); Serial.println(nn); } } else if (nn == 3) { setCalibrationMatrix(display, touch, &matrix); Serial.println("Matrix"); Serial.print("matrix.An = "); Serial.print(matrix.An); Serial.println(";"); Serial.print("matrix.Bn = "); Serial.print(matrix.Bn); Serial.println(";"); Serial.print("matrix.Cn = "); Serial.print(matrix.Cn); Serial.println(";"); Serial.print("matrix.Dn = "); Serial.print(matrix.Dn); Serial.println(";"); Serial.print("matrix.En = "); Serial.print(matrix.En); Serial.println(";"); Serial.print("matrix.Fn = "); Serial.print(matrix.Fn); Serial.println(";"); Serial.print("matrix.Divider = "); Serial.print(matrix.Divider); Serial.println(";"); nn+=1; } else { static int32_t col = ILI9341_RED; if (ts.touched()) { TS_Point p = ts.getPoint(); POINT touch; touch.x = p.x/4; touch.y = p.y/4; POINT display; getDisplayPoint(&display, &touch, &matrix); bool found = false; for (int c = 0; c < int(sizeof(colors)/sizeof(colors[0])); c++) { int16_t d=20; int16_t xa = 40+d*c; int16_t xb = 40+d*c + d; int16_t ya = 0; int16_t yb = 0 + d; if (display.x >= xa && display.x <= xb && display.y >= ya && display.y <= yb) { col = colors[c]; tft.fillRect(0, 0, d, d, col); tft.drawRect(0, 0, d, d, ILI9341_WHITE); found = true; if (col == ILI9341_BLACK) { cls(); col = ILI9341_WHITE; } break; } } if (found == false) tft.drawPixel(display.x, display.y, col); } } }
tsTouchError_t tsRead(tsTouchData_t* data, uint8_t calibrating) { uint32_t x1, x2, y1, y2, z1, z2; // Assign pressure levels regardless of touch state tsReadZ(&z1, &z2); data->z1 = z1; data->z2 = z2; data->xraw = 0; data->yraw = 0; data->xlcd = 0; data->ylcd = 0; // Abort if the screen is not being touched (0 levels reported) if (z1 < _tsThreshhold) { data->valid = false; return TS_ERROR_NONE; } // Get two X/Y readings and compare results x1 = tsReadX(); x2 = tsReadX(); y1 = tsReadY(); y2 = tsReadY(); // Throw an error if both readings aren't identical if (x1 != x2 || y1 != y2) { data->valid = false; data->xraw = x1; data->yraw = y1; return TS_ERROR_XYMISMATCH; } // X/Y seems to be valid and reading has been confirmed twice data->xraw = x1; data->yraw = y1; // Convert x/y values to pixel location with matrix multiply tsPoint_t location, touch; touch.x = x1; touch.y = y1; // Only calculate the relative LCD value if this isn't for calibration if (!calibrating) { getDisplayPoint( &location, &touch, &_tsMatrix) ; data->xlcd = location.x; data->ylcd = location.y; } else { // Assign some false values, but only xraw and yraw are // used for calibration data->xlcd = 0; data->ylcd = 0; } data->valid = true; return TS_ERROR_NONE; }