2015年4月11日 星期六

AMIGO Camera 開發記錄


經過細心的修正,紅外線相機的頂蓋終於能較為平滑地打印出來。外殻已經完成,線亦配好了,按鍵測試也完成了。接著是真正的編程部份。我的紅外線相機設計有兩顆按鈕:一顆用來拍攝;另一顆用來關機。畢竟 Raspberry Pi 是跑 Linux,不正當關機有可能導致下一次無法正常開機,還是小心駛得萬年船。

之前三個測試程式已經包含了影相程式的核心功能,還欠關機的程式。這個非常簡單,用一句指令就能達到:
os.system("shutdown now -h")
現在各個功能都測試好了,正式將所有東西拼在一起:
#!/usr/bin/python
##------------------------------------------------------------
##  AMIGO Camera Version 1.00
##  Copyright Pacess Studio, 2015.  All rights reserved.
##------------------------------------------------------------

import RPi.GPIO as GPIO
import picamera
import os.path
import time

##------------------------------------------------------------
##  Global variables
counter = 1
counterFile = ".counter"
folder = "/home/pi/camera/DCIM/"

camera = picamera.PiCamera()
camera.led = False

##------------------------------------------------------------
##  Function
def captureNow(channel):
    global camera
    global counter

    ##with picamera.PiCamera() as camera:
    filename = folder+"RPi_{0:05d}.jpg".format(counter)
    print "Capturing "+filename+"..."

    try:
        camera.led = True
        camera.rotation = 180
        camera.resolution = (2592, 1944)
        camera.exif_tags["IFD0.Copyright"] = "Copyright (c) 2015 Pacess Studio.  All rights reserved."
        camera.exif_tags["EXIF.UserComment"] = "AMIGO Camera"
        camera.capture(filename)
        camera.led = False

        ##  Update counter to file
        counter = counter+1
        file = open(folder+counterFile, "wb")
        file.write(str(counter))
        file.close()

    finally:
        print "Done"

##------------------------------------------------------------
def shutDownNow(chanel):
    print "Shutdown now..."
    os.system("shutdown now -h")

##============================================================
##  Program start
##============================================================
print "AMIGO Camera Version 1.00"

##------------------------------------------------------------
##  Check if file exists
isFile = os.path.isfile(folder+counterFile)
if isFile:

    ##  Read file content
    with open(folder+counterFile) as file:
        counter = int(file.read())

print "Counter: "+str(counter)

##------------------------------------------------------------
##  Setup pins
GPIO.setmode(GPIO.BCM)
GPIO.setup(20, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(21, GPIO.IN, pull_up_down=GPIO.PUD_UP)

GPIO.add_event_detect(20, GPIO.RISING, callback=captureNow, bouncetime=2000)
GPIO.add_event_detect(21, GPIO.RISING, callback=shutDownNow, bouncetime=2000)

print "Setup GPIO done, ready..."

##------------------------------------------------------------
##  Main loop
try:
    while True:
        time.sleep(1)

finally:
    ##------------------------------------------------------------
    ##  Clean up
    GPIO.remove_event_detect(21)
    GPIO.remove_event_detect(20)

GPIO.cleanup()
考慮到有機會在很短的時間內拍攝多張相片,我把本來官方範例中的熱身時間取消;同時把「with picamera.PiCamera() as camera:」這種寫法改為「camera = picamera.PiCamera()」廣域變量,使得程式不用每次都重新設定鏡頭,也不用熱身時間。不過這個做法會令鏡頭旁的紅燈長時間亮起,因此在程式開首加入了:
camera.led = False
原本 folder 的值是 Relative,但發現系統會找不到目錄;要改為完全路徑來解決問題。
folder = "/home/pi/camera/DCIM/"
為了在 Raspberry Pi 啟動後知道 AMIGO Camera 有在執行,因此在程式中加入了幾句 print 指令,順便能檢視數值有沒有不妥的地方。

最後就是開機設定。要令 Python 程式能在啟動時執行,我利用了 /etc/rc.local:
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
  printf "My IP address is %s\n" "$_IP"
fi

/home/pi/camera/bootup.sh &

exit 0
我沒有直接在 rc.local 執行拍照程式,改為執行拍照程式目錄內的 bootup.sh。這個 bootup.sh 內才執行拍照程式,為的是比較有結構地管理及備份。
#!/bin/sh
sudo python /home/pi/camera/camera.py

沒有留言: