1. 引言
    1.1 目的
    高温巡逻报警智能小车

  2. 学习了解Arduino的工作原理

  3. 实战拼接小车内部结构模板

  4. 掌握了解高温传感器如何识别环境温度和工作原理

  5. 学习了解火焰传感器如何识别火焰的工作原理

  6. 掌握了解蓝牙传感器连接智能小车实现按键操作的工作原理

  7. 掌握警报器的安装与连接

1.2 背景
随着科学技术的发展,机器人的设计越来越精细,功能越来越复杂,智能小车作为其中的一个分支也在不断的发展。在近几年的电子设计大赛中,关于小车的智能化功能的实现也越来越多样化,因此本次我们也打算设计一智能小车,使其能自动识别高温或者识别火焰,然后触发警报器,从而达到能自动监测训练报警的功能。
2. 需求分析
机器人的感觉传感器种类非常多,其中视觉传感器成为研制自动行走和驾驶机器人的重要部件。机器人要实现自动导引功能和避障功能就必须要感知导引线和障碍物,感知导引线相当给机器人一个视觉功能。本设计以超声波作为智能车避障的一种重要手段,以其避障实现方便,计算简单,易于做到实时控制,测量精度也能达到实用的要求,在未来汽车智能化进程中必将得到广泛应用。我国作为一个世界大国,在高科技领域也必须占据一席之地,近期的华为5G手机行业可谓是扬眉吐气,未来汽车的智能化是汽车产业发展必然的,在这种情况下研究智能车高温做出警报的应用具有深远意义,这将对我国未来智能汽车的研究在世界高科技领域占据领先地位具有重要作用。
本设计主要体现多功能小车的智能高温识别功能,本设计中的理论方案、分析方法及特色与创新点等可以为自动运输机器人、采矿勘探机器人、家用自动清洁机器人等自动半自动机器人的设计与普及一定的参考意义。同时小车可以作玩具的发展对象,为中国玩具市场技术含量的缺乏进行一定的弥补,实现经济收益,形成商业价值。我们所设计的高温巡逻智能小车利用高温传感器识别一定的温度,顺利识别高温物体,从而触发警报声,伴随功能也可火焰识别特定的波段触发警报声,从而在消防安全,智能防火和辅助人类行动方面也有着重要意义。

我们小组将会以两直流电动机为主驱动,通过各类传感器件来采集各类信息,送入主控单元Arduino单片机处理数据后完成相应的动作,以达到自身控制。电机驱动电路采用H桥驱动模块,驱动2个直流电机组成,小车上有超声波传感器具有避障功能,用作巡逻,同时高温传感器具有识别高温的功能,一旦发现可疑高温物体,可以马上识别出来进而触发警报。也可以延伸到火焰识别特定的波段触发警报。
2.1主要功能:无线蓝牙遥控、警报器触发、温度传感器。
2.2附加功能:火焰识别、小车可变向、速度调节、警报灯、等功能。

(1)通过无线蓝牙串口对小车进行无线遥控,通过遥控器实现对小车的运作(前进、后退、变向、变速等),让小车的便捷程度大大提升。
(2)遥控时,通过遥控器上的按钮可以方便灵活地控制小车的前进、后退、左转、右转、加速、减速等功能,避免了小车在一些狭窄或狭小的空间难以遥控的问题。
(3)检测高温物体或气体时,通过温度传感器识别,若其温度达到一定界限就出发连接好的警报(或者),通过蜂鸣器发出警报,警示灯亮起,并发出响亮的警报声,从而实现高温警报的功能。
(4)通过遥控器上的按钮同时控制一些其他辅助功能,如灯光的开启(有助于小车在一些昏暗的空间看清前方的路况)、连接个性化音乐、显示小车运作的时间等功能的实现。

2.4主要传感器功能模块分析
(1)温度报警实验
利用高温传感器感器检测道路上的可以高温物体,然后把数据传送给单片机,当高温传感器检测到局里小车前方有高温物时单片机触发警示灯,并发出响亮的警报声。该功能的小车能够实现在出现火灾的情况下发现并及时实现报警功能。
在有靠近高温和没有靠近高温两种情况下,模拟口读到的温度值是有变化的。
所以在程序一开始,我们用Arduino Uno控制器通过DallasTemperature函数库实现单总线的启动、发送测量温度的请求、读取0号传感器温度,最后通过串口发送出去,最后则判断靠近高温让蜂鸣器发出声音以作报警。
本程序可以模拟在有高温时报警的情况,在没有高温时一切正常,当高温时立刻报警做出提示。

