自動観察日記

自動で観察したい

Raspberry PiカメラモジュールをPythonのライブラリで動かす

日光が少ないためか、葉をあまりつけないままアボカドが縦にどんどん長くなってしまい、カメラの枠に収まらなくなってきていました。

saibaimen.hatenadiary.jp

カメラの向きを90°回転させると良さそうだったのですが、少し問題があったので、それについて書きます。

よくわからない問題

これまで、一応Pythonでカメラは動かしていましたが、標準ライブラリのosモジュールで無理やりコマンドを送っていました。

saibaimen.hatenadiary.jp

ですが、次のような問題に悩まされました。

$ raspistill -t 0

(-tオプションで0にすると、シャッターの待ち時間が無限になる)

横向きだとちゃんと枠内に収まるのに
f:id:shut9:20180913015939p:plain

$ raspistill -t 0 -rot 270

-rotオプションで回転させると、枠内に収まらなくなる
f:id:shut9:20180913020439p:plain

これは画面内に収まっていないだけではなく、画像として保存してもこのままになっています。

picameraモジュールを使う

カメラモジュールはpicameraというライブラリで動かせるそうです。

$ pip install picamera

とりあえず次のようなプログラムを書きます。

import time
import picamera

camera = picamera.PiCamera()

def takepic(picname):
    camera.resolution = (600,800)
    camera.rotation = 270
    camera.start_preview()

    # Camera warm-up time                                                                                                               
    time.sleep(200)
    camera.capture(picname)

def main():
    takepic("test.png")

if __name__ == '__main__':
    main()

これで回転しても全体が映るようになりました。

f:id:shut9:20180913021152p:plain

camera.resolution = (600,800)

この部分で画像サイズを決めていますが、最大撮影解像度である3280x2464を超える数値を入力するとエラーが出ます。
はてなブログにアップロードしている画像のサイズが800x600なので、それを横向きにしたときに一致するサイズ(600, 800)としています。

プログラムの修正

温湿度取得と写真撮影をするプログラムを次のように修正しました。

#!/home/pi/.pyenv/shims/python                                                                                                                                                                              
# -*- coding: utf-8 -*-                                                                                                                                                                                     

import os
import Adafruit_DHT
import datetime
import RPi.GPIO as GPIO  #GPIOにアクセスするライブラリをimportします。                                                                                                                                      
import time
import picamera

now = datetime.datetime.now() # 現在の日時を取得                                                                                                                                                            
camera = picamera.PiCamera()

sensor = Adafruit_DHT.DHT22
pin = 4
degC = '℃'

GPIO.setmode(GPIO.BCM)  #GPIOへアクセスする番号をBCMの番号で指定することを宣言します。                                                                                                                      
GPIO.setup(18,GPIO.OUT) #BCMの18番ピン、物理的12番ピンを出力に設定します。                                                                                                                                  

def condition():
    humidity, temperature = Adafruit_DHT.read_retry(sensor, pin)
    discomfort = 0.81*temperature + 0.01*humidity*(0.99*temperature - 14.3) + 46.3

    return humidity, temperature, discomfort

def takepic():
    camera.resolution = (600,800)
    camera.rotation=270

    GPIO.output(18,GPIO.HIGH)
    time.sleep(2)
    camera.capture("/home/pi/log_condition/log_pic/{0:%Y%m%d%H}.png".format(now))
    time.sleep(1)
    GPIO.output(18,GPIO.LOW)

def main():
    # log current condition                                                                                                                                                                                 
    file = open('/home/pi/log_condition/log_TH/{0:%Y%m%d}.txt'.format(now), 'a+')  #書き込みモードでオープン                                                                                                
    humidity, temperature, discomfort = condition()
    # Markdown記法(半角スペース2個で改行)                                                                                                                                                                 
    file.write('時刻:{0:%Y/%m/%d %H:%M:%S}  \n'.format(now))
    file.write('湿度:{0:3.1f}%  \n'.format(humidity))
    file.write('温度:{0:3.1f} {1}  \n'.format(temperature,degC))
    file.write('不快指数:{0:3.1f} \n\n'.format(discomfort))

    #    take a picture                                                                                                                                                                                     
    takepic()

if __name__ == '__main__':
    main()

GPIO.cleanup()

この修正は9/8から反映されています。
saibaimen.hatenadiary.jp

Raspberry Pi カメラ用フラッシュの作製(3)

続きです

saibaimen.hatenadiary.jp

