Arduino案例实战(卷Ⅳ)
上QQ阅读APP看书,第一时间看更新

4.3 功能及总体设计

本作品主要分为三部分进行设计:网络控制模块、显示模块和振动开门模块。

4.3.1 功能介绍

本开门装置可通过网络控制一个继电器来实现振动传感器的开关,即决定是否启用振动开门方式。启动振动传感器,进入游戏状态后,开门者根据显示屏提供的开门提示敲击对应歌曲旋律,由固定在门上的振动传感器感受两次敲击之间的时间间隔,在误差允许范围内敲击旋律正确则启动直流电机拉开门锁。若开门者敲击节奏错误则更换歌曲,可以继续验证,从安全方面考虑,总尝试次数有限,无论验证成功还是失败,均会亮起对应的提示灯。

4.3.2 总体设计

本项目开关部分选用ESP8266 WiFi模块与单路继电器模块来控制振动传感器的状态;显示部分选用12864液晶屏显示开门提示;主程序部分采用振动传感器感应敲门的节奏频率。若开门节奏正确,则驱动直流电机,门成功打开,同时接入1个RGB三色灯来对应是否成功开启。

1.整体框架图

项目的整体框架如图4-1所示。

图4-1 整体框架图

2.系统流程图

系统的流程如图4-2所示。

接通电源以后,服务器发送指令“on”,使继电器处于闭合状态,振动传感器开始工作,显示屏显示开门提示,开门者需按一定频率敲门,振动传感器感受振动频率。频率正确,驱动模块驱动直流电机,开门成功,RGB三色灯的绿灯亮;否则开门失败红灯亮;开门次数超过3次后,需等待10min后才有开门机会。

图4-2 系统流程图

3.总电路图

系统总电路及Arduino UNO开发板引脚如图4-3所示。

本电路图较为复杂,下面分模块说明各元器件间的引脚连线。

LCD显示模块:12864液晶显示屏采用SPI接线方式。其D/I口、R/W口、E口分别与开发板的数字I/O端10、11、13相连,K(-)、CS1及VSS与开发板GND相连,A(+)、VDD与+5V端口相连。

网络控制模块:ESP8266的VCC端连接Arduino开发板的3.3V来通电,CH_PD通过10kΩ的电阻连接到Arduino开发板的3.3V电源上,模块上的RX、TX作为通信端口,RX接Arduino上的TX,TX接Arduino开发板上的RX端口,两元件的地线相连即可;继电器接通电源,IN端接开发板数字信号I/O口5,COM端接+5V,NC端与振动传感器正极相连,振动传感器负极接地。

图4-3 总电路图

开门模块:振动传感器的DO口与开发板数字I/O端2相连;小直流电机与直流电机驱动板OA1、OB1相连,2个引脚无方向;电机驱动板的A-IA、A-IB口与开发板数字I/O端3、4相连,VCC和GND端分别接+5V和地;RGB三色灯的GND端口接地,R、G、B端分别接数字I/O口7、6、8。

4.3.3 模块介绍

本项目主要包括三个模块:网络控制模块、主程序模块和LCD显示模块。下面分别给出各部分的功能、元件、电路图和相关代码。

1.网络控制模块

1)功能介绍

Arduino通过ESP8266连接贝壳物联网服务,实现远程控制继电器的闭合断开状态,并将结果反馈至控制界面。

选用贝壳物联网,通过ESP8266-01S、Arduino开发板与PC连接。以AT指令将WiFi模块与物联网连接,并将其设置为透传模式,使其达到通电自动连接的功能;将WiFi模块通过Arduino开发板与继电器、振动传感器连接,进而通过控制继电器的闭合开关状态,控制传感器的工作。

所用元器件:1个Arduino UNO R3,1只继电器,1只振动传感器,1只ESP8266-01S,1只10kΩ电阻,1块面包板,若干杜邦线;ESP8266需先进行透传设置。电路如图4-4所示,元件间的连线如表4-1和表4-2所示。

图4-4 网络控制模块

