Arduino日本語リファレンス


by Paul Badger

Arduinoの複数のピンを使って静電容量センサを実現するライブラリです。数インチ離れた人間の手や体を検出することができます。必要な部品は10MΩの抵抗器とアルミホイルのような一片の金属だけです。

Version 04はArduino 1.0に対応し、ToneやServoライブラリのような、割り込みに影響を受ける他の機能との競合が改善されています。

Version 03はC++に対応し、複数の入力をサポートしています。また、タイムアウト値を変更する便利な機能を含んでいます。

CapSense04.zipとCapacitiveSense003.zipは次のURLからダウンロードできます。
http://arduino.cc/playground/uploads/Main/CapSense04.zip
http://www.arduino.cc/playground/uploads/Main/CapacitiveSense003.zip


【アプリケーション】

静電容量センサを使うとタッチセンシングが可能になります。Arduinoとこのライブラリによって、1/4インチ以上の厚さのプラスチック、木、セラミックなどを通してタッチを検出でき、センサを完全に隠蔽することができます。
センサを紙のような絶縁物で覆うことで、おおむね対数的な反応を示す圧力センサとなります。用途によっては、抵抗式の圧力センサよりも良い結果が得られるでしょう。


【動作原理】

capSenseメソッドは、まずマイコンの送信ピンの状態を変更し、それから受信ピンの状態がそれに一致するまで待ちます。ループ内で変数をインクリメントすることで、受信ピンが変化するまでの時間を記録し、それを報告します。単位は任意です。



ハードウエア的に必要なのは、送信ピンと受信ピンの間に接続する、大きな値(100K〜50MΩ)の抵抗器です。受信ピンがセンサの端子となります。アルミホイルをこのピンに接続すると、良いセンサになるでしょう。多くの場合、ユーザーが金属部分に直接触れないよう、ホイルを紙やプラスチックなどの絶縁材で覆ったほうが、扱いやすい範囲の値が得られます。

送信ピンの状態が変化すると、少し時間をおいてから受信ピンの状態が変化します。この2つのピンの間の遅延は時定数と呼ばれ、R*Cで表されます。このとき、Rは抵抗値、Cは受信ピン側の様々なキャパシタンスの計です。20〜400pF程度のコンデンサを人体のキャパシタンスに対して並列になるよう加えることで、センサの安定性が向上します。

【メソッド】

このライブラリは3つの主要なメソッドと、いくつかのユーティリティメソッドを持っています。

CapSense CapSense(byte sendPin, byte receivePin)

sendPin - 送信ピンの番号
receivePin - 受信ピンの番号

インスタンスを生成します。名前が大文字で始まる点に注意してください。後述するcapSenseとは別のものです。

long capSenseRaw(byte samples)

capSenseRawはサンプリングを行い、結果をlongで返します。この値はキャパシタンスの絶対値で、単位は任意です。引数samplesを増やすと、分解能が向上しますが、実行に必要な時間も増加します。戻り値は平均ではなく、合計です。

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

long capSense(byte samples)

capSenseはサンプリングを行って、キャパシタンスの増分をlongで返します。単位は任意です。
capSenseはセンサがなにも検出していない状態の値をベースラインとして保持し、現在のキャパシタンスから引いた値を返します。なにも検出していない状態で、値は最低になります。

ベースラインはCS_Autocal_Millisで指定された周期で再調整(リキャリブレート)されます。この値のデフォルトは20000ミリ秒(20秒)です。

void set_CS_Timeout_Millis(unsigned long timeout_millis)

このメソッドはCS_Timeout_Millisの値を設定します。受信ピンが送信ピンと同じ状態に変化するまで、最大何ミリ秒待つかを決定します。時間切れにならないと、whileループ内で実行したときに処理が止まってしまうためです。デフォルトの値は2000です。

void reset_CS_AutoCal()

キャリブレーションを直ちに実行します。

void set_CS_AutocaL_Millis(unsigned long autoCal_millis)

capSenseのタイムアウトを設定します。"0xFFFFFFFF"に設定すると、リキャリブレーションが行われなくなります。


