Ruby
AWS
RaspberryPi
IoT
Raspberrypi3

Raspberry Pi 3 と DSUN-PIR を使って人感センサーを作る + 人感センサー検知状況を表示する簡易Webアプリケーションを作る

More than 1 year has passed since last update.


はじめに

最近、Raspberry Piを使い出したのですが、色々な用途に使えるので面白いですね!

今回はRaspberry Piとセンサーの勉強を兼ねて、Raspberry Pi 3 と DSUN-PIR(赤外線センサー)を使って人感センサーを作り、人感センサーの検知状況を表示する簡易Webアプリケーションを作ってみました。


今回使用した機材 及び 実行環境

今回は以下の機材を使用しました。

Raspberry Pi3 Model Bを使用しました。

Raspberry Pi スターターパック (Pi3用Standard)

Raspberry Pi3 Model B ボード&ケースセット 3ple Decker対応 (Element14版, Blue)

Raspberry Piには以下の赤外線感知センサーを取り付けました。

PIRセンサーモジュール [DSUN-PIR]

人感センサーの検知状況を表示する簡易WebアプリケーションはAmazon EC2(Amazon Linux)のRuby + Sinatraで作りました。RubyやSinatraサーバのセットアップ手順は以下をご参照下さい。

Amazon LinuxにRuby Sinatra環境構築(rbenv + ruby-build + Ruby 2.3.1 + Sinatra 1.4.7インストール)


参考資料

以下の記事を参考にさせて頂きました。

とても参考になりました。ありがとうございました。

Raspberry PiのGPIO制御方法を確認する(GPIO制御編その1)

人感センサ A500BP (DSUN-PIR, SB00412A-1も) が安いだけでなく Raspberry Pi との相性もバッチリだったので、人感カメラが10分で出来てしまった話。

RaspberryPiで人感センサーを作る

Raspberry Pi 3 (Raspbian Jessie)の無線LANに固定IPアドレスを設定する

Raspberry Pi の初期設定


Raspberry Pi側のセットアップ手順


(1) Raspberry Piをセットアップします。

参考資料の記事を見ながら、Raspberry Piをセットアップします。

人感センサ A500BP (DSUN-PIR, SB00412A-1も) が安いだけでなく Raspberry Pi との相性もバッチリだったので、人感カメラが10分で出来てしまった話。

RaspberryPiで人感センサーを作る

Raspberry Pi 3 (Raspbian Jessie)の無線LANに固定IPアドレスを設定する

以下は任意ですが、Raspberry Piに無線LANでIPアドレスを自動付与するようにしておくと、Raspberry PiにLANケーブルを接続しなくても良くなるので便利です。

root@raspberrypi:~# wpa_passphrase 無線LANのSSID SSIDのパスフレーズ >> /etc/wpa_supplicant/wpa_supplicant.conf

root@raspberrypi:~# cat /etc/wpa_supplicant/wpa_supplicant.conf

country=GB
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
ssid="SSID"
psk=パスフレーズが暗号化されて設定される
}
root@raspberrypi:~#


(2) Raspberry PiのGPIO18に人感センサー(DSUN-PIR)を取り付けます。

Raspberry Piに人感センサー(DSUN-PIR)を取り付けます。

スクリーンショット 2017-04-02 23.17.25.png

スクリーンショット 2017-04-02 23.17.33.png

スクリーンショット 2017-04-03 1.25.56.png

スクリーンショット 2017-04-03 1.25.48.png


(3) Raspberry Piへsshログインします。

本記事では、例としてRaspberry Piに設定したIPアドレスを 198.51.100.10 と表記させて頂きます。

Raspberry Piへsshでログインします。piユーザでログインします。

MacBookProPC001:~ user$ ssh pi@198.51.100.10

pi@198.51.100.10's password: -> piユーザの初期パスワード raspberry を入力します。

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Tue Mar 28 18:05:14 2017
pi@raspberrypi:~ $