表4-1 ESP8266-01S接线对照表

表4-2 继电器与常开型振动传感器

继电器线圈没有电压时,继电器没有吸合,公共端与常闭端接通;当有电压时,继电器吸合,公共端与常开端接通。在这里采用继电器接常闭端法,如图4-5所示。

(1)ESP8266的透传设置。硬件包括USB转TTL模块,ESP8266-01S。软件包括网络调试助手。接线实物如图4-6所示,接线如表4-3所示。

表4-3 接线对照表

图4-5 接常闭端接法图

图4-6 接线实物图

(2)串口调试工具及AT指令调试示例。在串口调试工具中选择正确的串口及波特率,本项目采用的波特率为115200,打开“计算机”→“设备管理器”→“端口”,设置如图4-7所示。

图4-7 串口及波特率图

打开网络调试助手,设置ESP8266的波特率,如图4-8所示。

(3)AT指令。

①查看版本号(这个非常重要),不同的版本AT指令的操作不太一样。

图4-8 ESP8266的波特率图

②V1.0+固件命令如下:

第一步:关闭回显功能ATE0。第二步:重启AT+RESTORE。第三步:连接WiFi。

第四步:ESP8266设备连接服务器。

需要注意:在连接WiFi的AT指令中,必须使用字符串输入名称和密码,因此需要使用双引号;通过串口发送AT指令时,一定要回车换行,若没有回车换行,会导致发送和返回是一样的,同时串口也不承认"\r\n"指令,只能通过键盘来操作。

至此,ESP8266已经成为一个透传模块,只要给ESP8266通上电,它即可连上WiFi,最终显示结果如图4-9所示。

(4)ESP8266与服务器的通信。

①打开贝壳物联网,注册1个账号并创建1个设备,将会得到设备ID(DEVICEID)、设备密码(APIKEY),记录下来,此时设备不在线。

②将设置好的ESP8266与Arduino、继电器、振动传感器按上面所描述的接线方式连接。

图4-9 ESP8266连接成功

③烧录代码,上传程序。

④刷新贝壳物联网的界面,这时设备显示在线,如图4-10所示;需要注意的是,如果设备不在线,请检查透传是否正确、设备ID及设备密码是否正确。

图4-10 贝壳物联界面

⑤点开智能设备中的设备对话,选择上线设备后,命令发送目标选择“设备ID”,发送框内“play”,可观察到振动传感器的指示灯亮了,说明此时振动传感器在工作状态,网络控制模块运行成功。运行过程如图4-10所示。输入和反馈结果如下:

命令输入栏里,输入:play。

命令记录栏里,反馈:sensor on——振动传感器工作。

命令输入栏里,输入:stop。

命令记录栏里,反馈:sensor off——振动传感器不工作。

2)相关代码

2.LCD显示及振动模块

由于液晶屏显示文字与振动传感器获取的游戏者验证情况有关,代码连续,故将两模块合写。

1)功能介绍

主程序模块:继电器开关闭合使振动传感器接通电源后,振动传感器感受振动频率并与代码内设频率相比较。若敲击次数及时间间隔在容错范围内测试为验证成功,则绿色LED亮,直流电机转动拉动门锁开门;否则红色LED亮,换下一首歌,继续验证。连续错3次后,RGB三色灯闪烁,开门者被禁止继续尝试,10min后可进行下一轮验证。

显示屏模块:每次验证时显示内设歌曲名称,并在验证后显示验证成功或失败信息。

所用元件包括:1个Arduino UNO R3、1个振动传感器、1个普通小直流电机、1个12864LCD液晶屏、1个直流电机驱动板、1个面包板、若干杜邦线。

(1)振动传感器SW-1801P。

基本原理:振动传感器SW-1801P基于弹簧摆动原理,如图4-11所示。塑料管里有一个软弹簧围绕着中心的金属杆,两者平时互不接触,当受到一定外界振动时,就会令弹簧摇晃并碰到金属杆,输出一个接通信号。在静止时任何角度都为开路OFF状态,当受到外力碰撞或者大力晃动时,弹簧变形和中心电极接触导通使两个引脚瞬间为ON状态,当外力消失时,电路恢复为开路OFF状态。

