电容式触控开关实验(一):RC延时电路应用

实验材料

  • Arduino Uno控制板一片
  • 电阻:1MΩ×3、680Ω×2
  • LED×2(颜色不拘)
  • (没有塑料皮的)回形针×3
  • 公对母连接线×3
  • 铝箔纸:裁剪3枚(笔者剪裁的大小是15mm×12mm)

实验电路与面包板组装示范

本单元的实验电路如下,全部的1MΩ电阻的一端都连接到同一个数位脚(此处为第4脚,可改用其他脚位),电阻的另一端连接到不同的数位脚,以及充当「触控感测端」的铝箔纸,你可以尝试其他导体,像铜箔或香蕉番石榴之类的东东。

使用面包板组装电路的示范如下,用回形针固定电阻的一端和铝箔纸:

笔者把触控电路焊接在PCB板,铝箔纸用白胶黏贴:

电容触控与RC电路的原理

本实验程序将在电阻的一端(数位第4脚)发送脉冲信号,在没有人体碰触感测界面情况下,该脉冲信号几乎原封不动地传送到电阻的另一端:

当手指靠近感测端时,手指和感测端的导体(铝箔)之间会形成电容,相当于电阻的另一端接了一个电容器:

电容的基本结构像下图一样,用两片导体、中间以绝缘介质(如:空气、云母、陶瓷…)隔离。当两端导体通电时,导体就会聚集正、负电荷,形成「电的容器」。

左下图是用电阻(R)电容(C)组成的基本RC电路。对电容通电时,电容将开始储存电荷,直到注满到电压的相同准位;断电时,电容会开始放电,直到降到0(亦即,「接地」的准位)。

在充电过程中,电流与电容电压的变化量受到电阻与电容值影响。电阻R与电容值C的乘积称为时间常数(time constant),写成希腊字母τ(念作“tau”),有时也直接用英文字母t代表:

τ= RC

电容充电到约70%(实际为63.2%)仅需花费一个时间常数,充到饱和(约99.3%)需要5个时间常数;电阻或电容值愈大,充电所需时间也愈长。电容放电时,在一个时间常数之后,约剩下40%(实际为36.8%)。

因此,向电阻的一端输入脉冲信号,当手指接触电阻另一端时,输出脉冲的高、低电位时间将被「延后」。程序透过比对输入和输出的脉冲时间,就能得知是否有人碰触到感应器(铝箔)。

感测端的电容量,与手指和感应器的距离成反比。本单元程序采用Paul Stoffregen撰写的Captivative Sensor程序库,此程式库的说明页指出,电路中的电阻值可介于100KΩ~50MΩ,阻值越大越灵敏但反应变迟钝:

  • 若要侦测手指是否碰触到感测面,请使用1MΩ
  • 若要偵測4~6吋(註:1吋=2.54公分)的距離,請使用10MΩ。
  • 若要侦测12~24寸的距离(视感测面的金属片尺寸而定),请使用40MΩ。市面所能买到的最大电阻值为10MΩ,请自行串连4个电阻。

说明页也提到,在感测端加上一个100pF的电容(标示为101),可增加检测的稳定性。

触控开关实验程序

下载CaptivativeSensor程序库、解压缩之后,笔者将它重新命名成“CaptivativeSensor”,存入Arduino的libraries文件夹:

开启Arduino IDE,选择「档案→示例→CapacitiveSensor→CapacitiveSensorScketch」,开启程序库提供的示例程序。此示例程序的感测脉冲信号发射脚是4,接收脚是2,6和8,请将它们改成5,6,7:

其余代码不用改。编译并上传到Arduino控制板之后,开启序列端口监控视窗,这是尚未碰触任何感应界面的输出:

碰触感应界面的结果:

CapacitiveSensor程序库的方法

CapacitiveSensor程序库包含3个主要方法以及一些工具方法:

CapacitiveSensor CapacitiveSensor(byte脉冲发射脚,byte感测脚)

CapacitiveSensor用于建立程序库的物件实体(请留意大小写)。

long capacitiveSensorRaw(byte取样数)

capacitiveSensorRaw将传回长整数类型的原始电容值,「取样数」参数可用于增加传回值的分辨率,其代价是处理性能降低。传回的电容值并非取样数的平均,也不包含总电容量数。

capacitiveSensorRaw将传回-2,若电容值超过CS_Timeout_Millis(侦测超时)定义的毫秒值。CS_Timeout_Millis预设为2000毫秒(2秒)。

long capacitiveSensor(byte取样数)

capacitiveSensor将传回长整数类型的感应电容值,capacitiveSensor会纪录未感测到碰触时的最低电容值,并且用碰触时的电容量与之相减。

最低容量值每隔一段时间(由CS_Autocal_Millis定义)重新校正一次,预设校正间隔时间是200000毫秒(20秒)。此重新校正机制可透过设定一个很大的数值(0xFFFFFFFF)给CS_Autocal_Millis来关闭。

void set_CS_Timeout_Millis(unsigned long超时毫秒数)

set_CS_Timeout_Millis方法用于设定CS_Timeout_Millis的值,来设定等待感测端信号跟着发射端高、低变化的超时毫秒值。在等待感应脉冲变化之间,程序会暂停运作,所以必须设定超时,预设为2000毫秒(2秒)。

void reset_CS_AutoCal()

立即校正capacitiveSensor函式的电容值

void set_CS_AutocaL_Millis(unsigned long自定义校正的毫秒数)

设定capacitiveSensor函式超时间隔。给定”0xFFFFFFFF”数值可关闭自动校正功能。

触控LED开关

底下的程序将能在感测到使用者碰触时点亮LED,笔者设定的电容临界值是1500,请依照你的测试结果调整此值。

#include <CapacitiveSensor.h>

#define threshold 1500  // 感測電容量的臨界值
#define LED1 11         // LED1的腳位
#define LED2 12         // LED2的腳位
#define LED3 13         // LED3的腳位

// 設定電容觸控的訊號輸入和輸出腳位
CapacitiveSensor   cs_4_5 = CapacitiveSensor(4,5);
CapacitiveSensor   cs_4_6 = CapacitiveSensor(4,6);
CapacitiveSensor   cs_4_7 = CapacitiveSensor(4,7);

void setup() {
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  pinMode(LED3, OUTPUT);
}

void loop() {
    long total1 =  cs_4_5.capacitiveSensor(30);
    long total2 =  cs_4_6.capacitiveSensor(30);
    long total3 =  cs_4_7.capacitiveSensor(30);

    // 若第一個觸控點的電容量大於臨界值,則點亮LED。
    if (total1 > threshold) {
      digitalWrite(LED1, HIGH);
    } else {
      digitalWrite(LED1, LOW);
    }

    if (total2 > threshold) {
      digitalWrite(LED2, HIGH);
    } else {
      digitalWrite(LED2, LOW);
    }

    if (total3 > threshold) {
      digitalWrite(LED3, HIGH);
    } else {
      digitalWrite(LED3, LOW);
    }
}


坐沙发

发表评论