行空板,新一代国产开源硬件平台,仅需2步,即可让你轻松开启Python学习之路。 
 
多功能提醒器  
 
 
 
生活中,我们对于声音并不陌生,美妙动听的音乐令人陶醉,节奏感十足的鸣笛声令人警醒,然而,当音量达到一定的强度,妨碍到人们正常休息、学习和工作,声音就会成为噪音。 
 
与此同时,闹钟在许多小伙伴的生活中也有着举足轻重的作用,它能及时提醒我们时间。 
 
在这节课上,让我们一起来制作一个多功能提醒器吧,一方面监测环境音量并在音量过大时进行警告,另一方面实时显示时间,在达到指定时间后提醒我们。 
 
 
 
任务目标 
 
功能1:将通过麦克风检测到的环境音量显示在屏幕上,同时,设定一个噪音阈值,当音量超过阈值时使蜂鸣器发声进行警告。 
 
功能2:在屏幕上显示一个时钟,当到达设定的时间后,进行提醒。 
 
知识点 
 
1、了解声音及相关概念 
 
2、认识麦克风和蜂鸣器 
 
3、学习使用Pinpong库使蜂鸣器发声的方法 
 
4、学习使用unihiker库检测环境音量的方法 
 
5、学习使用unihiker库显示填充矩形、填充时钟的方法 
 
材料清单 
 
硬件清单: 
 
 
 
软件使用:Mind+编程软件x1 
 
知识储备 
 
1、声音及相关概念 
 
物理中声音是由物体振动发生的,正在发声的物体叫做声源。 
物体在一秒钟之内振动的次数叫做频率,单位是赫兹。 
响度是指人主观上感觉声音的大小,俗称音量。响度由振幅和与声源之间的距离决定,振幅越大,响度越大,和声源的距离越小,响度越大。 
音调是指声音的高低(高音、低音),由频率决定,频率越高,音调越高,这节课上我们将会学习通过控制频率的方式来设置音调。 
 
2、麦克风 
麦克风也叫传声器,是一种能够将声音信号转换成电信号的器件,可用于检测语音和声音响度,行空板的麦克风是内置在板子的单板机系统上的,这节课上我们使用其环境音量检测功能,检测时返回的是一个百分量,范围在0%-100%,声音越响数值越高。 
 
 
 
3、蜂鸣器 
 
蜂鸣器是一种能够发出类似蜂鸣声音的器件。行空板的蜂鸣器是内置在板子的单片机系统上的。 
 
 
 
同时,单片机系统上的所有元器件都有各自的功能引脚,蜂鸣器的引脚为P26,可见下图。 
 
 
4、Pinpong库Tone类中的常见方法 
 
Pinpong库中的Tone类可以控制蜂鸣器发声,在使用前,我们需要先导入Pinpong库,初始化行空板,实例化Tone类来创建一个对象。 
 
			
			
			- from pinpong.board import Board,Pin,Tone # 从pinpong.board包中导入Board,Pin,Tone模块
 - Board().begin() # 初始化,选择板型和端口号,不输入则进行自动识别
 - tone = Tone(Pin(Pin.P26)) # 将Pin传入Tone中实现模拟输出
 
  复制代码
  
其中,Pin、Tone与Board 类似,都是pinpong.board包下的模块。“P26”指的是板子上蜂鸣器所在的引脚,“Pin(Pin.P26)”是在创建一个引脚对象,最后将这个引脚对象传入Tone类中进行实例化,创建得到一个tone对象。 
 
同时,Tone类的方法有很多,我们只使用其中的一部分,在编程时,通过“对象.方法名()”的形式来实现功能。 
 
(1)freq()方法设置蜂鸣器发声的频率 
 
- tone.freq(200) # 按照设置的频率200播放
 
  复制代码
  
其中,“200”表示设定的具体的频率大小。 
 
(2)on()方法启动蜂鸣器 
 
复制代码
  
(3)off()方法关闭蜂鸣器 
 
复制代码
  
5、Unihiker库GUI类中的常见方法 
 
GUI类中的方法有很多,我们只使用其中的一部分,在编程时,通过“对象.方法名()”的形式来实现功能。 
 
(1)fill_rect()方法显示填充矩形 
 
