基于Arduino的手指灵敏度训练器

2020-02-02 03:25乐万德王永辉赵妮李珂程海洋
电子技术与软件工程 2020年17期
关键词:亮灯状态机蜂鸣器

乐万德 王永辉 赵妮 李珂 程海洋

(西安航空学院 陕西省西安市 710077)

近年来,Arduino 作为一款便捷灵活、方便上手的开源电子原型平台,受到了很多高校的青睐。陆泽华等对Arduino 单片机在信息技术教育中的应用进行了探究[1],李梅等设计了基于Arduino 家居安防智能报警电路[2],许金等设计了可见光浊度检测创新实验[3],耿丽娟等设计了基于Arduino 的智能防盗系统[4],Arduino 的应用和研究非常广泛,如何利用好Arduino 培养学生的创新创业能力成为研究热点。本文旨在在这些研究成果的基础上进一步探索基于Arduino 平台的创新创业教育方法及过程。

Arduino 平台包含各种型号的Arduino 板和Arduino IDE 软件。Arduino 创始人于2005年开始讨论这个项目,仅用了3 天时间就实现了最初的创意开发板[5]。Arduino UNO 于2011年9月份正式发布,目前广泛应用的是Arduino UNO R3,即第三版。Arduino 平台具有丰富的控制板序列及扩展板序列,支持多种传感器及外围电路,如Proteus 等仿真平台对Arduino 具有越来越完善的功能支持[6]。LED灯、蜂鸣器、按键这几个元器件虽然简单,但这也是最基本最常用的声光及控制器件。Arduino 基础的开发板及套件具有很高的性价比,我们鼓励学生在接触更广泛的传感器甚至虚拟开发平台之前,认真做好基础元器件的熟悉及创新实践,正所谓大道至简,然后触类旁通。这种强化实践基础的方法在教学实践中证明非常有效。

1 创意设计

面对LED、蜂鸣器和按键开关等基本元器件实验项目,通过按键控制来控制LED 等的亮和灭、控制蜂鸣器的响和停等基本操作学生基本都能想到;进一步需要引导学生通过按键的次数来控制LED 灯的亮度等级、蜂鸣器的频率变化等,逐渐体现出创意设计的意味;最后引导学生通过这几个简单元器件设计出了一个非常有趣的声光组合“眼疾手快”训练器。其基本设计思路如下:

(1)“眼疾手快”训练器的LED 灯根据设置的难度等级进行随机闪烁,每次闪烁亮灯与灭灯的时间间隔由随机函数产生,难度等级越高,随机时间间隔越短。

(2)LED 灯亮起后,玩家第一时间按下按键,从LED 灯亮灯开始计时,在规定的时间内按下按键被定义为“击中”并得分,超时按下按键则本次按键不得分。规定的时间也与难度等级有关,难度也高,留给玩家按键的时间越短。

(3)游戏需防止玩家一直按着按键或者连续不断进行按键等漏洞。

图1:系统外围电路及与Arduino 的接口

图2:系统的两个并行任务

(4)击中得分,蜂鸣器发出得分音乐声音。

(5)为增加娱乐性,游戏开始时响起特殊的音乐,提醒玩家游戏即将开始。

(6)项目可拓展,硬件上可拓展为双LED,双按键,双手控制等多种拓展玩法。软件上可随着后台数据的积累做统计后对游戏难度参数及分级做进一步优化。

2 电路连接

根据上述创意,基于Arduino UNO 控制板及其对应芯片ATmega328,用Proteus 设计外围电路仿真电路图及其与Arduino UNO 的接口如图1所示,Arduino UNO 电路板略。LED 灯经过分压电阻后接在Arduino UNO 数字口IO7 上,设置为输出模式。buzzer 分别接在IO3,设置为输出模式。注意根据选用buzzer 的电气特性参数,有的buzzer 可能需要外接电源。本实验中,选用集成了分压电路的LED 等和集成功能的buzzer。按键分别接在A0 口模拟输入口上。

3 算法设计

为了项目的需要,亮灯灭灯时间不能采用固定的时间间隔,而是采用随机数生成时间间隔。一方面,Arduino 系统不断地查询时间,如果时间满足了预先随机数对应的时间,则LED 等的亮灯灭灯状态发生变化。另一方面,Arduino 还要不断地查询开关状态的变化,以确定开关的按下事件,并记录下按键的时间,与亮灯的时间比对,以判定此次按键是否符合要求并进一步触发计分、播放提示音等动作。这样,监听时间以决定LED 灯的亮灭与监听开关的状态就形成了两个并行的任务,如图2所示。

Arduino 默认没有操作系统,对于这样的并行任务需要自行设计处理。对于闪灯,学生首先想到的是用delay( )函数,但delay( )会独占CPU,任何一个任务使用了delay( ),其它任务也就停下来了,不适合并行任务。对于开关的触发事件,学生首先想到的是中断,但是中断发生时delay( )函数不会生效,millis( )函数的计时数值也不会持续增加[5]。计时及计算时间差是本项目的关键因素之一,中断方案将会非常困难。因此本项目中最合适的解决方案是利用millis( )或者micros( )函数。本项目选用millis( )函数,函数则仅仅是一个时间记录者,在LED 闪灯任务里用millis( )函数来控制闪灯并不会让其他任务停滞。通过不停地循环查询并记录下LED 灯的亮灯时间和开关按下的时间,就可以模拟多任务的并行运行。本项目中引入基于millis( )函数的状态机,状态机是一种能解决多任务并发的有效方法[7]。定义两个状态机,一个状态机记录LED 等的状态并采用相应的策略,一个状态机记录按键的状态及时间。

