雷竞技注册
项目

采用EFM8微控制器的圆形触摸传感

2016年12月15日通过罗伯特Keim

在这个项目中,我们将开发一种算法,用于精确定位发生在圆形电容传感器上的触摸事件。

在这个项目中,我们将开发一种算法,用于精确定位发生在圆形电容传感器上的触摸事件。

相关信息

所需的硬件/软件

圆形的传感器

SLSTK2010A评估板包括EFM8瞌睡虫微控制器和圆形电容传感器。使用任何微控制器都可以进行电容式触摸传感,但使用专家设计的专门硬件模块会得到更好的结果,而这正是集成在沉睡蜜蜂中的东西。之前的一篇文章,标题为采用EFM8微控制器的电容式触摸传感,探索了这个外设的功能,它被称为CS0(电容感0)EFM8昏昏欲睡的蜜蜂参考手册。

圆形电容传感器提供非三维圆环形(或者,如果您喜欢甜甜圈形)区域,其中可以通过施加指尖接收用户输入。有真实的约束,限制了可以准确识别的单独触摸位置的数量,但总的来说,我会说该分辨率非常好 - 我的猜测是精心设计的固件可以可靠地区分5°增量,这意味着圆形传感器可能提供多达72个单独的用户输入位置。

这是相当令人印象深刻的,但是当您认为只有这些72个单独的位置只能实现这些72个单独的位置时变得更加令人印象深刻capacitive-sense频道。然而,这三个通道能够提供这种功能,只是因为它们连接到三个非常巧妙设计的电容PCB传感器,如下图所示。

图形的马克休斯

每个传感器的中心部分对应于弯曲突起的尖端之间的径向部分。当触摸中心部分时,该传感器的电容变化(AKA“帽Δ”)将是最高的,并且当指尖在任一方向上从中央部分移动时,盖子Δ将稳定地减小。

正如你所看到的,当你离开一个中心部分时,你正在向另一个中心部分移动。这意味着第一个通道上帽增量的减少与另一个通道上帽增量的增加同时发生。通过结合来自相邻传感器的cap-delta测量,我们可以计算出发生在环面某处的任何接触事件的近似角度位置。

在我们继续前进之前,让我们简要讨论为什么在现代电子产品的背景下是如此漂亮的原因。雷竞技最新app毕竟,我们需要一些相当复杂的固件,只使用三个传感器获得体面的角度定位。为什么不仅使用十几普通圆形传感器均匀地绕着圆圈间隔开?

每个传感器在微控制器上都需要一个引脚,所以现在你已经消耗了12个引脚,在这个过程中你的分辨率显著降低了。固件价格便宜,不占用任何空间,而微控制器引脚(以及连接到它们的PCB痕迹)相对于工程师现在期望设计的微型设备来说,占用了大量空间。从长远来看,硬件是昂贵的,至少与固件相比是这样。更少的引脚,更小的集成电路,更少的硬件,更多的固件——这是当前的范式,至少对消费电子产品来说是这样。雷竞技最新app

跟踪我们的传感器

下图显示了代码中使用的传感器编号如何与物理排列相对应。

同样,这些是“传感器数字”。,分配给三个物理传感器的任意标识符。这些数字与“通道”不一样。,其内部盖感通道连接到物理传感器。当然,通道数不一定以一种直观的方式对应于传感器电连接的外部引脚。下面是映射:

传感器数量 通道 地点
1 2 P0.2 底部的中间
2 3. P0.3 左上方
3. 13 P1.5 右上的

建立一个基线