(4) Raspberry PiのGPIO18を有効化します。

rootユーザにスイッチします。

pi@raspberrypi:~ $ sudo su - 

root@raspberrypi:~#

Raspberry PiのGPIO18を有効化するスクリプトを作成します。

root@raspberrypi:~# mkdir /root/scripts


/root/scripts/start_gpio.sh

root@raspberrypi:~# vi /root/scripts/start_gpio.sh 

#!/bin/sh

GPIO="18"

echo $GPIO > /sys/class/gpio/export

ls -lrta /sys/class/gpio/


root@raspberrypi:~# chmod 755 /root/scripts/start_gpio.sh 

root@raspberrypi:~#

スクリプトを実行し、Raspberry PiのGPIO18を有効化します。

root@raspberrypi:~# /root/scripts/start_gpio.sh 

total 0
drwxr-xr-x 50 root root 0 Jan 1 1970 ..
-rwxrwx--- 1 root gpio 4096 Mar 28 18:05 unexport
lrwxrwxrwx 1 root gpio 0 Mar 28 18:05 gpiochip100 -> ../../devices/platform/soc/soc:virtgpio/gpio/gpiochip100
lrwxrwxrwx 1 root gpio 0 Mar 28 18:05 gpiochip0 -> ../../devices/platform/soc/3f200000.gpio/gpio/gpiochip0
-rwxrwx--- 1 root gpio 4096 Apr 2 13:56 export
drwxrwx--- 2 root gpio 0 Apr 2 13:56 .
lrwxrwxrwx 1 root root 0 Apr 2 13:56 gpio18 -> ../../devices/platform/soc/3f200000.gpio/gpio/gpio18
root@raspberrypi:~#


(5) Raspberry PiのGPIO18に取り付けた人感センサー(DSUN-PIR)のテストを行います。

Raspberry PiのGPIO18に人感センサーを取り付けた場合、人感センサーに人が近くづくと /sys/class/gpio/gpio18/value の値が 0 から 1 へ変わります。

人感センサー周辺に人がいない場合、以下ファイルの値は 0 になります。

root@raspberrypi:~# cat /sys/class/gpio/gpio18/value 

0
root@raspberrypi:~#

人感センサーに近づいてみます。

スクリーンショット 2017-04-02 23.14.50.png

すると、以下ファイルの値が 0 から 1 に変わります。

root@raspberrypi:~# cat /sys/class/gpio/gpio18/value 

1
root@raspberrypi:~#

人感センサーから離れたら、以下ファイルの値が 1 から 0 に戻る事を確認します。

root@raspberrypi:~# cat /sys/class/gpio/gpio18/value 

0
root@raspberrypi:~#


人感センサー検知状況表示用Webアプリケーションサーバのセットアップ手順


(6) 人感センサー検知情報用の簡易Webアプリケーションを作ります。

人感センサー検知情報表示用の簡易Webアプリケーションサーバ(Webサーバ)を作成します。

人感センサーは人が近づくと、Raspberry Piの/sys/class/gpio/gpio18/valueの値が変化しますので、この値をAPIサーバへ送信するようにします。

今回の記事では、WebサーバはRubyとSinatraで作ります。

RubyやSinatraのセットアップ手順は以下を参考にしてみて下さい。

Amazon LinuxにRuby Sinatra環境構築(rbenv + ruby-build + Ruby 2.3.1 + Sinatra 1.4.7インストール)

本記事では、例としてWebサーバを 198.51.100.20 と表記させて頂きます。

Webサーバへsshログインします。

MacBookProPC001:~ user$ ssh -i EC2インスタンスログイン用のSSH秘密鍵 ec2-user@198.51.100.20

Last login: Sun Apr 2 23:29:03 2017 from i121-115-95-232.s42.a013.ap.plala.or.jp

