Arduino空气检测报警系统Proteus仿真实现与阈值调试
2026/9/16 16:09:34 网站建设 项目流程

简介:这套Arduino空气检测警报系统仿真资源面向电子、嵌入式及物联网方向学习者,采用Proteus完成整体仿真设计,实现对PM2.5、有毒气体和温湿度三项指标的实时监测与LCD屏显示。系统设定当PM2.5浓度超过150或有毒气体比例高于10%时触发蜂鸣器和报警灯,模拟空气异常预警场景,逻辑清晰适合入门复现。压缩包共12个文件,以pde程序源文件、pdsprj仿真工程、库支持文件、png电路图和docx说明文档为主,整体仅172KB,内容紧凑易用。资源附带液晶驱动库及依赖配置,便于直接加载运行,也可在此基础上扩展蓝牙上报、风扇联动等附加功能,适合课设、毕设和Proteus仿真练习参考。已有985人学习下载,可作为空气检测报警类项目起步整理的完整参考。

1. 空气检测警报系统在 Proteus 里跑通,先别急着买传感器

做 Arduino 开发的人大多有过这种经历:MQ-2 烟雾传感器、蜂鸣器、LED 都买回来了,代码也写好了,结果一上电,读数飘得离谱,要么乱响要么不响,根本分不清是传感器坏了、电路接错了,还是程序逻辑有 bug。Proteus 仿真最大的价值就是把这一步提前,用虚拟元件先把报警逻辑、阈值判定和响应时序调好,再带着方案去焊实物。

这个系统做了三件核心的事:采集空气质量数据、和阈值做比较、驱动声光报警。传统做法里,空气质量传感器通常采样模拟电压输出,但在 Proteus 里不一定要用气敏模型,用滑动变阻器模拟传感器输出是最常见也最可控的方案。本文用 Proteus 8 Professional 从建工程开始,把元件选型、代码流程、报警参数和仿真调试完整过一遍,最终得到一个能直接改阈值、换传感器、接后续逻辑的仿真模板。适合正在做课程设计、竞赛原型,或者想在没有硬件的情况下先把 Arduino 程序调通的人。仿真是工程环节里成本最低的验证手段,值得花半小时把这条路走通。

2. 系统拆解与仿真环境准备:把 Arduino 报警系统的最小单元搭出来

2.1 空气检测警报系统的组成结构

空气检测警报系统的本质是一个闭环的阈值判定系统,核心链路只有四段:传感器信号输入、模拟量读取、逻辑判断、报警执行。以 Arduino Uno 作为主控,传感器输出的模拟电压信号接入 A0 引脚,Arduino 通过analogRead()函数将 0–5V 电压映射为 0–1023 的数值,程序将这个数值与预设的报警阈值比较,一旦超过阈值就驱动蜂鸣器发声和 LED 闪烁。整个过程没有任何复杂的控制算法,难点在于阈值标定和报警逻辑的可靠性。

2.2 Proteus 8 Professional 建工程与元件清单

打开 Proteus 8 Professional,新建工程时选择 Schematic Capture 模板。工程命名建议带上项目语义,比如air_alarm_sim,文件路径不要包含中文和空格,否则后面的仿真和编译环境容易出路径问题。建好空白原理图后,进入 P(Pick Device)搜索元件。

以下是这份仿真需要用到的完整元件清单:

元件标识Proteus 搜索关键词用途说明
Arduino Uno 开发板ARDUINO UNO (或 ARDUINO NANO)主控板,Proteus 里直接作为虚拟固件载体
电位器POT-HG模拟空气质量传感器的电压输出
蜂鸣器BUZZER声音报警输出
LEDLED-RED光报警输出
电阻RESLED 限流保护
示波器OSCILLOSCOPE监测模拟信号波形
虚拟终端VIRTUAL TERMINAL查看串口输出数据

选完元件后,依次摆放到画布上。Arduino Uno 在 Proteus 元件库里有标准封装,直接搜索ARDUINO UNO就能找到。注意:Proteus 不同版本对 Arduino 支持度不一样,Proteus 8.9 以后内置了完整的 Arduino 仿真模型,旧版本可能需要额外添加第三方库文件,如果搜索不到ARDUINO UNO,优先检查 Proteus 版本而不是怀疑元件库损坏。