(2)火焰报警实验
或者利用火焰传感器感器检测道路上的着火的物体,如蜡烛,根据火焰不同的波段然后把数据传送给单片机,当火焰传感器检测到局里小车前方有火焰时单片机就发出指触发警示灯,并发出响亮的警报声。该功能的小车能够实现在出现火灾的情况下发现并及时实现报警功能。
在有火焰靠近和没有火焰靠近两种情况下,模拟口读到的电压值是有变化的。实际用万用表测量可知,在没有火焰靠近时,模拟口读到的电压值为0.3V左右;当有火焰靠近时,模拟口读到的电压值为1.0V左右,火焰靠近距离越近电压值越大。
所以在程序一开始,我们可以先存储一个没有火焰时模拟口的电压值i。接着不断的循环读取模拟口电压值j、同存储的值做差值k=j-i、差值k不0.6v做比较。差值k如果大于0.6V(数字二迕制值为123),则判断有火焰靠近让蜂鸣器发出声音以作报警;如果差值小于0.6v则蜂鸣器不响。
本程序可以模拟在有火焰时报警的情况,在没有火焰时一切正常,当有火焰时立刻报警做出提示。

2.4基于arduino的智能小车的设计图:

  1. 系统设计
    3.1总体设计
    3.1.1系统设计及方案
    依据所选题目的要求,我们制定出了系统的设计方案,并通过比较论证,选择合适的器件。最终确定手工制作小车,采用Arduino单片机作为主控制器,普通火焰传感器作为本系统的火焰传感器,用DS18B20温度传感器作为本系统的温度传感器,L298D作为直流电机的驱动芯片的设计方案。
    整体方案设计
    课题要求设计一个简易高温巡逻智能小车模型,在高温巡逻发出警报的基础上,我们也挑战自己,让功能实现升级,我们结合了灭火功能能到指定区域进行灭火工作(以蜡烛模拟火源,分布在小车行走的场地中)。小车必须通过内部设备采集现场环境情况进行分析并做出相应的动作,以达到小车智能灭火的目的。根据题目要求,本系统主要由控制器模块、电源模块、直流电机及其驱动模块、蓝牙模块、温度传感模块、火焰传感器、灭火系统及其驱动模块等模块构成,本系统的方框图如图1所示。

2.1 DS18B20编程与库的使用
Arduino要实现对DS18B20的操作,需要OneWire和Dallas Temperature Control两个库文件,下载地址分别为:http://playground.arduino/Learning/OneWire和https://github/milesburton/Arduino-Temperature-Control-Library。Dallas Temperature Control函数库是基于OneWire函数库进行开发的,更便于使用,下面讲解一下主要函数的功能和用法。
(1) void begin(void):初始化,无输入参数,无返回参数。
(2) getDeviceCount(void):获取单总线上所连接器件的总数,无输入参数,返回参数为器件数目。
(3) validAddress(uint8_t*):验证指定地址的器件是否存在,输入参数为器件地址,返回参数为布尔型。
(4) getAddress(uint8_t*, const uint8_t):验证的器件的地址与索引值是否匹配,输入参数为器件地址和索引值,返回参数为布尔型。
(5) getResolution(uint8_t*):获取指定器件的精度,输入参数为器件地址,返回参数为精度位数。
(6) setResolution(uint8_t*,uint8_t):设置器件的精度,输入参数为器件地址和精度位数,无返回参数。精度位数有9,10,11和12可供选择。
(7) requestTemperatures(void):向单总线上所有器件发送温度转换的请求,无输入参数,无返回参数。
(8) requestTemperaturesByAddress(uint8_t*):向单总线上指定地址的器件发送温度转换的请求,输入参数为器件地址,无返回参数。
(9) requestTemperaturesByIndex(uint8_t) :向单总线上指定索引值的器件发送温度转换的请求,输入参数为器件索引值,无返回参数。
(10) getTempC(uint8_t*):通过器件地址获取摄氏温度,输入参数为器件地址,返回参数为摄氏温度。
(11) getTempF(uint8_t*):通过器件地址获取华氏温度,输入参数为器件地址,返回参数为华氏温度。
(12) getTempCByIndex(uint8_t):通过索引值来获取摄氏温度,输入参数为器件索引值,返回参数为摄氏温度。
(13) getTempFByIndex(uint8_t):通过器件索引值来获取华氏温度,输入参数为器件索引值,返回参数为华氏温度。
2.2 使用实例
由于单总线上可以连接多个DS18B20,而不多占用Arduino控制器的IO口,从而很容易地就可以实现多点测温,下面分别两个使用实例来说明DS18B20与Arduino的用法。
2.3 一路温度测量
(1)硬件连接
将DS18B20温度传感器的VCC和GND分别连接至Arduino Uno控制器的 5V和GND,以给DS18B20提供电源,DS18B20的DQ引脚接至ArduinoUno控制器数字引脚D2,且并联4.7kΩ的上拉电阻,如图12所示。

图12 电路温度测量硬件连接图