__| __|_ )
_| ( / Amazon Linux AMI
___|\___|___|

https://aws.amazon.com/amazon-linux-ami/2016.09-release-notes/
[ec2-user@example-ruby-sinatra-server ~]$

sinatraユーザを追加します。

[ec2-user@example-ruby-sinatra-server ~]$ sudo su - 

最終ログイン: 2017/04/02 (日) 23:30:13 JST日時 pts/0
[root@example-ruby-sinatra-server ~]# groupadd sinatra
[root@example-ruby-sinatra-server ~]# useradd sinatra -g sinatra -d /home/sinatra -s /bin/bash
[root@example-ruby-sinatra-server ~]#
[root@example-ruby-sinatra-server ~]# su - sinatra
[sinatra@example-ruby-sinatra-server ~]$
[sinatra@example-ruby-sinatra-server ~]$ id
uid=501(sinatra) gid=501(sinatra) groups=501(sinatra)
[sinatra@example-ruby-sinatra-server ~]$

[sinatra@example-ruby-sinatra-server ~]$ /sbin/ifconfig eth0 | grep inet

inet addr:198.51.100.20 Bcast:198.51.100.255 Mask:255.255.255.0
inet6 addr: XXXX::XXX:XXXX:XXXX:XXXX/64 Scope:Link
[sinatra@example-ruby-sinatra-server ~]$

sinatraユーザに権限を付与します。

[root@example-ruby-sinatra-server ~]# echo "sinatra ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/sinatra

[root@example-ruby-sinatra-server ~]# chown root:root /etc/sudoers.d/sinatra
[root@example-ruby-sinatra-server ~]# chmod 644 /etc/sudoers.d/sinatra
[root@example-ruby-sinatra-server ~]#

[sinatra@example-ruby-sinatra-server ~]$ ruby -v

ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-linux]
[sinatra@example-ruby-sinatra-server ~]$


(7) 人感センサー検知情報用の簡易Webアプリケーションを作ります。

まずWebアプリケーション作成用のディレクトリを作成します。

[sinatra@example-ruby-sinatra-server ~]$ ls -lrta /home/sinatra/

total 24
-rw-r--r-- 1 sinatra sinatra 124 Aug 16 2016 .bashrc
-rw-r--r-- 1 sinatra sinatra 193 Aug 16 2016 .bash_profile
-rw-r--r-- 1 sinatra sinatra 18 Aug 16 2016 .bash_logout
drwxr-xr-x 4 root root 4096 Apr 2 23:31 ..
-rw------- 1 sinatra sinatra 8 Apr 2 23:31 .bash_history
drwx------ 2 sinatra sinatra 4096 Apr 2 23:31 .
[sinatra@example-ruby-sinatra-server ~]$

[sinatra@example-ruby-sinatra-server ~]$ mkdir /home/sinatra/example-pir-api
[sinatra@example-ruby-sinatra-server ~]$
[sinatra@example-ruby-sinatra-server ~]$ cd /home/sinatra/example-pir-api/
[sinatra@example-ruby-sinatra-server example-pir-api]$ pwd
/home/sinatra/example-pir-api
[sinatra@example-ruby-sinatra-server example-pir-api]$

Gemfileを作成します。

[sinatra@example-ruby-sinatra-server example-pir-api]$ ls -lrta /home/sinatra/example-pir-api/