GUI类中的fill_rect()方法可以实现在行空板屏幕上显示一个填充矩形。 
 
- gui.fill_rect(x=75, y=30, w=90, h=30, color="#00ff00") # 显示第一个填充矩形
 - gui.fill_rect(x=75, y=70, w=90, h=30, color="#00ff00") # 显示第二个填充矩形
 
  复制代码
  
其中,参数x和y分别表示填充矩形所在的横纵坐标位置,w和h表示填充矩形的宽度和高度,color对应要填充的颜色。 
 
(2)fill_clock()方法显示填充时钟 
 
GUI类中的fill_clock()方法可以实现在行空板屏幕上显示一个填充时钟。 
 
- clock = gui.fill_clock(x=120, y=230, r=60, h=3, m=4, s=5, color=(255, 255, 255), fill="#57b5ff")# 显示填充时钟
 
  复制代码
  
其中,参数x和y分别表示填充时钟所在的横纵坐标位置,r表示要填充时钟的半径,h、m、s分别表示初始时时钟的时针分针和秒针显示的数值,color表示边框颜色,fill表示填充颜色,同color一样也有三种不同的设定方法。 
 
(3)start_thread()方法开启线程 
 
GUI类中的start_thread()方法可以开启一条新的线程。 
 
- clock_thread = gui.start_thread(clock_update) # 启动线程
 
  复制代码
  
其中,“clock_thread”指的是线程对象,“clock_update”指的是要启动的线程函数。 
 
6、Unihiker库Audio类sound_level()方法检测环境音量 
 
Unihiker库Audio类的sound_level()方法可以检测板子的环境音量,在使用前,我们需要先导入库中的这个模块并通过实例化类的方式创建一个对象,之后,通过“对象.方法名()”的形式来实现功能。 
 
- from unihiker import Audio  # 导入unihiker库中的Audio模块
 - audio = Audio() # 实例化音频
 - Sound = audio.sound_level() # 检测环境音量大小,将数值存储到变量Sound中
 
  复制代码
  
其中,“Sound”是创建的一个变量,用来存储检测到的环境音量。 
 
7、Datetime库中的常见函数 
 
Datetime库是一个可以处理日期时间的Python内置库,其datetime模块下的now()函数可以获取系统本地时间,使用前,需要先导入它。 
 
- from datetime import datetime # 导入datetime库datetime模块
 - now_time = datetime.now().strftime('%H:%M') # 获取当前时间(时分)
 
  复制代码
  
其中,“strftime('%H:%M') ”函数可以将时间格式转换为字符串,这里的H和M分别表示小时和分钟。 
 
8、Time库中的常见函数 
 
Time库的localtime()函数可以格式化时间戳为本地的时间,使用前需要先导入该库。 
 
- import time # 导入time库
 - t = time.localtime() # 格式化时间戳为本地时间
 - clock.config(h=time.strftime("%H", t), m=time.strftime("%M", t), s=time.strftime("%S", t))   # 更新显示时钟
 
  复制代码
  
其中,“time.strftime("%H", t)”表示返回字符串表示的当前时间的小时数,“time.strftime("%M", t)”则是当前时间的分钟数,“time.strftime("%S", t)”则是当前时间的秒钟数。 
 
Tips:Datetime和Time库皆有获取时间的功能,但两者呈现的形式不同,这里我们不作详细讨论。 
 
动手实践 
 
任务描述1:检测环境音量 
 
将通过麦克风检测到的环境音量值呈现在屏幕上。 
 
1、硬件搭建 
 
STEP1:通过USB连接线将行空板连接到计算机 
 
2、程序编写 
 
STEP1:创建与保存项目文件 
 
启动Mind+,另存项目并命名为“003、多功能提醒器”。 
 
STEP2:创建与保存Python文件 
 
创建一个Python程序文件“main1.py”,双击打开。 
 
STEP3:导入图片 
 
在项目文件夹中导入背景图。(图片与程序文件同在项目文件夹中)(图片下载链接见附录1) 
 
STEP4:程序编写 
 
(1) 导入所需功能库 
 
在这个任务中,我们需要使用unihiker库中的GUI模块来在屏幕上显示文字等,以及Audio模块来检测环境音量,因此,我们首先需要导入它,代码如下。同时,由于后续在程序运行中时需要设置一定的延时,因此,我们还需导入time时间库。 
 