图4-11 振动传感器SW-1801P

对于该振动传感器模块来说,无振动或者振动强度达不到设定阈值时,D0口输出高电平;当外界振动强度超过设定阈值时,模块D0输出低电平。由于导通时间和弹簧的刚性有关,所以该振动传感器的输出带宽很窄,在使用Arduino读取时,使用外部中断功能,如图4-11所示。

图4-12 振动传感器调试

振动模块VCC接开发板VCC,GND接开发板GND,连接正常,模块电源指示灯会亮。将模块轻放桌面上,调节板上蓝色电位器,直到开关指示灯亮,然后稍微回调电位器,让开关指示灯灭,再用手敲打桌面,使振动传感器有震感,此时,开关指示灯再回到亮状态。振动停止,开关指示灯也会灭。即振动可以触发模块,从而使开关指示灯点亮,如图4-12所示。

示例程序如下:

串口输出部分数据举例如下:

     1023
     1023
     1023
     1023
     1023
     1023
     1023
     67
     257
     1023
     1023
     1023
     1023

通过串口监视器,观察敲击振动传感器使其静止时的数据变化,大致确定该振动传感器能否正常工作。可以看到,当传感器感受到振动时,数字会变小。

另外,由于传感器本身质量问题,金属棒可能不在弹簧正中间,此时传感器放置在不同方向(例如竖直和平放)时串口输出数据也不同,所以也要测试一下传感器向不同方向倾斜时的情况,以寻找摆放传感器的合适角度。

(2)12864LCD液晶显示屏(带字库)。

硬件连接:SPI连接方式如总电路所示,汉字内码转换软件、LCD12864RSPI库文件可从网络获取。如果12864库文件适用版本低,需要修改文件。操作如下:Arduino UNO的SPI为10(SS),11(MOSI),12(MISO),13(SCK)。所以,把LCD12864RSPI.h头文件中的

     Static const int latchPin = 8;
     Static const int clockPin = 3;
     Static const int dataPin = 9;

修改为

     Static const int latchPin = 10;
     Static const int clockPin = 13;
     Static const int dataPin = 11;

同时,将“LCD12864RSPI.cpp”中的开始部分修改为

(3)普通小直流电机+直流电机驱动板。

L9110 S桥两路直流电机驱动板,如果要将装置应用在真实的房门上,需要动力更大的直流电机,本项目的示意模型只用一个小直流电机即可实现。在后续测试中发现,直流电机驱动板在与其他元件接同一个5V电源时,容易出现问题,所以用另一块开发板单独给它供电。

①模块接口说明。

6P黑色弯排针说明:

1引脚VCC外接2.5~12V电压;

2引脚GND外接GND;

3引脚IA1外接单片机I/O口;

4引脚IB1外接单片机I/O口;

5引脚IA2外接单片机I/O口;

6引脚IB2外接单片机I/O口。

4P绿端子说明:

1引脚OA1 OB1接直流电机2个引脚,无方向;

2引脚OA2 OB2接直流电机2个引脚,无方向。

②模块使用说明。

接通VCC,GND模块电源指示灯亮;

IA1输入高电平,IA1输入低电平,【OA1 OB1】电机正转;

IA1输入低电平,IA1输入高电平,【OA1 OB1】电机反转;

IA2输入高电平,IA2输入低电平,【OA2 OB2】电机正转;

IA2输入低电平,IA2输入高电平,【OA2 OB2】电机反转。

测试程序如下,将电机驱动板的A-IA、A-IB口与开发板数字I\O端3、4相连,OA1、OB1接直流电机两个引脚,无方向,VCC外接5V电压,GND接地。

     #define MOTO_A 3
     #define MOTO_B 4
     void setup()
     {
     pinMode(MOTO_A,OUTPUT);
     pinMode(MOTO_B,OUTPUT);
     }
     void loop()
     {
     digitalWrite(MOTO_A,LOW);
     digitalWrite(MOTO_B,HIGH);
     delay(2000);
     digitalWrite(MOTO_A,HIGH);
     digitalWrite(MOTO_B,LOW);
     delay(2000);
     }

