ESPr Developerで人感センサを使ってみる(2)

先日、人感センサについての記事を書きました。

工場の製造装置に人感センサを設置して、装置の前に人がいること(≒段取り時間)を検知することを目標としているのですが、まずは実験で、ESPr Developer と人感センサを接続したデバイスを、家のテレビの前に設置して、子供がテレビを見ている時間を確認しようとしました。


実験の結果、一応検知はできるのですが、以下の2点が気になりました。

(1) 少しの動きでは検知できない

人が検知エリアに入ってきたときには検知できますが、少し手を動かした程度では検知できないことが多いため、テレビの前に座ってしばらくすると、座ったままの状態でも、頻繁にOFFになってしまいます。

(2) 遠くにいる人の動きも検知してしまう

センサから5〜6m離れた場所でも、人が動けば結構な頻度でONになってしまいます。

本来は、子供がテレビの前に座っていれば常にON、となりの部屋にいれば常にOFF、となるのが理想的ですが、そのような分かりやすい結果にはなりませんでした。

これらの問題に対して、プログラムで対処することも考えられますが、今回は別の人感センサを試してみることにしました。

これまで使っていたのは、パナソニックの「焦電型赤外線人感センサ PaPIRs」のうち、普及タイプの標準検出型である「EKMC1601111」です。
今回、高機能タイプの微動検出型である「AMN32112」を追加で購入し、比較してみました。

ふたつのセンサの仕様を比較した結果は、以下のとおりです。「AMN32112」は「EKMC1601111」に比べ、検出距離が短い一方、より小さいものがゆっくり動いても検出できるということで、今回の問題への対策としては、ぴったりのようです。

検出距離 移動スピード 検出対象サイズ
EKMC1601111 5m 1.0m/s 700x250mm
AMN32112 2m 0.5m/s 200x200mm

回路構成は以下のとおりです。2種類の人感センサをひとつのESPr Developerに接続し、両者を同じように処理します。

回路は今回もブレッドボードで組みました。こんな感じです。

スケッチは以下のような感じになりました。先日勉強した、割り込み処理を使いました。
センサが人を検知すると、その情報を30秒保持します。その間に再び人を検知すると、さらに30秒保持します。その期間はLEDを点灯します。
45秒毎に、検知情報をWebサーバに送信します。
送信したデータをWebプログラムで観測することで、ふたつのセンサが人をどのように検出したかを確認します。

// WiFi接続等のための各種設定(省略)

#include <Ticker.h>
Ticker ticker1;
Ticker ticker2;

volatile boolean state1 = false;
volatile boolean state2 = false;

#define SENSOR1 14
#define SENSOR2 12
#define LED1 5
#define LED2 4

void onDetected1() {
  if(state1) {
    ticker1.detach();
    ticker1.attach(30, onTimer1);
  } else {
    ticker1.attach(30, onTimer1);
    digitalWrite(LED1, HIGH);
    state1 = true;
  }
}

void onDetected2() {
  if(state2) {
    ticker2.detach();
    ticker2.attach(30, onTimer2);
  } else {
    ticker2.attach(30, onTimer2);
    digitalWrite(LED2, HIGH);
    state2 = true;
  }
}

void onTimer1() {
  ticker1.detach();
  digitalWrite(LED1, LOW);
  state1 = false;
}

void onTimer2() {
  ticker2.detach();
  digitalWrite(LED2, LOW);
  state2 = false;
}

void setup() {
  // WiFi接続等のための設定(省略)

  pinMode(SENSOR1, INPUT);
  pinMode(SENSOR2, INPUT);
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  attachInterrupt(digitalPinToInterrupt(SENSOR1), onDetected1, RISING);
  attachInterrupt(digitalPinToInterrupt(SENSOR2), onDetected2, RISING);
  digitalWrite(LED1, LOW);
  digitalWrite(LED2, LOW);
}

void loop() {
  delay(45000);
  sendRequest(state1, state2);
}

int sendRequest(boolean state1, boolean state2) {
  // データをWebサーバに送信する(省略)
}

これで動作確認してみたところ、結果は以下のようになりました。

この表は、1日分のセンサ検出結果を、1分間隔で一覧表示したもので、ONならば赤または緑、OFFならばグレイになっています。また、赤は「EKMC1601111(普及タイプ)」、緑は「AMN32112(高機能タイプ)」の結果です。両者の結果を上下に並べていますので、それらを見比べることで、両者の検出状況の違いが把握できます。

表を見ると分かるように、両者の検出結果に、それほど大きな違いはありませんでした。値段がそこそこ違う(「EKMC1601111」が432円、「AMN32112」が1151円。いずれもパナソニックのページにて)のですが、今回の用途では、それに見合うほどの差は見当たらないようです。

やはり、普及タイプをもっと使いこなす方法を、もう少し考えようと思います。