人感センサ(Motion Sensor)の実験を行って見ました

〔マイコンのトップに戻る〕


MyHPのリンク切れを見直している時に、おやぁ?、
人感センサの記事が無いぞぉっと気付いてしまいました。
こっこれはぁ、取り合えずぅ記事にして置かねばああっと使命感に燃えた次第です。<(`^´)>
(なぁ〜んて、大げさな、検出時にHIGH/LOW出力される信号を受けるだけなので大した記事ではない
 のですがぁ)

人を感じるセンサーとして色々有りそうですが、ここでは焦電型赤外線センサードップラーセンサー
について記述して置きます。


焦電型赤外線センサー

人や動物は熱エネルギーを放射しています、この放出される熱エネルギーは赤外線です、
その赤外線を焦電素子で受けると、その熱エネルギーによって電荷が生じます。
この現象を「焦電効果」と言いこの焦電効果を利用したセンサーです。
なので、このセンサーは人がいる・いないの判断に使用出来ます。
焦電型赤外線センサー
左図は、秋月電子通商のこちらの図を拝借しました。

電源は5V〜20Vで、検出時はHIGH(3V)出力です。
HIGHの出力時間は8秒〜15分で半固定抵抗調整可能
検知距離は最大7m、半固定抵抗で調整出来ます。

但し、出力電流は10mA程しかないのでリレー等に
接続する場合はTR/FETで受ける必要が有ります。
マイコンにはそのまま接続でも良いでしょう。

電源が3.3Vが良いならこちらを、CDS付きです。
小型が良いならこちら(検知距離2m)辺りでしょうか。

尚、この焦電型センサータイプは電源を入れてから検知が安定するまで1分程掛かります。
又、センサーモジュールによっては出力時間の調整が出来ない物も有ります、
この場合はマイコンで受けて出力時間の調整プログラムを記述すれば良いのですがぁ、
マイコンで受ける時も調整可能なモジュールを使った方がプログラムが簡単になるのでお勧めかもね。

焦電型センサーは手元にないので手に入れたらArduino辺りで記事にしたいと思います。

CDSの話はArduinoでの記事ですが、"CDS光センサーを付けて暗くなったらLEDを点灯させます"を
参考にして下さい。

ドップラーセンサー

このセンサーは発信器からマイクロ波を発射して物体(人間)に当てて反射して来た電波の周波数と
発射した電波の周波数を比較する事により物体の動きを検出する物です。
物体が移動していると「ドップラ効果」により反射波の周波数が変わるので物体の動きを知る事が可能
となります。なので、このセンサーは人が近づいている・離れているが検出出来ます。
ドップラーセンサー
左図は、秋月電子通商のこちらの図を拝借しました。

このセンサーは、新日本無線 NJR4265 J1 を
使用していて、センサーの電波は24GHzで、
電波法には適合しています。
電源は3.3/5Vで、検知距離は最大10mです。
センサーはアナログ出力とUARTによるデジタル入出力
が有ります。

アナログ出力は、検出時はHIGH出力で
出力電流は5mAです。
UART通信によりスリープモードへの移行や
設定の変更等が出来る様です。

又、電波なのでセンサー部を隠蔽出来、人や動物以外も検出可能です。

ここでの記事はこのドップラーセンサーを使った内容となります。
ドップラーセンサーのデータシートは秋月電子通商のこちらからダウンロードしましょう。
尚、データシートが日本語なのでモジュールの詳しい説明は省きます。

あ、そうそう、モジュールのピン間隔1.27mmピッチで2.54mmに変換する為に半田付けが必要ですがぁ
図の様に下駄状にするのってぇとっても難しいです、こちらの方が幾分か良いかも?ちょっとお高いがぁ
但し、モジュールのTxD/RxDはUSB側に配線されているので、外部に出す場合はパターンカットを行う
必要が有ります。

《実験1:アナログ出力》


ドップラーセンサ端子配列図  A TxD:UARTの送信
 B RxD:UARTの受信
 C 閾値設定(VDD=99.9m)
 D 検知[接近](最大供給可能電流=5mA )
 E 検知[離反](最大供給可能電流=5mA )
 F VDD(3.3/5.0V)
 J GND
 その他は、、電気的なフローティング(非接続)として、
 GHI同士も接続しない。

アナログ出力配線図  左が実態配線図です、
 左の番号と上の端子図の番号同士を接続します。
 電源は5Vですが、3.3Vでも動作はします。

 半固定抵抗は、左回しで99.9m、右回しで0mと調整出来ます。

 近づいて来る間は赤LEDが点灯し、離れて行く間は橙LEDが点灯です
 移動中は点灯しっぱなし、止まればLEDが消灯します。
 検知した場合は赤LEDが1秒間ほど点灯します。

 出力にリレーを繋ぎたい場合はFETを介して下さい。
 詳しくはこちらの取扱説明書を見ましょう。


《実験2:UART通信》

次はUART通信でモジュールとマイコン(Arduino/PIC)を接続して見ます。
通信パラメータは、9600bps,8ビットデータの1ストップ,パリティは奇数(odd),フロー制御なしです。
(通信パラメータは通常はパリティ無しですが、このモジュールはパリティが有ります注意しましょう)

モジュールのABFJのみ配線します、Cの閾値はUARTで設定します、
DEの出力は配線しても良いのですがここではマイコンの端子からLEDを接続する事にします。

(Arduino)

Arduinoの”SoftwareSerial ”はパリティの変更が出来ないので使えません、でぇハードウェアシリアルを
利用する事になります。

"Arduino UNO(Duemilanove 328)"については、0番と1番端子がハードウェアシリアルですので
"Seria.begin( )"関数で利用可能ですがぁ実験を行った所動作しませんでした。
この0番と1番端子はUSB側にも配線されているのでその辺りで上手く動作しないと思われます。

でぇ、0番と1番端子がUSBと繋がっていないArduinoは私の手持ちでは"Arduino Zero Pro"のみです、
これで実験を行った結果動作しました、なのでぇ、以下の記事は"Arduino Zero(M0) Pro"となります。

尚、"Arduino UNO(Duemilanove 328)"で行いたい場合は、モジュールのDE端子からデジタル入力で
そのまま受ければ良いでしょう。

Arduino実態配線図
 左が実態配線図で、"Arduino UNO"と
 なっているが"Arduino Zero Pro"での
 配線とします。

 電源は"Arduino Zero Pro"が3.3Vなので
 回路全体は3.3V電源としました。

 左の赤丸番号はモジュールの番号です。

 赤LEDが、[接近]確認用です。
 橙LEDが、[離反]確認用です。

 Cの閾値設定は配線せずに通信コマンド
 にて行います。


スケッチについて
---------------------------------------------------------------------
// NJR4265 J1 移動体検知センサモジュールのテスト
// Arduino Zero Pro での実験スケッチです。
// Arduinoは起動後、USART受信モードに入りコマンドを受信したらその内容に応じて処理する。
// センサーは起動後、初期化処理が終えたら"起動通知コマンド "を送って来るので、
// それを受けたら"閾値の設定コマンド"で接近/離反の閾値設定を行う。
#include <stdlib.h>
#include <ctype.h>
#include <string.h>

#define ApproachLEDpin 7      // 接近用LEDピン
#define LeaveLEDpin    8      // 離反用LEDピン

// 変数の定義
char ReceiveData[12] ;        // 通信コマンドの受信バッファ
int  ReceiveDataNum ;         // 通信コマンドの文字列長さ兼受信フラグ変数

union  pari_t {
  uint8_t  dt ;
  struct {
    unsigned b0     :1;
    unsigned b1     :1;
    unsigned b2     :1;
    unsigned b3     :1;
    unsigned b4     :1;
    unsigned b5     :1;
    unsigned b6     :1;
    unsigned b7     :1;
  } ;
} ;

/*******************************************************************************
*  電源起動時とリセットの時だけのみ処理される関数(初期化と設定処理)            *
*******************************************************************************/
void setup()
{
     pinMode(ApproachLEDpin, OUTPUT);   // 接近用LEDピンを出力に設定
     pinMode(LeaveLEDpin, OUTPUT);      // 離反用LEDピンを出力に設定

     // シリアルモニターの設定
     // (RX=0 TX=1 BaudRate=9600bps Data=8bit Parity=odd Stop=1bit Flow=none)
     Serial.begin(9600,SERIAL_8O1) ;

     ReceiveDataNum = -1 ;

 }
/*******************************************************************************
*  繰り返し実行される処理の関数(メインの処理)                                  *
*******************************************************************************/
void loop()
{
     int ans ;
     
     // 通信コマンドの受信
     ans = NJR_Receive() ;
     if (ans != -1) {
          // 受信した通信コマンドに対する各処理
          NJR_PrcCommands(ans) ;
     }
}

// 受信した通信コマンドに対して処理を行う
// num:受信コマンドの文字長さ
void NJR_PrcCommands(int num)
{
     switch(ReceiveData[1]) {
       case 'W':// 起動完了
                digitalWrite(ApproachLEDpin, HIGH) ;
                digitalWrite(LeaveLEDpin, HIGH) ;
                delay(2000) ;
                digitalWrite(ApproachLEDpin, LOW) ;
                digitalWrite(LeaveLEDpin, LOW) ;
                // 閾値の設定を行う(接近=5m/離反=5m)
                NJR_SetThreshold(500,500) ;
                break ;
       case 'C':// 移動物が接近
                digitalWrite(ApproachLEDpin, HIGH) ;
                break ;
       case 'L':// 移動物が離反
                digitalWrite(LeaveLEDpin, HIGH) ;
                break ;
       case 'N':// 移動物が無い
                digitalWrite(ApproachLEDpin, LOW) ;
                digitalWrite(LeaveLEDpin, LOW) ;
                break ;
       case 'E':// エラー
                break ;
     }
}
// 接近/離反時の閾値を設定する処理
// sp:接近時の閾値を指定(0-999cm)
// sm:離反時の閾値を指定(0-999cm)
void NJR_SetThreshold(int sp,int sm)
{
     char buf[8] ;

     // 接近時の閾値を送信する
     sprintf(buf,"@SP%d\r\n",sp) ;
     Serial.print(buf) ;
     // 離反時の閾値を送信する
     sprintf(buf,"@SM%d\r\n",sm) ;
     Serial.print(buf) ;
}
// 通信コマンドを受信する処理
// 受信したコマンドの文字長さを返す(CR/LFも含む)、未受信なら−1を返す。
// 受信したコマンドの文字はReceiveDataバッファに格納する。
int NJR_Receive()
{
     int  ans , ret ;
     char dt ;

     ret = -1 ;
     while(1) {
          // 受信データが有るなら処理を行う
          ans = Serial.available() ;
          if (ans > 0) {
               // 1バイト読み出す
               dt = Serial.read() ;
               // 通信コマンドの開始
               if (dt == '@') ReceiveDataNum = 0 ;
               if (ReceiveDataNum >= 0) {
                    // 通信コマンドをバッファに溜める
                    ReceiveData[ReceiveDataNum] = dt ;
                    ReceiveDataNum++ ;
                    // 通信コマンドの最後(CR/LF)
                    if (dt == '\n' && ReceiveData[ReceiveDataNum-2] == '\r') {
                         ret = ReceiveDataNum ;
                         ReceiveDataNum = -1 ;
                         break ;
                    }
               }
          } else break ;
     }
     return ret ;
}
---------------------------------------------------------------------
起動させると、センサーモジュールからの受信待ちになります。
でぇ、数秒後にモジュールから"起動完了"が送られて来ます、ここで赤LEDと橙LEDを2秒間点灯
させた後にモジュールへ接近=5m/離反=5mの閾値設定コマンドを発行しています。
後は、センサーの前で行ったり来たりすればそれに応じてLEDが点灯します。

詳しい通信コマンドの説明等はデータシートを見ましょう。

Serialについて

通常は「Serial.begin(9600)」と記述すれば、
通信パラメータは"BaudRate=9600bps Data=8bit Parity=none Stop=1bit Flow=none"となります。
でぇ、今回はパリティを奇数(odd)に変えるので「Serial.begin(9600,SERIAL_8O1)」と記述します、
するとぉ通信パラメータは"BaudRate=9600bps Data=8bit Parity=odd Stop=1bit Flow=none"となります。
因みに、パリティを偶数(even)とする場合は、「Serial.begin(9600,SERIAL_8E1)」となります。

パリティビット等のシリアル通信書式についてはこちらを参照下さい。

(PIC)

PIC実態配線図
 左が実態配線図です。
 回路電源は、3.3V/5.0V何方でもお好きにぃ。

 左の赤丸番号はモジュールの番号です。

 赤LEDが、[接近]確認用です。
 橙LEDが、[離反]確認用です。

 Cの閾値設定は配線せずに通信コマンドにて行います


ダウンロードプログラムについて

↓ここからサンプルプログラムソースファイルをダウンロードして下さい。
motion.zip

プログラムソースをダウンロードしたら、MPLAB Xにてプロジェクトを作成します。
以下のファイルをプロジェクトディレクトリにコピーしてプロジェクトに取込んで下さい。
次にコンパイルPIC書き込みを実行して下さい。
MPLAB(R) XC8 C Compiler Version 1.40コンパイラを使用しています。

ダウンロードファイルを解凍すると下記の様なファイル構成です。
motion.c・・・・・・・・・・・・・ 本体のサンプルプログラムソースファイル
skUARTlib.c・・・・・・・・・・ USART通信を行う関数ソースファイル
skUARTlib.h・・・・・・・・・・ USART通信を行う関数のヘッダーファイル

 尚、CPUのクロックは16MHzを想定しています。
 なので通信速度等(USART)はシステムクロック16MHzで計算されています。

motion.c

プログラムの動作は、Arduinoの場合と同じです。


skUARTlib.c
skUARTlib.h

この内容は”FT232RL使用によりUSBをシリアル変換してマイコンと繋ぎます”を参照下さい。
今回はパリティ有り(奇数:odd)なので、"skUARTlib.h"の宣言を
//#define UART_8N1      // Data=8bit Parity=none Stop=1bit Flow=none (標準)
#define UART_8O1      // Data=8bit Parity=0dd Stop=1bit Flow=none (奇数パリティ有り))
と#define定義しています。
また、USARTの受信バッファサイズは32byteとしています。

《その他》

PICで実験写真
 左はPICによる実験風景です。

 モジュールは比較的簡単に動作します、
 検知動作も意外と確実ですしね。
 但し、消費電流(60mA)はちょいとお高めで、
 古い電池では動作しなくちょいとぉハマったぞぉ!
 ピン間隔を2.54mmにして欲しいもんだぁ、
 縦でなく横に配列すればイケると思うぞぉ!





【きむ茶工房ガレージハウス】
Copyright (C) 2006-2017 Shigehiro Kimura All Rights Reserved.