- # 检测环境音量大小,单位:百分比
 - from unihiker import GUI , Audio  # 导入unihiker库中的GUI、Audio模块
 - import time  # 导入time库
 
  复制代码
  
(2) 实例化GUI类 
 
在使用unihiker库中的GUI模块和Audio模块前,我们需要先实例化GUI类和Audio类,来创建一个对象,以便使用该类中的各种方法。 
 
- gui = GUI()  # 实例化GUI类,创建gui对象
 - audio = Audio() # 实例化音频
 
  复制代码
  
(3) 显示背景图 
 
在创建gui对象后,我们可以在行空板的屏幕上显示一张背景图。 
 
- # 显示背景图
 - img = gui.draw_image(x=0,y=0,w=240, h=320, image='background.png')  # 显示背景图
 
  复制代码
  
(4) 显示填充矩形 
 
接着,我们可以在行空板的屏幕上显示两个带填充色的矩形。 
 
- # 显示填充矩形
 - gui.fill_rect(x=75, y=30, w=90, h=30, color="#00ff00") # 显示第一个填充矩形
 - gui.fill_rect(x=75, y=70, w=90, h=30, color="#00ff00") # 显示第二个填充矩形
 
  复制代码
  
(5) 显示环境音量值 
 
之后,我们可以在矩形上书写文字,显示出初始的环境音量。 
 
- # 显示文字
 - text1 = gui.draw_text(x=120, y=30, text='环境音量:', origin = 'top') # 显示文字“环境音量:”
 - text_sound = gui.draw_text(x=120, y=70,text='', font_size=15, origin = 'top') # 显示初始环境音量
 
  复制代码
  
(6) 显示表情 
 
同时,我们可以在环境音量值下方添加一个表情。 
 
- # 显示表情
 - emj1 = gui.draw_emoji(x=82, y=90, w=100,
 - h=100,emoji="Smile", duration=0.1) # 显示初始表情
 
  复制代码
  
(7) 循环检测环境音 
 
最后,我们每隔0.1秒检测并更新一次环境音量值。 
 
- while True :
 -     Sound = audio.sound_level() # 检测环境音量大小,将数值存储到变量Sound中
 -     text_sound.config(text = Sound) # 更新屏幕上环境音量的显示
 -     time.sleep(0.1) # delay 0.1 秒
 
  复制代码
  
Tips:完整示例程序如下: 
 
- # 检测环境音量大小,单位:百分比
 - from unihiker import GUI , Audio  # 导入unihiker库中的GUI、Audio模块
 - import time  # 导入time库
 - 
 - gui = GUI()  # 实例化GUI类,创建gui对象
 - audio = Audio() # 实例化音频
 - print("环境音大小")
 - 
 - # 显示背景图
 - img = gui.draw_image(x=0,y=0,w=240, h=320, image='background.png')  # 显示背景图
 - 
 - # 显示填充矩形
 - gui.fill_rect(x=75, y=30, w=90, h=30, color="#00ff00") # 显示第一个填充矩形
 - gui.fill_rect(x=75, y=70, w=90, h=30, color="#00ff00") # 显示第二个填充矩形
 - 
 - # 显示文字
 - text1 = gui.draw_text(x=120, y=30, text='环境音量:', origin = 'top') # 显示文字“环境音量:”
 - text_sound = gui.draw_text(x=120, y=70, text='', font_size=15, origin = 'top') # 显示初始环境音量
 - 
 - # 显示表情
 - emj1 = gui.draw_emoji(x=82, y=90, w=100, h=100, emoji="Smile", duration=0.1) # 显示初始表情
 - 
 - while True :
 -     Sound = audio.sound_level() # 检测环境音量大小,将数值存储到变量Sound中
 -     text_sound.config(text = Sound) # 更新屏幕上环境音量的显示
 -     time.sleep(0.1) # delay 0.1 秒
 
  复制代码
  
3、程序运行 
 
STEP1:远程连接行空板 
 
STEP2:点击右上方的运行按钮 
 
STEP3:观察效果 
 
观察行空板,可以看到初始时环境音量值为0,并且屏幕上伴有一个笑脸的表情,此时,我们对着行空板的麦克风吹一口气(人为制造噪音),可以发现音量值瞬间增大。 
 
 
任务描述2:添加反馈提醒 
 
