【CanMV K210】基础实验 板载输入 IO 检测与分级告警

在智能硬件项目中,传感器的价值不只是读取一个数字,而是让程序具备感知外部环境的能力。火焰检测、烟雾监测、温湿度采集、门磁状态判断,本质上都是把现实世界中的变化转换成程序可以处理的输入信号。对于 Python 硬件编程入门来说,火焰传感器实验很适合理解"输入检测"这类场景:开发板不再只是控制外设亮灭,而是持续读取外部模块状态,并根据状态变化做出响应。

本实验使用 CanMV K210 开发板读取火焰传感器的数字输出 DO 信号。程序将物理引脚 6 映射为 GPIO0,并配置为输入模式。火焰传感器未检测到火焰时输出安全电平,检测到火焰时输出危险电平。为了降低瞬间抖动带来的误判,代码加入了多次采样机制;为了避免串口持续刷屏,程序只在状态发生变化时输出完整提示,并在火焰持续存在时按时间统计告警等级。

学习目标 说明
理解数字输入检测 认识火焰传感器如何通过 DO 引脚输出高低电平状态
掌握 GPIO 输入读取 使用 maix.GPIO 创建输入对象,并通过 value() 读取传感器电平
理解灵敏阈值调节 通过模块上的黄色 E01 可调电位器设置触发灵敏度
掌握稳定采样方法 通过多次采样减少光线、距离和角度变化带来的误判
建立告警处理思路 根据状态变化和持续时间输出安全、危险和分级告警信息

这段代码的重点不是简单打印 0 或 1,而是把传感器输入、阈值判断、稳定采样、状态变化检测、持续时间统计和分级告警组合成一个完整的检测流程。后续接入蜂鸣器、继电器、LCD、网络通信或多传感器联动时,也可以沿用同样的输入检测思路。

文章目录

理论基础

火焰传感器属于输入检测类模块。模块上的敏感元件负责感知外部火焰或特定光源变化,电路部分负责把感知结果转换成可读取的电平信号。对于 CanMV K210 来说,程序并不直接读取"火焰"本身,而是读取传感器 DO 引脚输出的高低电平,再根据电平判断当前处于安全状态还是危险状态。

常见火焰传感器模块通常带有灵敏度调节结构。实物模块上的黄色 E01 可调电位器用于设置触发阈值:顺时针或逆时针旋转时,模块对外部光源或火焰信号的敏感程度会发生变化。阈值调得过低,模块可能一直触发危险状态;阈值调得过高,火焰靠近时也可能没有反应。因此这类实验不能只看代码,还需要结合模块上的阈值调节结构一起调试。

不同敏感元件的检测对象不同。光敏元件更适合检测环境亮暗变化,热敏元件更适合检测温度变化,火焰检测元件更适合检测火焰或红外光变化。实验时要区分模块类型,不要把光敏、热敏和火焰检测元件混为一个概念。下面这张图可以辅助区分几类常见敏感元件。