(4)RGB三色灯。

RGB三色灯原理和一般的LED不同的是,在RGB LED封装内有3个LED,分别为红色、绿色和蓝色。通过控制各个LED的亮度,可以混合几乎任何颜色。实验中用到的是共阴极RGB LED,1个引脚接地,另外3个引脚分别接到Arduino UNO开发板,注意颜色对应。下面是测试程序,这里用到了Arduino开发板的D6、D7、D8引脚。

程序下载好后,就可以看到颜色的依次循环变化。显示固定颜色的代码则更简单,下面以红灯闪烁为例,红灯对应脚与Arduino开发板D6相连,GND脚接地。

     #define red_led 6
     void setup()
     {
     pinMode(6,OUTPUT);
     }
     void loop()
     {
     digitalWrite(6,LOW);
     delay(1000);
     digitalWrite(6,HIGH);
     delay(1000);
     }

(5)歌曲旋律的设置。

①按如下步骤连接好测试电路。12864液晶显示屏:其D/I口、R/W口、E口分别与Arduino开发板的数字I/O端10、11、13相连,K(-)、CS1及VSS与开发板GND相连,A(+)、VDD与+5V端口相连;振动传感器:DO口与开发板的数字I/O端口2相连,VCC接5V,GND接地;小直流电机与直流电机驱动板OA1、OB1相连,两个引脚无方向;电机驱动板的A-IA、A-IB口与开发板的数字I/O端3、4相连,VCC和GND引脚分别接+5V和地;RGB三色灯的GND端口接地,R、G、B引脚分别接数字I/O口7、6、8。

②在Arduino IDE中写入该模块整体代码。

③修改测试程序。将代码内设置每两拍时间间隔的数组(这个数组同时确定了每首曲子的总拍数)设到足够大,以统计足够的拍数。以设置三首歌为例:

     int SingGameArr0[] = {100,100,100,100,100,100,100,100,100,100,100,100,100,100
     100,100,100,100,100,100,100,100,100,100,100,100,100,100};
     int SingGameArr1[] = {100,100,100,100,100,100,100,100,100,100,100,100,100,100
     100,100,100,100,100,100,100,100,100,100,100,100,100,100};
     int SingGameArr2[] = {100,100,100,100,100,100,100,100,100,100,100,100,100,100
     100,100,100,100,100,100,100,100,100,100,100,100,100,100};

④将程序下载到Arduino UNO开发板上,打开串口监视器和音乐播放软件,选一首节奏感比较强的歌,选一段旋律,一边听一边敲振动传感器,如果熟悉要设置的歌,并且能保证每次敲的节奏快慢都一样,那么就不用播放音乐了。

但是,出于准确性的考虑,代码中设置每两拍的时间间隔只有50ms的容错,总错拍数不超过两个,要求精确度高,所以建议在设置节奏时还是听着歌敲击。

⑤观察记录串口输出数据,对同一段旋律进行多次试验,对每段旋律统计每两拍间隔的平均值,记录的数据如表4-4所示。

表4-4 旋律统计数据

⑥如果出现只敲一下却出现一串数据的情况,导致每次敲同一段旋律时得到的拍数不一致,说明这个地方的阈值需要再调大一点,如图4-13所示。

图4-13 阈值设置点

⑦统计出全部所需旋律后,修改代码,将它们填入数组。

⑧重新下载新代码,敲击尝试。因为有误差存在,不能每次都验证成功也是正常的。

一般来说,设置代码的人更容易开门成功,因为不同的人对同一段旋律的把握也会有差别,就算敲门的人所敲击的节奏实际上是准确的,只要设置旋律的人听的旋律节奏有偏差,即使旋律正确也无法验证成功。

⑨电路图。电路图如图4-14所示。

图4-14 各模块的电路图

2)相关代码

3.主程序代码