在实现实时检测音量后,我们再添加反馈提醒功能,设定一个噪音阈值,当音量超过该值时,使蜂鸣器发声进行提醒,并切换表情为愤怒。 
 
1、程序编写 
 
STEP1:创建与保存项目文件 
 
新建一个Python程序文件“main2.py”,双击打开。 
 
Step2:程序编写 
 
(1)Pinpong库蜂鸣器功能设定 
 
这里,我们需要使用板载的蜂鸣器,因此在导入库时我们需要补充导入Pinpong库中的Board、Pin、Tone三个模块并初始化行空板,同时,我们还需要实例化Tone类并设定蜂鸣器发声频率。 
 
- from pinpong.board import Board,Pin,Tone # 从pinpong.board包中导入Board,Pin,Tone模块
 - Board().begin() # 初始化,选择板型和端口号,不输入则进行自动识别
 - tone = Tone(Pin(Pin.P26)) # 将Pin传入Tone中实现模拟输出
 - tone.freq(200) # 按照设置的频率200播放
 
  复制代码
  
(2)添加反馈提醒 
 
接下来,我们将在每隔0.1秒检测一次环境音量的基础上添加条件判断,使音量超过50的阈值后,屏幕表情切换至愤怒,并且蜂鸣器发声1.5秒。 
 
- while True :
 -     Sound = audio.sound_level()  # 检测环境音量大小,将数值存储到变量Sound中
 -     text_sound.config(text = Sound) # 更新屏幕上环境音量的显示
 -     time.sleep(0.1) # delay 0.1 秒
 -     if Sound > 50: # 如果 环境音量 > 50
 -         emj1.config(emoji= "Angry") # config“Angry”表情
 -         tone.on()  # 打开蜂鸣器
 -         time.sleep(1.5) # 延时1.5秒
 -         tone.off() # 关闭蜂鸣器
 -         time.sleep(0.5) # 延时0.5秒
 -         emj1.config(emoji= "Smile") # config“Smile”表情
 
  复制代码
  
Tips:完整示例程序如下: 
- from unihiker import GUI , Audio  # 导入unihiker库中的GUI、Audio模块
 - import time  # 导入time库
 - 
 - from pinpong.board import Board,Pin,Tone # 从pinpong.board包中导入Board,Pin,Tone模块
 - 
 - Board().begin() # 初始化,选择板型和端口号,不输入则进行自动识别
 - tone = Tone(Pin(Pin.P26)) # 将Pin传入Tone中实现模拟输出
 - tone.freq(200) # 按照设置的频率200播放
 - 
 - gui = GUI()  # 实例化GUI类,创建gui对象
 - audio = Audio() # 实例化音频
 - print("环境音大小")
 - 
 - # 显示背景图
 - img = gui.draw_image(x=0,y=0,w=240, h=320, image='background.png')  # 显示背景图
 - 
 - # 显示填充矩形
 - gui.fill_rect(x=75, y=30, w=90, h=30, color="#00ff00") # 显示第一个填充矩形
 - gui.fill_rect(x=75, y=70, w=90, h=30, color="#00ff00") # 显示第二个填充矩形
 - 
 - # 显示文字
 - text1 = gui.draw_text(x=120, y=30, text='环境音量:', origin = 'top') # 显示文字“环境音量:”
 - text_sound = gui.draw_text(x=120, y=70, text='', font_size=15, origin = 'top') # 显示初始环境音量
 - 
 - # 显示表情
 - emj1 = gui.draw_emoji(x=82, y=90, w=100, h=100, emoji="Smile", duration=0.1) # 显示初始表情
 - 
 - while True :
 -     Sound = audio.sound_level()  # 检测环境音量大小,将数值存储到变量Sound中
 -     text_sound.config(text = Sound) # 更新屏幕上环境音量的显示
 -     time.sleep(0.1) # delay 0.1 秒
 -     if Sound > 50: # 如果 环境音量 > 50
 -         emj1.config(emoji= "Angry") # config“Angry”表情
 -         tone.on()  # 打开蜂鸣器
 -         time.sleep(1.5) # 延时1.5秒
 -         tone.off() # 关闭蜂鸣器
 -         time.sleep(0.5) # 延时0.5秒
 -         emj1.config(emoji= "Smile") # config“Smile”表情
 
  复制代码
  
