ダミー監視カメラの中にRaspbery Pi zero とRPi-Cam-Web-Interfaceで監視カメラ作成(OFFLINE版)

Amazonでダミーカメラを購入して、その中にraspberry Pi zero とRPi-Cam-web-Interfaceで本物の監視カメラにいたしました。

この製品の材質は主にプラスチックですが、ぱっと見ただけでは本物のように見えます。その上、太陽電池セルと自己点滅型LEDによって昼間は電池無しで赤いLEDが点滅します。ですので、いかにも「録画監視中ですよ!」と言う雰囲気を醸し出しています。別売の充電式単3電池2本をセットすれば夜もLEDを点滅することができるみたいです。

これを本物の監視カメラに改造しました。

今回はインターネット回線が無い場所に設置しましたのでzero にアクセスポイントを兼任してもらい、カメラインターフェースのコントロール画面にアクセスできるようにしました。

購入したダミーカメラは大きくわけて5個のパーツに分解できます。本体の中は広くはありませんが、空洞になっていますのでzero を配置するスペースは確保できます。また、少し加工が必要ですが前面のダミーカメラモジュールを本物のカメラモジュールへ交換することができます。さらにダミーの照明用赤外線LEDを本物にしてしまう事も一瞬頭に浮かびましたが、熱で筐体が溶けてしまいそうなので却下しました。

製品を分解したところ(NO1)
製品を分解したところ(NO2)

ソーラーセルがついていますが、残念ながらraspberry Pi zeroを駆動できそうにないので、電源は別途用意が必要です。(結果、ソーラーセルは使用しません)

DS3231 RTC Real Time Clockモジュール

OFFLINEで使用するのでリアルタイムクロックを装着しました。
Raspberry Pi 用のDS3231 RTC Real Time Clockモジュールが手元にありましたので、これを使用しました。
このモジュールはZero のGPIO 1,3,5,7Pinに直接装着できます。WiFi環境下で使用するのであれば、このRTCは必要ありません。カメラモジュールとLED、電源をつなげるだけでOKです。

ダミーのLED照明・カメラレンズはプラスチックで上手に作られています

ダミーカメラの前面は保護ガラスが入っている黒いフードカバーとダミーLED赤外線照明およびダミーカメラモジュールに分解できます。ダミーカメラモジュールの代わりに本物のカメラモジュールをとりつけるために加工が必要です。

ダミーカメラモジュールの一部を切断することも考えましたが、黒い板状の物を切り抜いて作成することにしました。DVDの黒いケースが材料としてぴったりで、ハサミで切り抜いてカメラモジュール取り付けのアタッチメントとしました。

丸いガラス板も取り外せます

完成後カメラの画像をチェックして初めて気づきましたが、周囲が暗くなると前面に付いている保護ガラスに自己点滅型LEDの光が反射して画像に写ってしまいます。
これはでは都合が悪いので前面に付いている丸い保護ガラスを外しました。フード状のこの部品も3つに分解できます。
レンズがフードの奥になるので、魚眼レンズの等のカメラモジュールを装着した場合、解像度によっては画像の4隅の一部がケースに遮られて写らないことがあります。

Wifiドングルが不調でZero Wへ交換しました。

上記の追加基盤ですが、赤色自己点滅型LEDの点滅の周期がイマイチ気に入らなかったので普通の(自己点滅型ではない)LEDをzeroのGPIOから点滅制御できるよう回路を追加してみました。また、CDSセンサーをソーラーセルのそばに新たに取り付け、オペアンプを利用して照度センサーも追加しました。ただ、現時点では明るさによってLEDの照度を切り替えるぐらいなので、苦労の割にメリットはあまりありませんでした。(こういう事を私の住んでいる地方の方言で「おへんなし」と言います)

■ソフトウエアのインストール

raspberry-pi-OSをhttps://www.raspberrypi.org/downloads/raspberry-pi-os/ こちらからダウンロードしてbalenaEtcher https://www.balena.io/etcher/でフラッシュカードに書き込みます。

Raspberry Pi OS (32-bit) Lite
Minimal image based on Debian Buster
Version:May 2020
Release date:2020-05-27
Kernel version:4.19
Size:432 MB
2020-05-27-raspios-buster-lite-armhf.zip

こちらを使わせてもらいました