2.3 连线规则与模拟量采集电路设计

在 Proteus 里拉连接线时,Arduino Uno 的 A0 引脚对应元件示意图上的A0管脚。电位器三个引脚的处理方式:中间抽头(通常是 wiper 端,Proteus 元件图中标号为 T 或 W)连接到 A0,另外两端一端接 VCC,一端接 GND。这样旋动电位器就可以连续改变 A0 引脚上的电压,模拟真实空气传感器在不同污染浓度下的输出变化。

蜂鸣器接法要分清楚有源和无源的区别。Proteus 元件库里的 BUZZER 默认是有源蜂鸣器,给高电平就响,给低电平就停,适合直接做开关报警。如果后续要做呼吸灯式或者变频报警,那就需要改用无源蜂鸣器,用tone()函数输出不同频率的方波。这里采用最直接的方式:BUZZER 正极接 Arduino 的 D8 引脚,负极接 GND。LED 正极通过一个 220Ω 限流电阻接到 D7 引脚,负极接 GND。电位器的 A0 信号通道在中串联一个 1kΩ 电阻再接 A0,这是一个减少模拟信号端噪声的常规做法,仿真场景下不算必须,但保持这个习惯,移植到实物时会少踩一个坑。

整个布线确认后用 DRC(电气规则检查)验证,快捷键是T菜单下的Electrical Rule Check,重点看有没有虚接或短路告警。DRC 通过后进入下一步:给 Arduino 烧录固件程序。

3. 用 Arduino IDE 编写空气质量采集与报警逻辑,烧录进 Proteus 虚拟板

3.1 程序框架:先定状态机,再写代码

空气检测警报系统的代码不需要多难,但逻辑一定要清晰。我的做法是先把系统状态画出来:正常状态(绿灯或者说 LED 不闪、蜂鸣器不响)、报警状态(LED 闪烁、蜂鸣器鸣叫)、恢复状态(浓度回落到阈值以下,系统自动回到正常状态)。用状态机的方式来组织代码,后续增加 LCD 显示、风扇联动、联网上报都只需在对应状态分支里插入逻辑,不需要重构主干。

代码里定义两个关键阈值:报警阈值ALARM_THRESHOLD和恢复阈值RESET_THRESHOLD。这里用两个阈值而不是一个,是为了避免阈值附近的抖动导致报警和恢复来回横跳,这是一种简单的迟滞比较。生产环境里空气报警器几乎都做迟滞,仿真阶段就要把这种思想带进去。具体差值取多少,取决于传感器噪声幅度,Proteus 里把电位器调到一个固定位置,观察analogRead读数是否有跳动,一般留 3–5% 的余量就够。

执行读取与判定的周期:analogRead本身很快,但不需要每毫秒刷一次,我用 200ms 作为轮询间隔,蜂鸣器叫起来也有节奏感。如果你想模拟真实传感器的响应曲线——比如 MQ-2 加热丝需要预热——可以在初始化时加delay(60000)模拟一分钟预热期,仿真阶段为了不等待,用 5 秒就够了。

const int SENSOR_PIN = A0; const int BUZZER_PIN = 8; const int LED_PIN = 7; const int ALARM_THRESHOLD = 500; const int RESET_THRESHOLD = 450; const long READ_INTERVAL = 200; unsigned long lastReadTime = 0; bool alarmActive = false; void setup() { pinMode(BUZZER_PIN, OUTPUT); pinMode(LED_PIN, OUTPUT); pinMode(SENSOR_PIN, INPUT); Serial.begin(9600); } void loop() { unsigned long now = millis(); if (now - lastReadTime >= READ_INTERVAL) { lastReadTime = now; int sensorValue = analogRead(SENSOR_PIN); handleAlarmLogic(sensorValue); printStatus(sensorValue); } } void handleAlarmLogic(int value) { if (!alarmActive && value > ALARM_THRESHOLD) { alarmActive = true; } else if (alarmActive && value < RESET_THRESHOLD) { alarmActive = false; } if (alarmActive) { digitalWrite(LED_PIN, HIGH); digitalWrite(BUZZER_PIN, HIGH); delay(100); digitalWrite(LED_PIN, LOW); digitalWrite(BUZZER_PIN, LOW); delay(100); } else { digitalWrite(LED_PIN, LOW); digitalWrite(BUZZER_PIN, LOW); } } void printStatus(int value) { Serial.print("air_quality:"); Serial.print(value); Serial.print(" threshold:"); Serial.print(ALARM_THRESHOLD); Serial.print(" state:"); Serial.println(alarmActive ? "ALARM" : "NORMAL"); }

