用arduino直接检测电容值:一个不用外围电路的简易触摸传感器

原文链接:http://www.geek-workshop.com/thread-3335-1-1.html


Arduino除了接受数字端口的数字信号,唯一能检测的模拟物理量就是电压。任何模拟传感器的检测值几乎都要通过相关电路转化成电压值,再输入 arduino的模拟端口进行模数转换。电容值就需要相对更复杂和昂贵的电路转化为电压值,才能被Arduino检测,而对很多物理过程的检测,都可以很 方便可靠地通过来检测电容值来实现,其中最常用的地方就是触摸传感器。风靡一时的MaKey MaKey就是个例子。这里介绍一个除了一段导线和一个端口,不需要任何元器件的电容检测方法。 这个方法的思路是,首先把一个数字端口设成低电位,并打开arduino的内部上拉电阻,开始计算这个端口到达高电位所需要的时间。而这个时间与此端口的 对地电容值有关,电容越大,时间越长。在硬件上只需要在一个端口上连一根导线即可。用手指触摸这段导线的裸露端,就会导致电容变化,arduino可以通 过上述方法检测这个变化。如果要增加灵敏度,可以在导线上连一片锡箔。为防止你手上有强静电击穿芯片,可以在锡箔上盖一薄层绝缘纸。
使用的代码如下。你可以方便地把它用到你的项目里。程序下载运行后,用手指触摸接在8号口的导线,就可以点亮9号口的led,手指离开,led熄灭。这个图上用的是板子上的13号灯。

View Code
 1 int ledPin = 9;
 2 int capval;
 3 void setup()
 4 {
 5 pinMode(ledPin, OUTPUT);
 6 Serial.begin(9600);
 7 Serial.println("Touch senser");
 8 }
 9  
10 void loop ()
11 {
12 digitalWrite(ledPin,LOW);
13 capval = readCapacitivePin(8);
14 Serial.println(capval, DEC);
15 if (capval > 2) { 
16 // turn LED on: 
17 digitalWrite(ledPin, HIGH); 
18 delay(10);
19 } 
20 }
21  
22 uint8_t readCapacitivePin(int pinToMeasure) {
23 // Variables used to translate from Arduino to AVR pin naming
24 volatile uint8_t* port;
25 volatile uint8_t* ddr;
26 volatile uint8_t* pin;
27 // Here we translate the input pin number from
28 // Arduino pin number to the AVR PORT, PIN, DDR,
29 // and which bit of those registers we care about.
30 byte bitmask;
31 port = portOutputRegister(digitalPinToPort(pinToMeasure));
32 ddr = portModeRegister(digitalPinToPort(pinToMeasure));
33 bitmask = digitalPinToBitMask(pinToMeasure);
34 pin = portInputRegister(digitalPinToPort(pinToMeasure));
35 // Discharge the pin first by setting it low and output
36 *port &= ~(bitmask);
37 *ddr |= bitmask;
38 delay(1);
39 // Make the pin an input with the internal pull-up on
40 *ddr &= ~(bitmask);
41 *port |= bitmask;
42  
43 // Now see how long the pin to get pulled up. This manual unrolling of the loop
44 // decreases the number of hardware cycles between each read of the pin,
45 // thus increasing sensitivity.
46 uint8_t cycles = 17;
47 if (*pin & bitmask) { cycles = 0;}
48 else if (*pin & bitmask) { cycles = 1;}
49 else if (*pin & bitmask) { cycles = 2;}
50 else if (*pin & bitmask) { cycles = 3;}
51 else if (*pin & bitmask) { cycles = 4;}
52 else if (*pin & bitmask) { cycles = 5;}
53 else if (*pin & bitmask) { cycles = 6;}
54 else if (*pin & bitmask) { cycles = 7;}
55 else if (*pin & bitmask) { cycles = 8;}
56 else if (*pin & bitmask) { cycles = 9;}
57 else if (*pin & bitmask) { cycles = 10;}
58 else if (*pin & bitmask) { cycles = 11;}
59 else if (*pin & bitmask) { cycles = 12;}
60 else if (*pin & bitmask) { cycles = 13;}
61 else if (*pin & bitmask) { cycles = 14;}
62 else if (*pin & bitmask) { cycles = 15;}
63 else if (*pin & bitmask) { cycles = 16;}
64  
65 // Discharge the pin again by setting it low and output
66 // It's important to leave the pins low if you want to 
67 // be able to touch more than 1 sensor at a time - if
68 // the sensor is left pulled high, when you touch
69 // two sensors, your body will transfer the charge between
70 // sensors.
71 *port &= ~(bitmask);
72 *ddr |= bitmask;
73  
74 return cycles;
75 }

这个主意不是我的原创,readCapacitivePin函数来自官网playground,我写了setup和loop来示范它的用法。

原文地址:https://www.cnblogs.com/catmelo/p/2913576.html