利用树莓派制作智能感应灯

Aug 11,2019   4044 words   15 min

Tags: RaspberryPi

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灯配合不同容量的蓄电池。最终实现较低的成本。

本文作者原创,未经许可不得转载,谢谢配合

返回顶部