通过比较,使用DS18B20温度传感器充分发挥了它的功能,能准确地测量出实时温度,且价格不高,故选用DS18B20温度传感器来我们对周边环境温度的检测。

3.1.3电机驱动电路方案选择
方案一:采用专用芯片L298N作为电机驱动芯片。L298N是一个具有高电压大电流的全桥驱动芯片,它相应频率高,L298N芯片可以驱动两个二相电机,也可以驱动一个四相电机,输出电压最高可达50V,可以直接通过电源来调节输出电压;可以直接用单片机的IO口通过光耦芯片提供信号;电路简单,使用比较方便。
方案二:对于直流电机用分立元件构成驱动电路。由分立元件构成电机驱动电路,结构简单,价格低廉,在实际应用中应用广泛。但是这种电路工作性能不够稳定。

通过比较,使用L298N芯片充分发挥了它的功能,能稳定地驱动步进电机,且价格不高,故选用L298N驱动电机来驱动我们的二相电机。
3.1.4电源模块
由于本系统需要电池供电,我们考虑了如下集中方案为系统供电。
方案一:采用12V蓄电池为系统供电。蓄电池具有较强的电流驱动能力以及稳定的电压输出性能。
方案二:采用3节4.2V可充电式锂电池串联共12.6V给直流电机供电,经过7805的电压变换后为单片机,传感器和点击供电。经过实验验证,当电池为电机供电时,单片机、传感器的工作电压不够,性能不稳定。因此我们放弃了此方案。
方案三:用2节锂电池经另一套7805电压变换电路为电机供电。再用12V蓄电池为系统供电,蓄电池具有较强的电流驱动能力以及稳定的电压输出性能。采用此种供电方式后,单片机和传感器工作稳定,电机工作互不影响,且电池的体积较小,能够满足系统的要求。
综上考虑,采用了方案三。
3.1.5 蓝牙模块的选择
主机模块实物与从机一样,模块上有白点,主机模块会自动和从机模块配对,省却配对的麻烦,适合在需要两个设备间通过蓝牙串口无线通信的应用,无需电脑。
蓝牙透传模块可以让你原来使用串口的设备摆脱线缆的束缚在10米范围内实现无线串口通信。使用该模块无需了解复杂的蓝牙底层协议,只要简单的几个步骤即可享受到无线通信的便捷。蓝牙透传模块只有4个AT指令,分别是测试通讯,改名称,改波特率,改配对密码,AT指令必须从TXD,RXD信号脚设置,不能通过蓝牙信道设置。发送AT指令的设备可以是各种类型的MCU(比如51,avr,pic,msp430,arm等),也可以是电脑通过串口(PC串口接MAX232以后或者USB转串口)发送。
特别注意:
1、主机模块和从机模块均不能切换工作模式,只能是单一的工作模式(主或从)
2、主机模块只能配对HC06的从机模块,主机模块之间不能配对连接,主机模块也不能跟带蓝牙的电脑或者手机等其他蓝牙设备配对
3、从机模块可以跟带蓝牙的电脑或者部分带蓝牙的手机配对使用,从机模块之间不能连接,如果电脑没有蓝牙适配器,可以购买我们的蓝牙适配器
4、主机模块的AT指令比从机模块少了AT+NAME指令,其他指令相同
5、主机模块和从机模块的接口均为3.3V电平,可以直接连接各种TTL电平带串口MCU(5V的MCU请串联1K电阻)直接连接,设置参数可以用MCU或者本店的USB转串口,或者增加MAX232转换电路后的电脑串口
小常识:
TXD:发送端,一般表示为自己的发送端,正常通信的时候接另一个设备的RXD。
RXD:接收端,一般表示为自己的接收端,正常通信的时候接另一个设备的TXD。
正常通信时候本身的TXD永远接设备的RXD!
自收自发:顾名思义,也就是自己接收自己发送的数据,也就是自身的TXD接到自身的RXD,用来测试本身的发送和接收是否正常。也称回环测试。
由于蓝牙核心板不方便接线,因此我们把它焊接到底板上,底板上含3.3V LDO,为了方便再拆卸,仅焊接有用的引脚,引出VCC、GND、TXD、RXD(TXD、RXD均为3.3V电平)四根线方便接线,STATE为LED状态输出脚,未连接时输出脉冲,连接后输出高电平,可由MCU判断状态,需自行焊接插针,KEY接口对从机无效。该蓝牙模块可以接各种单片机,USB转串口等串口设备,输入电压3.6~6V(推荐5V,不得超过7V),
模块尺寸:3.57cm*1.52cm(cm)
注意:所标价格为单个模块的价格,并非一对模块的价格!!!
模块与单片机请遵循以下连接:

3.1.6 硬件总体设计方案
经过反复比较论证,本论文确定了如下方案

  1. 采用Arduino单片机作为主控制器.
  2. 用DS18B20温度传感器作为本系统的温度传感器.
  3. 用光敏火焰传感器作为本系统的火焰传感器.
  4. L298D作为直流电机的驱动芯片.
  5. 使用蜂鸣器进行灭火报警.
  6. 用手机蓝牙控制小车

3.2功能设计
3.2.1软件系统功能的设计
我们所采用同的编程工具Arduino1.7.8,介绍了主要的控制模块程序,编写相应的控制程序,主要是温度识别程序和灭火控制程序。
3.2.2软件开发平台介绍4.1编译语言及编译环境的选择
(1)汇编语言概述
为了克服机器语言的缺点,用英文字条来代替机器语言,这些英文字符被称为助记符,用助记符表示的指令称为符号语言或汇编语言。
汇编语言是面向机器的语言,程序设计人员必须对单片机的硬件有相当深入的了解。助记符指令和机器指令一一对应,所以用汇编语言编写的程序效率高,占用的存储空间小,运行速度快,因此用汇编语言能编写出最优化的程序。汇编语言程序能直接管理和控制硬件设备(功能部件),它能处理中断,也能直接访问存储器及I/O接口电路。但是,汇编语言和机器语言一样,都脱离不开具体机器的硬件,因此,这两种语言均是面向机器的语言,缺乏通用性。
(2)C语言概述
C语言是国际上广泛流行的计算机高级语言,既可用来写系统软件,也可用来写应用软件。C语言功能丰富,表达能力强,使用灵活方便,应用面广,目标程序效率高,可移植性好,既具有高级语言的优点,又具有低级语言的许多特点。因此,C语言特别适合于编写系统软件。它的特点如下:
1、语言简洁、紧凑,使用方便、灵活。
2、运算符丰富,数据结构丰富,具有现代化语言的各种数据结构。
4、具有结构化的控制语句用函数作为程序的模块单位,便于实现程序的模块化。
5、语法限制不大严格,程序设计自由度大。
6、C语言允许直接访问物理地址。
7、生成目标代码质量高,程序执行效率高,用C语言写的程序可移植性好。
(2) 编译语言及编译环境综述
兼于以上两种编译语言的优缺点,我选择了Arduino软件。Arduino软件是目前最流行开发Arduino系列单片机的软件,Arduino语言是建立在C/C++基础上的,其实也就是基础的C语言,Arduino语言只不过把AVR单片机(微控制器)相关的一些参数设置都函数化,不用我们去了解他的底层,让我们不了解AVR单片机(微控制器)的朋友也能轻松上手。如果使用C语言编程,那么Arduino几乎就是不二之选,即使不使用C语言而仅用汇编语言编程,其方便易用的集成环境、强大的软件仿真调试工具也会令事情变得事半功倍。
编程语言选用C语言。汇编语言作为传统的嵌入式系统的编程语言,具有执行效率高的优点,但其本身是低级语言,编程效率较低,可移植性和可读性差,维护极不方便。而C语言以其结构化,容易维护,容易移植的优势满足开发的需要。

3.2.3主程序流程图
主程序流程图如下图所示:

在我们蓝牙控制小车下,小车进行周围环境巡逻模式,在小车行进过程中检测火焰,一旦发现火焰则启动风扇灭火,随后警报声响起,灭火后检测火焰是否被扑灭,确定火焰被扑灭后关闭风扇和警报器。检测周边环境温度变化,超过我们上限的温度就会发出警报声。如果温度逐渐降低,随后警报声将关闭。

图9:蓝牙遥控连接说明 图10:蓝牙遥控界面说明图
3.2.4 巡逻程序流程图
小车巡逻时,对小车进行控制:小车前进时,两个电机速度相同;小车左转,左轮速度降低,右轮保持不变;小车右转,右轮速度降低,左轮保持不变;小车后退,电机反转。电机的速度采用延时控制电机绕组电压接通与断开的时间,这样即可改变电机的平均电压达到调速的目的。
当小车检测高温物体或气体时,通过温度传感器识别,若其温度达到一定界限就出发连接好的警报(或者),通过蜂鸣器发出警报,警示灯亮起,并发出响亮的警报声,从而实现高温警报的功能。
当小车检测火焰时,利用火焰传感器感器检测道路上的着火的物体,如蜡烛,根据火焰不同的波段然后把数据传送给单片机,当火焰传感器检测到局里小车前方有火焰时单片机就发出指触发警示灯,并发出响亮的警报声。该功能的小车能够实现在出现火灾的情况下发现并及时实现报警功能。
巡逻程序关系图如下:

  1. 系统开发
    4.1源程序清单