3.1 LED状态机类

据前述分析,LED 状态机以给定的一组随机数进行闪灯,设计LED 状态机类图主要成员如图3所示。为了项目的扩展性,系统设计中使用了面向对象的思想进行类的封装。LED 状态机的关键参数包括LED 当前是亮的状态还是灭的状态,用变量ledState 来表示,另外需要记录当前LED 灯状态的时间,以决定是否需要改变LED灯的状态,用变量ledChangeTime 来记录某次状态的起始时间点。当LED 等变为亮灯状态时,用ledOnTime 记下该时间点,供按键状态机checkButtonState( )函数使用。

其它成员变量还包括:ledPin 是连接LED 的Arduino 端口号,flashTimes 是LED 闪灯的次数,这两个参数通过构造函数传入。randomFlahsTime 为一个长度为flashTimes 的数组,数组长度为闪灯次数,数组中的元素通过随机数函数获得。

通过updateLEDState 函数结合LED 灯当前状态及当前状态的持续时间,根据闪灯随机数时间对LED 灯的状态进行更新。

3.2 按键状态机类

按键状态机类如图4所示。

图3:LED 状态机

图4:按键状态机

图5:基于Arduino的手指灵敏度训练器实验装置

图6:实验结果及后台显示

项目选用的是按压式开关,需要判定按压开关时按下还是弹起两种状态。按键状态机的关键参数是按键当前的状态及之前按键的状态,分别用变量buttonState 和previousButtonState 来表示,如果当前开关为按下状态,并不能判定开关按下事件发生,只有当当前开关为按下状态且之前的状态为弹起状态,才能判定为开关按下事件发生。

其他参数包括记录开关按下的时间buttonDownTime。buttonPin是连接button 的Arduino 端口号。buttonCount 记录按键的次数,如果按键次数达到预设值,则再按下按键无效,有效地避免了选手不停地按键的作弊行为。

checkButtonState( )函数执行上述算法规则,包括判定按键按下,记录按键按下的时间,与LED 状态机中的ledOnTime 比对,满足阈值要求判定为按键击中。

3.3 状态机协同

以LED 所连接的IO 口ledPin 和闪灯次数flashTimes 做为clsLED 构造函数的参数,以按键pin 脚buttonPin 及按键次数buttonCount 作为clsButton 构造函数,分别在setup 函数和loop 函数外分别构造clsLED 和clsButton 的对象。在loop 函数里分别调用clsLED 的成员函数updateLEDState 和clsButton 的成员函数checkButtonState,实现两个状态及之间的协同工作。

通过状态机类的设计,很容易构造出多个状态机对象,比如可以构造第二组LED 灯及按键,同时针对左右手,进一步提高可玩性。

3.4 蜂鸣器音乐

为了提高项目的可玩性,对蜂鸣器进行了tone( )函数音乐编程,tone 函数的原理不难,但要编出悦耳的音乐需要一些音乐知识和编程技巧。本文按键击中声音采用了频率按正弦规律变化的警报音,使玩家提高注意力。进一步的Arduino tone 的使用及音乐编程课参考文献[8,9]。

4 实验分析

实验装置如图5所示。Arduino UNO 板7 号数字口接LED 灯,3 号数字口接蜂鸣器,A0 口接按键。LED 灯、蜂鸣器和按键为集成元件模块、简单易用,所需电源由UNO 板引出。为了实验的方便和可扩展性,采用了面包板进行了转接。

实验中定义了不同的难度等级,以LEVEL1 为例,QUICKNESS 是闪灯后按键按下的最晚时间,TIMES 是总的允许的按键次数,MININTERVAL 与MAXINTERVAL 为随机数产生的取值范围:

图6为选择难度级别LEVEL1的某次测试通过串口显示的结果,按键时间与LED 亮灯的时间差如果小于规定的500ms,则蜂鸣器发声且提示soundHitted OK 并且将记分。最后根据击中的次数与总的允许按键的次数取百分比得到总成绩score.本次实验中一次击中距离亮灯时间664ms,超过500ms,击中失败,没有击中提示且不计分,其他9 次均小于设定的500ms,因此最终成绩为90 分。实验结果符合设计预期。

5 结束语

本文是在辅导大学生创新训练过程中,引导学生用声、光、按键等基本元器件,培养学生创新思维过程中形成的项目。项目原材料简单,但创意有趣,引入了状态机很好地解决了LED 闪灯与开关按键查询并行任务,并基于此开发了手指灵敏度训练器,项目设计过程中用面向对象的思想和方法对状态机进行了类封装,方便项目进一步拓展。该项目在大学生基于Arduino 平台进行创新实践训练初级阶段中起到了良好的效果。

猜你喜欢
亮灯状态机蜂鸣器
亮灯!
电动自行车产品车速提示音检测现状和整改技术研究(2)
巨型玉兔
掌控板制作简易钢琴
基于有限状态机的交会对接飞行任务规划方法
单片机驱动蜂鸣器的程序设计
丰田凯美瑞240V车间隙警告蜂鸣器异常鸣响
FPGA设计中状态机安全性研究
基于反熔丝FPGA的有限状态机加固设计
基于VHDL的一个简单Mealy状态机