本实验使用的是数字输出 DO 信号。DO 的特点是结果已经被模块电路转换成高低电平,程序读取起来比较简单。代码中默认 SAFE_LEVEL = 1,表示高电平为安全状态;FIRE_LEVEL = 0,表示低电平为检测到火焰。如果实际模块输出逻辑相反,只需要调整这两个常量,不需要重写主循环和状态处理函数。
#mermaid-svg-vc3i779WzFBBMdEh{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-vc3i779WzFBBMdEh .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-vc3i779WzFBBMdEh .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-vc3i779WzFBBMdEh .error-icon{fill:#552222;}#mermaid-svg-vc3i779WzFBBMdEh .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-vc3i779WzFBBMdEh .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-vc3i779WzFBBMdEh .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-vc3i779WzFBBMdEh .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-vc3i779WzFBBMdEh .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-vc3i779WzFBBMdEh .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-vc3i779WzFBBMdEh .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-vc3i779WzFBBMdEh .marker{fill:#333333;stroke:#333333;}#mermaid-svg-vc3i779WzFBBMdEh .marker.cross{stroke:#333333;}#mermaid-svg-vc3i779WzFBBMdEh svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-vc3i779WzFBBMdEh p{margin:0;}#mermaid-svg-vc3i779WzFBBMdEh .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-vc3i779WzFBBMdEh .cluster-label text{fill:#333;}#mermaid-svg-vc3i779WzFBBMdEh .cluster-label span{color:#333;}#mermaid-svg-vc3i779WzFBBMdEh .cluster-label span p{background-color:transparent;}#mermaid-svg-vc3i779WzFBBMdEh .label text,#mermaid-svg-vc3i779WzFBBMdEh span{fill:#333;color:#333;}#mermaid-svg-vc3i779WzFBBMdEh .node rect,#mermaid-svg-vc3i779WzFBBMdEh .node circle,#mermaid-svg-vc3i779WzFBBMdEh .node ellipse,#mermaid-svg-vc3i779WzFBBMdEh .node polygon,#mermaid-svg-vc3i779WzFBBMdEh .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-vc3i779WzFBBMdEh .rough-node .label text,#mermaid-svg-vc3i779WzFBBMdEh .node .label text,#mermaid-svg-vc3i779WzFBBMdEh .image-shape .label,#mermaid-svg-vc3i779WzFBBMdEh .icon-shape .label{text-anchor:middle;}#mermaid-svg-vc3i779WzFBBMdEh .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-vc3i779WzFBBMdEh .rough-node .label,#mermaid-svg-vc3i779WzFBBMdEh .node .label,#mermaid-svg-vc3i779WzFBBMdEh .image-shape .label,#mermaid-svg-vc3i779WzFBBMdEh .icon-shape .label{text-align:center;}#mermaid-svg-vc3i779WzFBBMdEh .node.clickable{cursor:pointer;}#mermaid-svg-vc3i779WzFBBMdEh .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-vc3i779WzFBBMdEh .arrowheadPath{fill:#333333;}#mermaid-svg-vc3i779WzFBBMdEh .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-vc3i779WzFBBMdEh .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-vc3i779WzFBBMdEh .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-vc3i779WzFBBMdEh .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-vc3i779WzFBBMdEh .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-vc3i779WzFBBMdEh .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-vc3i779WzFBBMdEh .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-vc3i779WzFBBMdEh .cluster text{fill:#333;}#mermaid-svg-vc3i779WzFBBMdEh .cluster span{color:#333;}#mermaid-svg-vc3i779WzFBBMdEh div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-vc3i779WzFBBMdEh .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-vc3i779WzFBBMdEh rect.text{fill:none;stroke-width:0;}#mermaid-svg-vc3i779WzFBBMdEh .icon-shape,#mermaid-svg-vc3i779WzFBBMdEh .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-vc3i779WzFBBMdEh .icon-shape p,#mermaid-svg-vc3i779WzFBBMdEh .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-vc3i779WzFBBMdEh .icon-shape .label rect,#mermaid-svg-vc3i779WzFBBMdEh .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-vc3i779WzFBBMdEh .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-vc3i779WzFBBMdEh .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-vc3i779WzFBBMdEh :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-vc3i779WzFBBMdEh .sensor>*{fill:#E8F3FF!important;stroke:#5B9BFF!important;stroke-width:2px!important;color:#1F3B6D!important;}#mermaid-svg-vc3i779WzFBBMdEh .sensor span{fill:#E8F3FF!important;stroke:#5B9BFF!important;stroke-width:2px!important;color:#1F3B6D!important;}#mermaid-svg-vc3i779WzFBBMdEh .sensor tspan{fill:#1F3B6D!important;}#mermaid-svg-vc3i779WzFBBMdEh .adjust>*{fill:#FFF4E8!important;stroke:#F4A261!important;stroke-width:2px!important;color:#7A4A00!important;}#mermaid-svg-vc3i779WzFBBMdEh .adjust span{fill:#FFF4E8!important;stroke:#F4A261!important;stroke-width:2px!important;color:#7A4A00!important;}#mermaid-svg-vc3i779WzFBBMdEh .adjust tspan{fill:#7A4A00!important;}#mermaid-svg-vc3i779WzFBBMdEh .input>*{fill:#EAFBF1!important;stroke:#42B983!important;stroke-width:2px!important;color:#1F5C3A!important;}#mermaid-svg-vc3i779WzFBBMdEh .input span{fill:#EAFBF1!important;stroke:#42B983!important;stroke-width:2px!important;color:#1F5C3A!important;}#mermaid-svg-vc3i779WzFBBMdEh .input tspan{fill:#1F5C3A!important;}#mermaid-svg-vc3i779WzFBBMdEh .code>*{fill:#F4EEFF!important;stroke:#8E6AD8!important;stroke-width:2px!important;color:#3D2B68!important;}#mermaid-svg-vc3i779WzFBBMdEh .code span{fill:#F4EEFF!important;stroke:#8E6AD8!important;stroke-width:2px!important;color:#3D2B68!important;}#mermaid-svg-vc3i779WzFBBMdEh .code tspan{fill:#3D2B68!important;}#mermaid-svg-vc3i779WzFBBMdEh .power>*{fill:#FCEEF4!important;stroke:#E76F51!important;stroke-width:2px!important;color:#7A2740!important;}#mermaid-svg-vc3i779WzFBBMdEh .power span{fill:#FCEEF4!important;stroke:#E76F51!important;stroke-width:2px!important;color:#7A2740!important;}#mermaid-svg-vc3i779WzFBBMdEh .power tspan{fill:#7A2740!important;} 火焰传感器敏感元件