total 8
drwx------ 3 sinatra sinatra 4096 Apr 2 23:37 ..
drwxrwxr-x 2 sinatra sinatra 4096 Apr 2 23:37 .
[sinatra@example-ruby-sinatra-server example-pir-api]$
[sinatra@example-ruby-sinatra-server example-pir-api]$ bundle init
Writing new Gemfile to /home/sinatra/example-pir-api/Gemfile
[sinatra@example-ruby-sinatra-server example-pir-api]$
[sinatra@example-ruby-sinatra-server example-pir-api]$ ls -lrta /home/sinatra/example-pir-api/Gemfile
-rw-r--r-- 1 sinatra sinatra 75 Apr 2 23:37 /home/sinatra/example-pir-api/Gemfile
[sinatra@example-ruby-sinatra-server example-pir-api]$
[sinatra@example-ruby-sinatra-server example-pir-api]$ echo "gem 'sinatra'" >> /home/sinatra/example-pir-api/Gemfile
[sinatra@example-ruby-sinatra-server example-pir-api]$ echo "gem 'sinatra-contrib'" >> /home/sinatra/example-pir-api/Gemfile
[sinatra@example-ruby-sinatra-server example-pir-api]$ echo "gem 'json'" >> /home/sinatra/example-pir-api/Gemfile
[sinatra@example-ruby-sinatra-server example-pir-api]$

[sinatra@example-ruby-sinatra-server example-pir-api]$ cat /home/sinatra/example-pir-api/Gemfile

# frozen_string_literal: true
source "https://rubygems.org"

# gem "rails"
gem 'sinatra'
gem 'sinatra-contrib'
gem 'json'
[sinatra@example-ruby-sinatra-server example-pir-api]$

Sinatraをインストールします。

[sinatra@example-ruby-sinatra-server example-pir-api]$ pwd

/home/sinatra/example-pir-api
[sinatra@example-ruby-sinatra-server example-pir-api]$ ls -lrta /home/sinatra/example-pir-api/
total 12
drwx------ 3 sinatra sinatra 4096 Apr 2 23:37 ..
drwxrwxr-x 2 sinatra sinatra 4096 Apr 2 23:37 .
-rw-r--r-- 1 sinatra sinatra 122 Apr 2 23:39 Gemfile
[sinatra@example-ruby-sinatra-server example-pir-api]$
[sinatra@example-ruby-sinatra-server example-pir-api]$ bundle install --path vendor/bundle
Fetching gem metadata from https://rubygems.org/..........
Fetching version metadata from https://rubygems.org/.
Resolving dependencies...
Installing backports 3.7.0
Installing json 2.0.3 with native extensions
Installing multi_json 1.12.1
Installing rack 1.6.5
Installing tilt 2.0.7
Using bundler 1.13.2
Installing rack-protection 1.5.3
Installing rack-test 0.6.3
Installing sinatra 1.4.8
Installing sinatra-contrib 1.4.7
Bundle complete! 3 Gemfile dependencies, 10 gems now installed.
Bundled gems are installed into ./vendor/bundle.
[sinatra@example-ruby-sinatra-server example-pir-api]$

[sinatra@example-ruby-sinatra-server example-pir-api]$ ls -lrta /home/sinatra/example-pir-api/

total 24
-rw-r--r-- 1 sinatra sinatra 122 Apr 2 23:39 Gemfile
drwxrwxr-x 2 sinatra sinatra 4096 Apr 2 23:39 .bundle
drwxrwxr-x 3 sinatra sinatra 4096 Apr 2 23:39 vendor
drwx------ 4 sinatra sinatra 4096 Apr 2 23:39 ..
-rw-rw-r-- 1 sinatra sinatra 568 Apr 2 23:39 Gemfile.lock
drwxrwxr-x 4 sinatra sinatra 4096 Apr 2 23:39 .
[sinatra@example-ruby-sinatra-server example-pir-api]$
[sinatra@example-ruby-sinatra-server example-pir-api]$

人感センサー検知状況表示用の簡易Webアプリケーションを作成します。

[sinatra@example-ruby-sinatra-server ~]$ vi /home/sinatra/example-pir-api/example-pir-api.rb 


/home/sinatra/example-pir-api/example-pir-api.rb

require 'sinatra'

require 'sinatra/reloader'
require 'json'

PIR_STATUS_FILE = "/tmp/example-pir-status.log"
PIR_STATUS_FILE.freeze

get '/' do

if File.exist?(PIR_STATUS_FILE)