2、程序运行 
 
STEP1:远程连接行空板 
 
STEP2:运行程序并观察效果 
 
点击运行后,观察行空板,可以看到初始时环境音量值为0,屏幕上的表情为“Smile”,此时,对着行空板的麦克风吹一口气(人为制造噪音),可以发现音量值瞬间增大,超过设定的50 的噪音阈值后,行空板屏幕的小表情瞬间转为愤怒,同时蜂鸣器鸣声1.5秒。 
 
 
任务描述3:添加闹钟功能 
 
接下来,我们将在噪音提醒的基础上再添加闹钟功能,在屏幕上显示时钟,当到达设定的时间后,使蜂鸣器发声进行提醒。 
 
1、程序编写 
 
STEP1:创建与保存项目文件 
 
新建一个Python程序文件“main3.py”,双击打开。 
 
Step2:程序编写 
 
(1)导入所需功能库 
 
由于需要检测系统时间,因此,我们需补充导入datetime库以便在后续使用。 
 
- import datetime # 导入datetime库
 
  复制代码
  
(2)显示填充时钟 
 在屏幕的初始表情下方,我们新增显示一个时钟。 
 
- # 显示填充时钟
 - clock = gui.fill_clock(x=120, y=230, r=60, h=3, m=4, s=5, color=(255, 255, 255), fill="#57b5ff")
 
  复制代码
  
(3)定义更新时钟函数 
 
为了使时钟能够与真实时间保持一致,我们需要定义一个更新时钟显示的功能函数,并在其中设定达到指定时间后,蜂鸣器发声提醒。 
Tips:这里的时间可自行更改。 
 
- def clock_update():
 -     print("thread1 start")
 -     while True: # 循环执行
 -         t = time.localtime() # 格式化时间戳为本地时间
 -         clock.config(h=time.strftime("%H", t), m=time.strftime("%M", t), s=time.strftime("%S", t)) # 更新显示时钟
 -         time.sleep(1)
 -         now_time = datetime.datetime.now().strftime('%H:%M') # 获取当前时间(时分)
 -         print(now_time)
 -         if  now_time == '18:00': # 如果当前时间为晚上6点(可自行更改)
 -             tone.on()  # 打开蜂鸣器
 -             time.sleep(1.5) # 延时1.5秒
 -             tone.off() # 关闭蜂鸣器  
 - time.sleep(0.5) # 延时0.5秒      
 -     print("thread1 end")
 
  复制代码
  
(4)启动更新时钟的线程 
 由于环境音量与时间皆需要实时更新,因此,我们将更新时钟的功能作为一个新的线程,单独启动。 
 
- # 线程1启动
 - clock_thread = gui.start_thread(clock_update)
 
  复制代码
  