自宅のWifi環境でSSHを使い接続して作業しました。SDカード /boot に2つのファイル作成します。

ファイル名: ssh                   //中身は無し,SSHサーバが自動起動する
ファイル名: wpa_suppliant.conf      //UTF8N LF コード wifiへ接続
              country=JP
              ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
              update_config=1
              network={
           ssid="your SSID"        //SSDI
           psk="your PASSWORD"     //接続のためのパスフレーズ
              }

・RPi カメラモジュールをつなぎ、フラッシュメモリーをセットしてzeroを起動します。rspi-configを起動して各種設定を行います

$ sudo raspi-config
・camera support 5 Interfaceing OPtions - P1 Camera - Enable
・I2c support 5 Interfaceing OPtions - P5 I2C - Enable
・password change 1 Change User Password
・hostname 2 Network Options - N1 Hostname
・time zone 4 Localisation Options -I2 Change Time Zone - Asia - Tokyo
・Expand Filesystem 7 Advanced Options - A1 Expand Filesystem
・GPU memory 7 Advanced Options - A3 Memory Split - 128 --> 16

以上を設定した後にRPi-Cam-Web-Interfaceをインストールします。蛇足になりますが、安全のためにsshの待受ポートは設定変更した方が良いと思います。

・RPi-Cam-Web-Interfaceインストールは基本的にweb https://elinux.org/RPi-Cam-Web-Interface に書いてある通りに行いました。

$ sudo apt-get update
$ sudo apt-get dist-upgrade
$ sudo apt-get install git
$ git clone https://github.com/silvanmelchior/RPi_Cam_Web_Interface.git
$ cd RPi_Cam_Web_Interface
$ sudo ./install.sh

web serverはlighttpを選択しました。

スタンドアロンで運用するためアクセスポイントソフト・DHCPサーバ設定を行います。なかなかうまく行かず、かなり試行錯誤しました。私の頭の中にある旧型低速 CPUが処理の限界を超えていましたので、記述が正確ではないかもしれません。

・ hostapd アクセスポイントソフトウエア設定 (参考URL) https://www.raspberrypi.org/documentation/configuration/wireless/access-point-routed.md

$ sudo apt-get install hostapd
$ sudo systemctl unmask hostapd
$ sudo systemctl enable hostapd
$ sudo vim.tiny /etc/hostapd/hostapd.conf     //エディタで編集します
       country_code=JP
       interface=wlan0
       ssid=NewSSID                //新たなSSIDをセット
       hw_mode=g
       channel=7
       macaddr_acl=0
       auth_algs=1
       ignore_broadcast_ssid=0
       wpa=2
       wpa_passphrase=NewPassWord //新たなパスフレーズ
       wpa_key_mgmt=WPA-PSK
       wpa_pairwise=TKIP
       rsn_pairwise=CCMP

・インターフェースアドレスの固定 (管理画面をアクセスするアドレスになります)

今回は 172.25.2.1 に設定しました

$ sudo vim.tiny /etc/dhcpcd.conf    //エディタで編集、最下行に追記
        …
       interface wlan0
       static ip_address=172.25.2.1/24  //お好きなネットーワークアドレス
       nohook wpa_supplicant

・ isc-dhcp-server DHCPサーバインストール (参考URL) https://qiita.com/homines22/items/cccd711c9a77680d1e2c

ネットワーク: 172.25.2.0 サブネットマスク:255.255.255.0 の設定を行いました

$ sudo apt-get install isc-dhcp-server
$ sudo vim.tiny /etc/dhcp/dhcpd.conf    //エディタで編集
        …
       #option definitions common to all supported networks...
       #option domain-name "example.org";              //コメントアウト
       #option domain-name-servers ns1.example.org, ns2.example.org; 
                                                       //コメントアウト
        …
       authoritative;   //#を外す
                        // 最下行に追記
       subnet 172.25.2.0 netmask 255.255.255.0 {
       range 172.25.2.2 172.25.2.20;
       option broadcast-address 172.25.2.255;
       max-lease-time 7200;
       ignore declines;
       }

$ sudo vim.tiny /etc/default/isc-dhcp-server //エディタで編集
                                             //最終行を変更
       INTERFACESv4 = "wlan0"
       INTERFACESv6=""

・isc-dhcp-server 起動問題を解決 (参考URL)

https://www.raspberrypi.org/forums/viewtopic.php?t=170758

