Arduino除了接受數字端口的數字信號,唯一能檢測的模擬物理量就是電壓。任何模擬傳感器的檢測值幾乎都是通過相關電路轉化成電壓值,再輸入它的模擬端口進行模數轉換的。電容值就需要相對更復雜和昂貴的電路轉化為電壓值,才能被Arduino檢測,而對很多物理過程的檢測,都可以很方便可靠地通過檢測電容值來實現,其中最常用的地方就是觸摸傳感器。現在,創客集結號為大家介紹一個除了一段導線和一個端口,不需要任何元器件的電容檢測方法。
簡易觸摸傳感器.jpg (23.32 KB, 下載次數: 84)
下載附件
xk100com
2018-7-31 09:54 上傳
這個方法的思路是,首先把一個數字端口設成低電位,并打開arduino的內部上拉電阻,開始計算這個端口到達高電位所需要的時間。而這個時間與此端口的對地電容值有關,電容越大,時間越長。在硬件上只需要在一個端口上連一根導線即可。用手指觸摸這段導線的裸露端,就會導致電容變化,arduino可以通過上述方法檢測這個變化。如果要增加靈敏度,可以在導線上連一片錫箔。為防止你手上有強靜電擊穿芯片,可以在錫箔上蓋一層薄紙。
使用的代碼如下:
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;
}
若想學習更多arduino項目教程,可以搜索創客集結號或xk100。
|