Arduinoで静電容量を測る

デジタルグッズ

*Arduino PlayGroundのCapacitive Sensing Libraryの私家版翻訳

概要

このCapacitiveSensor Libraryは2つもしくはそれ以上のピンを静電容量センサーにし、人体の静電容量を測定します。センサーのセットアップに必要なのは、100Kオームから数十Mオームの抵抗、結線と、端につけるる小さな (または大きな) アルミ ホイルだけです。
最も感度が高い場合、センサーはセンサーから数インチ離れた手や体を感知し始めます。

バージョン 04 では、Arduino 1.0 のサポートが追加され、発振(トーン)、サーボ、および割り込みなどを実行するその他のライブラリとの競合状態が修正されました。

バージョン 03 は C++ に更新され、複数の入力をサポートします。 また、タイムアウト値を変更するのに便利ないくつかのユーティリティ関数も含まれています。

適用業務

静電容量のセンシングは、人間が軽く、もしくはタッチしたことを感知します。Arduino とライブラリを使用して、1/4インチ(5mm???)以上のプラスチック、木材、セラミック、またはその他の絶縁材料 (金属ではありません) を通して人間の接触を感知し、センサーを視覚的に完全に隠すことができます。

紙またはその他の絶縁体で覆われた静電容量式センサーは、ほぼ対数数値のかなり良好な (人間の接触)センサーとして機能します。 この点で、アプリケーションによっては力で変化する抵抗感知センサーを凌駕する可能性があります。

動作原理

capacitySensorのメソッドは、マイクロコントローラーの送信ピンを新しい状態に切り替えてから、受信ピンが送信ピンと同じ状態に変化するのを待ちます。
while ループ内で変数がインクリメントされ、受信ピンの状態が変化するタイミングを計ります。次に、このメソッドは変数の値を任意の単位で報告します。

物理的なセットアップとして、送信ピンと受信 (センサー) ピンの間に中程度から高い値 (100Kオームから50Mオーム) の抵抗器をセットします。
受信ピンがセンサーとなります。 終端にホイルなどを付けてこのピンに接続された線は、優れたセンサーになります。
多くのアプリケーションでは、ユーザーが実際に金属箔に触れないように、センサーを紙、プラスチック、またはその他の絶縁材料で覆うと、より有用な値の範囲が得られます。
調査によると、センサー ピンとグランドの間に小さなコンデンサ (100 pF) 程度を接続すると、安定性と再現性が向上することが示されています。