这段代码的关键点集中在handleAlarmLogic:先判断当前是否处于报警状态,再决定用哪个阈值去比较,这样实现的迟滞区间是ALARM_THRESHOLDRESET_THRESHOLD之间的 50 个读数单位。LED 和蜂鸣器在报警状态里交替亮灭 100ms,实现闪烁和断续蜂鸣,占空比 50%,报警的辨识度很高。

3.2 配置板卡型号与烧录,连接 Proteus 虚拟串口

代码在 Arduino IDE 里编译前,要先把板卡型号选对。Proteus 里的ARDUINO UNO用的是 ATmega328P 芯片,所以在 Arduino IDE 的「工具 → 开发板 → Arduino AVR Boards」里选择Arduino Uno。处理器一项保持默认的 ATmega328P 不要动。

Proteus 的 Arduino 仿真模型分为两种:直接加载 HEX 文件,或者通过 VSM Studio 联调。最稳定的做法是先用 Arduino IDE 导出 HEX 文件。快捷键Ctrl+Shift+S或者菜单「项目 → 导出已编译的二进制文件」,生成的 HEX 文件位于项目的build文件夹下。如果找不到,可以打开 Arduino IDE 的「文件 → 首选项 → 显示详细输出」,上传时控制台会打印完整的临时目录路径,HEX 就藏在那里。

回到 Proteus,双击原理图上的 Arduino Uno 元件,在弹出的属性对话框里找到 Program File 一栏,点文件夹图标选择刚才导出的 HEX 文件。然后配置虚拟串口监视:Proteus 在运行时会自动把 Arduino 板上的 TX/RX 引脚虚拟出来,在原理图上放置一个 VIRTUAL TERMINAL 元件,把它的 RXD 引脚接 Arduino 的 TX(D1),TXD 引脚接 Arduino 的 RX(D0),这样串口打印的数据就能在虚拟终端里直接看到。运行仿真时,如果虚拟终端没显示数据,检查一下终端元件的Baud Rate属性是否设成了 9600,和代码里的Serial.begin(9600)保持一致。

烧录后运行,第一件事就是旋动电位器,把 A0 的电压从 0 慢慢往上调,观察虚拟终端打印的值和报警逻辑是否联动。这里有条件的话可以加一个 OSCILLOSCOPE(示波器)在 A0 那根线上,直接看电压波形和 LED 动作的时序对应关系,比只盯数据有用得多。

4. 阈值标定、报警联动和防误报:仿真里最容易出问题的环节

4.1 电压区间划分和阈值取法

空气检测系统的阈值不该拍脑袋定,得从 A0 引脚的电压区间往下推。Arduino 的analogRead把 0–5V 线性映射到 0–1023,所以阈值 500 对应的电压大概是 500 × 5 / 1023 ≈ 2.45V。在 Proteus 里看电位器分压是否准确,可以直接双击电位器,把 Resistance 属性改成总值 10k,然后用光标悬停在电位器上查看当前位置的抽头电压比例。

通常把整个测量区间划成三段:安全区(读值 0–450)、警戒区(450–600)、报警区(600 以上)。这里的警戒区不应触发报警,只是为将来的分级预警留出余地,比如驱动一个黄色 LED 慢闪。因为有了迟滞阈值,ALARM_THRESHOLD定在警戒区的上限 600,RESET_THRESHOLD定在警戒区下限 450,这样只要读数不跌回安全区,报警就不会因为轻微波动而解除。

4.2 MQ 系列传感器特性与电位器模拟的换算

