USBカメラで自動撮影と外気温度のグラフ化
三郡山にあるレピーター局舎内の温度・湿度、大気圧を測定できるようになりましたが
三郡山は標高が高いため12月から3月までは、メンテナンスに伴う山頂への車の通行が禁止されます。
(*三郡山は、一般車両の通行は年中禁止されています。)
このため冬場の外気温度計測と周囲の状況も撮影したくなり、そのための手順をまとめます。
設定にあたりラズパイのupgraeをしようとしたら、Busterのupgradeが遅かったのでsources.listを
国内用に変更しました。
sudo nano /etc/apt/sources.list
#deb http://raspbian.raspberrypi.org/raspbian/ buster main contrib non-free rpi
# Uncomment line below then 'apt-get update' to enable 'apt-get source'
#deb-src http://raspbian.raspberrypi.org/raspbian/ buster main contrib non-free$ #コメントアウト
deb http://ftp.jaist.ac.jp/raspbian/ buster main contrib non-free rpi #追加
1.USBカメラを使えるようにする。
ラズパイには、カメラモジュールが用意されていますが今回は屋外で撮影するので、防水USBカメラを
使用することにしました。インストールは、
このページを参考にしました。
Amazonで購入したのは、
ELP-USB100W05MT-DL36-JPというカメラです。USBケーブルが5mついています。
取り付け金具も一緒に購入しました。
USBカメラの場合は、ラズパイのUSBポートに差し込むだけで使用可能となります。
(1)Pythonで画像を扱うためのライブラリーであるOpenCVをラズパイにインストール
@pipを最新のバージョンにする
sudo pip3 install opencv-python==4.5.1.48
AOpenCVをバージョン指定でインストール
sudo pip3 install opencv-python==4.5.1.48
BPythonでの多次元配列を扱う数値計算ライブラリnumpyというライブラリを最新にする
pip install -U numpy
少し時間がかかります。待ち長いです。Pi3で20分ちょっと。 (°д°)
Cパッケージリストを最新
sudo apt update
D「libatlas3-base」 パッケージをインストール
sudo apt install libatlas3-base
これでUSBカメラが使えるようになります。
Pythonプログラムでカメラ映像(動画)を表示するのには、
ここを参考にしました。
(2)USBカメラで撮影
撮影シェルスプリクトを作成
cd ~
mkdir camera
cd /home/pi/camera
このシェルスプリクトがあるところに撮影したファイルができるので
撮影画像を保存するディレクトリーに撮影シエルスプリクトを作成します。
nano camera.py
# -*- coding: utf-8 -*-
import cv2
import datetime
dt_now = datetime.datetime.now()
file_name = dt_now.strftime('%Y年%m月%d日%H時%M分%S秒')
cap = cv2.VideoCapture(0)
ret, frame = cap.read()
cv2.imwrite(file_name + '.jpg', frame)
cap.release()
撮影するコマンドは、次の通りです。
cd /home/pi/camera
python3 camera.py
このコマンドで撮影ができることを確認します。
*トラブルが発生
ちゃんと撮影できていたのに、VNCを使用する状態でディスプレーを接続せずにラズパイを起動したら
カメラ撮影ができなくなるというトラブルが発生。
ラズパイは、デフォルトではディスプレーを接続していないと720×480になるので解像度を上げてみました。
raspi-configで 2: Display Options D1 Resolutionで
ディスプレー解像度をDMT Mode 85 1024×768 60Hz 4:3を選択
pi@sangun:~ $ sudo nano /boot/config.txt
下記部分を変更・追加
# uncomment to force a specific HDMI mode (this will force VGA)
hdmi_group=2
hdmi_mode=85
これで解決しました。おかしくなったら試してみてください。
(3)imagemagickをインストール
撮影したファイルには、撮影日時で名前が付きますがほとんど変化のない風景画像だけ見てもいつ撮影されたのか
わからないので、撮影した画像に時間を書き込むためimagemagickをインストールしてみます。
sudo apt install imagemagick
インストールができたらバージョンを確認
pi@sangun:~ $ convert -version
Version: ImageMagick 6.9.10-23 Q16 arm 20190101 https://imagemagick.org
Copyright: c 1999-2019 ImageMagick Studio LLC
もし、プログラムファイルがないとでたらフルパスで実行
/usr/bin/convert -version
(4)時間を書き込むために元画像をコピーして別ファイル名にするスプリクト
ホームページに撮影した画像をアップするために少し小技をいれます。
2022月日時分秒.jpgファイル名を別名(sangunpre.jpg)でコピーするスプリクトを作ります。
cd /home/pi
nano changejpg.sh
#!/bin/sh
cd /home/pi/camera
cp 202*.jpg sangunpre.jpg
sudo chmod a+x changejpg.sh
(5)imagemagickで画像に撮影時間を書き込む
cd /home/pi/camera
/usr/bin/convert /home/pi/camera/sangunpre.jpg -pointsize 48 -fill white -strokewidth 1 -stroke black -gravity SouthEast -annotate +20+20 "$(date +'%Y-%m-%d %H:%M' -r sangunpre.jpg)" -font arial.ttf /home/pi/camera/sangun.jpg
出来上がったsangun.jpgファイルを見ると年月日時分の入った画像ファイルになっている。 |
|
|
|
imagemagickで変更前 |
imagemagickで撮影時間書き込み |
|
|
3.HPサーバーへアップロードするための設定
撮影した画像をHPでどこからでも見れるように サーバーへアップロードするため
FTPコマンドをインストールします。
sudo apt-get install ftp
*下記テキストに書き込むFTPのためのIDは、自局用にあわせてください。
nano cameraup.txt
open サーバードメイン(hogehoge.jp)
user ID password (FTPでコネクトするためのIDとパスワードを記入)
binary
prompt
lcd /home/pi/camera(ラズパイ側でアップするファイルがあるディレクトリー)
cd /hoge(ホームぺージ側のアップするディレクトリ)
put sangun.jpg
bye
最終的に。satuei.shというシエルスプリクトを作成して一連の動作を行う
nano satuei.sh
#!/bin/sh
cd /home/pi/camera
python3 camera.py
sleep 20
cd /home/pi/camera
cp 202*.jpg sangunpre.jpg
/usr/bin/convert /home/pi/camera/sangunpre.jpg -pointsize 48 -fill white -strokewidth 1 -stroke black -gravity SouthEast -annotate +20+20 "$(date +'%Y-%m-%d %H:%M' -r sangunpre.jpg)" -font arial.ttf /home/pi/camera/sangun.jpg
sleep 2
/usr/bin/ftp -n < /home/pi/cameraup.txt
sleep 5
mv 202*.jpg file
rm sangun.jpg
rm sangunpre.jpg
4.DSB18B20を使用して外気温度を計測
すでに三郡山レピータをいれた局舎内の温度・湿度・大気圧は測定できるようにしていますが
外気温度の動きを知りたくなりました。
防水処理されたDSB18B20温度センサーを利用して外気温度を測定します。
DS18B20のデータ線はプルアップする必要があります。
ラズパイの3.3VとGPIO4の間に、4.7kΩのプルアップ抵抗をつないでください。
1−WIREのプルアップ電圧とは、単一のラインを使ってホストデバイスとスレーブデバイスの間に
通信と電力の両方を供給します。一部の1-Wireデバイスは、EEPROM、温度測定、およびSHA-1エンジンを含む
拡張機能を提供しています。これらの特別な機能の動作には追加の電力が必要になる可能性があるため、
1-Wireデバイスのプルアップ抵抗(RPUP)の大きさをそれに応じて決める必要があるとのことでその電圧を
確保するための抵抗です。
配線図は、探せばたくさん出てきます。DS18B20の動作電圧は、3.0V〜5.5V系二対応していますのでGPIOの
空いている電圧PINを使用します。
(1)DS18B20を使用するために「1-Wire」を有効化
sudo /etc/modules
w1-gpio
w1-thermを追加
sudo nano /boot/config.txt
dtoverlay=w1-gpio,gpiopin=4,pullup=y
再起動して設定を反映
sudo reboot
pi@sangun:~ $ lsmod | grep w1 このコマンドで下記が出ればi-wireが有効になっている
w1_therm 28672
w1_gpio 16384 0
wire 36864 2 w1_gpio,w1_therm
1-Wireが有効化され、温度センサの認識に成功すると、「 /sys/bus/w1/devices 」にファイルが生成されるので
下記コマンドでDS18B20の固有デバイスIDを調べます。
pi@sangun:~ $ ls /sys/bus/w1/devices/
28-0120683dfe52 w1_bus_master1
デバイスIDは、28-0120683dfe52とわかりました。w1_slave」というファイルの中に、温度の情報が格納されているので
cat /sys/bus/w1/devices/28-0120683dfe52/w1_slave コマンドで中身を見てみます。
pi@sangun:~ $ cat /sys/bus/w1/devices/28-0120683dfe52/w1_slave
57 01 4b 46 7f ff 0c 10 38 : crc=38 YES
57 01 4b 46 7f ff 0c 10 38 t=21437
ここの21437を1/1000した数字が温度です。この例では、21.437度ということになります。
(2)温度を自動取得
PHPを使用する場合は、「php」と「apache2」のパッケージを事前にインストールしておきます。
apache2をインストール
sudo apt-get install apache2
PHPをインストール
sudo apt-get install php
pi@sangun:~ $ php -v
PHP 7.3.31-1~deb10u1 (cli) (built: Oct 24 2021 15:18:08) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.31, Copyright (c) 1998-2018 Zend Technologies
with Zend OPcache v7.3.31-1~deb10u1, Copyright (c) 1999-2018, by Zend Techno
PHP7.3がインストールされました。
温度データの取得・保存を行うプログラムを準備
cd /var/www/html
mkdir temperature
nano temperature.php
<?php
$deviceId = '28-0120683dfe52';
$today = date("Ym");
$month = date("md");
$time = date("H:i");
$sensor_path = '/sys/bus/w1/devices/'.$deviceId.'/w1_slave';
$csv_dir = '/var/www/html/temperature/';
$csv_file = $today.'.csv';
$t = null;
//温度取得
exec("cat ".$sensor_path, $w1_slave);
if(isset($w1_slave[1])){
$tmp = explode('t=', $w1_slave[1]);
if(isset($tmp[1])) $t = $tmp[1] / 1000;
}
//CSV書き込み
if(!file_exists($csv_dir)){
mkdir($csv_dir);
}
if( $handle = fopen( $csv_dir.$csv_file , 'a' ) ){
fputcsv( $handle, Array("'".$month.$time."'", $t) );
fclose($handle);
}
return;
説明
$deviceId = '28-0120683dfe52'; #接続したデバイスIDを記入
$today = date("Ym"); #作成するcsvを月単位にする
$month = date("md"); #グラフを表示する時に月日を表示するために設定しておく
$csv_dir = '/var/www/html/temperature/'; #CSVファイルを作るディレクトリー
下記コマンドでCSVファイルに取得した温度を書き込む
php /var/www/html/temperature.php
(3)Google Chartsを利用してグラフ化します
これもホームページから見れるように先人のお知恵を拝借し、Google Chartsを利用しました。
cd /var/www/html/index.php
nano index.php
<?php
$today = date("Ym");
$csv_dir = '/var/www/html/temperature/';
$csv_file = $today.'.csv';
$grapgh = '';
//CSV読み込み
if (($handle = fopen($csv_dir.$csv_file, "r")) !== false) {
while (($line = fgets($handle)) !== false) {
$grapgh .= '['.rtrim($line).'],'.PHP_EOL;
}
fclose($handle);
}else{
echo 'no data';
}
?>
<html>
<head>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load('visualization', '1.1', {packages: ['line']});
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('string', 'Time');
data.addColumn('number');
data.addRows([
<?php echo $grapgh; ?>
]);
var options = {
chart: {
title: '飯塚三郡山 山頂 外気温度',
},
height: '500'
};
var chart = new google.charts.Line(document.getElementById('linechart_material'$
chart.draw(data, options);
}
</script>
</head>
<body>
<div id="linechart_material"></div>
</body>
</html>
ホームぺージを見る場合は、http://IPアドレス/index.php
自分のraspberry piで動作させる場合は問題ありませんが、
レンタルサーバで行う場合は、phpの動作を許可していないサーバーもありますので
確認してください。
なお、データをレンタルサーバに送る場合は、raspberry piから cronで定期的にFTPでアップします。
graph.sh シェルスプリクト を作成
#!/bin/sh
php /var/www/html/temperature.php
sleep 5
/usr/bin/ftp -n < /home/pi/temp.txt
temo.txtを次のように作成しておきます
open ホームぺージドメイン
user ID passwd #ホームぺージのIDとパスワードを記入
binary
prompt
lcd /var/www/html/temperature
cd /var/www/html/pue/temp
put *.csv
bye
グラフ作成ができずに画面が真っ白になる場合があります。(私もはまりました (笑)
温度を記録している(Ym).csvファイルの先頭部分に温度データの抜けがあると
この現象が発生します。
'031813:40'
'031813:50'
'031814:00'22.687
'031814:10'23.562
'031814:20'23.625
'031814:30'23.625
'031814:35'23.625
上記の場合は、上2行を削除するとグラフが作成されます。
各種動作をcronに書き込みます
crontab -e
0-59/10 * * * * ~/php /var/www/html/temperature.php #10分に1回温度尾測定しCSVファイルに書き込む
00 0-6 * * * /home/pi/satuei.sh #0時〜6時は、正時に1度だけ撮影
*/21 7-17 * * * /home/pi/satuei.sh #7時〜17時は、21分毎に1度撮影
00 18-23 * * * /home/pi/satuei.sh #18時〜23時は、正時に1度撮影
Raspberry piは、cronのlogが初期設定では見れません。
cronの動作を確認するには、rsyslogでcronのログを取る設定にします。
確認がとれれば、コメントアウトして元に戻しでもよいと思います。
$ sudo nano /etc/rsyslog.conf
# First some standard log files. Log by facility.
#
auth,authpriv.* /var/log/auth.log
*.*;auth,authpriv.none -/var/log/syslog
cron.* /var/log/cron.log #ここを有効化する
daemon.* -/var/log/daemon.log
kern.* -/var/log/kern.log
lpr.* -/var/log/lpr.log
syslog サービスを再起動して設定を反映する。
$ sudo /etc/init.d/rsyslog restart
sudo tail -f -n100 /var/log/cron.log #tailコマンドを使えばリアルタイムでcronの動作が確認できます。