昉·星光系列课程11:昉·星光开发板火灾报警装置

昉·星光系列课程11:昉·星光开发板火灾报警装置

本次课程为昉·星光开发板IoT开发系列课程的第十一讲,将带领同学们在昉·星光开发板上,使用火焰传感器和蜂鸣器制作火灾报警装置。
本次课程,在昉·星光开发板V1和V2上,操作步骤相同。

一、学习目标

  • 学习昉·星光开发板通过火焰传感器探测火光,通过蜂鸣器进行报警

二、准备工作

在开始本次课程的实际操作之前,同学们需要做好一些准备工作,课程中涉及到的硬件如下:

  • 开发板:昉·星光开发板
  • 火焰传感器: 带AO输出的火焰传感器
  • 模数转换模块:ADS1115
  • 蜂鸣器:无源蜂鸣器
  • 杜邦线:若干

关于火焰传感器和ADS1115的具体使用,请提前阅读 昉·星光系列课程9:昉·星光开发板火焰传感器探测火光

三、蜂鸣器使用原理

本次课程中,使用的蜂鸣器模块具体如下:

蜂鸣器分为有源蜂鸣器和无源蜂鸣器。这里的源不是指电源,而是指蜂鸣器内部的是否带有震荡源。
有源蜂鸣器内部自带震荡源,只要给他电压就能发声,其使用也较为简单,开发板上的程序使用一个数字GPIO口控制其信号输入口即可,输出高电平就发出声音,输出低电平就不发声。不过,其发声的频率都是固定的,使用中无法变化。
无源蜂鸣器内部没有震荡源,直接输出高电平到其信号输入口不会使其发声,需要通过200~5KHz的方波才能驱动其发声。不同频率的方波,能带来音调的变化,通过控制频率和时长,能够实现midi单声道音乐的播放。
在这篇课程中,讲的是无源蜂鸣器的使用。有源蜂鸣器的使用,大家可以自己了解,没有任何难度。

四、无源蜂鸣器使用

通过上述无源蜂鸣器的原理,我们可以得知,要驱动其发声,需要给其提供一个200~5KHz频率的方波驱动信号。

因为200~5KHz的频率并不高,所以可以直接控制GPIO口的高低电平时间来实现方波的输出。

首先,将火焰传感器模块的AO接口与和ADS1115的A0接口相连,使得ADS1115能够获取火焰传感器输出的模拟电压信号。具体连接方式,请参考 昉·星光系列课程9:昉·星光开发板火焰传感器探测火光
然后,参考下图,将无源蜂鸣器连接到昉·星光开发板:

实物连接如下:

注意:
应根据实际使用的传感器,确定供电电压。本次课程中使用的火焰传感器模块和ADS1115模块,均使用5V供电电压,使用的无源蜂鸣器,可以使用5V或者3.3V供电,课程中为3.3V。

赛昉官方已经为我们提供了蜂鸣器测试的程序,可以从演示源代码 buzzer.py 下载,其具体内容如下:

'''
Please make sure the buzzer is connected to the correct pins.
The following table describes how to connect the buzzer to the 40-pin header.
-----------------------------------------
Passive Buzzer___Pin Number_____Pin Name
    VCC             1         3.3V Power
    GND             6           GND
    I/O             18          GPIO51
-----------------------------------------
'''

import VisionFive.gpio as GPIO
import time

buzz_pin = 12
ErrOutOfRange = 0

def setup():
    #Configure the direction of buzz_pin as out.
    GPIO.setup(buzz_pin, GPIO.OUT)
    #Configure the voltage level of buzz_pin as high.
    GPIO.output(buzz_pin, GPIO.HIGH)

def pitch_in_check():
    val_in = input('Enter Pitch (200 to 20000): ')
    val = float(val_in)

    if 200 <= val <= 20000:
        return val
    else:
        print('The input data is out of range (200 to 20,000 Hz). Please re-enter.')
        return ErrOutOfRange

def loop(pitch, cycle):
    delay = 1.0 / pitch
    cycle = int((cycle * pitch)/2)

    #Buzzer beeps.
    while cycle >= 0:
        GPIO.output(buzz_pin, GPIO.LOW)
        time.sleep(delay)
        GPIO.output(buzz_pin, GPIO.HIGH)
        time.sleep(delay)

        cycle = cycle - 1

def destroy():
    GPIO.output(buzz_pin, GPIO.HIGH)
    GPIO.cleanup()

if __name__ == '__main__':
    setup()
    try:
        #Input value of pitch (200 to 20,000 Hz).
        pitch = pitch_in_check()
        while pitch == 0:
            pitch = pitch_in_check()

        #Input value of cycle time (seconds).
        cycle_in = input("Enter Cycle (seconds): ")
        cycle = int(cycle_in)

        #The buzzer beeps with the specified pitch and cycle.
        loop(pitch, cycle)
    finally:
        destroy()

上述程序的关键部分,为loop(pitch, cycle),前者为频率,后者为播放时长。在loop()调用中,会根据频率,计算高低电平保持的时间,根据播放时长,计算需要循环的次数,从而实现特定频率的方波,并持续指定的时间。

要运行以上的程序,还需要安装相应的赛昉GPIO支持库,具体如下:

