昉·星光系列课程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音乐在单片机上的使用,在昉·星光开发板上实现通过蜂鸣器播放。