【抵抗値の選択】

抵抗の選び方のガイドラインを示します。ただし、希望の動作を得るためには、実験して確かめるようにしましょう。

・1MΩ (あるいはそれ未満)
 完全にタッチしたときに有効になる

・10MΩ
 4〜6インチの距離から反応しはじめる。

・40MΩ (10MΩ以上は入手しにくいので直列につなぐ)
 12〜24インチの距離から反応しはじめる

唯一のトレードオフは、感度を上げるとそれだけ遅くなる点です。露出した金属をセンサにしている場合、いつまでも受信ピンの状態が変化せず、タイムアウトになってしまう可能性があります。


【接地】

静電容量センサを試すときは、Arduinoボードを接地(grounding)することが重要です。水道管のようにローインピーダンスではないとしても、何かしらのグランドが必要です。
ノートPCの電源ケーブルをコンセントに接続するだけでも普通はじゅうぶんうまく機能します。センサ用のアルミホイルの下側に紙やプラスチックで絶縁したホイルを敷いてグランドプレーンとし、ArduinoのGNDに接続する方法もあります。これによりセンサからの値が安定し、感度がよくなります。


【スクロールホイール】

スライド抵抗型のリニアなセンサはわずか2本のピンとラダー抵抗(ここでは直列に接続された複数の抵抗器)によって実現できます。基本的なレイアウトについてはQuantum Scroll Wheelのデータシートを参照してください。

コードは次のような構成になります。

CapSense Left32  = CapSense(3, 2); // 抵抗のラダーの左端をピン2へ
CapSense Right23 = CapSense(2, 3); // 抵抗のラダーの右端をピン3へ

2本のピンの間で送受信の向きを切り替えます。リニアな抵抗ラダーの効果で、指が送信ピンに近いほど小さな値を返します。2本のピンの間で指が動いていても、両方のピンがcapSenseRawを実行することで、相補的な値が得られます。それはおおむね一定ですが、接触の度合いによって値の大きさが変わるので、タッチの強さを知ることができます。


【エラーメッセージ】

capSenseとcapSenseRawは、パラメータのピン番号が不適切な場合-1を返します。※この仕様は現在機能していません
capSenseとcapSenseRawは、タイムアウトのとき-2を返します。タイムアウトはCS_Timeout_Millis(デフォルトでは2秒)を超えたときに発生します。このエラーは抵抗の値を間違えたり、設定と違うピンに抵抗がつながっているときによく起きます。センサが+5VやGNDに接触しているときにも生じるかもしれません。


【例】

#include <CapSense.h>

/*
 * CapitiveSense Library Demo Sketch
 * Paul Badger 2008
 * 10MΩくらいの抵抗器を用います。
 * 抵抗値は感度に影響します。50K〜50MΩで実験しました。
 * 抵抗値が大きくなるほど、返ってくる値も大きくなります。
 * Receive pinがsensor pinです。いろいろな大きさのアルミ
 * ホイルや金属片を試してみましょう。センサとなる金属を
 * 紙やプラスチックシートなどでくるむと良い結果が得られます。
 */


CapSense   cs_4_2 = CapSense(4,2);  // ピン4-2間に10MΩ、ピン2にアルミホイル
CapSense   cs_4_5 = CapSense(4,6);
CapSense   cs_4_8 = CapSense(4,8);

void setup() {
   // cs_4_2.set_CS_AutocaL_Millis(0xFFFFFFFF);  // 自動キャリブレーションをオフ
   Serial.begin(9600);
}

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

    Serial.print(millis() - start);
    Serial.print("\t");

    Serial.print(total1);    // ひとつめのセンサの値
    Serial.print("\t");
    Serial.print(total2);
    Serial.print("\t");
    Serial.println(total3);

    delay(10);
}



[目次へ戻る]

Creative Commons Attribution-ShareAlike 3.0 License.
このドキュメントはArduino Teamにより執筆され、Takumi Funadaが翻訳し、一部加筆修正したものです
ご意見はtf at musashinodenpa.comまでお送りください [ドキュメント一覧]