```csharp
//  智能小车微信遥控实验
//============================================================================
//    温度传感器头文件
//#include <LiquidCrystal.h>
//#include <DallasTemperature.h>
//#include <OneWire.h>
//#define ONE_WIRE_BUS 12    //定义单总线连接的端口
//OneWire oneWire(ONE_WIRE_BUS);
//DallasTemperature sensors(&oneWire);
const int ledPin = 13; //设置LED灯的数字引脚为13
const int flamePin = 12; //设置火焰传感器的数字引脚为12
const int windPin=11;  //设置蜂鸣器的数字引脚为11
#define run_car     '1'//按键前
#define back_car    '2'//按键后
#define left_car    '3'//按键左
#define right_car   '4'//按键右
#define stop_car    '0'//按键停
/*小车运行状态枚举*/
enum{
  enSTOP = 0,
  enRUN,
  enBACK,
  enLEFT,
  enRIGHT
}enCarState;

//==============================
//
//车速控制量 control
#define level1  0x08//速度控制标志位1
#define level2  0x09//速度控制标志位2
#define level3  0x0A//速度控制标志位3
#define level4  0x0B//速度控制标志位4
#define level5  0x0C//速度控制标志位5
#define level6  0x0D//速度控制标志位6
#define level7  0x0E//速度控制标志位7
#define level8  0x0F//速度控制标志位8
//==============================
//==============================
int Left_motor_back = 9;     //左电机后退(IN1)
int Left_motor_go = 5;       //左电机前进(IN2)
int Right_motor_go = 6;      // 右电机前进(IN3)
int Right_motor_back = 10;   // 右电机后退(IN4)
int Right_motor_en = 8;      // 右电机前进(EN2)
int Left_motor_en = 7;       // 右电机后退(EN1)

int buzzer = 3;              //设置控制蜂鸣器的数字IO脚

int control = 150;          //PWM控制量
int incomingByte = 0;       // 接收到的 data byte
String inputString = "";         // 用来储存接收到的内容
boolean newLineReceived = false; // 前一次数据结束标志
boolean startBit  = false;  //协议开始标志
int g_carstate = enSTOP; //  1前2后3左4右0停止



/*超声波*/
int Echo = A1;  // Echo回声脚(P1.1)
int Trig =A0;  //  Trig 触发脚(P1.0)
int Distance = 0;
String returntemp = ""; //存储返回值 

void setup()
{
  //初始化电机驱动IO为输出方式
  pinMode(Left_motor_go, OUTPUT);    // PIN 5 (PWM)
  pinMode(Left_motor_back, OUTPUT);  // PIN 9 (PWM)
  pinMode(Right_motor_go, OUTPUT);   // PIN 6 (PWM)
  pinMode(Right_motor_back, OUTPUT); // PIN 10 (PWM)
  pinMode(Right_motor_en,OUTPUT);    // PIN 8 
  pinMode(Left_motor_en,OUTPUT);     // PIN 7 
  
  pinMode(buzzer,OUTPUT);//设置数字IO脚模式,OUTPUT为输出 
  pinMode(Echo, INPUT);    // 定义超声波输入脚
  pinMode(Trig, OUTPUT);   // 定义超声波输出脚
  
  Serial.begin(9600);	//波特率9600 (蓝牙通讯设定波特率)
 
  digitalWrite(buzzer,HIGH);    //不发声
  digitalWrite(Left_motor_en,HIGH);  // 右电机前进
  digitalWrite(Right_motor_en,HIGH);  // 右电机前进
  
 //  温度
  //pinMode(ledPin,OUTPUT);//将13号引脚设置为输出信号
  //Serial.println("Dallas Temperature IC Control Library Demo");
 // sensors.begin();    //启动单总线
 // digitalWrite(buzzer, HIGH);//将3号数字引脚的输出设置为高电平,蜂鸣器关闭
  // 火焰
  pinMode(flamePin,INPUT);//将12号引脚设置为输入信号
}

void Distance_test()   // 量出前方距离 
{
  digitalWrite(Trig, LOW);   // 给触发脚低电平2μs
  delayMicroseconds(2);
  digitalWrite(Trig, HIGH);  // 给触发脚高电平10μs,这里至少是10μs
  delayMicroseconds(10);
  digitalWrite(Trig, LOW);    // 持续给触发脚低电
  float Fdistance = pulseIn(Echo, HIGH);  // 读取高电平时间(单位:微秒)
  Fdistance= Fdistance/58;       //为什么除以58等于厘米,  Y米=(X秒*344)/2
  // X秒=( 2*Y米)/344 ==》X秒=0.0058*Y米 ==》厘米=微秒/58
  //Serial.print("Distance:");      //输出距离(单位:厘米)
  //Serial.println(Fdistance);         //显示距离
  Distance = Fdistance;
}  

void run()     // 前进
{
  digitalWrite(Right_motor_go,HIGH);  // 右电机前进
  digitalWrite(Right_motor_back,LOW);     
  analogWrite(Right_motor_go,control);//PWM比例0~255调速,左右轮差异略增减
  //analogWrite(Right_motor_back,0);
  digitalWrite(Left_motor_go,HIGH);  // 左电机前进
  digitalWrite(Left_motor_back,LOW);
  analogWrite(Left_motor_go,control);//PWM比例0~255调速,左右轮差异略增减
  //delay(time * 100);   //执行时间,可以调整
}

void brake()         //刹车,停车
{
  digitalWrite(Left_motor_back, LOW);
  digitalWrite(Left_motor_go, LOW);
  digitalWrite(Right_motor_go, LOW);
  digitalWrite(Right_motor_back, LOW);
  //delay(time * 100);//执行时间,可以调整
}

void left()         //左转(左轮不动,右轮前进)
{
  digitalWrite(Right_motor_go, HIGH);	// 右电机前进
  digitalWrite(Right_motor_back, LOW);
  analogWrite(Right_motor_go, 180);//control);
  //analogWrite(Right_motor_back,0);//PWM比例0~255调速
  digitalWrite(Left_motor_go, LOW);  //左轮不动
  digitalWrite(Left_motor_back, LOW);
  //analogWrite(Left_motor_go,0);
  //analogWrite(Left_motor_back,0);//PWM比例0~255调速
//  delay(100);	//执行时间,可以调整
//  digitalWrite(Right_motor_go, LOW);	//全部停止
//  delay(100);	//执行时间,可以调整
}

void spin_left()         //左转(左轮后退,右轮前进)
{
  digitalWrite(Right_motor_go, HIGH);	// 右电机前进
  digitalWrite(Right_motor_back, LOW);
  analogWrite(Right_motor_go,control);
  //analogWrite(Right_motor_back,0);//PWM比例0~255调速
  digitalWrite(Left_motor_go, LOW);  //左轮后退
  digitalWrite(Left_motor_back, HIGH);
  //analogWrite(Left_motor_go,0);
  analogWrite(Left_motor_back,control);//PWM比例0~255调速
  //delay(time * 100);	//执行时间,可以调整
}

void right()        //右转(右轮不动,左轮前进)
{
  digitalWrite(Right_motor_go, LOW);  //右电机不动
  digitalWrite(Right_motor_back, LOW);
  //analogWrite(Right_motor_go,0);
  //analogWrite(Right_motor_back,0);//PWM比例0~255调速
  digitalWrite(Left_motor_go, HIGH); //左电机前进
  digitalWrite(Left_motor_back, LOW);
  analogWrite(Left_motor_go,180);  //control);
//  delay(100);	//执行时间,可以调整
//  digitalWrite(Left_motor_go, LOW);	//全部停止
//  delay(100);	//执行时间,可以调整
}

void spin_right()        //右转(右轮后退,左轮前进)
{
  digitalWrite(Right_motor_go, LOW);  //右电机后退
  digitalWrite(Right_motor_back, HIGH);
  //analogWrite(Right_motor_go,0);
  analogWrite(Right_motor_back,control);//PWM比例0~255调速
  digitalWrite(Left_motor_go, HIGH); //左电机前进
  digitalWrite(Left_motor_back, LOW);
  //analogWrite(Left_motor_go,200);
  analogWrite(Left_motor_go,control);//PWM比例0~255调速
  //delay(time * 100);	//执行时间,可以调整
}

void back()          //后退
{
  digitalWrite(Right_motor_go, LOW); //右轮后退
  digitalWrite(Right_motor_back, HIGH);
  //analogWrite(Right_motor_go,0);
  analogWrite(Right_motor_back,control);//PWM比例0~255调速
  digitalWrite(Left_motor_go, LOW); //左轮后退
  digitalWrite(Left_motor_back, HIGH);
  //analogWrite(Left_motor_go,0);
  analogWrite(Left_motor_back,control);//PWM比例0~255调速
  //delay(time * 100);     //执行时间,可以调整
}
void whistle()   //鸣笛
{
    int i;
    for(i=0;i<80;i++)//输出一个频率的声音
    { 
      digitalWrite(buzzer,LOW);//发声音
      delay(10);//延时1ms 
      digitalWrite(buzzer,HIGH);//不发声音
      delay(1);//延时ms 
    } 
    for(i=0;i<100;i++)//输出另一个频率的声音 
    { 
      digitalWrite(buzzer,LOW);//发声音
      delay(20);//延时2ms 
      digitalWrite(buzzer,HIGH);//不发声音
      delay(2);//延时2ms 
    } 
}
/*void temperature()  //温度
{
   Serial.print("Requesting temperatures...");
  sensors.requestTemperatures();    //发送温度测量请求命令
  Serial.println("DONE");
  Serial.print("Temperature for the device 1 (index 0) is: ");
  Serial.print(sensors.getTempCByIndex(0));    //获取0号传感器温度数据并发送
  
  Serial.println( "C");
 if(sensors.getTempCByIndex(0)>30)
 {
 digitalWrite(buzzer, LOW);//将3号数字引脚的输出设低,蜂鸣器 开启 
  //tone(3,320,200);//将3号数字引脚的输出设置为320Hz频率,持续时间200毫秒,蜂鸣器触发
  digitalWrite(ledPin,HIGH);//将13号数字引脚的输出设置为高电平,LED灯点亮
  delay(6000);  //六秒刷新一次
  digitalWrite(ledPin,LOW);//将13号数字引脚的输出设置为低电平,LED灯熄灭
  digitalWrite(buzzer, HIGH);//将3号数字引脚的输出设置为高电平,蜂鸣器关闭
 }
 delay(500); //停留500毫秒,进行下一次循环 温度传感器是否触发
}*/
 //火焰
 
 void flame()
 {
  //读取火焰传感器的数字输出,高电平表示“1”,低电平表示“0”,以布尔值的形式储存在news变量中;
  boolean news = digitalRead(flamePin);
  if(news == 1)//没有感应到火焰!
  {
   Serial.println("No Flame !");//串口监控器显示“NO flame!”
    digitalWrite(ledPin, LOW);//将13号数字引脚的输出设置为低电平,LED灯熄灭
    digitalWrite(buzzer, HIGH);//将3号数字引脚的输出设置为高电平,蜂鸣器关闭
    digitalWrite(windPin, HIGH);//将11号数字引脚的输出设置为gao电平,wind close

  }
  else // 感应到火焰!
  {   
     Serial.println("Flame!");//串口监控器显示“Flame!”
    digitalWrite(ledPin,HIGH);//将13号数字引脚的输出设置为高电平,LED灯点亮
    tone(3,320,200);//将3号数字引脚的输出设置为320Hz频率,持续时间200毫秒,蜂鸣器触发
   digitalWrite(windPin, LOW);//将11号数字引脚的输出设置为di电平,wind open
    delay(1000);//停留1000毫秒
    digitalWrite(ledPin,LOW);//将13号数字引脚的输出设置为低电平,LED灯熄灭
    noTone(7);//
  }
  delay(500); //停留500毫秒,进行下一次循环判断火焰传感器是否触发
 } 
 
/*程序主循环入口*/
void loop() 
{     
  //  温度
   //temperature();
   
  //火焰
   flame();
   
  
    if (newLineReceived)
    {
      switch(inputString[1])
      {
        case run_car:   g_carstate = enRUN; Serial.print("run\r\n"); break;
        case back_car:  g_carstate = enBACK;  Serial.print("back\r\n");break;
        case left_car:  g_carstate = enLEFT; Serial.print("left\r\n");break;
        case right_car: g_carstate = enRIGHT; Serial.print("right\r\n");break;
        case stop_car:  g_carstate = enSTOP; Serial.print("brake\r\n");break;
        default:g_carstate = enSTOP;break;
       }
       if(inputString[3] == '1')  //旋转
       {
          spin_left();
          Serial.print("revolve\r\n");
          delay(2000);//延时2ms 
          brake();
       }
       else if(inputString[3] == '2')  //旋转
       {
          spin_right();
          Serial.print("revolve\r\n");
          delay(2000);//延时2ms 
          brake();
       }
       if(inputString[5] == '1')  //鸣笛
       {
          whistle();
          Serial.print("whistle\r\n");
       }
       if(inputString[7] == '1')  //加速
       {
          control +=50;
          if(control > 255)
          {
            control = 255;
          }
          Serial.print("expedite\r\n");
       }
       if(inputString[9] == '1')  //减速
       {
          control -= 50;
          if(control < 50)
          {
            control = 100;
          }
          Serial.print("reduce\r\n");
       }           
      
       //返回状态
       Distance_test();
       returntemp = "$0,0,0,0,0,0,0,0,0,0,0,";
       returntemp.concat(Distance);
       returntemp += "cm,8.2V#";
       Serial.print(returntemp); //返回协议数据包       
       inputString = "";   // clear the string
       newLineReceived = false;    
 
    }
    
    switch(g_carstate)
    {
      case enSTOP: brake();break;
      case enRUN:run();break;
      case enLEFT:left();break;
      case enRIGHT:right();break;
      case enBACK:back();break;
      default:brake();break;
    }
    
}
  
//serialEvent()是IDE1.0及以后版本新增的功能,不清楚为什么大部份人不愿意用,这个可是相当于中断功能一样的啊!  
void serialEvent()
{
  while (Serial.available()) 
  {    
    incomingByte = Serial.read();              //一个字节一个字节地读,下一句是读到的放入字符串数组中组成一个完成的数据包
    if(incomingByte == '$')
    {
      startBit= true;
    }
    if(startBit == true)
    {
       inputString += (char) incomingByte;     // 全双工串口可以不用在下面加延时,半双工则要加的//
    }  
    if (incomingByte == '#') 
    {
       newLineReceived = true; 
       startBit = false;
    }
  }
}


4.2功能实现
(1)我选择了最核心的部分,在实现两个主要功能的两个传感器:火焰传感器和温度传感器。
(2)启动火焰传感器结合警报灯,还有小型电风扇代码:
 //火焰
 const int ledPin = 13; //设置LED灯的数字引脚为13
const int flamePin = 12; //设置火焰传感器的数字引脚为12
const int windPin=11;  //设置蜂鸣器的数字引脚为11

 void flame()
 {
  //读取火焰传感器的数字输出,高电平表示“1”,低电平表示“0”,以布尔值的形式储存在news变量中;
  boolean news = digitalRead(flamePin);
  if(news == 1)//没有感应到火焰!
  {
   Serial.println("No Flame !");//串口监控器显示“NO flame!”
    digitalWrite(ledPin, LOW);//将13号数字引脚的输出设置为低电平,LED灯熄灭
    digitalWrite(buzzer, HIGH);//将3号数字引脚的输出设置为高电平,蜂鸣器关闭
    digitalWrite(windPin, HIGH);//将11号数字引脚的输出设置为gao电平,wind close

  }
  else // 感应到火焰!
  {   
     Serial.println("Flame!");//串口监控器显示“Flame!”
    digitalWrite(ledPin,HIGH);//将13号数字引脚的输出设置为高电平,LED灯点亮
    tone(3,320,200);//将3号数字引脚的输出设置为320Hz频率,持续时间200毫秒,蜂鸣器触发
   digitalWrite(windPin, LOW);//将11号数字引脚的输出设置为di电平,wind open
    delay(1000);//停留1000毫秒
    digitalWrite(ledPin,LOW);//将13号数字引脚的输出设置为低电平,LED灯熄灭
    noTone(7);//
  }
  delay(500); //停留500毫秒,进行下一次循环判断火焰传感器是否触发
 } 
 
/*程序主循环入口*/
void loop() 
{     
  //火焰
   flame();
}3)启动温度传感器结合警报灯代码:
//    温度传感器头文件
//#include <LiquidCrystal.h>
//#include <DallasTemperature.h>
//#include <OneWire.h>
//#define ONE_WIRE_BUS 12    //定义单总线连接的端口
//OneWire oneWire(ONE_WIRE_BUS);
//DallasTemperature sensors(&oneWire);
const int ledPin = 13; //设置LED灯的数字引脚为13
const int windPin=11;  //设置蜂鸣器的数字引脚为11
void temperature()  //温度
{
   Serial.print("Requesting temperatures...");
  sensors.requestTemperatures();    //发送温度测量请求命令
  Serial.println("DONE");
  Serial.print("Temperature for the device 1 (index 0) is: ");
  Serial.print(sensors.getTempCByIndex(0));    //获取0号传感器温度数据并发送
  
  Serial.println( "C");
 if(sensors.getTempCByIndex(0)>30)
 {
 digitalWrite(buzzer, LOW);//将3号数字引脚的输出设低,蜂鸣器 开启 
  //tone(3,320,200);//将3号数字引脚的输出设置为320Hz频率,持续时间200毫秒,蜂鸣器触发
  digitalWrite(ledPin,HIGH);//将13号数字引脚的输出设置为高电平,LED灯点亮
  delay(6000);  //六秒刷新一次
  digitalWrite(ledPin,LOW);//将13号数字引脚的输出设置为低电平,LED灯熄灭
  digitalWrite(buzzer, HIGH);//将3号数字引脚的输出设置为高电平,蜂鸣器关闭
 }
 delay(500); //停留500毫秒,进行下一次循环 温度传感器是否触发
}
void loop() 
{     
  //火焰
   temperature()}

(1)结合温度传感器在Arduino编译器上的监视窗口测试的实验数据如下图:

(2)结合火焰传感器在Arduino编译器上的监视窗口测试的实验数据如下图:

结论与心得 刚开始我们接触到硬件设计这门课,在选题时,发现智能小车是个有趣的方向。我们三不一而同选择它。 一开始我们选定了这个温度探测这个功能,是因为想区别于其他小组的小车,并且算是一个较突破那些的传统功能,如循迹,红外避障等功能的小车。因此下定决心选了此功能。 后来我们也尝试不断扩充其功能,后面发现小车的输入输出信号口已经用完了,若有剩余,我们便可以让火焰传感器和温度传感器同时存在并实现功能。

附有趣小视频

高温报警灭火

更多推荐

基于Arduino高温巡逻报警智能小车