Raspberry And Cam

前言

春节期间家里长期没人,想做个大门口的监控。现在有些不错的“智能”摄像头,能做到有活物报警等,但考虑到未来的扩展性和灵活性,再加上玩票,选择了树莓派。

材料准备

采购

  • 树莓派2代B型 raspberry pi2 model B 现货 喜迎春节[交易快照]200.00
  • 包邮 树莓派摄像头500万像素RASPBERRY PI RPI CAMERA OV5647模块[交易快照] 72.90
  • EDUP EP-N8508GS黄金版 迷你USB无线网卡 树莓派专用[交易快照] 27.00
  • 树莓派摄像头延长线500mm 加长排线 50CM Raspberry Pi camera[交易快照] 3.00
  • YS-18 HC-SR501 人体红外感应模块 进口探头 防盗感应开关模块[交易快照] 3.70
  • 电磁式蜂鸣器5V 采用SOT塑封管 5V有源蜂鸣器 蜂鸣器[交易快照] 0.39
  • LED灯实验包 包含10个LED+10个电阻 适合树莓派MCU入门[交易快照] 2.97
  • 40P 杜邦公头转母头 杜邦线 公对母 面包线 20CM长 40根一排 特价[交易快照] 2.81

自有

  • SD 卡16G
  • USB电源转换器
  • USB 线
  • 胶带、双面胶、硬纸壳(给摄像头和人体感觉模块粘了个外壳)
  • 冰雪聪明才智

配置

树莓派系统

https://www.raspberrypi.org/downloads/raspbian/ 下载 RASPBIAN JESSIE 镜像,然后按 镜像安装说明把下载的 raspbian 写到 SD 卡中,把 sd 卡插入树莓派;把 usb 无线网卡插到树莓派;把网张插入树莓派;把 usb 线插入树莓派,不出意外的话树莓派上的有些灯就亮了,启动了。

ssh 登陆树莓派(默认主机名是raspberrypi,默认密码是 raspberry),先配置无线网卡,vi 打开文件 /etc/wpa_supplicant/wpa_supplicant.conf,插入下面4行:
network={
ssid=”YOUR_SSID”
psk=”YOUR_WIFI_PASSWORD”
}

然后试试能否用无线连上。