感知火焰或外部光源变化
黄色 E01 可调电位器

设置触发灵敏阈值
模块比较电路

生成 DO 数字输出
CanMV K210 物理引脚 6

GPIO0 输入
Python 程序

flame_sensor.value()
稳定采样

多次读取减少误判
状态判断

安全 / 危险
串口提示

状态变化与分级告警
模块供电

VCC
公共地线

GND

这条链路可以从硬件和程序两个角度理解。硬件侧,敏感元件负责感知外部变化,黄色 E01 负责设置触发阈值,模块比较电路负责输出 DO 高低电平。程序侧,CanMV K210 读取物理引脚 6 的输入状态,通过多次采样得到稳定结果,再根据状态变化输出安全提示、危险提示和持续告警等级。

硬件设施

本实验真正使用到的硬件对象比较集中,核心是 CanMV K210 开发板和火焰传感器数字输出引脚。代码没有使用 LCD、蜂鸣器、摄像头、电机等模块,因此这些内容不作为本节讲解重点。软件侧主要依赖 timemaix.GPIOfpioa_manager.fm,分别承担延时计时、GPIO 读取和物理引脚映射功能。

实物接线和模块位置可以通过下面这张图建立整体印象。图中需要重点关注传感器敏感元件、黄色 E01 调节电位器、模块指示灯以及连接到 CanMV K210 的信号线。黄色 E01 不是程序里的变量,而是硬件上的阈值调节器,用来改变模块 DO 输出的触发条件。

硬件 / 软件 作用 说明
CanMV K210 开发板 实验运行平台 执行 MicroPython 程序,并通过 GPIO 输入读取传感器状态
火焰传感器模块 环境检测模块 通过 DO 数字输出引脚反馈是否检测到火焰信号
敏感元件 外部信号感知部分 感知火焰、红外光或外部光源变化,具体表现受模块类型影响
黄色 E01 可调电位器 灵敏阈值调节 用于调节模块触发阈值,影响 DO 输出何时发生变化
DO 数字输出端 传感器信号输出 接入 CanMV K210 物理引脚 6
物理引脚 6 信号输入引脚 根据代码配置,连接火焰传感器 DO 输出端
maix.GPIO GPIO 控制模块 创建 GPIO 输入对象,并通过 value() 读取电平
fpioa_manager.fm 引脚功能映射模块 将开发板物理引脚绑定到指定 GPIO 功能
time 延时与计时模块 用于采样间隔、循环检测间隔和火焰持续时间统计

