アメグラ2号のブログ

1980年代後半の古き良きビデオゲームのほか、オッサンの個人的備忘録

ラズパイ LED点滅しながら撮影

f:id:game-allergy:20210422123309j:plain

ラズパイで定時撮影をしようと思ったが、夜間は何かしら照明をつけて撮影したい。真っ暗では撮影ができないし、当たり前か。

それならLEDを点灯させながら撮影したらええやん。

ってことでやってみようとしたら、あ~~~これ、並列処理なのか。。。。


スクリプト(撮影、LED点滅)

#! /usr/bin/env python3
# ===================================
# 【機能】:撮影
# 【機能】:LED点滅
# 【備考】:撮影、LED点滅の並列制御
# ===================================

import RPi.GPIO as GPIO
import time,datetime
import sys
import threading
import picamera

# ===================================
# 関数
# ===================================

# LED on/off
def ledonoff():
  print("Start led on/off")
  GPIO.setmode(GPIO.BCM)
  GPIO.setup(4,GPIO.OUT)

  while flag:
    try:
      GPIO.output(4,GPIO.HIGH)
      time.sleep(1)

      GPIO.output(4,GPIO.LOW)
      time.sleep(1)

    except KeyboardInterrupt:
      GPIO.output(4,GPIO.LOW)
      GPIO.cleanup()
      sys.exit()

# LED off and clearup
def ledoff():
  GPIO.setmode(GPIO.BCM)
  GPIO.setup(4,GPIO.OUT)
  GPIO.output(4,GPIO.LOW)
  time.sleep(1)
  GPIO.cleanup()
  sys.exit()

  print("Led off, done")

# Take a photo
def TakePhoto():
  time.sleep(2)
  now1 = datetime.datetime.now()
  now2 = now1.strftime('%Y%m%d_%H%M_%S')
  now3 = '/var/www/html/weather/fig/' + now2 + '.jpg'
  with picamera.PiCamera() as camera:
    camera.resolution = (640, 480)
    camera.start_preview()
    time.sleep(2)
    camera.capture(now3)
    time.sleep(5)

    print("Take a photo, done")

# ===================================
# 実行
# ===================================
# Create instance
thread1 = threading.Thread(target=ledonoff)
thread2 = threading.Thread(target=TakePhoto)

# start both of processes
flag=True
thread1.start()
thread2.start()

# Meeting up both of processes
# thread2[End thread]
# Taking photo is over,then flag's changed
thread2.join()
flag=False

# thread1[End thread]
# LED on/off is over
thread1.join()

# process for Led off
ledoff()

print("--------------------")
print("end of line")

最初は並列処理の意味が分からず、単にLEDをONにしてカメラ撮影をし、最後にLEDをOFFにする逐次処理をした。それはそれでできるんだけど、これでは制御とは言えないよな。

ということでググったら複数タスクを同時に処理=並列処理というものがあると。。。

処理したいタスクは「撮影」「LED点滅」の2つ。撮影が終わったらLED点滅も終了させる。これだけ。

これだけなのに、、、LED点滅処理がwhileループで終わってくれない…これでけっこうハマった。LED点滅自体をループにしないで回数制限を設けて終了させれば良いんだろうけど、、、これだとなんかやりたいことから逃げたような気がするし、、、逃げちゃダメだ、戦えオレ。

で、ほかの方のを参考にすると、ループの抜け方に「True」フラグを使っている点。
あー、なるほど、撮影処理が終了したらフラグをfalseにしてあげればLEDのループが終了し、スレッドが無事に終了になってくれるのか。素晴らしい~。


ということで今回はthreadingを使って2つのタスクを同時処理を進める方法を確認できた。次はカラーLEDを点灯して撮影してみようかな。