如果你最终要接真实的 MQ-2 或 MQ-135,仿真阶段的电位器模型无法表达传感器上电后的初始漂移和响应时间,但输出特性可以做等效换算。MQ-2 在洁净空气中输出电压约 0.1–0.3V,对应读数 20–60;在丙烷烟雾浓度达到一定值时,模拟输出可以升到 2.5V 以上。仿真时把电位器从接地端往 VCC 方向旋转的过程,就相当于烟雾浓度从低到高的过程。想更真实一点,可以手动拖动电位器到一个位置后等一下再看读数,用物理操作模拟传感器的响应延迟——虽然不能代表真实的化学响应时间,但至少能让系统逻辑展现出一个完整的上升-报警-回落-复位的过程。

4.3 调参的标准流程:先录数据,再定阈值,最后测误报

不要上来就写死ALARM_THRESHOLD = 500然后祈祷它能用。我在仿真里调这个系统有一套固定的流程,整个流程在虚拟终端里完成。

第一步:把电位器拧到最小(A0 接 GND 端),记录稳定读数,记为baseline,这个值是洁净空气的基准。第二步:把电位器慢慢拧到最大(VCC 端),记录稳定读数,记作saturated。第三步:设置ALARM_THRESHOLD = baseline + (saturated - baseline) * 0.6,这个公式给出的是一个偏保守的 60% 位置阈值;想灵敏就把系数降到 0.4,想稳定就往 0.75。第四步:RESET_THRESHOLD在报警阈值基础上减去 10% 的满量程读数,即RESET_THRESHOLD = ALARM_THRESHOLD - (1023 * 0.1)

调完参数以后做三组测试:缓慢旋动电位器越过阈值,看报警能否可靠触发;在阈值边缘来回小幅旋动,看是否有反复通断的抖动;快速把电位器从报警区拧回零位,看恢复阈值是否能让系统及时解除报警。这三组过完,报警逻辑的稳定性心里就有底了。

4.4 蜂鸣器不响、LED 常亮、仿真卡死:Proteus 仿真三大常见故障

故障一:LED 亮但蜂鸣器不响。八成是蜂鸣器型号选错,Proteus 的 BUZZER 和 BUZZER ACTIVE 是有区别的,确认用的是有源蜂鸣器。如果用无源蜂鸣器接了digitalWrite电平,它能响才怪,无源蜂鸣器必须给方波比如用tone(8, 1000)

故障二:LED 和蜂鸣器都在动作,但虚拟终端数据停了。Arduino 板载 UART 在 Proteus 里如果接了两个虚拟终端会互抢 RX 引脚。确认虚拟终端只接了一组,且方向是板子的 TX 到终端的 RXD,反过来接就收不到数据。

故障三:仿真一点运行 CPU 占用就拉满或者直接卡死。这类问题通常不是逻辑错误而是 Proteus 仿真步长太激进,在菜单 System → Animation Options 里把仿真帧率调低到 10–20fps,同时在代码的循环里保持READ_INTERVAL = 200的节流,这两个动作能解决绝大多数卡顿。

5. 用信号源接入替代手拧电位器,让报警系统更接近真实测量环境

5.1 为什么要换成信号源做动态输入

手拧电位器只能验证通断逻辑,无法验证系统的动态响应,比如浓度突然飙升时报警的反应时间、正弦波起伏时会不会因为迟滞区间太小而触发误报。把 A0 输入从电位器切换到一个信号发生器或使用 Proteus 的模拟信号源,可以注入阶跃波、正弦波、三角波三组测试波形:阶跃波对应环境突变,正弦波对应缓慢变化,三角波对应比较中等变化速率的趋势。这种测试方式能逼出代码和阈值设计里的隐藏抖动。

5.2 在 Proteus 里换用信号发生器作为 A0 输入源

在元件库搜索SINE(正弦信号发生器),放到原理图上,输出引脚接 A0 输入,把 A0 和电位器抽头之间的连线断开。双击 SINE 元件设置参数:用幅值 2.5V、偏置 2.5V、频率 0.1Hz,这样输出信号在 0V 到 5V 之间缓慢摆动。0.1Hz 的周期是 10 秒,足够让虚拟终端打印出几十行有效数据来观察报警状态切换。