接线关系主要由 FLAME_PINFLAME_GPIOfm.register()GPIO() 推导。代码中 FLAME_PIN = 6 表示火焰传感器 DO 连接到物理引脚 6,FLAME_GPIO = fm.fpioa.GPIO0 表示该物理引脚被映射为 GPIO0,flame_sensor = GPIO(GPIO.GPIO0, GPIO.IN) 表示程序会以输入模式读取该传感器状态。

接口 / 引脚 GPIO 功能 代码变量 对应硬件 说明
物理引脚 6 GPIO0 flame_sensor 火焰传感器 DO 读取火焰传感器数字输出状态
VCC 模块供电 火焰传感器 VCC 根据模块标识连接对应供电端
GND 公共地线 火焰传感器 GND 与 CanMV K210 共地,保证输入电平稳定
黄色 E01 硬件阈值调节 模块灵敏度调节电位器 通过旋转调节触发灵敏度,不由程序直接控制

物理引脚可以理解成开发板对外接收信号的接口,GPIO 是芯片内部的通用输入输出功能,代码变量则是程序中操作这个输入通道的名称。当前实验中,火焰传感器负责把外部检测结果转换成高低电平,CanMV K210 通过 GPIO0 读取这个电平,再由程序判断当前是安全状态还是危险状态。

调试时需要特别关注黄色 E01 调节电位器。若传感器在没有火焰时一直输出危险状态,通常说明阈值过于敏感,或者环境光干扰较强;若靠近火焰或测试光源时没有任何变化,可能是阈值过低敏感、方向不对、距离过远,或者 DO 信号线未正确连接。实际调试时可以一边观察模块指示灯和串口输出,一边缓慢旋转 E01,直到状态变化符合实验预期。

实验现象 正常表现 异常提示
程序启动 串口输出安全状态提示 没有输出时检查程序运行和串口连接
未检测到火焰 DO 保持安全电平,程序显示安全 若一直危险,优先调整黄色 E01 或检查环境光干扰
检测到火焰 DO 切换为危险电平,程序输出危险提示 若无反应,检查 DO 到物理引脚 6 的接线
火焰持续存在 串口按时间输出一级、二级、三级告警 告警过于频繁时可调整循环间隔或告警时间阈值
火焰移开 程序输出恢复安全和本次持续时间 不恢复时检查阈值是否过敏或模块是否被强光照射
阈值调节 旋转黄色 E01 后触发距离和灵敏度发生变化 调节时应缓慢旋转,避免一次性调节过大

软件代码

本实验代码围绕火焰传感器数字输入检测展开。程序先完成物理引脚到 GPIO 的映射,再创建 GPIO 输入对象,随后通过原始读取、多次采样、状态判断、消息输出和主循环调度组成完整检测流程。与普通读取示例相比,这段代码增加了稳定采样、状态变化检测、持续时间统计和分级告警,更接近真实硬件项目中的输入检测写法。

软件环境 作用 检查重点
CanMV IDE 编辑、运行和调试 K210 程序 能识别开发板串口,并能运行基础 print() 测试
CanMV 固件 提供 maix.GPIOfpioa_manager 等模块 固件环境需要支持当前 GPIO 与 FPIOA 写法
USB 串口驱动 让电脑识别开发板串口 串口工具中能看到对应端口
串口终端 查看安全、危险和分级告警信息 状态变化时能看到完整提示
火焰传感器 DO 输出 程序读取对象 输出电平应能随检测状态变化
黄色 E01 调节电位器 硬件阈值调节 程序无法直接修改,需要手动调节
python 复制代码
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
CanMV K210 火焰传感器实验 Demo

功能:
1. 初始化火焰传感器数字输出引脚
2. 读取火焰传感器 DO 状态
3. 增加多次采样,降低误触发
4. 只在状态变化时输出提示,避免刷屏
5. 统计火焰持续时间
6. 根据火焰持续时间输出不同告警等级

说明:
常见火焰传感器 DO 输出:
- 1:未检测到火焰,安全状态
- 0:检测到火焰,危险状态

