人感センサというものを買ったので、ESPr Developer につないで動作を確認してみようと思います。
将来的には、例えば、工場の製造装置に人感センサを設置して、装置の前に人がいること(≒段取り時間)を検知できれば、と思っていますが、まずは実験で、家のテレビの前にでも設置して、子供がテレビを見ている時間でも確認しようと思います。
購入したのは、パナソニックの「焦電型赤外線人感センサ PaPIRs」です。人体から放出される熱エネルギーの変化を検出するもので、人がいても、動きがほとんどない時は検出できないようです。
PaPIRsにはいくつかのラインアップがありますが、今回使うのは、最も一般的だと思われる「EKMC1601111(普及タイプの標準検出型)」です。
これをESPr Developerにつなぎ、人を検出したときにLEDを光らせようと思います。
人感センサにはVDD, OUT, GNDの3つのピンがあります。
この人感センサの動作電圧は3V〜7Vなので、ESPr Developerの出力電源(3.3V)を使うことができます。このため、VDDピンをESPr Developerの3V3ピンへ、GNDピンをESPr DeveloperのGNDピンへつなぎます。
この人感センサはデジタル出力で、人を検知するとOUTがHighになります。なお、プルダウン抵抗が必要なので、OUTピンとGNDの間に10kΩの抵抗をつないだ上で、OUTピンとESPr Developerの信号入力ピンをつなぎます。
本来はこのようにつなげば良いのですが、今回は、ESPr Developerと8chのADコンバータをつなぎ、8つのアナログ信号を取り込めるようにした回路(ブレッドボード)を既に作っていましたので、このうちの1chに人感センサをつなぐことにしました。よって、人感センサの出力するデジタル信号を、アナログ信号としてESPr Developerに取り込むことになります。
また、ESPr Developerの5番ピンとGNDの間に、LEDと330Ωの抵抗を直列につなぎます。人を検出したときには、このLEDを光らせます。
スケッチは以下のような感じになります。0.5秒毎に人感センサのデータを取り込み、それがHighであればLEDを点灯、そうでなければ消灯させます。また、データを90回取り込む毎に、その時のデータをWebサーバに送信します。
送信したデータをWebプログラムで観測することで、人がどのくらいの期間、そこにいたかを確認できます。
int count=0; // WiFi接続や、ADコンバータとの通信のための各種設定(省略) void setup() { pinMode(5, OUTPUT); // WiFi接続や、ADコンバータとの通信のための設定(省略) } void loop() { uint32 val0 = check(0); // 人感センサのデータを取り込み if(val0 > 511) { digitalWrite(5, HIGH); } else { digitalWrite(5, LOW); } count++; if(count>=90){ sendRequest(val0) count=0; } delay(500); } int sendRequest(int val0) { // データをWebサーバに送信する(省略) } uint32 check(int channel) { // ADコンバータのデータを取り出す(省略) }
これで動作確認してみました。
自分から50cmぐらい離れたところに人感センサを置き、パソコン作業をしているときの検知状況を確認したところ、センサに手をかざしたりすると、もちろんLEDが点灯しますが、キーボードをタイプしている程度では、頻繁にLEDが消灯してしまいます。
思ったよりもセンサの感度が悪く、これでは、テレビの前に座っている子供を検知できそうにはありません。
センサ本体には感度を調整する機能はないので、センサのラインアップをもう少し調べてみました。
パナソニックの「PaPIRs」には、以下のラインアップがあります。
- EKMC(VZ)シリーズ:普及タイプ(デジタル出力)
- 標準検出型、長距離検出型、壁取付型、広角検出型
- EKMB(WL)シリーズ:低消費電流タイプ(デジタル出力)
- 標準検出型、長距離検出型、壁取付型、広角検出型
- AMN(NaPiOn)シリーズ:高機能タイプ(デジタル、およびアナログ出力)
- 標準検出型、微動検出型、スポット検出型、10m検出型
今回使ったのは、EKMC(VZ)シリーズ(標準検出型)です。AMN(NaPiOn)シリーズ(微動検出型)などを使えば、もっと動きが少なくても、人を検知できるのかもしれません。
と、いろいろ調べているうちに、ひとつ思いつきました。
テレビを見ている子供であろうが、装置の段取り中の作業者だろうが、人がいれば、少なくとも1分に1度ぐらいは、センサが検知する程度には動くのではないか? そうであれば、90回に1度、データをWebサーバに送信する際に、その期間のデータの最大値を送信すればいいのではないか?と考えました。
そうすれば、90回のうち1回でも人を検知すれば、Webサーバには「人がいる」というデータが送られることになります。
スケッチを以下のように修正しました。
int count=0; int vmax=0; // WiFi接続や、ADコンバータとの通信のための各種設定(省略) void setup() { pinMode(5, OUTPUT); // WiFi接続や、ADコンバータとの通信のための設定(省略) } void loop() { uint32 val0 = check(0); // 人感センサのデータを取り込み if(val0 > 511) { digitalWrite(5, HIGH); } else { digitalWrite(5, LOW); } count++; if(val0>vmax) { vmax=val0; } if(count>=90){ sendRequest(vmax) count=0; vmax=0; } delay(500); } int sendRequest(int val0) { // データをWebサーバに送信する(省略) } uint32 check(int channel) { // ADコンバータのデータを取り出す(省略) }
この回路を、子供がいる場所の近くに設置しました。
これで、しばらく動作確認しようと思います。