saibaimen.hatenadiary.jp

Raspberry PiのGPIOを制御する

RPI.GPIOをインストールします。

$ pip install rpi.gpio

次のようなコードを書いて動かすと、GPIO18から3.3Vをかけることができるようになります。
LEDを5秒おきに点灯-消灯を繰り替えすようにしています。

#!/home/pi/.pyenv/shims/python                                                                                                          
#coding=utf-8                                                                                                                           

import RPi.GPIO as GPIO  #GPIOにアクセスするライブラリをimportします。                                                                  
import time

GPIO.setmode(GPIO.BCM)  #GPIOへアクセスする番号をBCMの番号で指定することを宣言します。                                                  
GPIO.setup(18,GPIO.OUT) #BCMの18番ピン、物理的12番ピンを出力に設定します。                                                              

while True:
    GPIO.output(18,GPIO.HIGH)
    time.sleep(5)
    GPIO.output(18,GPIO.LOW)
    time.sleep(5)

Raspberry PiでパワーLEDを制御 - YouTube

(2)で作ったフラッシュを機能させる

以前作った、温湿度や写真を取得するプログラムを少し変えます。

#!/home/pi/.pyenv/shims/python                                                                                                          
# -*- coding: utf-8 -*-                                                                                                                 

import os
import Adafruit_DHT
import datetime
import RPi.GPIO as GPIO  #GPIOにアクセスするライブラリをimportします。                                                                  
import time

now = datetime.datetime.now() # 現在の日時を取得                                                                                        

sensor = Adafruit_DHT.DHT22
pin = 4
degC = '℃'

GPIO.setmode(GPIO.BCM)  #GPIOへアクセスする番号をBCMの番号で指定することを宣言します。                                                  
GPIO.setup(18,GPIO.OUT) #BCMの18番ピン、物理的12番ピンを出力に設定します。                                                              

def condition():
    humidity, temperature = Adafruit_DHT.read_retry(sensor, pin)
    discomfort = 0.81*temperature + 0.01*humidity*(0.99*temperature - 14.3) + 46.3

    return humidity, temperature, discomfort

def takepic():
    cmd = 'raspistill -n -o /home/pi/log_condition/log_pic/{0:%Y%m%d%H}.png -t 500 -q 15 -e'.format(now)
    GPIO.output(18,GPIO.HIGH)
    time.sleep(1)
    cmdact = os.popen(cmd)
    time.sleep(1)
    GPIO.output(18,GPIO.LOW)

def main():
    # log current condition                                                                                                             
    file = open('/home/pi/log_condition/log_TH/{0:%Y%m%d}.txt'.format(now), 'a+')  #書き込みモードでオープン                            
    humidity, temperature, discomfort = condition()
    # Markdown記法(半角スペース2個で改行)                                                                                             
    file.write('時刻:{0:%Y/%m/%d %H:%M:%S}  \n'.format(now))
    file.write('湿度:{0:3.1f}%  \n'.format(humidity))
    file.write('温度:{0:3.1f} {1}  \n'.format(temperature,degC))
    file.write('不快指数:{0:3.1f} \n\n'.format(discomfort))

    #    take a picture                                                                                                                 
    takepic()

if __name__ == '__main__':
    main()

GPIO.cleanup()

これでフラッシュが使えるようになりました。
(9/2くらいから動かしています)

その他

今回は最大1000 mAまで印加できるパワーLED使いましたが、本当は3000 mAまで印加できるもの(XM-L2 U31A)を用意していました。
ですが、1Wまでしか耐えられない抵抗を買ってしまっていたので、とりあえず安かったのでついでに買っていたXP-E R2WCを使いました。
でも実際に使ってみて、ぶっちゃけもっとIfの小さいLEDで良かったんじゃないかと思うくらい明るかったです。

Raspberry Pi カメラ用フラッシュの作製(2)

続きです
saibaimen.hatenadiary.jp

作りたい回路

作成したい回路のメインは、MOS FET(2SK4017)になります。
MOS FETはスイッチの役目を果たし、ゲートに一定以上の電圧がかかるとドレイン-ソース間に電流が流れるようになります。
そこで、次の図のような回路を作ることを考えます。

f:id:shut9:20180913004439j:plain

図の左側(ゲート-スイッチを含む回路)がトリガーとなって、図の右側(ドレイン-ソースを含む回路)のパワーLEDに電流が流れるような回路を作ります。

