ラズパイでサソリの管理~ソフト編~
温湿度計を入れるために蓋を半開きにしていたら、脱走されちゃった。ちょっと運用方法考えなければ、、、
前回はハード設計、今回は制御のソフトを設計。
サソリ管理コード
仕様
今回の仕様はコレ
・10分に一回温湿度測定
・温度(temp)湿度(hum)をCSVに記録
・夜中0~6時は10分に一回写真撮影
設計思想
温湿度測定のクラスとカメラ撮影のクラス作る。
測定時間が起動時間に依存しないように分(minute)が10で割れるときに走らせる。
一日の開始を6時として、次の日の5時59分までを1つのCSVにまとめる。
# モジュールのインポート
from time import sleep
from datetime import datetime, timedelta
import os
import RPi.GPIO as GPIO
#from DHT11_Python import dht11
import dht11
from picamera import PiCamera
# pathの設定
PATH = '/home/pi/Scorpion/'
TEMP_SENSOR_PIN = 4
INTERVAL = 60
LED_PIN = 24
# initialize GPIO
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(LED_PIN, GPIO.OUT)
# 温湿度センサークラス
class SensorClass():
# 温湿度測定
def GetTemp(self):
instance = dht11.DHT11(pin=TEMP_SENSOR_PIN)
result = instance.read()
# もし取得できなかったら99.9、99.9を返すようにする
if result.is_valid():
return result.temperature, result.humidity
else:
return 99.9, 99.9
# CSVに記録
# CSVの下に['取得時間','温度','湿度']を追記していく
def writeTemp(self):
f = open(PATH + 'SensorData' + today.strftime('%Y%m%d') + '.csv','a')
f.write(datetime.now().strftime('%Y-%m-%d %H:%M:%S')+','+str(temp)+','+str(hum)+'\n')
f.close()
return
# カメラクラス
class PicClass():
# 写真撮影
def takepic(self):
pdir = 'pic'+today.strftime('%Y%m%d')
os.makedirs(PATH+pdir, exist_ok =True)
# 赤外線のフラッシュ
GPIO.output(LED_PIN,True)
sleep(0.5)
with PiCamera() as camera:
# ラズパイを横に置くのでカメラを回転させる
camera.rotation = 90
# 画像サイズ
camera.resolution = (640, 480)
camera.start_preview()
sleep(2)
camera.capture(PATH+pdir+'/img'+datetime.now().strftime('%Y%m%d%H%M%S')+'.png')
GPIO.output(LED_PIN,False)
return
# クラスのインスタンス化
env = SensorClass()
pic = PicClass()
try:
while True:
# 00,10,20,30,40,50分で走らせる
if datetime.now().minute%10 == 0:
today = datetime.now()-timedelta(hours=6)
temp, hum = env.GetTemp()
# コンソールにも温湿度を表示
print('time{}, temp{}, hum{}'.format(datetime.now(),temp,hum))
env.writeTemp()
# 0~6時はカメラを起動
if datetime.now().hour < 6:
pic.takepic()
# 9分50秒スリープさせる
sleep(590)
except KeyboardInterrupt:
print("Cleanup")
GPIO.cleanup()
こんな感じでコードを書いた。
実際想定通りに動いている。問題は無い。
写真はわかる人にはわかる程度のものが撮れた。
手前の丸がケースの空気穴で、その奥にてを上げているのがサソリである。
可視化
ついでなので取得した、温湿度の可視化をする。
import time
from datetime import datetime
import numpy as up
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib as mpl
# 取得した日付
date = 20210421
# ヘッダーは無し、renameで明記してあげる
df = pd.read_csv('<CSVのpath>'+str(date)+'.csv', header=None).rename(columns={0:'time',1:'temp',2:'hum'})
df['time'] = pd.to_datetime(df['time'])
df['temp'][df['temp'] == 99.9] = None
df['temp'] = df['temp'].interpolate()
df['hum'][df['hum'] == 99.9] = None
df['hum'] = df['hum'].interpolate()
fig = plt.figure(figsize=(15,8))
# 2軸
ax1 = fig.add_subplot(111)
ln1 = ax1.plot(df['time'], df['temp'], label='temp', color="blue")
ax2 = ax1.twinx()
ln2 = ax2.plot(df['time'], df['hum'], label='hum', color="orange", linestyle="dotted")
h1, l1 = ax1.get_legend_handles_labels()
h2, l2 = ax2.get_legend_handles_labels()
ax1.legend(h1+h2, l1+l2, loc='lower right')
# 横軸
xloc = mpl.dates.HourLocator()#byhour=None
plt.gca().xaxis.set_major_locator(xloc)
xfmt = mpl.dates.DateFormatter("%H:%M")
plt.gca().xaxis.set_major_formatter(xfmt)
# ラベル
ax1.grid(True)
ax1.set_xlabel('time')
ax1.set_ylim(15,40)
ax1.set_ylabel('temp')
ax2.set_ylim(50,100)
ax2.set_ylabel('hum')
青が温度で、オレンジが湿度
湿度が尖っている2か所は多分手入れのため蓋を開けた時だと思う。湿度は測定限界の95%をほぼキープしている。
温度は大体20~30℃の間を保っている。
ケース真下にヒーターがあり温湿度計がケースの上にあるため、サソリのいる地表とは少し異なると思うが、大体の環境がわかる。
まとめ
ラズパイでやりたかったことはできた。
あとやりたいことは、
・データをGoogleDriveに送信すること
・ラズパイの設置位置(軽すぎて安定しない)
・ケースの配線(脱走しないようにセンサーをケースに入れる)
などなど、、、
こんな感じてサソリちゃんの管理はOK