status = File.read(PIR_STATUS_FILE, :encoding => Encoding::UTF_8)
status = status.chomp

if status == "1" then
room_status = "[リビングに人がいます] " + status + ""
else
room_status = "[リビングに人はいません] " + status + ""
end

else

room_status = "[リビングの人感センサー検知状況を表示できません]"

end

room_status

end

post '/put' do
body = request.body.read

File.open(PIR_STATUS_FILE, "w") do |f|
f.puts(body);
end

if body == ''
status 400
else
body.to_json
end
end



(8) Webサーバを起動します。

[sinatra@example-ruby-sinatra-server example-pir-api]$ sudo /usr/local/rbenv/shims/bundle exec ruby /home/sinatra/example-pir-api/example-pir-api.rb -o 0.0.0.0 -p 80 &

[1] 4965
[sinatra@example-ruby-sinatra-server example-pir-api]$ [2017-04-03 00:28:03] INFO WEBrick 1.3.1
[2017-04-03 00:28:03] INFO ruby 2.3.1 (2016-04-26) [x86_64-linux]
== Sinatra (v1.4.8) has taken the stage on 80 for development with backup from WEBrick
[2017-04-03 00:28:03] INFO WEBrick::HTTPServer#start: pid=4966 port=80

 -> Enterキーを押します。

[sinatra@example-ruby-sinatra-server example-pir-api]$ ps awux | grep -v grep | grep ruby

root 4965 0.0 0.4 186148 4452 pts/2 S 00:28 0:00 sudo /usr/local/rbenv/shims/bundle exec ruby /home/sinatra/example-pir-api/example-pir-api.rb -o 0.0.0.0 -p 80
root 4966 1.7 2.7 360380 28236 pts/2 Sl 00:28 0:00 ruby /home/sinatra/example-pir-api/example-pir-api.rb -o 0.0.0.0 -p 80
[sinatra@example-ruby-sinatra-server example-pir-api]$


Raspberry Pi側の作業


(9) Raspberry Piで人感センサーが検知した情報をWebサーバへ定期的に送信するようにします。

人感センサー検知情報をWebサーバへ送信するスクリプトを作成します。

本記事では例としてWebサーバを 198.51.100.20 と表記しておりますので、198.51.100.20 を指定します。

root@raspberrypi:~# vi /root/scripts/put_gpio_status.sh 


/root/scripts/put_gpio_status.sh

#!/bin/sh

GPIO="18"
GPIO_VALUE="/sys/class/gpio/gpio$GPIO/value"
API="https://198.51.100.20/put"

SLEEP="2"

if [ ! -f $GPIO_VALUE ] ; then
echo "$GPIO_VALUE not found."
exit
fi

while :
do
curl -H "Accept: text/plain" -X POST -d `cat $GPIO_VALUE` $API

sleep $SLEEP
done


スクリプトを実行し、人感センサー検知情報をWebサーバへ定期的に送信するようにします。

root@raspberrypi:~# chmod 755 /root/scripts/put_gpio_status.sh

root@raspberrypi:~#

root@raspberrypi:~# /root/scripts/put_gpio_status.sh &

[1] 1833
root@raspberrypi:~#


動作確認


(10) Webブラウザを起動して、人感センサー検知情報表示用の簡易Webアプリケーションを表示してみます。

WebブラウザからWebサーバへアクセスしてみます。

 http://198.51.100.20/

人感センサーの周辺に人がいない場合は [リビングに人はいません] と表示されます。

スクリーンショット 2017-04-03 0.51.01.png

人感センサーに近づいてみます。

スクリーンショット 2017-04-03 1.01.45.png

すると、[リビングに人がいます] と表示が変わる事を確認します。

スクリーンショット 2017-04-03 0.54.05.png


Raspberry Piとセンサー類を組み合わせると、部屋の入室検知やそれに応じたアクションの自動化等、色々な事に活用出来そうですね!

以上になります。