送信ピンの状態が変化すると、受信ピンの状態も変化します。 送信ピンの変化と受信ピンの変化の間の遅延は、R * C で定義される RC 時定数によって決まります。
ここで、R は抵抗の値、C は受信ピンの静電容量とその他の静電容量 ( センサー (受信) ピンに存在します。
ボディ容量と並列に小さなコンデンサ (20 ~ 400 pF) を追加することも、検出された読み取り値を安定させるため、非常に望ましいことです。

ライブラリーのメソッド

このライブラリーは3つのメソッドといくつかのユーティリティメソッドをもちます。

CapacitiveSensor CapacitiveSensor(byte sendPin, byte receivePin)

CapacitiveSonsorメソッドはインスタンスを作ります。(大文字に注意してください。以下のメソッドとは異なります)

 


long capacitiveSensorRaw(byte samples)

capacitiveSensorRawはひとつのパラメーターが必要です。Long Integerの形式で静電容量の絶対ちを返します。
samplesパラメーターは返される値の解像度をあげるために使われます。しかし、上げるとパフォーマンスは下がります。
返される値は得たサンプルの平均値ではありません。トータルの値が返されます。

capacitiveSensorRawは、CS_Timeout_Millis(ミリ秒単位)の値を超えると、-2を返します。
CS_Timeout_Millisのデフォルト値は2000ミリ秒(2秒)です。


long capacitiveSensor(byte samples)

capacitySensorは1つのパラメーターが必要です。サンプル数です。任意の単位で追加された (検出された) 静電容量をlongの形式で返します。
capacitySensor は、最小のベースライン (未検出) 時の静電容量を追跡し、検出された静電容量からそれを差し引くため、検出されていない状態では低い値を示すはずです。

ベースライン値は、CS_Autocal_Millis によって決定される間隔で再調整(re-calibrate)されます。
デフォルト値は 200000 ミリ秒 (20 秒) です。
この再キャリブレーションは、set_CS_AutocaL_Millis() メソッドで CS_Autocal_Millis を高い値(“0xFFFFFFFF”)に設定することでオフにすることができます。


void set_CS_Timeout_Millis(unsigned long timeout_millis)

set_CS_Timeout_Millis メソッドを使用して CS_Timeout_Millis 値を設定できます。
この値は、受信 (センス) ピンが送信ピンと同じ方向に変化しない場合にメソッドがタイムアウトするまでの時間を決定します。
タイムアウトを指定しないと while ループがスケッチをロックしてしまうため、タイムアウトが必要です。
CS_Timeout_Millis のデフォルト値は 2000 ミリ秒 (2 秒) です。


void reset_CS_AutoCal()

reset_CS_AutoCalはcapacitiveSnsor機能のカリブレーションを即座にリセットします。


void set_CS_AutocaL_Millis(unsigned long autoCal_millis)

set_CS_Autocal_Millis(unsigned long autoCal_millis)はcapacitiveSensor機能のタイムアウト値として使われます。
リキャリブレーションはset_CS_Autocal_Millisに”0xFFFFFFFF”をセットするとオフにできます。

レジスターの選択

ここに抵抗のガイドラインをいくつか示しますが、必要な応答を必ず実験してください。

  • 絶対タッチを有効にするには、1 メガオーム (またはそれ以下) の抵抗を使用します。
  • 10 メガオームの抵抗器を使用すると、センサーは 10センチから15センチ離れた場所から応答を開始します。
  • 40 メガオームの抵抗器を使用すると、センサーは 30センチから60センチ離れたところから応答を開始します (ホイルのサイズによって異なります)。 一般的な抵抗は 10Mオーム程度なので、4 つの 10Mオームを直列にはんだ付けする必要がある場合があります。
  • 抵抗を大きくすることのトレードオフの 1 つは、センサーの感度が上がるとセンサーが遅くなることです。 また、センサーの金属が露出している場合、送信ピンが受信 (センサー) ピンの変更を強制できず、センサーがタイムアウトする可能性があります。
  • 小さなコンデンサ (100 pF ~ 0.01 uF) をセンス ピンのグラウンドに接続してみてください。 それらはセンサーの安定性を向上させます。

ハードウェアは、1 つの sPin(送信) と複数の抵抗器、つまり静電容量センサーへの rPin(受信) を使用してセットアップできます。サンプル スケッチを参照してください。

設置と他の既知の問題

静電容量センシングでは、Arduino ボードの接地が非常に重要です。 ボードは、水道管に接続されたワイヤなどの低インピーダンス パスとまでいかなくても、グランドに接続する必要があります。

静電容量センシングには、主電源に接続されていないラップトップでの癖があります。 ラップトップ自体は敏感になる傾向があり、ラップトップに手を近づけると返される値が変化します。

通常、電源コードをラップトップに接続するだけで正常に動作します。 Arduino のアースをアース (水道管など) に接続することも、別の解決策になる可能性があります。

少なくとも 1 つの設置でうまく機能したと思われる別の解決策は、センサー フォイル (プラスチック、紙などで絶縁) の下にフォイル グランド プレーンを敷設し、ワイヤでグランドに接続することです。 これは、センサー値を安定させるのに非常にうまく機能し、センサーの感度も劇的に向上したようです。

輪を回す

スライド ポット タイプのリニア センサーを使用した実験は、わずか 2 つのピンと抵抗をラダーにすることで成功しています。 基本的なレイアウトは、Quantum Scrollwheel センサーのデータシートに示されています。

この方法のコードは

CapacitiveSensor Left32  = CapacitiveSensor(3, 2); // wire from pin 2 to left side of resistor ladder\
CapacitiveSensor Right23 = CapacitiveSensor(2, 3); // wire from pin 3 to right side of resistor ladder

ここでピンが送信位置と受信位置を切り替えています。線形抵抗ラダーでは、送信ピンに指を近づけると低い値を報告します。
これは、静電容量より下の抵抗は基本的に回路の外にあるためです。

このように、指が 1 つのピンから別のピンに移動すると、capacitiveSensorRaw への 2 つの呼び出しは、ほぼ一定の値を持つ相補的な値を報告します。 複雑なのは、どれだけの接触 (容量) が存在するかを処理しようとするときに発生します。これにより、両方の値が上昇 (または低下) しますが、必ずしも線形ではありません。

エラーメッセージ

capacitySensor と capacitySensorRaw は、無効なピン パラメーターの選択で -1 を返しますが、この記事の執筆時点では、この機能は機能していないようです。

メソッドがタイムアウトした場合、capacitiveSensor と capacitySensorRaw は -2 を返します。 これは、デフォルト値の 2000 ミリ秒 (2 秒) に設定されている CS_Timeout_Millis の値を超えるカウントが原因です。 これは、ほとんどの場合、抵抗器の欠落または間違ったピンの抵抗器によって引き起こされます。 また、センサーが接地されているか、+5 V に接続されていることが原因である可能性もあります。

たとえば、sendPin と receivePin の間の抵抗器が切断された場合、CapacitiveSensor メソッドでタイミングを実行する while ループがスケッチをロックアップする (関数が戻らない) ため、タイムアウトが必要です。

デモスケッチ

#include <CapacitiveSensor.h>
/*
 * CapitiveSense Library Demo Sketch
 * Paul Badger 2008
 * Uses a high value resistor e.g. 10 megohm between send pin and receive pin
 * Resistor effects sensitivity, experiment with values, 50 kilohm - 50 megohm. Larger resistor values yield larger sensor values.
 * Receive pin is the sensor pin - try different amounts of foil/metal on this pin
 * Best results are obtained if sensor foil and wire is covered with an insulator such as paper or plastic sheet
 */

CapacitiveSensor   cs_4_2 = CapacitiveSensor(4,2); // 10 Mohm resistor between pins 4 & 2, pin 2 is sensor pin, add wire, foil
CapacitiveSensor   cs_4_5 = CapacitiveSensor(4,5); // 10 Mohm resistor between pins 4 & 6, pin 6 is sensor pin, add wire, foil
CapacitiveSensor   cs_4_8 = CapacitiveSensor(4,8); // 10 Mohm resistor between pins 4 & 8, pin 8 is sensor pin, add wire, foil

void setup()                    
{
   cs_4_2.set_CS_AutocaL_Millis(0xFFFFFFFF);     // turn off autocalibrate on channel 1 - just as an example
   Serial.begin(9600);
}

void loop()                    
{
    long start = millis();
    long total1 =  cs_4_2.capacitiveSensor(30);
    long total2 =  cs_4_5.capacitiveSensor(30);
    long total3 =  cs_4_8.capacitiveSensor(30);

    Serial.print(millis() - start);        // check on performance in milliseconds
    Serial.print("\t");                    // tab character for debug window spacing

    Serial.print(total1);                  // print sensor output 1
    Serial.print("\t");
    Serial.print(total2);                  // print sensor output 2
    Serial.print("\t");
    Serial.println(total3);                // print sensor output 3

    delay(10);                             // arbitrary delay to limit data to serial port 
}

もっとシンプルな例

(これはDigiKeyの記事です)

#include <CapacitiveSensor.h>

CapacitiveSensor sensor = CapacitiveSensor(2,12); void setup() { Serial.begin(9600); // Disable the automatic re-calibration feature of the // capacitive sensor library sensor.set_CS_AutocaL_Millis(0xFFFFFFFF); } void loop() { long current_millis = millis(); long capacitance = sensor.capacitiveSensor(30); // Print the result of the sensor reading // Note that the capacitance value is an arbitrary number // See: https://playground.arduino.cc/Main/CapacitiveSensor/ for details Serial.println(capacitance); // Wait for 50 milliseconds while(millis() - current_millis < 50); }