まずはパワーLED(CREE XLamp XP-E R2WC)に何 Aの電流を流したいか考えます。
今回使用するパワーLED
www.led-paradise.com

Vf : 3.05V(350mA) 3.5V(1000mA)

なので、とりあえず700 mA(LEDを長持ちさせるために、順電流の最大値に対して7~8割くらいに抑えると良いらしいです)くらい流したいと思うと、電源電圧5.3 Vの場合に必要な抵抗は
{ \displaystyle
R = \frac{電源電圧 - V_f }{ I_f \times0.7} = \frac{5.3 - 3.5}{700 \times 10^{-3}} \sim 2.6 \ {\rm \Omega}
}
になります。
ただ、今回は消費電力1 Wまででしか使用できない抵抗を購入したので、
{ \displaystyle
P = I^{2} \times R = 0.7^{2} \times 2.6 \sim 1.3 \ \rm {W}
}
となり、少し超えてしまいます。
そのために、安全に4 Ω入れておき、 { \displaystyle
I = \frac{電源電圧 - V_{f}}{抵抗} = \frac{5.3 - 3.5}{4} \sim 450 \ {\rm mA}
}

{ \displaystyle
P = I^{2} \times R = 0.45^{2} \times 4 \sim 0.8 \ {\rm W}
}
抵抗での消費電力は0.8 Wくらいになるように抑えておきます。

ということで、次のような回路を作ります。

f:id:shut9:20180913004331j:plain

作った回路

このような回路を作成しました。
写真上方の電源モジュールがLEDを点灯させ、写真下方の電源モジュールがスイッチの役目を果たします。
下方の電源モジュールは実際にはRaspberry PiのGPIOからの出力に置き換わります。
(そのため、上方のモジュールは5 V端子にジャンパーワイヤを挿していますが、下方のモジュールには3.3V 端子にジャンパーワイヤを挿しています。)
f:id:shut9:20180905171138j:plain

スイッチオフ時

Raspberry PiのGPIOからの出力が無い場合に相当。
LEDは点灯しない。
f:id:shut9:20180905171145j:plain

スイッチオン時

Raspberry PiのGPIOからの出力がある場合に相当。
LEDが点灯する。
f:id:shut9:20180905171151j:plain

スイッチオン時に可変抵抗を調整

LEDの明るさが変わる。
f:id:shut9:20180905171159j:plain

設置

先程の電源の3.3 V側(白いUSBの方)をRaspberry PiのGPIOに置き換えます。

こんな感じで設置しています。
f:id:shut9:20180905171211j:plain

せぼね君便利です。

ORIONS せぼね君 10連結 黒 CC-500-BL

ORIONS せぼね君 10連結 黒 CC-500-BL

続きます
次はRaspberry Piで制御します

今日の観察(2018/09/12)

時刻:2018/09/12 07:00:02
湿度:56.5%
温度:25.2 ℃
不快指数:72.7

時刻:2018/09/12 12:00:02
湿度:47.1%
温度:27.6 ℃
不快指数:74.8

時刻:2018/09/12 22:00:01
湿度:55.8%
温度:26.4 ℃
不快指数:74.3

f:id:shut9:20180912235005p:plain

今日の観察(2018/09/11)

時刻:2018/09/11 07:00:02
湿度:67.4%
温度:26.3 ℃
不快指数:75.5

時刻:2018/09/11 12:00:02
湿度:56.4%
温度:27.2 ℃
不快指数:75.5

時刻:2018/09/11 22:00:01
湿度:64.4%
温度:26.2 ℃
不快指数:75.0

f:id:shut9:20180911235005p:plain

今日の観察(2018/09/10)

時刻:2018/09/10 07:00:02
湿度:73.5%
温度:28.3 ℃
不快指数:79.3

時刻:2018/09/10 12:00:01
湿度:68.0%
温度:29.2 ℃
不快指数:79.9

時刻:2018/09/10 22:00:02
湿度:66.4%
温度:26.7 ℃
不快指数:76.0

f:id:shut9:20180910235006p:plain

今日の観察(2018/09/09)

時刻:2018/09/09 07:00:01
湿度:72.7%
温度:28.4 ℃
不快指数:79.3

時刻:2018/09/09 12:00:02
湿度:66.0%
温度:29.5 ℃
不快指数:80.0

時刻:2018/09/09 22:00:02
湿度:68.0%
温度:28.6 ℃
不快指数:79.0

f:id:shut9:20180909235010p:plain