コード例 #1
0
ファイル: tsd_com.c プロジェクト: alexrayne/freemodbus
/**
 * \brief Performs the calibration process using the provided buffer to display
 * information.
 *
 * \return True if calibration was successful; otherwise false.
 */
uint8_t TSDCom_Calibrate(void)
{
    volatile uint32_t i; /* to keep the tempo with gcc code optimisation */
    int32_t slope1, slope2;
    CalibrationPoint measuredPoint;
    uint8_t xOk, yOk;
    int32_t xDiff, yDiff;

    /* Calibration setup */
    LCDD_Fill(COLOR_WHITE);
    LCDD_DrawString(30, 50, (uint8_t *)"LCD calibration", COLOR_BLACK);
    LCDD_DrawString(1, 140, (uint8_t *)"Touch the dots to\ncalibrate the screen", COLOR_DARKBLUE);

    /* Calibration points */
    for (i=0; i < 4; i++) {

        DrawCalibrationPoint(&calibrationPoints[i]);

        /* Wait for touch & end of conversion */
        TSD_WaitPenPressed();
        TSD_GetRawMeasurement(calibrationPoints[i].data);
        ClearCalibrationPoint(&calibrationPoints[i]);

        /* Wait for contact loss */
        TSD_WaitPenReleased();
    }

    /**
     * Calculate slopes using the calibration data
     * Theory behind those calculations:
     *   - We suppose the touchscreen measurements are linear, so the following equations are true (simple
     *     linear regression) for any two 'a' and 'b' points of the screen:
     *       dx = (a.data[0] - b.data[0]) / (a.x - b.x)
     *       dy = (a.data[1] - b.data[1]) / (a.y - b.y)
     *
     *   - We calculate dx and dy (called xslope and yslope here) using the calibration points.
     *
     *   - We can then use dx and dy to infer the position of a point 'p' given the measurements performed
     *     by the touchscreen ('c' is any of the calibration points):
     *       dx = (p.data[0] - c.data[0]) / (p.x - c.x)
     *       dy = (p.data[1] - c.data[1]) / (p.y - c.y)
     *     Thus:
     *       p.x = c.x - (p.data[0] - c.data[0]) / dx
     *       p.y = c.y - (p.data[1] - c.data[1]) / dy
     *
     *   - Since there are four calibration points, dx and dy can be calculated twice, so we average
     *     the two values.
     */
    slope1 = ((int32_t) calibrationPoints[0].data[0]) - ((int32_t) calibrationPoints[1].data[0]);
    slope1 *= 1024;
    slope1 /= ((int32_t) calibrationPoints[0].x) - ((int32_t) calibrationPoints[1].x);
    slope2 = ((int32_t) calibrationPoints[2].data[0]) - ((int32_t) calibrationPoints[3].data[0]);
    slope2 *= 1024;
    slope2 /= ((int32_t) calibrationPoints[2].x) - ((int32_t) calibrationPoints[3].x);
    xSlope = (slope1 + slope2) / 2;

    slope1 = ((int32_t) calibrationPoints[0].data[1]) - ((int32_t) calibrationPoints[2].data[1]);
    slope1 *= 1024;
    slope1 /= ((int32_t) calibrationPoints[0].y) - ((int32_t) calibrationPoints[2].y);
    slope2 = ((int32_t) calibrationPoints[1].data[1]) - ((int32_t) calibrationPoints[3].data[1]);
    slope2 *= 1024;
    slope2 /= ((int32_t) calibrationPoints[1].y) - ((int32_t) calibrationPoints[3].y);
    ySlope = (slope1 + slope2) / 2;

    /* Test point */
    LCDD_Fill(0xFFFFFF);
    LCDD_DrawString(30, 50, (uint8_t *)"LCD calibration", COLOR_BLACK);
    LCDD_DrawString(1, 100, (uint8_t *)" Touch the point to\nvalidate calibration", COLOR_DARKBLUE);
    DrawCalibrationPoint(&testPoint);

    /* Wait for touch & end of conversion */
    TSD_WaitPenPressed();

    TSD_GetRawMeasurement(measuredPoint.data);
    TSDCom_InterpolateMeasurement(measuredPoint.data, (uint32_t *) &measuredPoint);
    DrawCalibrationPoint(&measuredPoint);

    /* Check resulting x and y */
    xDiff = (int32_t) measuredPoint.x - (int32_t) testPoint.x;
    yDiff = (int32_t) measuredPoint.y - (int32_t) testPoint.y;
    xOk = (xDiff >= -POINTS_MAX_ERROR) && (xDiff <= POINTS_MAX_ERROR);
    yOk = (yDiff >= -POINTS_MAX_ERROR) && (yDiff <= POINTS_MAX_ERROR);

    /* Wait for contact loss */
    TSD_WaitPenReleased();

    /* Check calibration result */
    if (xOk && yOk) {

        bCalibrationOk = 1;
        LCDD_Fill(COLOR_WHITE);
        LCDD_DrawString(30, 50, (uint8_t *)"LCD calibration", COLOR_BLACK);
        LCDD_DrawString(80, 140, (uint8_t *)"Success !", COLOR_GREEN);

    }
    else {

        bCalibrationOk = 0;
        LCDD_Fill(COLOR_WHITE);
        LCDD_DrawString(30, 50, (uint8_t *)"LCD calibration", COLOR_BLACK);
        LCDD_DrawString(40, 140, (uint8_t *)"Error too big", COLOR_RED);
    }

    /* Slight delay */
    for (i = 0; i < DELAY_RESULT_DISPLAY; i++);

    return (xOk && yOk);
}
コード例 #2
0
ファイル: tsd_com.c プロジェクト: Flyagin/BS-MRZV
//------------------------------------------------------------------------------
/// Performs the calibration process using the provided buffer to display
/// information.
/// \param pLcdBuffer  LCD buffer to display.
/// \return True if calibration was successful; otherwise false.
//------------------------------------------------------------------------------
unsigned char TSDCom_Calibrate(void *pLcdBuffer)
{
#ifdef AT91C_ID_LCDC
    void *pOldLcdBuffer;
#endif
    volatile unsigned int i; // to keep the tempo with gcc code optimisation
    signed int slope1, slope2;
    CalibrationPoint measuredPoint;
    unsigned char xOk, yOk;
    signed int xDiff, yDiff;

    // Calibration setup
    LCDD_Fill(pLcdBuffer, COLOR_WHITE);
    LCDD_DrawString(pLcdBuffer, 30, 50, "LCD calibration", COLOR_BLACK);
    LCDD_DrawString(pLcdBuffer, 1, 100, " Touch the dots to\ncalibrate the screen", COLOR_DARKBLUE);
#ifdef AT91C_ID_LCDC
    pOldLcdBuffer = LCDD_DisplayBuffer(pLcdBuffer);
#endif

    // Calibration points
    for (i=0; i < 4; i++) {

        DrawCalibrationPoint(pLcdBuffer, &calibrationPoints[i]);

        // Wait for touch & end of conversion
        TSD_WaitPenPressed();
        TSD_GetRawMeasurement(calibrationPoints[i].data);
        ClearCalibrationPoint(pLcdBuffer, &calibrationPoints[i]);

        // Wait for contact loss
        TSD_WaitPenReleased();
    }

    // Calculate slopes using the calibration data
    // Theory behind those calculations:
    //   - We suppose the touchscreen measurements are linear, so the following equations are true (simple
    //     linear regression) for any two 'a' and 'b' points of the screen:
    //       dx = (a.data[0] - b.data[0]) / (a.x - b.x)
    //       dy = (a.data[1] - b.data[1]) / (a.y - b.y)
    //
    //   - We calculate dx and dy (called xslope and yslope here) using the calibration points.
    //
    //   - We can then use dx and dy to infer the position of a point 'p' given the measurements performed
    //     by the touchscreen ('c' is any of the calibration points):
    //       dx = (p.data[0] - c.data[0]) / (p.x - c.x)
    //       dy = (p.data[1] - c.data[1]) / (p.y - c.y)
    //     Thus:
    //       p.x = c.x - (p.data[0] - c.data[0]) / dx
    //       p.y = c.y - (p.data[1] - c.data[1]) / dy
    //
    //   - Since there are four calibration points, dx and dy can be calculated twice, so we average
    //     the two values.
    slope1 = ((signed int) calibrationPoints[0].data[0]) - ((signed int) calibrationPoints[1].data[0]);
    slope1 *= 1024;
    slope1 /= ((signed int) calibrationPoints[0].x) - ((signed int) calibrationPoints[1].x);
    slope2 = ((signed int) calibrationPoints[2].data[0]) - ((signed int) calibrationPoints[3].data[0]);
    slope2 *= 1024;
    slope2 /= ((signed int) calibrationPoints[2].x) - ((signed int) calibrationPoints[3].x);
    xSlope = (slope1 + slope2) / 2;

    slope1 = ((signed int) calibrationPoints[0].data[1]) - ((signed int) calibrationPoints[2].data[1]);
    slope1 *= 1024;
    slope1 /= ((signed int) calibrationPoints[0].y) - ((signed int) calibrationPoints[2].y);
    slope2 = ((signed int) calibrationPoints[1].data[1]) - ((signed int) calibrationPoints[3].data[1]);
    slope2 *= 1024;
    slope2 /= ((signed int) calibrationPoints[1].y) - ((signed int) calibrationPoints[3].y);
    ySlope = (slope1 + slope2) / 2;

    // Test point
    LCDD_Fill(pLcdBuffer, 0xFFFFFF);
    LCDD_DrawString(pLcdBuffer, 30, 50, "LCD calibration", COLOR_BLACK);
    LCDD_DrawString(pLcdBuffer, 1, 100, " Touch the point to\nvalidate calibration", COLOR_DARKBLUE);
    DrawCalibrationPoint(pLcdBuffer, &testPoint);

    // Wait for touch & end of conversion
    TSD_WaitPenPressed();

    TSD_GetRawMeasurement(measuredPoint.data);
    TSDCom_InterpolateMeasurement(measuredPoint.data, (unsigned int *) &measuredPoint);
    DrawCalibrationPoint(pLcdBuffer, &measuredPoint);

    // Check resulting x and y
    xDiff = (signed int) measuredPoint.x - (signed int) testPoint.x;
    yDiff = (signed int) measuredPoint.y - (signed int) testPoint.y;
    xOk = (xDiff >= -POINTS_MAX_ERROR) && (xDiff <= POINTS_MAX_ERROR);
    yOk = (yDiff >= -POINTS_MAX_ERROR) && (yDiff <= POINTS_MAX_ERROR);

    // Wait for contact loss
    TSD_WaitPenReleased();

    // Check calibration result
    if (xOk && yOk) {

        bCalibrationOk = 1;
        LCDD_Fill(pLcdBuffer, COLOR_WHITE);
        LCDD_DrawString(pLcdBuffer, 30, 50, "LCD calibration", COLOR_BLACK);
        LCDD_DrawString(pLcdBuffer, 80, 100, "Success !", COLOR_GREEN);

    }
    else {

        bCalibrationOk = 0;
        LCDD_Fill(pLcdBuffer, COLOR_WHITE);
        LCDD_DrawString(pLcdBuffer, 30, 50, "LCD calibration", COLOR_BLACK);
        LCDD_DrawString(pLcdBuffer, 40, 100, "Error too big", COLOR_RED);
    }

    // Slight delay
    for (i = 0; i < DELAY_RESULT_DISPLAY; i++);

#ifdef AT91C_ID_LCDC
    // Restore old LCD buffer
    LCDD_DisplayBuffer(pOldLcdBuffer);
#endif

    return (xOk && yOk);
}