Tips:完整示例程序如下: 
- from unihiker import GUI , Audio  # 导入unihiker库中的GUI、Audio模块
 - import time  # 导入time库
 - from datetime import datetime # 导入datetime库datetime模块
 - 
 - from pinpong.board import Board,Pin,Tone # 从pinpong.board包中导入Board,Pin,Tone模块
 - 
 - Board().begin() # 初始化,选择板型和端口号,不输入则进行自动识别
 - tone = Tone(Pin(Pin.P26)) # 将Pin传入Tone中实现模拟输出
 - tone.freq(200) # 按照设置的频率200播放
 - 
 - gui = GUI()  # 实例化GUI类,创建gui对象
 - audio = Audio() # 实例化音频
 - print("环境音大小")
 - 
 - # 显示背景图
 - img = gui.draw_image(x=0,y=0,w=240, h=320, image='background.png')  # 显示初始背景图
 - 
 - # 显示填充矩形
 - gui.fill_rect(x=75, y=30, w=90, h=30, color="#00ff00") # 显示第一个填充矩形
 - gui.fill_rect(x=75, y=70, w=90, h=30, color="#00ff00") # 显示第二个填充矩形
 - 
 - # 显示文字
 - text1 = gui.draw_text(x=120, y=30, text='环境音量:', origin = 'top') # 显示文字“环境音量:”
 - text_sound = gui.draw_text(x=120, y=70, text='', font_size=15, origin = 'top') # 显示初始环境音量
 - 
 - # 显示表情
 - emj1 = gui.draw_emoji(x=82, y=90, w=100,h=100, emoji="Smile", duration=0.1) # 显示初始表情
 - 
 - # 显示填充时钟
 - clock = gui.fill_clock(x=120, y=230, r=60, h=3, m=4, s=5, color=(255, 255, 255), fill="#57b5ff")
 - 
 - # 定义更新时钟函数
 - def clock_update():
 -     print("thread1 start")
 -     while True: # 循环执行
 -         t = time.localtime() # 格式化时间戳为本地时间
 -         clock.config(h=time.strftime("%H", t), m=time.strftime("%M", t), s=time.strftime("%S", t)) # 更新显示时钟
 -         time.sleep(1)
 -         now_time = datetime.now().strftime('%H:%M') # 获取当前时间(时分)
 -         print(now_time)
 -         if  now_time == '18:00':  # 如果当前时间为晚上6点(可自行更改)
 -             tone.on()  # 打开蜂鸣器
 -             time.sleep(1.5) # 延时1.5秒
 -             tone.off() # 关闭蜂鸣器
 -             time.sleep(0.5) # 延时0.5秒     
 -     print("thread1 end")
 - 
 - # 线程1启动
 - clock_thread = gui.start_thread(clock_update)
 - 
 - while True :
 -     Sound = audio.sound_level()  # 检测环境音量大小,将数值存储到变量Sound中
 -     text_sound.config(text = Sound) # 更新屏幕上环境音量的显示
 -     time.sleep(0.1) # delay 0.1 秒
 -     if Sound > 50: # 如果 环境音量 > 50
 -         emj1.config(emoji= "Angry") # config“Angry”表情
 -         tone.on()  # 打开蜂鸣器
 -         time.sleep(1.5) # 延时1.5秒
 -         tone.off() # 关闭蜂鸣器
 -         time.sleep(0.5) # 延时0.5秒,避免蜂鸣器自己把麦克风触发
 -         emj1.config(emoji= "Smile") # config“Smile”表情
 
  复制代码
  
2、程序运行 
 
STEP1:远程连接行空板 
 
STEP2:运行程序并观察效果 
 
点击运行后,观察行空板,可以看到在表情下方新增显示了一个时钟,在达到程序中设定的“18:00”后,蜂鸣器发出警报声。同时,环境音量也在实时检测。 
 
Tips:若想保持时钟显示正确,需将行空板连入网络,操作方法可见附录2。 
 
 
挑战自我 
 
尝试给我们的多功能提醒器添加一张合适的背景图吧,使得效果更加逼真! 
 
想一想,除了噪音和时间提醒外,我们还能给多功能提醒器增加哪些功能呢?结合已学过的内容,自己动手试一试吧! 
 
扩展阅读 
 
麦克风的工作原理及发展 
20世纪初,麦克风由最初通过电阻转换声电发展为电感、电容式转换,大量新的麦克风技术逐渐发展起来。常见的麦克风的工作原理是传感器内置一个对声音敏感的电容式驻极体话筒。声波使话筒内的驻极体薄膜振动,导致电容的变化,而产生与之对应变化的微小电压。这一电压随后被转化成0-5V的电压,经过A/D转换被数据采集器接受并进行传送。 
 
生活中使用的包括声控灯、智能电视等很多声控设备,都离不开麦克风。麦克风的应用领域更是不断扩展,从机器人到航空航天技术,麦克风在现代科技领域中的作用越来越大。 
 
附录 
 
附录1:背景图链接 
 
链接:https://pan.baidu.com/s/1hn2dVvWY3Y6QGV-_Ue-NYg 
提取码:r0lk 
 
附录2:行空板联网方法 
 
STEP1:在行空板使用usb线连接电脑后,打开浏览器,输入“10.1.2.3”,进入行空板网页菜单 
 
 
 
STEP2:进入网络设置,会自动扫描板子周围的热点以及当前网络状态,扫描完毕后选择要连接的热点,输入密码后连接网络 
 
 
STEP3:联网成功后刷新网页即可看到WiFi连接状态 
 
 
 
 
 |