zoukankan      html  css  js  c++  java
  • 用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来示范它的用法。

  • 相关阅读:
    Leetcode 811. Subdomain Visit Count
    Leetcode 70. Climbing Stairs
    Leetcode 509. Fibonacci Number
    Leetcode 771. Jewels and Stones
    Leetcode 217. Contains Duplicate
    MYSQL安装第三步报错
    .net 开发WEB程序
    JDK版本问题
    打开ECLIPSE 报failed to load the jni shared library
    ANSI_NULLS SQL语句
  • 原文地址:https://www.cnblogs.com/catmelo/p/2913576.html
Copyright © 2011-2022 走看看