更新系统

  • 把更新源换为日本的(日本的感觉比较快)(把所有行注释掉,添加一行

    1
    deb http://ftp.jaist.ac.jp/raspbian jessie main contrib non-free rpi
    1
    2
    3
    4
    5
    6
    sudo apt-get update
    sudo apt-get upgrade
    sudo rpi-update
    sudo apt-get install python-rpi.gpio
    sudo apt-get install python3-rpi.gpio
    sudo reboot

系统配置(扩展文件系统和打开摄像头模块)

sudo raspi-config
选择1 Expand Filesystem,回车
选择 5 Enable Camera,Enable,回车
然后到主菜单后,按右箭头,选中 Finish 后,回国,是否重启时,选择重启;
关机(拔电源)后,把摄像头装上(注意别装在 Dispaly 槽了,两个插口差不多,我为这事搞了一晚上奇怪为何摄像头检测不到呢)

应用

把摄像头和人体红外感应模块穿过防盗门,贴在门外,然后把红外感应模块和树莓派连起来;我在树莓派上又装了一个 LED 灯和蜂鸣器
下面是代码(python3是现学的,写的比较渣。本来是用的多线程和锁机制,以让录像的同时 led 闪、蜂鸣器响,但不知道为何重复触发时树莓派就死机,就单线程了):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#!/usr/bin/env python3

import RPi.GPIO as GPIO
import os
import time
import threading

HCPIN = 12
LEDPIN = 11
BUZZPIN = 13

phone_dir = '/mnt/doorkeeper/'
temp_dir = '/home/pi/temp'
#mutex = threading.Lock()
#log_lock= threading.Lock()

#初始化
def init():
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(HCPIN,GPIO.IN)
GPIO.setup(LEDPIN,GPIO.OUT)
GPIO.setup(BUZZPIN,GPIO.OUT)

def capture():

mylog('prepare start to capture.')
filename="video-" + time.strftime("%Y%m%d%H%M%S", time.localtime()) + ".h264"
h264absfile = os.path.join(temp_dir,filename)

#if mutex.acquire(1):
try:
mylog("capture start.")
os.system("raspivid -w 1280 -h 720 -t 15000 -fps 20 -o " + h264absfile )
mylog("capture end.")

# 文件存在,开始编码转换为mp4
if os.path.exists(h264absfile):
subdir = time.strftime("%Y%m%d", time.localtime())
mp4dir = os.path.join(phone_dir, subdir)

if not os.path.exists(mp4dir):
mylog("mkdir " + mp4dir)
os.mkdir(mp4dir)
mp4filename= filename + ".mp4"
mp4absfile = os.path.join(mp4dir, mp4filename)
mylog("encode " + mp4absfile+ " start.")
os.system("MP4Box -quiet -fps 20 -add " + h264absfile + " " + mp4absfile)
os.remove(h264absfile)
mylog("encode h264:" + h264absfile + " to mp4file:" + mp4absfile + " end.")
else:
mylog("encode cancel(file " + h264absfile + " not exists.")
finally:
pass
# mutex.release()

#else:
# mylog("acquire lock fail, capture cancel.")


#感应器侦测函数
def detct():
while(1):
#normal()
#如果感应器针脚输出为True,则打印信息并执行蜂鸣器函数
if GPIO.input(HCPIN) == True:
mylog("somebody there!")
shine(2)
else:
#mylog("none")
time.sleep(2)


def shine(t):
#t1 = threading.Thread(target=capture)
#t1.start()

trys = int(t) * 1;
try:
while trys > 0:
GPIO.output(LEDPIN,GPIO.HIGH)
GPIO.output(BUZZPIN,GPIO.HIGH)
time.sleep(0.1)
GPIO.output(LEDPIN,GPIO.LOW)
GPIO.output(BUZZPIN,GPIO.LOW)
time.sleep(0.1)
trys -= 1
## 获取
capture()
finally:
GPIO.output(LEDPIN,GPIO.LOW)
GPIO.output(BUZZPIN,GPIO.LOW)

def normal():
mount_nfs_flag = os.popen("mount -l | grep doorkeeper | wc -l").read()
mount_nfs_flag = int(mount_nfs_flag)
if mount_nfs_flag <= 0:
mylog("mount fail? remount nfs")
os.system("sudo mount.nfs 192.168.0.117:/volume1/doorkeeper /mnt/doorkeeper -o nolock")

min=int(time.strftime("%M"))
sec=int(time.strftime("%S"))
if min % 10 == 0 and sec % 60 <= 4 :
t1 = threading.Thread(target=capture)
t1.start()

trys = 2
while trys > 0:
GPIO.output(LEDPIN,GPIO.HIGH)
GPIO.output(BUZZPIN,GPIO.HIGH)
time.sleep(0.25)
GPIO.output(LEDPIN,GPIO.LOW)
GPIO.output(BUZZPIN,GPIO.LOW)
time.sleep(0.25)
trys -= 1

def mylog(l):
#if log_lock.acquire(5):
try:
print(time.strftime("%Y-%m-%d %H:%M:%S"), l)
f = open('/var/log/doorkeep.log', 'a')
f.write(time.strftime("%Y-%m-%d %H:%M:%S ") + l + "\n")
f.close()
finally:
pass
# log_lock.release()


time.sleep(5)
init()
shine(2)
detct()

GPIO.cleanup()

效果

上门的效果,外壳好黑好丑(没找到合适的壳):

上门效果

下面是拍到的打扫楼道的阿姨。发现物业较差,好几天才打扫一次。

其它

问题

这个摄像头不是鱼眼摄像头,范围有限;在楼道较暗,如果楼道的声控灯没开,效果很差。

扩展

可以通过 bypy 把文件同步到云盘。可以写个 app,有人时发送消息,查看录像;可接个 mic 和小喇叭来对话;可换个鱼眼+红外摄像头;可再接个陀机。

看来,得搞台 ECS了。。。