# 安装扩展库
sudo pip show VisionFive.gpio

编写完成后,运行 buzzer.py ,根据提示输入频率Pitch和循环时长Cycle,即可驱动蜂鸣器发声。

python3 buzzer.py

驱动蜂鸣器发声成功后,我们再编写一个程序buzzer_alarm.py,让蜂鸣器能够交替以两种频率发声,具体代码如下:

# -*- coding: utf-8 -*-
# file: ~/projects/buzzer/buzzer_alarm.py
import VisionFive.gpio as GPIO
import time

buzz_pin = 12
ErrOutOfRange = 0

def setup():
    #Configure the direction of buzz_pin as out.
    GPIO.setup(buzz_pin, GPIO.OUT)
    #Configure the voltage level of buzz_pin as high.
    GPIO.output(buzz_pin, GPIO.HIGH)

def loop(pitch, cycle):
    delay = 1.0 / pitch
    cycle = int((cycle * pitch)/2)

    #Buzzer beeps.
    while cycle >= 0:
        GPIO.output(buzz_pin, GPIO.LOW)
        time.sleep(delay)
        GPIO.output(buzz_pin, GPIO.HIGH)
        time.sleep(delay)

        cycle = cycle - 1

def destroy():
    GPIO.output(buzz_pin, GPIO.HIGH)
    GPIO.cleanup()

if __name__ == '__main__':
    setup()
    try:
        while True:
            pitch = 1200
            cycle = 1
            loop(pitch, cycle)

            pitch = 1000
            cycle = 1
            loop(pitch, cycle)
    finally:
        destroy()

编写完成后,运行 buzzer_alarm.py,蜂鸣器就会以两种不同的音调,交替发声了。

python3 buzzer_alarm.py

五、火灾报警器功能实现

无源蜂鸣器使用 部分,已经能够驱动蜂鸣器发声了,再结合 昉·星光系列课程9:昉·星光开发板火焰传感器探测火光,当检测到火光强度高于一定阈值的时候,就驱动蜂鸣器发声,从而实现火灾报警的功能。

具体的代码如下:

# -*- coding: utf-8 -*-
# file: ~/projects/buzzer/fire_alarm.py
import VisionFive.gpio as GPIO
import ADS1115
import time
import numpy
import smbus2

FIRE_ALARM_VALUE = 40
buzz_pin = 12

# 初始化ADS1115模块
ads = ADS1115.ADS1115()

def setup():
    #Configure the direction of buzz_pin as out.
    GPIO.setup(buzz_pin, GPIO.OUT)
    #Configure the voltage level of buzz_pin as high.
    GPIO.output(buzz_pin, GPIO.HIGH)

def loop(pitch, cycle):
    delay = 1.0 / pitch
    cycle = int((cycle * pitch)/2)

    #Buzzer beeps.
    while cycle >= 0:
        GPIO.output(buzz_pin, GPIO.LOW)
        time.sleep(delay)
        GPIO.output(buzz_pin, GPIO.HIGH)
        time.sleep(delay)

        cycle = cycle - 1

def destroy():
    GPIO.output(buzz_pin, GPIO.HIGH)
    GPIO.cleanup()

if __name__ == '__main__':
    setup()
    try:
        while True:
            # 读取ADS1115模块通道0的数据,也就是A0
            volt = ads.readADCSingleEnded(0)

            # 转换
            per = numpy.interp(volt, [0, 5000], [0, 100])

            # 输出信息
            print("%d mV of A0, val is %f" % (volt, per))

            if per >= FIRE_ALARM_VALUE:
                print("    Fire Alarm!!!")
                pitch = 800
                cycle = 0.2
                loop(pitch, cycle)

                pitch = 1000
                cycle = 0.2
                loop(pitch, cycle)
            else:
                time.sleep(1)
    finally:
        destroy()

在上面的程序中,先通过ADS1115获取火焰传感器的检测数据,然后检查该数据是否达到了阈值,如果达到了,则驱动蜂鸣器发声,否则不发声。

编写完成后,运行 fire_alarm.py,蜂鸣器默认不会发声,如果使用火光靠近火焰传感器,达到一定距离内,将会发声,并且使用不同的频率变化。

python3 fire_alarm.py

本课程实际测试的情况如下:

测试时,没有检测到时,火焰传感器模拟输出结果数值较小。
当使用火柴火焰靠近到一定距离时,火焰传感器的模拟输出结果显著上升超过40,从而触发报警,并使用不同的频率交替发声提醒注意。

六、总结

在本次课程中,我们学习了无源蜂鸣器的使用,以及配合火焰传感器,实现火灾报警的功能。
在实际应用中,往往需要多种外部设备相互配合,来实现特定的功能。火灾报警的功能,除了配合蜂鸣器发生声音警告,还可以配合使用红色灯光闪烁警告。

七、课后作业

  • 了解蜂鸣器的具体使用
  • 完善演示程序,根据检测到的火光强度,实现不同音调(频率)的报警
  • 结合烟雾传感器,根据检测到的烟雾强度,实现烟雾报警
  • 了解midi音乐在单片机上的使用,在昉·星光开发板上实现通过蜂鸣器播放。

八、参考资料

2 Likes