1.目的与效果介绍
本篇博客灵感来源于某宝上的这个商品。
看到了之后觉得并没有多少技术含量还卖的不便宜。所以便想尝试利用手上的树莓派和传感器自己实现一个智能感应灯,做到真正的“人来即亮、人走即灭”。分别基于红外障碍传感器、超声波测距传感器以及红外人体传感器配合LED灯,从不同方式实现了功能。最终做好的效果如下视频演示。
2.硬件准备
(1)树莓派
这个就不用多说了,准备好可用的树莓派以及稳定的电源即可。
(2)LED灯
如下图所示,相关介绍与使用可以参考这篇博客。
(3)红外避障传感器
如下图所示,相关介绍可以参考这篇博客。
(4)超声波测距传感器
如下图所示,相关介绍可以参考这篇博客。
(5)人体传感器
如下图所示,其基本原理是利用人体会发出红外线这一特性进行检测。传感器由白色的菲涅尔透镜遮罩,当有人进入感应范围时输出高电平,否则输出低电平。其工作电压为4.5-20V,因此必须连接在树莓派的5V GPIO口上,否则不工作。 由于其感应范围在7-10m左右,其实并不太适合本篇博客的需求,因此实际实现中并没有使用它,仅作为学习。更详细的介绍可以参考这个网页。
这里主要是为了演示不同传感器的用法所以准备的多一些,如果只是想实现功能,不需要准备这么多,以上三个传感器三选一即可,如直接树莓派+LED+红外避障传感器。
3.软件准备
整个代码并没有用到什么特别的库,因此无需特别准备软件环境。硬要说的话就是Python的GPIO控制库,如果没有的话直接pip install RPi.GPIO
即可。
4.代码编写
(1)传感器使用
对于每一个传感器都编写了一个简单的demo方便学习,都放在了Github的仓库里,点击查看,均以sensor_
开头。
这里为了节省篇幅就不贴之前说过的传感器了,人体传感器的使用demo如下。
# coding=utf-8
import RPi.GPIO as GPIO
import time
time_out = 2
human = 35
GPIO.setmode(GPIO.BOARD)
GPIO.setup(human, GPIO.IN)
try:
while True:
if (GPIO.input(human) == True):
print time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())) + " Someone is here!"
else:
print time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())) + " No one!"
time.sleep(time_out)
except:
pass
GPIO.cleanup()
运行上述代码即可开启人体传感器,注意这里我是插在GPIO的35号针脚上的。
(2)智能小灯
要想实现“人来即开、人走即关”的目标,就是需要让传感器一直在检测,若满足条件,则开启LED灯,反之关闭。因此代码逻辑相对简单,这里直接放代码,代码在Github项目中也有。
# coding=utf-8
import RPi.GPIO as GPIO
import time
import sys
def ledLightRed(pinR, colorR=255, durTime=2):
GPIO.setmode(GPIO.BOARD)
GPIO.setup(pinR, GPIO.OUT)
pwmR = GPIO.PWM(pinR, 70)
pwmR.start(0)
R = 100 - int((colorR / 255.0) * 100)
pwmR.ChangeDutyCycle(R)
time.sleep(durTime)
pwmR.stop()
GPIO.cleanup()
def getDistance(trig_pin, echo_pin):
GPIO.setmode(GPIO.BOARD)
GPIO.setup(trig_pin, GPIO.OUT, initial=GPIO.LOW)
GPIO.setup(echo_pin, GPIO.IN)
GPIO.output(trig_pin, GPIO.HIGH)
time.sleep(0.00015)
GPIO.output(trig_pin, GPIO.LOW)
while not GPIO.input(echo_pin):
pass
t1 = time.time()
while GPIO.input(echo_pin):
pass
t2 = time.time()
GPIO.cleanup()
return (t2 - t1) * 340 * 100 / 2
def isHumanThereUltraSonic(trig_pin, echo_pin, lowTh, highTh):
dist = getDistance(trig_pin=trig_pin, echo_pin=echo_pin)
print "distance", dist, " cm"
if lowTh <= dist <= highTh:
return True
else:
return False
def isHumanThereInfrared(GPIO_PIN):
GPIO.setmode(GPIO.BOARD)
GPIO.setup(GPIO_PIN, GPIO.IN)
# 当有障碍物时,传感器输出低电平,所以检测低电平
if GPIO.input(GPIO_PIN) == 0:
GPIO.cleanup()
return True
else:
GPIO.cleanup()
return False
if __name__ == '__main__':
# config parameters
sleepTime = 1 # sample interval
pinInfra = 37 # GPIO pin number(BOARD) of infrared obstacle sensor
pinTrig = 7 # trig GPIO pin number(BOARD) of ultrasonic distance sensor
pinR = 36 # GPIO pin number(BOARD) of LED
pinEcho = 11 # echo GPIO pin number(BOARD) of ultrasonic distance sensor
th_low = 10 # low distance threshold(unit:cm) for ultrasonic distance sensor
th_high = 50 # high distance threshold(unit:cm) for ultrasonic distance sensor
if len(sys.argv) == 1:
print "======Use infrared sensor as default======"
while True:
isHuman = isHumanThereInfrared(pinInfra)
if isHuman is True:
print "there is a person"
ledLightRed(pinR=pinR, durTime=sleepTime)
else:
print "there is no person"
time.sleep(sleepTime)
elif len(sys.argv) == 2:
flag = sys.argv[1]
if flag == "infra" or flag == "Infra" or flag == "INFRA":
print "======Use infrared sensor======"
while True:
isHuman = isHumanThereInfrared(pinInfra)
if isHuman is True:
print "there is a person"
ledLightRed(pinR=pinR, durTime=sleepTime)
else:
print "there is no person"
time.sleep(sleepTime)
elif flag == "ultra" or flag == "Ultra" or flag == "ULTRA":
print "======Use ultrasonic sensor======"
while True:
isHuman = isHumanThereUltraSonic(pinTrig, pinEcho, th_low, th_high)
if isHuman is True:
print "there is a person"
ledLightRed(pinR=pinR, durTime=sleepTime)
else:
print "there is no person"
time.sleep(sleepTime)
else:
print "check input parameters."
else:
print "check input parameters."
为了兼容多个传感器,因此在代码中将不同传感器以启动参数的形式指定,若不指定默认则是使用红外避障传感器。 红外避障传感器传感器的逻辑是当检测到有障碍物时即认为有人,打开LED灯,否则关闭。超声波测距传感器的逻辑是根据距离范围进行判断,有一个低阈值和一个高阈值,只有当物体距离在这个阈值范围内才认为有人,太远、太近都认为没人。
此外在使用时需要注意你的传感器GPIO接口是否与代码中的一致,或者插好之后修改代码中的数字。
5.总结
总体而言,本篇博客实现的功能从技术上不复杂,和光控、声控灯没有本质的区别。但因为突出了“人来即开、人走即关”的特点,让人觉得有种智能的感觉、相对新奇,所以才会在淘宝上卖得出去。但只要仔细分析就会发现其实实现并不难。 当然如果要做到商品的级别,还需要考虑很多因素,如成本等。不可能一个20多块的智能灯内部放一个300多的树莓派,所以应该会使用低成本单片机进行控制,并选用低能耗的LED灯配合不同容量的蓄电池。最终实现较低的成本。
本文作者原创,未经许可不得转载,谢谢配合