如果实际模块输出逻辑相反,只需要修改 FIRE_LEVEL 和 SAFE_LEVEL。
"""

import time
from maix import GPIO
from fpioa_manager import fm


# =========================
# 硬件配置区
# =========================

FLAME_PIN = 6                  # 火焰传感器 DO 连接的物理引脚
FLAME_GPIO = fm.fpioa.GPIO0    # 将物理引脚映射到 GPIO0

SAFE_LEVEL = 1                 # 安全状态电平
FIRE_LEVEL = 0                 # 检测到火焰时的电平

SAMPLE_COUNT = 5               # 每次读取时连续采样次数
SAMPLE_INTERVAL_MS = 20        # 每次采样之间的间隔
LOOP_DELAY_MS = 200            # 主循环检测间隔


# =========================
# 初始化传感器
# =========================

fm.register(FLAME_PIN, FLAME_GPIO, force=True)
flame_sensor = GPIO(GPIO.GPIO0, GPIO.IN)


# =========================
# 基础读取函数
# =========================

def read_flame_raw():
    """
    读取火焰传感器原始数字电平
    返回值:
    1 表示高电平
    0 表示低电平
    """
    return flame_sensor.value()


def read_flame_stable():
    """
    多次采样读取火焰传感器状态

    火焰传感器属于外部环境检测模块,容易受到光线、角度、
    距离和电位器灵敏度影响。连续采样可以减少瞬间抖动造成的误判。
    """
    fire_count = 0
    safe_count = 0

    for _ in range(SAMPLE_COUNT):
        value = read_flame_raw()

        if value == FIRE_LEVEL:
            fire_count += 1
        else:
            safe_count += 1

        time.sleep_ms(SAMPLE_INTERVAL_MS)

    if fire_count > safe_count:
        return FIRE_LEVEL
    else:
        return SAFE_LEVEL


def is_fire_detected():
    """
    判断是否检测到火焰
    """
    return read_flame_stable() == FIRE_LEVEL


# =========================
# 状态显示函数
# =========================

def print_safe_message():
    """
    安全状态提示
    """
    print("")
    print("================================")
    print(" 状态:安全")
    print(" 说明:当前未检测到火焰信号")
    print("================================")
    print("")


def print_fire_message():
    """
    火焰状态提示
    """
    print("")
    print("================================")
    print(" 状态:危险")
    print(" 说明:检测到火焰信号,请立即检查现场")
    print("================================")
    print("")


def print_fire_level(duration_ms):
    """
    根据火焰持续时间输出告警等级
    """
    seconds = duration_ms / 1000

    if seconds < 2:
        level = "一级告警:疑似火焰"
        advice = "建议继续观察传感器状态"
    elif seconds < 5:
        level = "二级告警:持续火焰"
        advice = "建议检查火源位置和传感器安装角度"
    else:
        level = "三级告警:高风险火焰"
        advice = "建议立即触发报警、断电或联动灭火设备"

    print("火焰持续时间:%.1f 秒 | %s | %s" % (seconds, level, advice))


# =========================
# 主循环函数
# =========================

def loop():
    """
    火焰检测主循环

    运行逻辑:
    程序持续读取火焰传感器状态。
    当状态从安全变为危险时,输出火焰告警。
    当状态从危险恢复为安全时,输出恢复提示。
    火焰持续存在时,周期性输出持续时间和告警等级。
    """

    last_status = SAFE_LEVEL
    fire_start_time = 0
    last_report_time = 0

    print_safe_message()

    while True:
        current_status = read_flame_stable()
        now = time.ticks_ms()

        # 安全 -> 火焰
        if last_status == SAFE_LEVEL and current_status == FIRE_LEVEL:
            fire_start_time = now
            last_report_time = now
            print_fire_message()

        # 火焰 -> 安全
        elif last_status == FIRE_LEVEL and current_status == SAFE_LEVEL:
            fire_duration = time.ticks_diff(now, fire_start_time)

            print("")
            print("================================")
            print(" 状态:恢复安全")
            print(" 本次火焰持续时间:%.1f 秒" % (fire_duration / 1000))
            print("================================")
            print("")

            fire_start_time = 0
            last_report_time = 0

        # 火焰持续存在,每 1 秒输出一次告警等级
        elif current_status == FIRE_LEVEL:
            if time.ticks_diff(now, last_report_time) >= 1000:
                fire_duration = time.ticks_diff(now, fire_start_time)
                print_fire_level(fire_duration)
                last_report_time = now

        last_status = current_status
        time.sleep_ms(LOOP_DELAY_MS)


# =========================
# 程序入口
# =========================

if __name__ == '__main__':
    try:
        loop()
    except KeyboardInterrupt:
        print("")
        print("程序已停止,火焰传感器检测结束")

这段程序可以分成输入读取、稳定判断和告警输出三个层级。输入读取层由 flame_sensor.value()read_flame_raw() 完成,负责获得 DO 引脚当前电平;稳定判断层由 read_flame_stable() 完成,负责通过多次采样降低误触发;告警输出层由 loop()print_fire_message()print_fire_level() 完成,负责在状态变化和持续危险时输出提示。

配置区集中保存物理引脚、GPIO 映射、电平含义、采样次数和检测间隔。火焰传感器模块输出逻辑如果和默认设定不同,优先修改 SAFE_LEVELFIRE_LEVEL;检测太灵敏或不灵敏时,优先调节黄色 E01;状态仍然频繁跳变时,再调整 SAMPLE_COUNTSAMPLE_INTERVAL_MSLOOP_DELAY_MS

函数名 功能 对应现象
read_flame_raw() 读取传感器原始电平 作为底层读取能力,不直接负责告警
read_flame_stable() 多次采样并返回稳定状态 降低光线抖动、距离变化和阈值边缘造成的误判
is_fire_detected() 判断是否检测到火焰 返回布尔结果,便于后续扩展调用
print_safe_message() 输出安全状态提示 串口显示当前未检测到火焰
print_fire_message() 输出危险状态提示 串口显示检测到火焰信号
print_fire_level() 根据持续时间输出告警等级 火焰持续存在时,周期显示一级、二级或三级告警
loop() 持续检测火焰状态 状态变化时输出提示,火焰持续时统计时长
KeyboardInterrupt 捕获 停止程序时输出结束提示 手动中断程序后,串口显示检测结束

扩展应用

火焰传感器实验的调试重点在信号电平、接线、灵敏度和环境干扰。火焰传感器模块通常带有黄色 E01 可调电位器,用于调节触发阈值;环境光源、传感器角度、检测距离也会影响 DO 输出状态。排查时应先确认硬件连接,再观察原始电平,再调整模块阈值和代码中的电平逻辑。

问题现象 可能原因 处理思路
串口一直显示安全 火焰距离过远、传感器角度不对、DO 未接到物理引脚 6、黄色 E01 阈值设置不合适 缩短检测距离,调整传感器朝向,核对 DO 与物理引脚 6 的连接,并缓慢调节 E01
串口一直显示危险 模块输出逻辑相反、环境光干扰、黄色 E01 调得过于敏感 调换 SAFE_LEVELFIRE_LEVEL,避开强光直射,并重新调节 E01
状态频繁跳变 火焰信号不稳定、采样次数太少、检测间隔太短、阈值处在临界位置 增大 SAMPLE_COUNT,适当增加 SAMPLE_INTERVAL_MSLOOP_DELAY_MS,并微调 E01
没有任何串口输出 程序未运行、开发板连接异常、串口未打开 检查脚本是否执行,确认 CanMV 串口连接和运行状态
检测反应较慢 采样次数和循环间隔偏大 适当减小 SAMPLE_COUNTLOOP_DELAY_MS,在响应速度和稳定性之间取平衡
告警等级不符合预期 时间阈值与实验场景不匹配 根据项目需求调整 print_fire_level() 中的 2 秒和 5 秒判断条件
靠近火焰仍无明显变化 使用的敏感元件类型不匹配、测试方向不对、模块阈值过低敏 确认模块类型,调整检测角度和距离,并旋转黄色 E01 找到合适触发点
普通灯光下误触发 环境光或红外成分影响模块输出 更换测试环境,遮挡强光源,调低灵敏度或增加稳定采样次数

火焰传感器实验的核心价值在于把外部环境状态转化为程序判断条件。当前代码已经具备传感器读取、稳定采样、状态变化检测、持续时间统计和分级告警能力,因此可以自然延伸到更多安全监测和自动化控制场景。需要注意的是,本实验属于教学演示代码,不能直接替代专业消防报警系统;真实工程还需要考虑传感器认证、误报率、供电可靠性、外壳安装、联动策略和安全规范。

应用场景 实现思路 可扩展能力
火焰状态监测 持续读取 DO 电平,根据安全电平和火焰电平判断现场状态 可增加日志记录,把火焰发生时间保存下来
设备安全保护 火焰持续时间超过阈值时输出高风险告警 后续可扩展继电器或断电控制模块
声光报警系统 当前代码已经能判断火焰等级,可把不同等级映射到不同提示方式 后续可扩展蜂鸣器、LED 指示灯或警示灯
教学演示实验 用传感器状态变化解释 GPIO 输入、条件判断和循环检测 可作为数字输入类传感器课程模板
环境监控终端 将火焰状态作为监控数据的一部分 后续可扩展 LCD 显示、Wi-Fi 上传或 Web 控制台
多传感器联动 火焰检测结果与温度、烟雾等数据一起判断风险 后续可扩展多条件判断,降低单一传感器误报
自动化巡检反馈 状态变化时输出记录,持续危险时分级提示 可结合时间戳、设备编号和日志系统形成巡检报告

从工程结构看,当前代码已经比较适合扩展。硬件参数集中放在配置区,读取逻辑封装成独立函数,状态显示与主循环分离,告警等级也被单独封装。后续增加蜂鸣器、继电器、屏幕显示或网络上传时,不需要推翻现有结构,只需要在状态变化或告警等级判断处增加对应动作。

总结

本实验通过 CanMV K210 开发板完成了火焰传感器数字输入检测,核心能力包括 FPIOA 引脚映射、GPIO 输入读取、传感器电平判断、多次采样防抖、状态变化检测、持续时间统计和分级告警输出。代码从物理引脚 6 的映射开始,把火焰传感器 DO 信号转换成程序可判断的安全状态和危险状态,再通过主循环持续检测外部环境变化。

火焰传感器实验同时包含软件和硬件两类调试点。软件侧需要理解 SAFE_LEVELFIRE_LEVEL、多次采样和持续时间统计;硬件侧需要正确连接 DO、VCC、GND,并通过黄色 E01 设置合适的灵敏阈值。掌握这类输入检测思路后,后续可以继续扩展到烟雾检测、温度检测、蜂鸣器报警、LCD 显示、继电器联动和网络告警等智能硬件项目中。

相关推荐
'pi%'4 小时前
RAG系统的“最后一公里“:数据清洗、特征工程与向量化策略的工程化实践
人工智能
tachibana24 小时前
性能指标的口径选择
数据库·人工智能·架构·大模型·llm
HIT_Weston4 小时前
183、【Agent】【OpenCode】TuiThreadCmd(JS&TS 历史)
人工智能·agent·opencode
蓝狐社4 小时前
你的软件越来越卡,是因为它多了个AI
人工智能
万悉科技4 小时前
AI时代的“搜索战争“变了:从关键词排名到意图匹配,品牌正在大模型的注意力机制里“失声“
人工智能
W_326004 小时前
Python-OpenCV HSV颜色空间与inRange颜色分割:按颜色提取目标物体
图像处理·人工智能·python·opencv·机器学习
小小测试开发4 小时前
Agent 安全测试:pytest 原生红队框架 RAMPART 实战解析
人工智能·pytest
FunTester4 小时前
DeepSeek Harness 常用插件介绍
人工智能·语言模型·常用插件·deepseek·harness
九硕智慧建筑一体化厂家4 小时前
楼宇自控|智慧建筑核心引擎!楼宇自控系统,赋能建筑高效低碳运维
运维·人工智能·笔记·智慧城市
byte轻骑兵5 小时前
【BlueZ 】蓝牙 SDAP 协议入门:BlueZ 中设备服务发现的基础逻辑
linux·人工智能·bluez·电脑蓝牙·嵌入式蓝牙