|
Arduino除了接受數(shù)字端口的數(shù)字信號(hào),唯一能檢測(cè)的模擬物理量就是電壓。任何模擬傳感器的檢測(cè)值幾乎都是通過相關(guān)電路轉(zhuǎn)化成電壓值,再輸入它的模擬端口進(jìn)行模數(shù)轉(zhuǎn)換的。電容值就需要相對(duì)更復(fù)雜和昂貴的電路轉(zhuǎn)化為電壓值,才能被Arduino檢測(cè),而對(duì)很多物理過程的檢測(cè),都可以很方便可靠地通過檢測(cè)電容值來實(shí)現(xiàn),其中最常用的地方就是觸摸傳感器。現(xiàn)在,創(chuàng)客集結(jié)號(hào)為大家介紹一個(gè)除了一段導(dǎo)線和一個(gè)端口,不需要任何元器件的電容檢測(cè)方法。
簡易觸摸傳感器.jpg (23.32 KB, 下載次數(shù): 84)
下載附件
xk100com
2018-7-31 09:54 上傳
這個(gè)方法的思路是,首先把一個(gè)數(shù)字端口設(shè)成低電位,并打開arduino的內(nèi)部上拉電阻,開始計(jì)算這個(gè)端口到達(dá)高電位所需要的時(shí)間。而這個(gè)時(shí)間與此端口的對(duì)地電容值有關(guān),電容越大,時(shí)間越長。在硬件上只需要在一個(gè)端口上連一根導(dǎo)線即可。用手指觸摸這段導(dǎo)線的裸露端,就會(huì)導(dǎo)致電容變化,arduino可以通過上述方法檢測(cè)這個(gè)變化。如果要增加靈敏度,可以在導(dǎo)線上連一片錫箔。為防止你手上有強(qiáng)靜電擊穿芯片,可以在錫箔上蓋一層薄紙。
使用的代碼如下:
int ledPin = 9;
int capval;
void setup()
{
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
Serial.println("Touch senser");
}
void loop ()
{
digitalWrite(ledPin,LOW);
capval = readCapacitivePin(8);
Serial.println(capval, DEC);
if (capval > 2) {
// turn LED on:
digitalWrite(ledPin, HIGH);
delay(10);
}
}
// readCapacitivePin
// Input: Arduino pin number
// Output: A number, from 0 to 17 expressing
// how much capacitance is on the pin
// When you touch the pin, or whatever you have
// attached to it, the number will get higher
#include "pins_arduino.h" // Arduino pre-1.0 needs this
uint8_t readCapacitivePin(int pinToMeasure) {
// Variables used to translate from Arduino to AVR pin naming
volatile uint8_t* port;
volatile uint8_t* ddr;
volatile uint8_t* pin;
// Here we translate the input pin number from
// Arduino pin number to the AVR PORT, PIN, DDR,
// and which bit of those registers we care about.
byte bitmask;
port = portOutputRegister(digitalPinToPort(pinToMeasure));
ddr = portModeRegister(digitalPinToPort(pinToMeasure));
bitmask = digitalPinToBitMask(pinToMeasure);
pin = portInputRegister(digitalPinToPort(pinToMeasure));
// Discharge the pin first by setting it low and output
*port &= ~(bitmask);
*ddr |= bitmask;
delay(1);
uint8_t SREG_old = SREG; //back up the AVR Status Register
// Prevent the timer IRQ from disturbing our measurement
noInterrupts();
// Make the pin an input with the internal pull-up on
*ddr &= ~(bitmask);
*port |= bitmask;
// Now see how long the pin to get pulled up. This manual unrolling of the loop
// decreases the number of hardware cycles between each read of the pin,
// thus increasing sensitivity.
uint8_t cycles = 17;
if (*pin & bitmask) { cycles = 0;}
else if (*pin & bitmask) { cycles = 1;}
else if (*pin & bitmask) { cycles = 2;}
else if (*pin & bitmask) { cycles = 3;}
else if (*pin & bitmask) { cycles = 4;}
else if (*pin & bitmask) { cycles = 5;}
else if (*pin & bitmask) { cycles = 6;}
else if (*pin & bitmask) { cycles = 7;}
else if (*pin & bitmask) { cycles = 8;}
else if (*pin & bitmask) { cycles = 9;}
else if (*pin & bitmask) { cycles = 10;}
else if (*pin & bitmask) { cycles = 11;}
else if (*pin & bitmask) { cycles = 12;}
else if (*pin & bitmask) { cycles = 13;}
else if (*pin & bitmask) { cycles = 14;}
else if (*pin & bitmask) { cycles = 15;}
else if (*pin & bitmask) { cycles = 16;}
// End of timing-critical section; turn interrupts back on if they were on before, or leave them off if
they were off before
SREG = SREG_old;
// Discharge the pin again by setting it low and output
// It's important to leave the pins low if you want to
// be able to touch more than 1 sensor at a time - if
// the sensor is left pulled high, when you touch
// two sensors, your body will transfer the charge between
// sensors.
*port &= ~(bitmask);
*ddr |= bitmask;
return cycles;
}
若想學(xué)習(xí)更多arduino項(xiàng)目教程,可以搜索創(chuàng)客集結(jié)號(hào)或xk100。
|
|