見出し画像

ラズパイでサソリの管理~ソフト編~

温湿度計を入れるために蓋を半開きにしていたら、脱走されちゃった。ちょっと運用方法考えなければ、、、
前回はハード設計、今回は制御のソフトを設計。

サソリ管理コード

仕様

今回の仕様はコレ
・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()

こんな感じでコードを書いた。
実際想定通りに動いている。問題は無い。

写真はわかる人にはわかる程度のものが撮れた。
手前の丸がケースの空気穴で、その奥にてを上げているのがサソリである。

画像1

可視化

ついでなので取得した、温湿度の可視化をする。

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

いいなと思ったら応援しよう!