也可以再加一个PULSE发生器,用阶跃信号测试系统对突变的响应速度。PULSE 设置初始电压 0V、脉冲电压 4V(差不多对应读数 820)、脉冲宽度 1 秒、周期 3 秒,运行后观察 LED 的闪烁周期和 Beep 的节奏是否与预期一致。注意这里的 4V 电压远超过报警阈值 2.45V,系统应该在一个读值周期内(200ms)进入报警态。

5.3 通过串口打印的数据做迟滞区间验证

换成信号源输入后,虚拟终端的打印值会更平滑,这特别适合验证迟滞阈值是否真的在工作。观察这类数据有个技巧:把Serial.print输出的读数下载或复制下来,在 Excel 里画折线图,对报警区间打上高亮标记。如果发现曲线在ALARM_THRESHOLD附近出现了快速的高低电平交替,说明迟滞区间过窄,或者读间隔太快跟不上信号斜率,这时应当调大RESET_THRESHOLDALARM_THRESHOLD之间的差值到 8–10% 的满量程。这个验证流程在实物调试时也能照搬,用示波器或者用 Arduino 自带的Plotter(绘图仪)工具实现。

# Arduino IDE 串口绘图仪的位置:工具 → 串口绘图仪(Serial Plotter) # 打开后将收到类似以下格式的两路数据: # air_quality:412.00 threshold:600.00

串口绘图仪的横轴是时间,纵轴是数值,能同时看到传感器读数和阈值线,比对抖动是否穿越阈值线一目了然,比肉眼盯文本快得多。

5.4 方波测试和报警延时测量

在公安消防标准里,报警响应时间通常要求在浓度超标后 XX 秒内发声,仿真阶段虽然没有硬性指标的压力,但可以自己加一个响应时间的测试。在代码里用millis()记录系统报警状态翻转的时刻,串口打印出进入报警状态后的第一个时间戳,然后在 PULSE 发生器里对比输入信号的上升沿时刻,差值即是系统的报警延迟。这个延迟由两部分组成:主循环的READ_INTERVAL(最大 200ms)加上蜂鸣器控制逻辑判断的耗时(毫秒级),总共约 200–400ms 是合理范围。

6. 进阶:在仿真的基础上做传感器接法和多级报警扩展

仿真跑通后,最有价值的动作是把这份方案往真实硬件方向迁移。一个常见但很容易出错的点是传感器的模拟输出能不能直接连 Arduino。像 MQ 系列模块,板载比较器输出的是数字信号,要改接 A0 得调整模块上电位器改变灵敏度;而传感器本身的模拟输出端(AOUT)接 A0 时,要确认模块工作电压是 5V 还是 3.3V,Proteus 里 Arduino Uno 模型只有 5V 供电轨,所以真机用 3.3V 的传感器模块时阈值必须重新按分压计算,不能直接搬仿真里的 500 这个数。

另一条值得扩展的方向是给系统加 LCD 1602 显示模块,在 Proteus 元件库里搜索LM016L接 I2C 或直接并行接法,把air_quality读数和当前状态同步显示出来。这会让整套系统更接近一个完整产品而不只是报警盒子。LCD 接 I2C 时要注意,Arduino Uno 上的 I2C 引脚是 A4(SDA)和 A5(SCL),Proteus 上如果找不到 I2C 版本的 LCD 元件,就改用标准并行接口的 LM016L,用 D4–D7 四根数据线加 RS、EN 控制引脚,正好把 D7、D8 之外的引脚利用起来。在多级报警扩展上,可以在现有二阈值基础上增加第三级:超过警戒区但低于报警区时,风扇引脚输出高电平,用 PWM 控制转速,报警区则直接锁存报警状态。这套逻辑在仿真里验证通过后,做成实际产品时还能顺带完成联动排风的需求,这也是空气检测报警系统最常见的落地形态。

最后要给新接触这类仿真的人一个容易被忽略的提醒:Proteus 仿真的运行速度不等于单片机的实时运行速度,报警延迟在仿真里看得见摸得着,但其绝对数值和真实晶振 16MHz 下跑出来的会有偏差,要精确测量延迟,还是得靠实物。仿真的正确用途是把逻辑边界和参数范围摸清楚,减少焊板子时反复换电阻找基准点的次数——把时间省下来,自然能多留些工夫在设计真正的产品逻辑上。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询