电阻触摸屏校正,一般采用5点校正法,核心就是解方程,得系数。具体实现tslib里面就有,但裸机的话,那就的靠自己了,今天抽了点时间,重现实现了之前因框架变化而屏蔽掉的代码,算补全这个功能。
求解方程实现函数
struct tscal_t {
int x[5], xfb[5];
int y[5], yfb[5];
int a[7];
int index;
};
static int perform_calibration(struct tscal_t * cal)
{
float n, x, y, x2, y2, xy, z, zx, zy;
float det, a, b, c, e, f, i;
float scaling = 65536.0;
int j;
n = x = y = x2 = y2 = xy = 0;
for(j = 0; j < 5; j++)
{
n += 1.0;
x += (float)cal->x[j];
y += (float)cal->y[j];
x2 += (float)(cal->x[j]*cal->x[j]);
y2 += (float)(cal->y[j]*cal->y[j]);
xy += (float)(cal->x[j]*cal->y[j]);
}
det = n * (x2 * y2 - xy * xy) + x * (xy * y - x * y2) + y * (x * xy - y * x2);
if(det < 0.1 && det > -0.1)
return 0;
a = (x2 * y2 - xy * xy) / det;
b = (xy * y - x * y2) / det;
c = (x * xy - y * x2) / det;
e = (n * y2 - y * y) / det;
f = (x * y - n * xy) / det;
i = (n * x2 - x * x) / det;
z = zx = zy = 0;
for(j = 0; j < 5; j++)
{
z += (float)cal->xfb[j];
zx += (float)(cal->xfb[j] * cal->x[j]);
zy += (float)(cal->xfb[j] * cal->y[j]);
}
cal->a[0] = (int)((b * z + e * zx + f * zy) * (scaling));
cal->a[1] = (int)((c * z + f * zx + i * zy) * (scaling));
cal->a[2] = (int)((a * z + b * zx + c * zy) * (scaling));
z = zx = zy = 0;
for(j = 0; j < 5; j++)
{
z += (float)cal->yfb[j];
zx += (float)(cal->yfb[j] * cal->x[j]);
zy += (float)(cal->yfb[j] * cal->y[j]);
}
cal->a[3] = (int)((b * z + e * zx + f * zy) * (scaling));
cal->a[4] = (int)((c * z + f * zx + i * zy) * (scaling));
cal->a[5] = (int)((a * z + b * zx + c * zy) * (scaling));
cal->a[6] = (int)scaling;
return 1;
}
校正参数有7个数,最后一个是scaling,一般是65536
"ts-ns2009@0": {
"i2c-bus": "i2c-v3s.0",
"slave-address": 72,
"median-filter-length": 5,
"mean-filter-length": 5,
"calibration": [14052, 21, -2411064, -67, 8461, -1219628, 65536],
"poll-interval-ms": 10
},
这里有个特殊的校正参数,设定这个校正参数后,坐标不做任何变化,采样多少,就输出多少,用于获取原始采样值
[1, 0, 0, 0, 1, 0, 1]
有了校正参数后,所有坐标通过,如下公式,就可以进行校正坐标了
*x = (filter->cal[2] + filter->cal[0] * tx + filter->cal[1] * ty) / filter->cal[6];
*y = (filter->cal[5] + filter->cal[3] * tx + filter->cal[4] * ty) / filter->cal[6];
校正程序代码
https://gitee.com/xboot/xboot/blob/master/src/kernel/command/cmd-tscal.c
好了,水完了!
离线
随便水一下都这么有水平,认真起来是怎样的人?
离线
请问楼主,命令行怎么执行这个触摸校正?
离线
tscal <framebuffer> <input>
后面两个参数,一个fb设备名,一个touch screen 设备名
离线
楼主,我触摸校正之后坐标还是不对,触摸线序不一样 算法是不是就不一样了
离线
校正算法需要跟坐标映射运算保持对应关系,两者之间要互为逆运算的关系,不要随便跟其他平台的方案随便搭配,至少这7个参数的顺序跟tslib里面的是不对应的。
离线
如果这个电阻屏的阻值是非线性的话,建议你换掉这个垃圾供应商,材料一致性都做不好,靠算法来解决是歪门邪道,如果真要去搞非线性校正,参数就不是6个了,你要做的工作是用一组参数,能将一个曲面给展平。这数学得过关,可以当成博士的毕业课题了,估计能搞死人。
离线
@XBOOT 大神,您好,问下触摸参数是从json文件中读取的,校准完能保存吗
最近编辑记录 Sam (2022-04-09 15:35:22)
离线
xboot大神的水贴真香!
离线
我的屏幕校正 仅用了三点,是不是 不够专业。
抽空 也弄个 视频, 水一帖。
离线
xboot大神,我想把左下角的坐标原点转换为 左上角的坐标原点,怎么搞
离线