【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程) 
  实验二百三十八:ESP32开发板WiFi蓝牙2.8寸240*320智能液晶显示屏带触摸屏TFT模块 
  项目实验之二十:ESP32 CYD液晶2.8寸开发板电阻式触摸屏校准 
 
实验开源代码 
 
			
			
			- /*
 -   【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
 -   实验二百三十八:ESP32开发板WiFi蓝牙2.8寸240*320智能液晶显示屏带触摸屏TFT模块
 -   项目实验之二十:ESP32 CYD液晶2.8寸开发板电阻式触摸屏校准
 - */
 - 
 - #include <lvgl.h>                 // 引入LVGL图形库
 - #include <TFT_eSPI.h>             // 引入TFT_eSPI库,用于驱动TFT显示屏
 - #include <XPT2046_Touchscreen.h>  // 引入XPT2046触摸屏库
 - #include <BasicLinearAlgebra.h>   // 引入线性代数库,用于计算触摸屏校准参数
 - 
 - // Touchscreen pins
 - #define XPT2046_IRQ 36   // T_IRQ
 - #define XPT2046_MOSI 32  // T_DIN
 - #define XPT2046_MISO 39  // T_OUT
 - #define XPT2046_CLK 25   // T_CLK
 - #define XPT2046_CS 33    // T_CS
 - 
 - unsigned long delay_start = 0;
 - #define DELAY_1S 1000
 - #define DELAY_5S 5000
 - 
 - SPIClass touchscreenSPI = SPIClass(VSPI);
 - XPT2046_Touchscreen touchscreen(XPT2046_CS, XPT2046_IRQ);
 - 
 - #define SCREEN_WIDTH 240
 - #define SCREEN_HEIGHT 320
 - 
 - String s;
 - 
 - int ts_points[6][2];
 - 
 - /* define the screen points where touch samples will be taken */
 - const int scr_points[6][2] = { {13, 11}, {20, 220}, {167, 60}, {155, 180}, {300, 13}, {295, 225} };
 - 
 - struct point {
 -   int x;
 -   int y;
 - };
 - 
 - /* pS is a screen point; pT is a resistive touchscreen point */
 - struct point aS = {scr_points[0][0], scr_points[0][1] };
 - struct point bS = {scr_points[1][0], scr_points[1][1] };
 - struct point cS = {scr_points[2][0], scr_points[2][1] };
 - struct point dS = {scr_points[3][0], scr_points[3][1] };
 - struct point eS = {scr_points[4][0], scr_points[4][1] };
 - struct point fS = {scr_points[5][0], scr_points[5][1] };
 - 
 - struct point aT;
 - struct point bT;
 - struct point cT;
 - struct point dT;
 - struct point eT;
 - struct point fT;
 - 
 - /* coefficients for transforming the X and Y coordinates of the resistive touchscreen
 -    to display coordinates... the ones with the "pref_" prefix are retrieved from NVS   */
 - float alphaX, betaX, deltaX, alphaY, betaY, deltaY;
 - float pref_alphaX, pref_betaX, pref_deltaX, pref_alphaY, pref_betaY, pref_deltaY;
 - 
 - #define DRAW_BUF_SIZE (SCREEN_WIDTH * SCREEN_HEIGHT / 10 * (LV_COLOR_DEPTH / 8))
 - uint32_t draw_buf[DRAW_BUF_SIZE / 4];
 - 
 - // If logging is enabled, it will inform the user about what is happening in the library
 - void log_print(lv_log_level_t level, const char * buf) {
 -   LV_UNUSED(level);
 -   Serial.println(buf);
 -   Serial.flush();
 - }
 - 
 - // Declare function to get the Raw Touchscreen data
 - void touchscreen_read_pts(bool, bool, int, int);
 - 
 - /* Declare function to display a user instruction upon startup */
 - void lv_display_instruction(void);
 - 
 - /* Declare function to display crosshair at indexed point */
 - void display_crosshair(int);
 - 
 - /* Declare function to display crosshairs at given coordinates */
 - void display_crosshairs(int, int);
 - 
 - /* Declare function to display 'X's at given coordinates */
 - void display_xs(int, int);
 - 
 - /* Declare function to compute the resistive touchscreen coordinates to display coordinates conversion coefficients */
 - void ts_calibration (
 -   const point, const point,
 -         const point, const point,
 -         const point, const point,
 -   const point, const point,
 -         const point, const point,
 -         const point, const point);
 - 
 - void gather_cal_data(void) {
 -   //Function to draw the crosshairs and collect data
 -   bool reset, finished;
 -   int x_avg, y_avg;
 - 
 -   for (int i = 0; i < 6; i++) {
 -     lv_obj_clean(lv_scr_act());
 -     //lv_draw_cross(i);
 -     display_crosshair(i);
 - 
 -     reset = true;
 -     x_avg = 0;
 -     y_avg = 0;
 -     
 -     touchscreen_read_pts(reset, &finished, &x_avg, &y_avg);
 - 
 -     reset = false;
 -     while (!finished) {
 -       touchscreen_read_pts(reset, &finished, &x_avg, &y_avg);
 - 
 -       /* found out the hard way that if I don't do this, the screen doesn't update */
 -       lv_task_handler();
 -       lv_tick_inc(10);
 -       delay(10);
 -     }
 - 
 -     lv_obj_clean(lv_scr_act());
 -     lv_task_handler();
 -     lv_tick_inc(10);
 -     delay(10);
 - 
 -     ts_points[i][0] = x_avg;
 -     ts_points[i][1] = y_avg;
 - 
 -     String s = String("x_avg = " + String(x_avg) + " y_avg = " + String(y_avg) );
 -     Serial.println(s);
 -     delay(1500);
 -   }
 - }
 - 
 - void compute_transformation_coefficients(void) {
 -   /* finished collecting data, now compute correction coefficients */
 -   /* first initialize the function call parameters */
 -   aT = { ts_points[0][0], ts_points[0][1] };
 -   bT = { ts_points[1][0], ts_points[1][1] };
 -   cT = { ts_points[2][0], ts_points[2][1] };
 -   dT = { ts_points[3][0], ts_points[3][1] };
 -   eT = { ts_points[4][0], ts_points[4][1] };
 -   fT = { ts_points[5][0], ts_points[5][1] };
 - 
 -   /* compute the resisitve touchscreen to display coordinates conversion coefficients */
 -   ts_calibration(aS, aT, bS, bT, cS, cT, dS, dT, eS, eT, fS, fT);
 - }
 - 
 - void check_calibration_results(void) {
 -   int x_touch, y_touch, x_scr, y_scr, error;
 - 
 -   /* if we did our job well, the screen points computed below should match
 -      aS, bS, and cS defined near the top */
 -   for (int i = 0; i < 6; i++) {
 -     /* define some touch points and translate them to screen points */
 -     x_touch = ts_points[i][0];
 -     y_touch = ts_points[i][1];
 - 
 -     /* here's the magic equation that uses the magic coefficients */
 -     /* use it to convert resistive touchscreen points to display points */
 -     x_scr = alphaX * x_touch + betaX * y_touch + deltaX;
 -     y_scr = alphaY * x_touch + betaY * y_touch + deltaY;
 - 
 -     display_crosshairs(scr_points[i][0], scr_points[i][1]);
 -     display_xs(x_scr, y_scr);
 - 
 -     s = String("x_touch = " + String(x_touch) + " y_touch = " + String(y_touch) );
 -     Serial.println(s);
 - 
 -     s = String("x_scr = " + String(x_scr) + " y_scr = " + String(y_scr) );
 -     Serial.println(s);
 - 
 -     error = (int) sqrt( sq(x_scr - scr_points[i][0]) + sq(y_scr - scr_points[i][1]) );
 -     s = String("error = " + String(error) );
 -     Serial.println(s);
 -     Serial.println();
 -   }
 - 
 -   Serial.println("******************************************************************");
 -   Serial.println("******************************************************************");
 -   Serial.println("USE THE FOLLOWING COEFFICIENT VALUES TO CALIBRATE YOUR TOUCHSCREEN");
 -   s = String("Computed X:  alpha_x = " + String(alphaX, 3) + ", beta_x = " + String(betaX, 3) + ", delta_x = " + String(deltaX, 3) );
 -   Serial.println(s);
 -   s = String("Computed Y:  alpha_y = " + String(-alphaY, 3) + ", beta_y = " + String(-betaY, 3) + ", delta_y = " + String(SCREEN_WIDTH-deltaY, 3) );
 -   Serial.println(s);
 -   Serial.println("******************************************************************");
 -   Serial.println("******************************************************************");
 - }
 - 
 - void setup() {
 -   String LVGL_Arduino = String("LVGL Library Version: ") + lv_version_major() + "." + lv_version_minor() + "." + lv_version_patch();
 -   Serial.begin(115200);
 -   Serial.println(LVGL_Arduino);
 -   
 -   // Start LVGL
 -   lv_init();
 -   // Register print function for debugging
 -   lv_log_register_print_cb(log_print);
 - 
 -   // Start the SPI for the touchscreen and init the touchscreen
 -   touchscreenSPI.begin(XPT2046_CLK, XPT2046_MISO, XPT2046_MOSI, XPT2046_CS);
 -   touchscreen.begin(touchscreenSPI);
 -   // Set the Touchscreen rotation in landscape mode
 -   // Note: in some displays, the touchscreen might be upside down, so you might need to set the rotation to 0: touchscreen.setRotation(0);
 -   touchscreen.setRotation(2);
 - 
 -   // Create a display object
 -   lv_display_t * disp;
 -   // Initialize the TFT display using the TFT_eSPI library
 -   disp = lv_tft_espi_create(SCREEN_WIDTH, SCREEN_HEIGHT, draw_buf, sizeof(draw_buf));
 -   lv_display_set_rotation(disp, LV_DISPLAY_ROTATION_270);
 - 
 -   lv_display_instruction();
 -   delay_start = millis();
 -   while ((millis() - delay_start) < DELAY_5S) {
 -     lv_task_handler();
 -     lv_tick_inc(10);
 -     delay(10);   
 -   } 
 - 
 -   /* display crosshairs and have the user tap on them until enough samples are gathered */;
 -   gather_cal_data();
 - 
 -   /* crunch the numbers to compute the touchscreen to display coordinate transformation equation coefficients */
 -   compute_transformation_coefficients();
 - 
 -   /* display stored correction data and display generated vs measured screen points */
 -   check_calibration_results();
 - }
 - 
 - void loop() {
 -   lv_task_handler();  // let the GUI do its work
 -   lv_tick_inc(5);     // tell LVGL how much time has passed
 -   delay(5);           // let this time pass
 - }
 -  
 - /* Function to read a number of points from the resistive touchscreen as the user taps
 -    a stylus on displayed crosshairs.  Once the samples have been collected, they are
 -    filtered to remove outliers and then averaged and the average x & y are returned to the caller. */
 - void touchscreen_read_pts(bool reset, bool *finished, int *x_avg, int *y_avg) {
 -   /* nr_samples = samples taken; good_samples = samples used, samples = array of 100 samples */
 -   static int i, nr_samples, good_samples;
 -   static uint32_t samples[100][2];
 - 
 -   /* coordinates to shift and rotate touch screen coordinates to display coordinates */
 -   static float mean_x, mean_y, filt_mean_x, filt_mean_y, stdev_x, stdev_y;
 - 
 -   /* caller resets the sample run at each new displayed crosshair */
 -   if (reset) {
 -     nr_samples = 0;
 -     *x_avg = 0;
 -     *y_avg = 0;
 -     *finished = false;
 -   }
 -   // Checks if Touchscreen was touched, and prints X, Y
 -   if(touchscreen.tirqTouched() && touchscreen.touched()) {
 -     // Get Touchscreen points
 -     TS_Point p = touchscreen.getPoint();
 -     samples[nr_samples][0] = p.x;
 -     samples[nr_samples][1] = p.y;
 -    
 -     s = String("x, y = " + String(samples[nr_samples][0]) + ", " + String(samples[nr_samples][1]) );
 -     Serial.println(s);
 - 
 -     nr_samples++;
 - 
 -     /* first compute the x & y averages of all the samples */
 -     if (nr_samples >= 100) {
 -       mean_x = 0;
 -       mean_y = 0;
 -       for (i = 0; i < 100; i++) {
 -         mean_x += (float)samples[i][0];
 -         mean_y += (float)samples[i][1];
 -       }
 -       mean_x = mean_x / (float)nr_samples;
 -       mean_y = mean_y / (float)nr_samples;
 -       s = String("Unfiltered values:  mean_x = " + String(mean_x) + ", mean_y = " + String(mean_y));
 -       Serial.println(s);
 - 
 -       /* now compute the x & y standard deviations of all the samples */
 -       stdev_x = 0;
 -       stdev_y = 0;
 -       for (i = 0; i < 100; i++) {
 -         stdev_x += sq((float)samples[i][0] - mean_x);
 -         stdev_y += sq((float)samples[i][1] - mean_y);
 -       }
 -       stdev_x = sqrt(stdev_x / (float)nr_samples);
 -       stdev_y = sqrt(stdev_y / (float)nr_samples);
 - 
 -       s = String("stdev_x = " + String(stdev_x) + ", stdev_y = " + String(stdev_y));
 -       Serial.println(s);   
 - 
 -       /* now average the samples that are less than one standard deviation from the mean */
 -       /* this filtering is called "outlier rejection," and is included because outliers were observed in testing */
 -       good_samples = 0;
 -       filt_mean_x = 0;
 -       filt_mean_y = 0;
 -       for (i = 0; i < 100; i++) {
 -         if ((abs((float)samples[i][0] - mean_x) < stdev_x) && (abs((float)samples[i][1] - mean_y) < stdev_y)) {
 -           filt_mean_x += (float)samples[i][0];
 -           filt_mean_y += (float)samples[i][1];
 -           good_samples++;
 -         }        
 -       }
 - 
 -       s = String("Good samples = " + String(good_samples));
 -       Serial.println(s);      
 - 
 -       filt_mean_x = filt_mean_x / (float)good_samples;
 -       filt_mean_y = filt_mean_y / (float)good_samples;
 -       s = String("Filtered values:  filt_mean_x = " + String(filt_mean_x) + ", filt_mean_y = " + String(filt_mean_y));
 -       Serial.println(s);
 -       Serial.println();
 - 
 -       *x_avg = (int)mean_x;
 -       *y_avg = (int)mean_y;
 - 
 -       *finished = true;
 -     }
 -   }
 -   else {
 -     // nada
 -   }
 - }
 - 
 - /* Function to display a user instruction on startup */
 - void lv_display_instruction(void) {
 -   // Create a text label aligned center: https://docs.lvgl.io/master/widgets/label.html
 -   lv_obj_t * text_label = lv_label_create(lv_screen_active());
 -   lv_label_set_text(text_label, "Tap each crosshair until it disappears.");
 -   lv_obj_align(text_label, LV_ALIGN_CENTER, 0, 0);
 -   // Set font type and font size. More information: https://docs.lvgl.io/master/overview/font.html
 -   static lv_style_t style_text_label;
 -   lv_style_init(&style_text_label);
 -   lv_style_set_text_font(&style_text_label, &lv_font_montserrat_14);
 -   lv_obj_add_style(text_label, &style_text_label, 0);
 - }
 - 
 - /* function to display crosshair at given index of coordinates array */
 - void display_crosshair(int cross_nr) {
 - 
 -   static lv_point_precise_t h_line_points[] = { {0, 0}, {10, 0} };
 -   static lv_point_precise_t v_line_points[] = { {0, 0}, {0, 10} };
 - 
 -   static lv_style_t style_line;
 -   lv_style_init(&style_line);
 -   lv_style_set_line_width(&style_line, 2);
 -   lv_style_set_line_color(&style_line, lv_palette_main(LV_PALETTE_RED));
 -   lv_style_set_line_rounded(&style_line, true);
 - 
 -   // Create crosshair lines
 -   lv_obj_t* crosshair_h = lv_line_create(lv_screen_active());
 -   lv_obj_t* crosshair_v = lv_line_create(lv_screen_active());
 - 
 -   lv_line_set_points(crosshair_h, h_line_points, 2); // Set the coordinates for the crosshair_h line
 -   lv_obj_add_style(crosshair_h, &style_line, 0);
 - 
 -   lv_line_set_points(crosshair_v, v_line_points, 2); // Set the coordinates for the crosshair_h line
 -   lv_obj_add_style(crosshair_v, &style_line, 0);
 - 
 -   lv_obj_set_pos(crosshair_h, scr_points[cross_nr][0] - 5, scr_points[cross_nr][1]);
 -   lv_obj_set_pos(crosshair_v, scr_points[cross_nr][0], scr_points[cross_nr][1] - 5);
 - }
 - 
 - /* function to display crosshairs at given coordinates */
 - void display_crosshairs(int x, int y) {
 - 
 -   static lv_point_precise_t h_line_points[] = { {0, 0}, {10, 0} };
 -   static lv_point_precise_t v_line_points[] = { {0, 0}, {0, 10} };
 - 
 -   static lv_style_t style_line;
 -   lv_style_init(&style_line);
 -   lv_style_set_line_width(&style_line, 2);
 -   lv_style_set_line_color(&style_line, lv_palette_main(LV_PALETTE_BLUE));
 -   lv_style_set_line_rounded(&style_line, true);
 - 
 -   // Create crosshair lines
 -   lv_obj_t* crosshair_h = lv_line_create(lv_screen_active());
 -   lv_obj_t* crosshair_v = lv_line_create(lv_screen_active());
 - 
 -   lv_line_set_points(crosshair_h, h_line_points, 2); // Set the coordinates for the crosshair_h line
 -   lv_obj_add_style(crosshair_h, &style_line, 0);
 - 
 -   lv_line_set_points(crosshair_v, v_line_points, 2); // Set the coordinates for the crosshair_h line
 -   lv_obj_add_style(crosshair_v, &style_line, 0);
 - 
 -   lv_obj_set_pos(crosshair_h, x - 5, y);
 -   lv_obj_set_pos(crosshair_v, x, y - 5);
 - }
 - 
 - /* function to display 'X's at given coordinates */
 - void display_xs(int x, int y) {
 - 
 -   static lv_point_precise_t u_line_points[] = { {0, 0}, {10, 10} };  //upsloping
 -   static lv_point_precise_t d_line_points[] = { {0, 10}, {10, 0} };  //downsloping
 - 
 -   static lv_style_t style_line;
 -   lv_style_init(&style_line);
 -   lv_style_set_line_width(&style_line, 2);
 -   lv_style_set_line_color(&style_line, lv_palette_main(LV_PALETTE_RED));
 -   lv_style_set_line_rounded(&style_line, true);
 - 
 -   // Create crosshair lines
 -   lv_obj_t* x_u = lv_line_create(lv_screen_active());
 -   lv_obj_t* x_d = lv_line_create(lv_screen_active());
 - 
 -   lv_line_set_points(x_u, u_line_points, 2); // Set the coordinates for the upsloping line
 -   lv_obj_add_style(x_u, &style_line, 0);
 - 
 -   lv_line_set_points(x_d, d_line_points, 2); // Set the coordinates for the downsloping line
 -   lv_obj_add_style(x_d, &style_line, 0);
 - 
 -   lv_obj_set_pos(x_u, x - 5, y - 5);
 -   lv_obj_set_pos(x_d, x - 5, y - 5);
 - }
 - 
 - /* function to compute the transformation equation coefficients from resistive touchscreen
 -    coordinates to display coordinates...
 -   This was based on the Texas Instruments appnote at:
 -   https://www.ti.com/lit/an/slyt277/slyt277.pdf
 -   It implements Equation 7 of that appnote, which computes a least-squares set of coefficients. */
 - void ts_calibration (
 -         const point aS, const point aT,
 -         const point bS, const point bT,
 -         const point cS, const point cT,
 -   const point dS, const point dT,
 -         const point eS, const point eT,
 -         const point fS, const point fT) {
 - 
 -         bool defined;
 -         uint16_t screenWidth, screenHeight;
 - 
 -   BLA::Matrix<6, 3> A;
 -   BLA::Matrix<3, 6> transA;
 -   BLA::Matrix<6> X;
 -   BLA::Matrix<6> Y;
 -   BLA::Matrix<3, 3> B;
 -   BLA::Matrix<3, 6> C;
 -   BLA::Matrix<3> X_coeff;
 -   BLA::Matrix<3> Y_coeff;
 - 
 -   s = String("aS = " + String(aS.x) + ", " + String(aS.y));
 -   Serial.println(s);
 -   s = String("bS = " + String(bS.x) + ", " + String(bS.y));
 -   Serial.println(s);
 -   s = String("cS = " + String(cS.x) + ", " + String(cS.y));
 -   Serial.println(s);
 -   s = String("dS = " + String(dS.x) + ", " + String(dS.y));
 -   Serial.println(s);
 -   s = String("eS = " + String(eS.x) + ", " + String(eS.y));
 -   Serial.println(s);
 -   s = String("fS = " + String(fS.x) + ", " + String(fS.y));
 -   Serial.println(s);
 - 
 -   s = String("aT = " + String(aT.x) + ", " + String(aT.y));
 -   Serial.println(s);
 -   s = String("bT = " + String(bT.x) + ", " + String(bT.y));
 -   Serial.println(s);
 -   s = String("cT = " + String(cT.x) + ", " + String(cT.y));
 -   Serial.println(s);
 -   s = String("eT = " + String(dT.x) + ", " + String(dT.y));
 -   Serial.println(s);
 -   s = String("eT = " + String(eT.x) + ", " + String(eT.y));
 -   Serial.println(s);
 -   s = String("fT = " + String(fT.x) + ", " + String(fT.y));
 -   Serial.println(s);
 -   Serial.println();
 - 
 -   struct f_point {
 -     float x;
 -     float y;
 -   };
 - 
 -   struct f_point faS, fbS, fcS, fdS, feS, ffS, faT, fbT, fcT, fdT, feT, ffT;
 - 
 -   faS.x = (float)aS.x; fbS.x = (float)bS.x; fcS.x = (float)cS.x, fdS.x = (float)dS.x; feS.x = (float)eS.x; ffS.x = (float)fS.x;
 -   faS.y = (float)aS.y; fbS.y = (float)bS.y; fcS.y = (float)cS.y; fdS.y = (float)dS.y; feS.y = (float)eS.y; ffS.y = (float)fS.y;
 - 
 -   faT.x = (float)aT.x; fbT.x = (float)bT.x; fcT.x = (float)cT.x; fdT.x = (float)dT.x; feT.x = (float)eT.x; ffT.x = (float)fT.x;
 -   faT.y = (float)aT.y; fbT.y = (float)bT.y; fcT.y = (float)cT.y; fdT.y = (float)dT.y; feT.y = (float)eT.y; ffT.y = (float)fT.y;
 - 
 -   A = { faT.x, faT.y, 1,
 -         fbT.x, fbT.y, 1,
 -         fcT.x, fcT.y, 1,
 -         fdT.x, fdT.y, 1,
 -         feT.x, feT.y, 1,             
 -         ffT.x, ffT.y, 1 };
 - 
 -   X = { faS.x,
 -         fbS.x,
 -         fcS.x,
 -         fdS.x,
 -         feS.x,
 -         ffS.x };
 - 
 -   Y = { faS.y,
 -         fbS.y,
 -         fcS.y,
 -         fdS.y,
 -         feS.y,
 -         ffS.y };
 - 
 -   /* Now compute [AtA]^-1 * AtA * X and [AtA]^-1 * AtA * Y */
 -   Serial.print ("A = ");
 -   Serial.println(A);
 - 
 -   transA = ~A;
 -   Serial.print ("transA = ");
 -   Serial.println(transA);
 - 
 -   B = transA * A;
 -   Serial.print ("Before inversion, B = ");
 -   Serial.println(B);
 - 
 -   if (!Invert(B) ) {
 -     Serial.println("Singular matrix in computation of inverse of B = transA*A!");
 -   }
 -   Serial.print ("After inversion, B = ");
 -   Serial.println(B);
 - 
 -   C = B * transA;
 -   Serial.print ("C = ");
 -   Serial.println(C);
 - 
 -   X_coeff = C * X;
 -   Y_coeff = C * Y;
 - 
 -   /* transfer the X and Y coefficients to the Greek-letter variables
 -      Note that BLA requires round brackets while MatrixMath requires square ones */
 -   alphaX = X_coeff(0); betaX = X_coeff(1); deltaX = X_coeff(2);
 -   alphaY = Y_coeff(0); betaY = Y_coeff(1); deltaY = Y_coeff(2);
 - 
 -   Serial.println();
 - }
 
  复制代码
  
 
 |