我们需要做的第一件事是设置一个特定传感器的官方“未压”电容值。这一步是至关重要的——首先,因为电容式触摸传感是围绕电容的变化而进行的,而不是绝对电容;其次,因为这三个传感器在无压电容方面可以表现出很大的变化。例如,我刚刚插入我的电路板,此时三个(看起来相同的)传感器的未压电容值约为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_电容(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个。也许这是矫枉过正的,但所有的帽子义功能都是基于这些未压制的值,所以我想确保他们不会被瞬态噪声源或某种测量毛刺损坏。

注意:重要的是要避免这些初始未溢出的测量值之间的主要差异,但是在正常操作期间对CAP义通道进行采样。我具体参考维护频道序列并确保测量之间的类似间隔。For example, if during normal operation you sample sensor 1, then sensor 2, then sensor 3, with 1 ms between each measurement, you don’t want to determine your unpressed values by taking 16 rapid-fire sensor 1 measurements, then immediately taking 16 rapid-fire sensor 2 measurements, then immediately taking 16 rapid-fire sensor 3 measurements. This would lead to small but noticeable discrepancies between normal-operation measurements and establishing-unpressed-capacitance measurements, such that your official unpressed values will be different from the actual typical unpressed values observed during normal program operation.

检测一个新闻

在计算角度位置之前,我们需要认识到指尖与圆形传感器接触。我们通过扫描通道,计算帽delta,并将其与阈值进行比较来做到这一点。

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次(我将盖感增益设置为4x)。我是通过触摸两个传感器的中间来做到的;这导致了最小单传感器电容的增加,因为总增加是平分两个传感器。

因此,我们可以假设与圆形传感器的任何部分接触的指尖将导致至少6000个计数的帽子。基于此,您可能使用4000或5000计数作为CAP-DELTA阈值,但我选择了2000年,仅仅因为2000年仍然远远超过典型的噪声幅度,并将给我们更高的灵敏度(也许一些手指的电容比其他指示较低。。。)。

接下来,我们简单地比较每个传感器的上限delta与阈值,如果至少有一个超过阈值,我们继续处理传感器数据,以确定触摸事件的角度位置。

计算位置

在我继续之前,我应该提到以下几点:我所开发的角度-位置算法可能远不是最优的。但这不是重点。关键在于,这个算法是一个常识性思维过程的结果,它反映了从意向、考虑、观察和分析到实现的“直觉路径”。我更喜欢从这条直观的路径开始,因为它将可靠地导致对当前问题的更深层次的理解,并且在寻找其他人创建的可能更好的实现之前,寻求这种更深层次的理解是一个好主意。

我首先确定的120°段,其中触摸事件正在发生;这是通过寻找测量值最低的传感器来实现的。例如,如果传感器1的测量值最低,指尖就在传感器2和3之间。

if(传感器1_delta> touch_delta_threshold || Sensor2_Delta> Touch_Delta_Threshold || Sensor3_Delta> Touch_Delta_Threshold){Switch(Find_minimum(Sensor1_delta,Sensor2_delta,Sensor3_delta)){Case Sensor_1:段= Upper_middle;休息;案例SENSOR_2:段= DIFFER_RIGHT;休息;案例SENSOR_3:段= DIGHT_LEFT;休息;} ......

该算法的下一部分的关键是假设电容的总增加与角度位置相同。Let’s say that the finger is on the center of sensor 2 and produces an increase of 15000 counts from sensor 2 and an increase of zero counts from sensor 3. Under this assumption, both sensor 2 and sensor 3 will have an increase of 7500 counts if the touch event is halfway between the two. I don’t know how accurate this assumption is, but the general idea seems to be valid enough to produce good results.

接下来,我们简单地将传感器2(或传感器3或传感器1)delta除以总delta,然后将这个比值乘以120°。最后,我们把这个角加到120°段的“起始”角上。

The main weakness with this technique is the following: The angles near the center of the sensors (i.e., 30°, 150°, 270°) get “skipped” because the cap delta doesn’t go all the way to zero—for example, if your fingertip is right on the center of sensor 3, the sensor 2 reading might be 400 counts instead of zero counts. The result is that the ratio of sensor 2 delta to total delta will not extend all the way from 0% to 100%. To correct for this, I assume (based on observations) that the initially calculated ratio will extend from 5% to 95%, and then I map the ratio from the range 5–95 to the range 0–100. The mapping constants are determined by solving the following simultaneous equations:

$ $ \{病例}开始0.05 x + y = 0 \ \ 0.95 x + y = 1 \ \ \{病例}$ $

我对这种方法提供的性能很满意,但是需要一些额外的微调,以完全消除发生在30°、150°和270°过渡区域的“跳动”测量。

if(Segment == UPPER_MIDDLE) {TotalDelta = Sensor2_Delta + Sensor3_Delta;率=(浮动)Sensor2_Delta / TotalDelta;比值= (Ratio*1.1111) - 0.05556;AngularPosition = (Ratio*120) + 30;} else if(Segment == LOWER_RIGHT) {TotalDelta = Sensor3_Delta + Sensor1_Delta;率=(浮动)Sensor3_Delta / TotalDelta;比值= (Ratio*1.1111) - 0.05556;AngularPosition = (Ratio*120) + 270;if(AngularPosition >= 360) AngularPosition = 360;} else if(Segment == LOWER_LEFT) {TotalDelta = Sensor2_Delta + Sensor1_Delta; Ratio = (float)Sensor1_Delta/TotalDelta; Ratio = (Ratio*1.1111) - 0.05556; AngularPosition = (Ratio*120) + 150; }

结论

您可以使用以下链接下载所有源文件和项目文件。

EFM8_CapacitiveCircularSense.zip

如下面的视频所示,程序有两种模式:在默认模式下,它显示当前或最近的触摸事件的角度位置。在第二种模式中,它显示每个通道的上限增量。

在未来的文章中,我们将把这种角度位置功能纳入基于循环 - 触摸传感器的用户界面。

自己试试这个项目吧!BOM。