$ sudo vim.tiny /etc/systemd/system/isc-dhcp-server.service
       [Service]
        …
       // Restart=no ------>この行を下記2行へ書き換え
       Restart=on-failure
       RestartSec=5

       // 最下行に追記
       [Install]
       WantedBy=multi-user.target

$ sudo systemctl enable isc-dhcp-server.service

・ipv6 無効化

$ sudo vim.tiny /etc/sysctl.conf  //エディタで編集
       // 最下行に追記
       net.ipv6.conf.all.disable_ipv6 = 1

リアルタイムクロック設定  RTC DS3231

  (参考URL) https://www.sigmdel.ca/michel/ha/rpi/guide_buster_03_en.html#rtc

$ sudo vim.tiny /boot/config.txt   //エディタで編集
  ...
  # Uncomment some or all of these to enable the optional hardware interfaces
       dtparam=i2c_arm=on
       #dtparam=i2s=on
       #dtparam=spi=on
       dtoverlay=i2c-rtc,ds3231     //追記します
 
$ sudo shutdown -r now                 //再起動

インストールされたかチェック
$ ls /dev/rt*                          //デバイスファイル作成されたか
       /dev/rtc  /dev/rtc0

$ sudo hwclock --verbose               //下記の表示がされるか
       hwclock from util-linux 2.33.1
       System Time: 1573672406.546382
       Trying to open: /dev/rtc0
       Using the rtc interface to the clock.
       Assuming hardware clock is kept in UTC time.
       Waiting for clock tick...
       ioctl(3, RTC_UIE_ON, 0): Invalid argument
       Waiting in loop for time from /dev/rtc0 to change
       ...got clock tick
       Time read from Hardware Clock: 2019/11/13 19:13:28
       Hw clock time : 2019/11/13 19:13:28 = 1573672408 seconds since 1969
       Time since last adjustment is 1573672408 seconds
       Calculated Hardware Clock drift is 0.000000 seconds
       2019-11-13 15:13:27.408018-04:00
     
 起動時にRTCから時間を読み込み
$ sudo vim.tiny /lib/udev/hwclock-set
       #!/bin/sh
       # Reset the System Clock to UTC if the hardware clock from which it
       # was copied by the kernel was in localtime.
                                    
       dev=$1
                                         
       #if [ -e /run/systemd/system ] ; then //コメントアウト
       #    exit 0                         //コメントアウト
       #fi                                   //コメントアウト                    ...

RTC初期設定
$ sudo date -s "2020/06/29 22:53:00"   //現在の日付・時刻をセット
$ hwclock -w && date && hwclock -r     //RTCに書込

■ 追加ハードの設定 (ここからは賢明な読者の方には不要な記述です。労力が多くて得るものが少ないです。)

zeroのGPIO pin1~pin12を使用します。GPIO18(OUTPUT)が自己点滅型LEDに変わる赤色通常LEDのコントロール。GPIO17(INPUT)が光センサーからの入力になります。

・wiring pi インストール (参考URL) http://wiringpi.com/download-and-install/

$ sudo apt-get install wiringpi

・system起動時に赤色LED点滅

$ sudo vim.tiny /etc/rc.local      //エディタで編集 
       // exit 0 の前に追記:
       gpio mode 1 pwm
       gpio pwm-ms
       gpio pwmc 4095
       gpio pwmr 4096
       gpio pwm 1 100

・ 明るさによりLEDの照度を変更

$ vim.tiny /SOME/PATH/illuminance_led.sh   //新しいファイルを作成
    !/bin/bash
       var=`gpio -g read 17`
       if [ "$var" = 1 ]
       then
       gpio pwm 1 100
       else
       gpio pwm 1 10
       fi
$ chmod +x /SOME/PATH/illuminace_led.sh   //実行権をつける

$ sudo corontab -e                  //rootでcronへ登録
       5 * * * * /SOME/PATH/illuminance_led.sh  //追記 5分ごとに実行

ソフトでLEDを点滅させているので、ひと目でraspberry pi zeroが動いているか否か分かる利点はあります。

続-ガイガカウンタ・簡易モニタリングポスト製作日記(3)

この様な流れでしょうか


