名侦探番外——Arduino“炸弹”引爆摩天大楼
- 硬件准备
- 1.材料准备
- 2.模块介绍
- 电路设计
- 1.硬件接线
- 程序设计
- 1.设计思路
- 2.部分程序
- 3.功能优化
- 总结
好久不见,童鞋们!小编突然想到很久以前看的柯南剧场版——计时引爆摩天大楼的情景,对剧里的“炸弹”情有独钟,最近几天刚好有空,顺便用Arduino做了一个“炸弹”模型,这篇文章就跟大家分享一下“炸弹”的制作过程吧!
硬件准备
1.材料准备
今天的作品比较特殊,需要我们做一部分手工——制作”炸弹“模型,大家在制作之前可以先准备好以下材料:
Arduino UNO、TM1637数码管时钟模块、MP3语音模块、小喇叭、无源蜂鸣器、10kΩ电阻(3个)、杜邦线、牛皮纸、黑色胶带、美工刀、剪刀等。
注意:
- TM1637数码管时钟模块,小编在这里不方便贴链接,各位童鞋从某宝上自己购买吧。当然,小编在程序开头的注释里贴了一个链接,供大家参考。
- MP3语音模块,小编用的是多年以前从DFRobot买的语音模块,现在应该还有,大家从某宝上搜DFRobot官方商铺,在官方商铺里再搜语音模块就可以了,不过他们家的传感器模块比较贵,童鞋们也可以换其他替代产品,能用即可。
- 为了让作品更像”炸弹“,小编特意拆了几个牛皮纸包装袋,裁出大小相同的几张纸,然后把每张纸卷成圆筒,卷纸的时候可以在里面夹几只铅笔,这样卷出来的圆筒更结实,最后把所有圆筒用黑色胶带粘到一起就可以了。
- 最后调试完传感器和程序以后再把所有的硬件粘到圆筒上面即可。
特别声明:小编并没有为某宝和某商铺打广告,只是刚好手里有该模块而已,大家可以用自己的方式购买。
2.模块介绍
TM1637数码管时钟模块:驱动芯片为TM1637,共有四个引脚,分别为VCC、GND、DIO、CLK,其中VCC可接+5V或者+3.3V,DIO为数据输入/输出引脚,CLK为时钟信号引脚,这两个引脚可以接Arduino的任意数字引脚。
在Arduino中控制TM1637数码管模块可以直接调用TM1637库,库文件小编放在文档里了,文末有下载链接,大家也可以自己从Arduino软件中下载。小编在作品中用到了以下几个函数:
TM1637 tm1637(CLK, DIO);//初始化数码管,CLK和DIO是指定的连接到Arduino引脚。
tm1637.init();//初始化数码管,其实就是清空屏幕
tm1637.set(BRIGHT_TYPICAL);//设置数码管的亮度,BRIGHT_TYPICAL = 2,BRIGHT_DARKEST = 0,BRIGHTEST = 7;其中0最暗,7最亮
tm1637.point(true);//指定数码管中间的冒号是否显示,false不显示,true显示
tm1637.display(Addr, data); //指定数码管中某一位的显示内容,第一个参数指定数码管的某一位,四位数码管从左到右顺序为0,1,2,3,第二个参数是显示的内容,其实是个序号,库中自带有一个长度为16的数组,默认显示0-9,A-F,第二个参数指定的是这个数组的序号。
注:其他函数及其用法,各位童鞋可以自行查询和测试,小编就不在这里过多赘述了。
DFRobot MP3语音模块:工作电压为3.3V~5V,模块上有很多引脚,VCC和GND分别是电源正极和负极;RX、TX是串口通信引脚;BUSY是忙信号引脚,播放音乐时为高电平,其它为低电平;SP+和SP-分别连接喇叭的正极和负极;DACL和DACR分别是DAC音频输出的左声道和右声道;ONE是一线串口控制脚。我们的”炸弹“作品功能比较简单,所以仅用到了VCC、GND、RX、TX、SP+和SP-这几个引脚。
DFRobot MP3语音模块可以播放其内部存储的音效文件,自带8MB的存储空间,存储音效文件的方式和使用U盘一样,直接用micro usb线连接到电脑上,电脑就能识别出一个U盘一样的存储空间,然后我们就可以把音效文件存进去了,这与U盘的操作是一样的。
DFRobot MP3语音模块支持mp3和wav两种格式的音效文件,在存储音效文件之前一定要给文件编好序号,例如:01.MP3,02.mp3…,该模块需要使用串口和Arduino通信,而且它有自己的一套通讯指令,大家可以登录官方网站:
https://wiki.dfrobot.com.cn/_SKU_DFR0534_Voice_Module
自行查阅模块手册,小编在这里用到的功能比较少,所以直接抄了官方手册里的播放音乐和设置音量的示例程序:
void play(unsigned char Track)
{
unsigned char play[6] = {0xAA,0x07,0x02,0x00,Track,Track+0xB3};//0xB3=0xAA+0x07+0x02+0x00,即最后一位为校验和
Serial1.write(play,6);
}
void volume( unsigned char vol)
{
unsigned char volume[5] = {0xAA,0x13,0x01,vol,vol+0xBE};//0xBE=0xAA+0x13+0x01,即最后一位为校验和
Serial1.write(volume,5);
}
注:小编用的电脑是win10系统,插上U盘就能自动识别,但是win7或者MAC系统没有测试过,大家可以根据自己的电脑系统自行测试,如有问题可以直接访问DFRobot官方wiki或者客服解决。
电路设计
1.硬件接线
“炸弹”作品的硬件接线还是比较简单的,整个电路图如下:
TM1637数码管模块:数码管模块只有4个引脚,所以接线非常简单,这里小编把DIO和CLK引脚接到了Arduino UNO的A0和A1引脚:
TM1637数码管----------------------Arduino UNO
VCC -------------- +5V
GND -------------- GND
DIO -------------- A0
CLK -------------- A1
MP3语音模块:“炸弹”作品中仅用到了VCC、GND、RX、TX、SP+和SP-这几个引脚,接线如下:
MP3语音模块---------------------- Arduino UNO
VCC -------------- +5V
GND -------------- GND
RX -------------- 11
TX -------------- 10
MP3语音模块---------------------- 小喇叭
SP+ -------------- 正极
SP- -------------- 负极
注:MP3语音模块要使用串口发送指令,作品中我们用的是Arduino UNO的软串口,所以这里把RX和TX接到了Arduino UNO的11和10号引脚。
拆弹线:因为作品中需要检测是否出现拆弹的情况,可以通过获取Arduino数字引脚的高低电平信号进行判断,这里为了避免断开拆弹线时Arduino引脚出现悬空,导致电平不稳定的情况,所以设计了一个下拉电阻的电路,当拆弹线未断开时,Arduino的数字引脚是高电平信号,当拆弹线断开时,Arduino的数字引脚是低电平信号。忘记下拉电阻电路的童鞋要补补课啦图片图片
拆弹线---------------------- Arduino UNO
红 -------------- 2
绿 -------------- 3
黄 -------------- 4
无源蜂鸣器:无源蜂鸣器只有两个引脚,正极和负极,接线非常简单:
无源蜂鸣器---------------------- Arduino UNO
正极 -------------- A2
负极 -------------- GND
程序设计
1.设计思路
“炸弹”模型做完了,电路部分也搞定了,接下来就是程序设计了,小编按照自己写的程序简单分享以下几点:
-
首先是倒计时问题,小编在Arduino中使用了millis()函数计算程序运行的时间,这种计时方法并不精确,但是用起来方便,当计时时间达到阈值时,秒数要递减,若秒数小于0,则需要从分钟借位,然后继续递减,若分钟也小于0,就表示计时结束了,此时语音模块就要播放炸弹爆炸的声音了。程序中还设置了标志,用于控制程序是否需要继续执行倒计时以及控制倒计时过程中蜂鸣器滴滴响。
-
然后是三条拆弹线,这三条拆弹线要连接到Arduino的数字引脚,为了增加趣味性,小编在程序开始设置了随机分配三条线的引脚,方法是先用二维数组把三个数字引脚的6种情况全部排列出来,然后用随机数函数产生0~6之间的数字作为二维数组的行下标,以此获取随机的三个数字引脚,并赋值给check数组,然后再初始化引脚为输入模式。
-
最后在主程序中判断剪断了哪一条线,分别实现拆弹失败、拆弹成功以及倒计时加速的功能,当拆弹失败时,分钟和秒全部置0,此时语音模块就会发出爆炸的音效;当拆弹成功时,时间停止即可;当拆到倒计时加速的线时,倒计时会先暂停一会,然后时间会加速递减,直到时间为0则炸弹爆炸,如果时间还未加速递减到0时又拆到了拆弹成功的线那么时间会立刻停止,炸弹也不会爆炸了!
2.部分程序
void loop() {
if (millis() - tt > nn && !bombFlag) {//判断当前时间是否超过nn的值,即达到计时时间了
tt = millis();
s--;//秒数递减
if (s < 0) {//若秒数减到0
if (m > 0) {//如果分钟仍然大于0则秒数从分钟借位
s = 60;//秒数重新从60开始递减
m--;//m被秒借走了1分钟,则应该减1
} else {//若分钟不大于0,此时表示计时结束
m = 0;
s = 0;
bombFlag = true;//改变标志值
play(0x01);//语音模块播放爆炸声
}
}
if (!bombFlag) {//若标志值还未改变,则蜂鸣器滴滴响
tone(BUZZER, 1600);
}
} else {
noTone(BUZZER);//蜂鸣器响一次就要关闭一次
}
if (digitalRead(check[0]) == LOW && !bombFlag) {//当check[0]被剪断,此时炸弹立即爆炸,拆弹失败
m = 0;//分钟和秒直接置0
s = 0;
} else if (digitalRead(check[1]) == LOW && !bombFlag) {//当check[1]被剪断,此时炸弹停止,拆弹成功
bombFlag = true;//改变标志值即可
} else if (digitalRead(check[2]) == LOW && !bombFlag) {//当check[2]被剪断,此时炸弹暂停1500毫秒,随即快速倒计时(此时再拆check[1]仍然会停止,但拆check[0]则直接爆炸)
if (!colorFlag)
{
delay(1500);//暂停1500毫秒
colorFlag = true;
}
nn -= 10;//nn每次减10,倒计时由慢变快
if (nn < 100)nn = 100;//nn虽然逐渐递减,但不能小于100
}
displayTime(m, s);//数码管显示倒计时时间
delay(20);
}
3.功能优化
由于时间比较仓促,材料准备也不是很充足,这个“炸弹”作品还有很大的优化空间,例如可以使用时钟模块提升计时精度,增加按键用于设置倒计时时间。各位童鞋如果有更好的想法也可以跟小编分享一下!
总结
模拟“炸弹”的音效文件、完整程序等文件已经上传到百度网盘了,想要资料的同学,请移步公粽号并回复“模拟炸弹”即可获得下载链接,好东西不容错过!
本期分享就到这里咯,撰文不易,欢迎各位小伙伴持续关注 初芯未来,更多内容分享等着你哦~!