|
在本篇文章中,我们将开发一种算法,用于精确定位在圆形电容传感器上某处发生的触摸事件。
所需的硬件/软件 ● SLSTK2010A Sleepy Bee入门套件 ● Simplicity Studio
圆形传感器 SLSTK2010A评估板包括EFM8 Sleepy Bee微控制器和圆形电容式传感器。可以使用任何微控制器执行电容式触摸感应,但是通过专家设计的专用硬件模块可以获得更好的结果,这正是Sleepy Bee中集成的功能。前一篇题为“使用EFM8微控制器进行电容式触摸感应”的文章探讨了该外设的功能,在EFM8 Sleepy Bee参考手册中称为CS0(Capacitive Sense 0)。
圆形电容传感器提供非三维圆环形(或者,如果您喜欢的圆环形)区域,其中可以通过指尖的应用来接收用户输入。现实的限制条件限制了可以准确识别的单独触摸位置的数量,但总的来说我会说分辨率非常好 - 我猜测这些精心设计的固件可以可靠地区分5°增量,这意味着圆形传感器可提供多达72个独立的用户输入位置。
这是相当令人印象深刻的,但是当您想到仅使用三个电容感应通道实现这72个独立位置时,它会变得更加令人印象深刻。但是,这三个通道能提供此功能,只是因为它们连接到三个非常巧妙设计的电容式PCB传感器,如下图所示。
每个传感器的中心部分对应于弯曲突起的尖端之间的径向部分。当您触摸中心部分时,该传感器的电容变化(也称为“上限三角形”)将最高,并且当指尖在任一方向上远离中心部分移动时,上限增量将稳定下降。
但是,正如您所看到的那样,当您离开一个中心部分时,您正朝着另一个中心部分移动。这意味着第一个通道上的下降增量与另一个通道上的上限增量一起发生。通过组合来自相邻传感器的三角测量,我们可以计算出在环面某处发生的任何触摸事件的近似角位置。
在我们继续之前,让我们简要讨论一下为什么这个圆形滑块在现代电子设备的背景下非常漂亮。毕竟,我们需要一些相当复杂的固件才能使用三个传感器获得合适的角度定位。为什么不使用十几个普通的圆形传感器在圆周上均匀分布?
好吧,每个传感器都需要一个微控制器上的引脚,所以现在你已经消耗了12个引脚,在此过程中你的分辨率会大大降低。固件价格便宜且不占用任何空间,而微控制器引脚(以及连接到它们的PCB走线)相对于工程师现在期望设计的微小设备占用了大量空间。从长远来看,硬件很昂贵,至少与固件相比。更少的引脚、更小的IC、更少的硬件、更多的固件 - 这是当前的趋势,至少对于消费电子产品而言。
了解我们的传感器 下图显示了代码中使用的传感器编号如何与物理布置相对应。
同样,这些是“传感器编号” - 即,分配给三个物理传感器的任意标识符。这些数字与“通道”不同,内部感应通道连接到物理传感器。当然,通道编号不一定以直观的方式对应于传感器电气连接的外部引脚。以下是映射表: 传感器编号
(Sensor Number)
| 通道
(Channel)
| 引脚号
(Pin)
| 位置
(Location)
| 1 | 2 | P0.2 | 底部中间 | 2 | 3 | P0.3 | 左上角 | 3 | 1 | P1.5 | 右上角 |
建立基线(Baseline) 我们需要做的第一件事是将某个值设置为特定传感器的官方“未压缩”电容。这一步骤至关重要,因为电容式触摸感应围绕电容的变化而非绝对电容,其次,因为三个传感器的未压缩电容会有很大的变化。例如,我只是插入我的电路板,目前这三个(看似相同的)传感器的未压缩电容值约为15700、14800和14150。
我建立了未压缩的电容值如下: - Accumulated_Capacitance_Sensor1 = 0;
- Accumulated_Capacitance_Sensor2 = 0;
- Accumulated_Capacitance_Sensor3 = 0;
- for (n = 0; n < 16; n++)
- {
- Accumulated_Capacitance_Sensor1 += Measure_Capacitance(SENSOR_1);
- Delay_us(1000);
- Accumulated_Capacitance_Sensor2 += Measure_Capacitance(SENSOR_2);
- Delay_us(1000);
- Accumulated_Capacitance_Sensor3 += Measure_Capacitance(SENSOR_3);
- Delay_10ms(5); Delay_us(6000);
- }
- Sensor1_Unpressed = (Accumulated_Capacitance_Sensor1 >> 4);
- Sensor2_Unpressed = (Accumulated_Capacitance_Sensor2 >> 4);
- Sensor3_Unpressed = (Accumulated_Capacitance_Sensor3 >> 4);
复制代码
你可以在这里看到我做了很多平均。 CS0硬件配置为每次测量平均64个样本,然后我平均这些已经平均的测量值中的16个。也许这有点矫枉过正,但所有的上限检测功能都是基于这些未压缩的值,因此我想确保它们不会被瞬态噪声源或某种测量故障所破坏。
注意:重要的是要避免这些初始未压缩测量之间的主要差异,然而在正常操作期间对电容感应通道进行采样。我特别提到维护信道序列并确保测量之间的间隔相似。例如,如果在正常操作期间您对传感器1,传感器2,传感器3进行采样,每次测量之间的间隔为1 ms,则您不希望通过进行16次快速传感器1测量来确定您的未压缩值,然后立即采取16个快速传感器2测量,然后立即采取16个快速传感器3测量。这将导致正常操作测量与建立非压缩电容测量之间的小但明显的差异,使得您的官方未压缩值将与正常编程操作期间观察到的实际典型未压缩值不同。
检测按下 在计算角度位置之前,我们需要认识到指尖与圆形传感器接触。我们通过扫描通道,计算上限增量并将其与阈值进行比较来实现此目的。 - Sensor1_Measurement = Measure_Capacitance(SENSOR_1);
- Sensor1_Delta = Sensor1_Measurement - Sensor1_Unpressed;
- if(Sensor1_Delta < 0)
- Sensor1_Delta = 0;
- Delay_us(1000);
- Sensor2_Measurement = Measure_Capacitance(SENSOR_2);
- Sensor2_Delta = Sensor2_Measurement - Sensor2_Unpressed;
- if(Sensor2_Delta < 0)
- Sensor2_Delta = 0;
- Delay_us(1000);
- Sensor3_Measurement = Measure_Capacitance(SENSOR_3);
- Sensor3_Delta = Sensor3_Measurement - Sensor3_Unpressed;
- if(Sensor3_Delta < 0)
- Sensor3_Delta = 0;
- if(Sensor1_Delta > TOUCH_DELTA_THRESHOLD
- || Sensor2_Delta > TOUCH_DELTA_THRESHOLD
- || Sensor3_Delta > TOUCH_DELTA_THRESHOLD)
- {
- ...
复制代码
通过实验,我发现不太坚固的手指按压时电容的最小增加大约是6000个计数(我将帽感增益设置为4倍)。 我通过触摸两个传感器之间的中途来做到这一点; 这导致单个传感器的电容增加最小,因为两个传感器之间的总增加量相等。
因此,我们可以假设与圆形传感器的任何部分接触的指尖将导致至少6000计数的上限。 基于此,您可以使用4000或5000计数作为上限 - 增量阈值,但我选择2000,仅仅因为2000仍然远高于典型的噪声幅度并且将给予我们更高的灵敏度(可能一些手指具有比其他手指更小的电容。)。
接下来,我们简单地将每个传感器的电容增量与阈值进行比较,如果至少有一个超过阈值,我们继续处理传感器数据以确定触摸事件的角位置。 |