ハードの方はめどがたちましたが、さて問題はソフトです。全ての処理を1つのマイクロコントローラに任せるプログラムを書くのは相当高度なテクニックが必要そうですが、今回は豪華に2つ使うことにしました。まるで大名のような贅沢ですね。いや、ひょっとするとそれ以上かもしれません。放射線のカウント、表示の処理は「ちびでぃ~の2」にまかせて、もう一つはパルス発生だけに専念します。これなら初心者の私でも何とかなりそうです。

e-電子工房さんのサイトを見ると400Vの場合、1KHzの周期でパルス幅が大体62n秒であれば良いことがわかります。まったくもって貴重な情報を公開していただき本当にありがとうございます。今回はアッセンブラでプログラムを作り、秋月電子通商から仕入れた新品のATmega168Pへ書き込みます。

当然のことながらAVRのアッセンブラも初めて触る私です。Nの電子講座・AVRマイコン編AVRマイコンで学ぶ コンピュータの仕組みのサイトに詳しく記述されていましたので勉強させていただきました。ありがとうございました。今回は特に小山さんが書かれた「AVRマイコンで学ぶ コンピュータの仕組み」から、ソフトウエアタイマー “blink.asm”の項を参考にプログラムを組ませていただきました。本当にお世話になりました。

フローを考えると次のようになります

スタート–>初期設定–>①–>1を出力する–>62μS待つ–>0を出力する–>938μS待つ–>①へジャンプ

前述のBlink.asmを参考にコードを書いていきます。特に変える必要もなさそうなので、出力ポートも同じPB3にさせていただきました。

GeigerClock.asm

 .include "m168Pdef.inc"
 .cseg
	LDI	R16,0b00001000
	OUT	DDRB,R16		;PB3は出力,他は入力

	LDI	 R16,HIGH(RAMEND)	;RAM最終アドレス上位を取得
    	OUT	 SPH,R16		;スタック ポインタ上位を初期化
	LDI	 R16,LOW(RAMEND)	;RAM最終アドレス下位を取得
    	OUT	 SPL,R16		;スタック ポインタ下位を初期化

LOOP:
	LDI	R16,0b00001000
	OUT	PORTB,R16		;PB3は1, 他は0

	RCALL	T62us			;62μ秒待つ

	LDI	R16,0b00000000
	OUT	PORTB,R16		;PB3は0, 他も0

	RCALL	T938uS			;938μ秒待つ

	RJMP	LOOP			;LOOPの箇所にジャンプ

62μSと938μS待機するサブルーチンを作成します。ATMEGA168Pを8MHzのクロックで動作させて1クロックサイクル=0.125μSで計算します。62μSは50μs+12μSで、938μSは50μSを18回繰り返し、さらに+38μSとすれば大体良さそうです。コメントに書いてある数値、計算は参考にさせて頂いた「AVRマイコンで学ぶ コンピュータの仕組み」サイト中に丁寧な説明があります。


; timer subroutine
T50US:			;((3)+1+5*78-1+4)*0.125=397*0.125=49.625μ秒
	LDI	R20,78	;1 以下を78回繰り返す
_TUS:
	NOP		;1
	NOP		;1
	DEC	R20	;1 R20から1を減じ
	BRNE	_TUS	;1/2 結果が0でなければ_TUSへ
	RET		;4

T62us:			;((3)+397+1+8*12-1+4)*0.125=500*0.125=62.5μ秒
	RCALL	T50US	;397
	LDI	R21,12	;1 以下を12回繰り返す
_T12US:
	NOP		;1
	NOP		;1
	NOP		;1
	NOP		;1
	NOP		;1
	DEC	R21	;1 R21から1を減じ
	BRNE	_T12US	;1/2 結果が0でなければ_T12USへ
	RET		;4

T938us:			;((3)+1+400*18-1+1+8*38-1+4)*0.125=7510*0.125=938.875μ秒
	LDI	R21,18	;1 以下を18回繰り返す
_T900US:
	RCALL	T50US	;397
	DEC R21		;1
	BRNE	_T900US	;1/2 結果が0でなければ_T900USへ

	LDI	R21,38	;1 以下を38回繰り返す
_T38US:
	NOP		;1
	NOP		;1
	NOP		;1
	NOP		;1
	NOP		;1
	DEC	R21	;1 R21から1を減じ
	BRNE	_T38US	;1/2 結果が0でなければ_T38USへ
	RET		;4

うまく動くでしょうか????