当前位置: 首页 > news >正文

Arduino智能灭火灯笼:从火焰传感器到3D打印的完整创客项目实践

1. 项目概述:一个“无用”却充满巧思的智能灯笼

在创客圈子里,总有一些项目,它们解决的问题可能不那么“刚需”,甚至带点无厘头的幽默感,但其背后蕴含的技术整合与工程实现思路,却往往能给人带来深刻的启发。今天要分享的,就是这样一个项目——一个能自动检测并熄灭蜡烛火焰的“智能灭火灯笼”。它源于一个学生课程设计,核心目标很简单:当检测到灯笼内的蜡烛被点燃时,自动启动水泵将其浇灭。听起来有点“多此一举”?但正是这种“无用之用”,让我们可以抛开商业产品的束缚,专注于如何将火焰传感、压力交互、机电控制和快速原型制造等技术,优雅地集成到一个物理实体中。

这个项目非常适合有一定Arduino基础,并希望挑战综合性实体项目制作的爱好者。你将亲历从概念设计、电子选型、代码编写到结构建模、3D打印、激光切割,再到最终组装调试的全过程。它不仅锻炼你的嵌入式编程和电路设计能力,更考验你的机械结构设计思维、对制造工艺(如3D打印的支撑、激光切割的参数)的理解,以及面对实物装配中各种“意料之外”问题的解决能力。最终,你会得到一个独一无二、会“自己思考”的智能装置,其技术内核完全可以迁移到更严肃的安防监控或环境感知项目中。

2. 整体设计思路与核心方案选型

2.1 从“灭火”到“灯笼”:产品形态的演变逻辑

项目的起点是一个纯粹的功能性需求:检测火焰并熄灭它。最初的构思天马行空,团队考虑了多种灭火方式:用机械臂掐灭烛芯、用小风扇吹灭,或者用水浇灭。掐灭烛芯的方案首先被否决,因为它机械结构复杂,且需要针对不同尺寸的蜡烛进行精密调整,鲁棒性差。风扇吹灭的方案相对简单,但存在两个问题:一是可能将火星或烟灰吹得到处都是,不够“干净”;二是在相对封闭的灯笼空间内,气流可能不稳定。最终,水浇灭火的方案胜出。原因很直接:灭火效果可靠、彻底,且视觉上更具戏剧性和趣味性,符合项目“玩趣”的基调。

确定了灭火方式,下一个问题是载体。如果仅仅做一个固定在桌上的灭火器,项目就止步于一个功能原型。团队引入了“可移动性”和“一体化”两个约束,这直接催生了“灯笼”的形态。这意味着,蜡烛、储水箱、水泵、电路板、电池等所有部件,都必须集成在一个便于手提的箱体内。这个约束极大地提升了设计难度,也赋予了项目完整的“产品”感。灯笼的形态自然地划分出了上下结构:下部作为储水兼蜡烛底座,上部容纳电子控制系统,中间通过支柱和亚克力板连接,形成经典的灯笼外观。

2.2 电子系统架构:感知、决策与执行的闭环

整个电子系统的设计遵循经典的“传感器-控制器-执行器”架构,但加入了一个巧妙的人机交互层。

  1. 感知层(输入)

    • 火焰传感器:这是系统的“眼睛”,负责核心的火焰检测任务。选用的是常见的红外火焰传感器模块。它并非检测温度,而是探测火焰特定波段(通常是760纳米-1100纳米红外线)的辐射强度。其优点在于响应速度快、非接触式检测,且模块通常自带比较器,可通过电位器调节灵敏度,直接输出数字信号(高/低电平),极大简化了Arduino的编程。
    • 力敏电阻:这是系统的“触觉”,也是本项目交互设计的亮点。一个简单的灭火装置,可能检测到火就立刻行动。但作为一个灯笼,我们希望它更“聪明”一些:只有当你提起它(准备移动)时,它才执行灭火动作,防止平时蜡烛正常燃烧时被误触发。FSR被安装在灯笼把手上,当人手握持施加压力时,其电阻值会发生显著变化,从而被Arduino的模拟输入引脚读取。
  2. 控制层(大脑)

    • Arduino Uno:作为项目核心控制器,它负责循环读取两个传感器的状态,执行逻辑判断。其逻辑非常清晰:如果(火焰传感器检测到火)并且(力敏电阻检测到压力大于阈值),则触发灭火动作。否则,系统保持待机。Arduino的易用性和丰富的社区资源,使其成为此类原型开发的不二之选。
  3. 执行层(输出)

    • 继电器模块:这是连接弱电控制与强电驱动的关键桥梁。Arduino的I/O引脚只能提供5V、几十毫安的电流,根本无法驱动12V的水泵。继电器本质上是一个由小电流(Arduino控制)来控制大电流(水泵电路)通断的电子开关。本项目选用的是常见的单路5V继电器模块,使用非常方便。
    • 12V直流水泵:灭火动作的执行者。需要注意的是,本项目使用的是一种小型潜水泵,这意味着它必须完全浸没在水中才能正常工作,否则会空转烧毁。这个特性直接影响了灯笼底部水箱的结构设计。
  4. 供电系统

    • 双电源设计:这是很多初做机电一体项目的朋友容易忽略的一点。系统存在两种电压:Arduino及传感器模块需要5V或3.3V,而水泵需要12V。因此,采用了分离供电方案:一块9V电池通过DC接口或Vin引脚为Arduino供电;一个外接的12V直流电源适配器专门为水泵电路供电。两者共地(GND连接在一起),确保信号电平基准一致。继电器模块的控制端(接Arduino)使用Arduino的5V,被控端(接水泵)则接入12V电路。

注意:安全永远是第一位的。在连接12V水泵电源时,务必确保线路连接牢固,用电工胶布做好绝缘,避免短路。调试时,先单独测试Arduino逻辑和传感器,最后再接通12V电源测试水泵。

3. 核心电子元件详解与电路搭建

3.1 火焰传感器模块的调试与校准

市面上常见的火焰传感器模块,通常有三个引脚:VCC、GND和DO(数字输出)。模块上有一个蓝色的电位器,用于调节灵敏度。

实操要点

  1. 连接:VCC接Arduino 5V,GND接GND,DO引脚接任一个数字输入引脚(如D2)。
  2. 校准:这是关键步骤。先不要点火,观察模块上的指示灯。逆时针缓慢旋转电位器,直到指示灯刚好点亮(此时模块输出低电平,表示检测到火焰)。然后,反向(顺时针)微微调节,直到指示灯熄灭(此时输出高电平,表示未检测到火焰)。这个临界点就是当前环境光下的灵敏度阈值。
  3. 测试:用打火机在传感器前方不同距离和角度进行测试。记录下稳定检测到火焰的最远距离。本项目中提到在40cm外仍能检测,这得益于传感器60°的探测角。你需要根据灯笼内部蜡烛与传感器的实际安装高度和距离,微调电位器,确保既能可靠检测烛火,又不会因环境红外干扰(如白炽灯、阳光)而误触发。
// 火焰传感器简单测试代码 const int flameSensorPin = 2; // DO引脚接D2 void setup() { Serial.begin(9600); pinMode(flameSensorPin, INPUT); } void loop() { int flameState = digitalRead(flameSensorPin); // 注意:有些模块逻辑是检测到火焰时输出LOW,未检测时输出HIGH,具体看模块说明书 if (flameState == LOW) { Serial.println("Fire Detected!"); } else { Serial.println("No Fire."); } delay(500); }

3.2 力敏电阻的使用与阈值设定

FSR是一个模拟元件,其电阻随压力增大而减小。我们通过一个“下拉电阻”将其连接成分压电路,从而将电阻变化转化为Arduino可读的电压变化。

电路连接: 将FSR的一端接至Arduino的5V。另一端同时连接一个10kΩ的固定电阻(下拉电阻)和Arduino的一个模拟输入引脚(如A0)。固定电阻的另一端接地。这样,FSR和10kΩ电阻就构成了一个分压器。当没有压力时,FSR电阻极大,A0点电压接近0V(读取值接近0)。当压力增大,FSR电阻减小,A0点电压升高(读取值增大,最大1023)。

阈值确定: 没有绝对标准的阈值,这取决于你的FSR型号、安装方式和握力。需要通过实验来设定。

const int fsrPin = A0; void setup() { Serial.begin(9600); } void loop() { int fsrValue = analogRead(fsrPin); Serial.print("FSR Value: "); Serial.println(fsrValue); delay(200); }

上传代码后,打开串口监视器。先不要触碰FSR,记录下静止值(通常很小,几十以内)。然后,用你预想的握持方式握住安装好的手柄,观察数值。这个数值可能会达到几百甚至上千。选择一个介于两者之间的值作为阈值,例如if (fsrValue > 150)。可以适当留些余量,避免轻微触碰导致误触发。

3.3 继电器模块的正确驱动与水泵控制

继电器模块通常有6个引脚:DC+、DC-(接Arduino侧电源,通常5V)、IN(控制信号)、常开(NO)、常闭(NC)、公共端(COM)。我们控制水泵通断,使用常开(NO)和公共端(COM)即可。

接线步骤

  1. 控制端:继电器模块的DC+接Arduino 5V,DC-接GND,IN接一个数字输出引脚(如D7)。
  2. 负载端:将12V电源适配器的正极(+)接至继电器模块的COM口。将水泵的正极(+,通常是红线)接至继电器模块的NO口。最后,将12V电源适配器的负极(-)和水泵的负极(-,黑线)直接相连。
  3. 逻辑注意:大多数继电器模块是低电平触发。即,当IN引脚为LOW时,继电器吸合,NO和COM接通;为HIGH时,继电器断开。编程时需要特别注意。
const int relayPin = 7; // 继电器IN引脚接D7 void setup() { pinMode(relayPin, OUTPUT); digitalWrite(relayPin, HIGH); // 初始化为高电平,确保继电器断开 // ... 其他初始化代码 } void loop() { // 当需要启动水泵时 digitalWrite(relayPin, LOW); // 输出低电平,继电器吸合,水泵通电 delay(2000); // 喷水2秒 digitalWrite(relayPin, HIGH); // 输出高电平,继电器断开,水泵停止 // ... 其他逻辑 }

重要心得:继电器在通断瞬间,线圈会产生反向电动势,可能对Arduino造成干扰。虽然模块通常已有保护二极管,但为求稳妥,可以在继电器IN引脚和GND之间焊接一个104(0.1uF)的瓷片电容,以吸收尖峰脉冲。

3.4 最终系统集成与代码逻辑

将所有元件集成到面包板或焊接在洞洞板上。务必规划好走线,尤其是12V大电流线路要与5V信号线分开,避免干扰。最终的核心控制逻辑代码如下:

// 引脚定义 const int flameSensorPin = 2; // 火焰传感器数字引脚 const int fsrPin = A0; // 力敏电阻模拟引脚 const int relayPin = 7; // 继电器控制引脚 // 阈值定义 const int fsrThreshold = 150; // 手握压力阈值,需根据实测调整 const int waterPumpDuration = 2000; // 水泵工作时间(毫秒) // 变量定义 bool pumpActivated = false; // 标记水泵是否已被触发,防止连续触发 void setup() { Serial.begin(9600); pinMode(flameSensorPin, INPUT); pinMode(relayPin, OUTPUT); digitalWrite(relayPin, HIGH); // 初始化继电器为断开状态 Serial.println("System Started."); } void loop() { // 1. 读取传感器状态 int flameDetected = digitalRead(flameSensorPin); // 火焰传感器,LOW表示有火 int fsrValue = analogRead(fsrPin); // 读取压力值 // 2. 打印调试信息(完成后可注释掉) Serial.print("Flame: "); Serial.print(flameDetected == LOW ? "YES" : "NO"); Serial.print(" | FSR: "); Serial.println(fsrValue); // 3. 核心逻辑判断 // 条件:检测到火焰 (flameDetected == LOW) 且 手握压力超过阈值 且 水泵未被触发过 if (flameDetected == LOW && fsrValue > fsrThreshold && !pumpActivated) { Serial.println("Condition met! Activating water pump."); activateWaterPump(); pumpActivated = true; // 标记已触发,防止循环中重复启动 } // 4. 重置逻辑:如果火焰熄灭且手松开,则重置触发标记 // 这允许下次提起点燃的灯笼时再次灭火 if (flameDetected == HIGH && fsrValue < fsrThreshold) { pumpActivated = false; Serial.println("System reset. Ready for next activation."); } delay(100); // 主循环延迟 } // 控制水泵的函数 void activateWaterPump() { digitalWrite(relayPin, LOW); // 继电器吸合,水泵启动 delay(waterPumpDuration); // 持续喷水 digitalWrite(relayPin, HIGH); // 继电器断开,水泵停止 Serial.println("Water pump stopped."); }

4. 机械结构设计与快速原型制造

4.1 3D打印部件的设计与优化

灯笼的结构件全部通过3D打印完成,主要分为五个部分:下壳体(水箱)上壳体内部抽屉手柄四个支柱。使用CATIA或Fusion 360等软件进行建模。

设计避坑指南

  1. 壁厚与强度:作为承重和盛水部件,下壳体的壁厚不能太薄,建议至少3-4mm。支柱是受力关键,也要保证足够的截面积。
  2. 装配公差:这是3D打印组装中最容易出问题的地方。对于需要紧配合的部件(如抽屉滑轨),需要在设计时预留间隙。通常,对于PLA材料,建议单边预留0.2mm-0.4mm的间隙。例如,如果抽屉宽度是50mm,抽屉槽的宽度就应设计为50.4mm-50.8mm。本项目中原型抽屉过紧,就是公差没留好。
  3. 防水设计:下壳体作为水箱,必须考虑防水。单纯依靠3D打印层间的缝隙是无法防水的。原项目采用内部粘贴防水帆布(tarpaulin)的方式,这是非常实用且可靠的做法。在设计时,可以在壳体内部设计一圈凹槽,用于压紧和粘贴防水布的边缘,增强密封性。
  4. 支撑与打印方向:合理选择打印方向可以减少支撑材料,提高表面质量并节省时间。例如,支柱如果竖直打印,侧面会留下支撑疤痕;如果水平打印,则侧面光滑,但需要为两端的卡槽添加支撑。需要在Cura或PrusaSlicer中仔细预览支撑生成情况。对于底部大面积接触打印床的部件(如壳体),一定要启用“附着”选项,如裙边(Skirt)、边缘(Brim)或筏板(Raft),这能有效防止打印件翘边。
  5. 手柄的打印:手柄是与人接触最多的部件,要求表面光滑。如原项目所述,可以将层高设置为0.1mm以获得更细腻的表面纹理。同时,打印方向应使手柄的弧形外表面朝上,这样即使有层纹,触摸感也较好。

4.2 激光切割亚克力板的经验

亚克力板用于制作灯笼的四个侧面,提供透光性和美观度。

核心步骤与参数

  1. 图纸准备:在Rhino、AutoCAD或Inkscape中绘制精确的矩形轮廓线。确保尺寸与3D打印的支柱上的卡槽尺寸匹配。
  2. 软件设置:在激光切割机配套软件(如LightBurn、RDWorks)中,将轮廓线设置为切割模式,而不是雕刻。需要为亚克力材料创建或选择一个合适的切割参数集。
  3. 参数测试(至关重要!):不同品牌、厚度、颜色的亚克力,以及不同功率的激光管,所需参数(功率、速度、频率)都不同。务必先进行测试切割!找一块边角料,切割一个小正方形或圆形。理想的切割效果是切缝干净,切下的部分轻轻一推就能脱落,背面有轻微的熔渣但不多。如果切不透,需要增加功率或降低速度。如果切割边缘烧焦严重、起泡或产生大量熔渣,则功率可能过高或速度过慢。
  4. 材料固定与对焦:确保亚克力板平整地放在切割床上,用夹具或重物压好边缘,防止切割过程中移动。调整激光头到材料表面的距离,确保焦点准确(通常使用对焦块)。
  5. 通风与安全:激光切割亚克力会产生有害气体和烟雾,必须开启抽风系统,并在通风良好的环境下操作,佩戴防护眼镜。

实操心得:原项目中提到第一次切割功率不足,以及材料库参数不匹配,这都是典型问题。每次更换材料批次,都建议做测试切割。切割完成后,亚克力板边缘可能比较锋利,可以用砂纸或专门的亚克力抛光机进行打磨抛光,使其更光滑透明。

4.3 总装流程与问题排查

按照“从内到外,从下到上”的顺序进行组装:

  1. 功能测试先行:在将所有电子部件塞进抽屉前,先连接好所有线路,上传代码,进行完整的系统功能测试。确保火焰检测、压力感应、水泵启动都工作正常。
  2. 安装下壳体与防水:将防水帆布裁剪合适,使用环氧树脂胶硅酮密封胶仔细粘贴在下壳体内壁和底部接缝处。确保完全覆盖,静置足够时间固化。之后可以进行灌水测试,检查是否渗漏。
  3. 安装水泵与管路:将潜水泵放入下壳体底部,水泵的进水口最好加上滤网防止堵塞。出水口连接一段软管(如硅胶管),将软管沿着预先设计好的路径(如通过支柱内部或侧面)引向上方,管口对准蜡烛的位置。用扎带或卡扣固定管路。
  4. 电子集成与布线:将Arduino、面包板(或焊接好的电路板)、继电器模块、电池等整齐地布置在上壳体的抽屉里。这是一个考验“理线”功夫的环节。使用尼龙扎带、线槽或热熔胶固定线束,确保抽屉能顺畅推拉,且线路不会被挤压拉扯。将火焰传感器用热熔胶或螺丝固定在预定的观察孔位置,将FSR用双面胶或胶带粘贴在手柄内侧。
  5. 机械总装
    • 先将四个支柱安装到下壳体上。
    • 将四块亚克力板依次插入支柱的卡槽。
    • 将上壳体对准支柱上端安装好。
    • 将装有电子元件的抽屉推入上壳体。
    • 最后安装手柄。
  6. 最终联调:接通电源,点燃蜡烛,提起灯笼。观察火焰传感器指示灯、串口输出信息,并期待水泵成功喷水灭火的那一刻。

5. 调试实录、优化思考与项目总结

5.1 开发过程中遇到的典型问题与解决

  1. 问题:水泵不工作,但继电器有“咔嗒”声。

    • 排查:首先检查12V电源适配器是否通电,用万用表测量其输出电压。其次,检查继电器到水泵的接线是否牢固,特别是COM和NO口是否接反。最后,确认水泵是否为潜水泵且已完全浸入水中。
    • 解决:确保所有大电流连接点接触良好;将水泵完全浸没;检查代码中继电器控制逻辑(高/低电平触发)是否正确。
  2. 问题:火焰传感器误触发,在无火时也亮灯。

    • 排查:检查环境是否有强烈的红外光源,如白炽灯、阳光直射、取暖器等。用手在传感器前晃动,观察是否因人体红外辐射导致触发。
    • 解决:重新进行灵敏度校准,顺时针调节电位器,提高阈值。如果可能,为传感器加装一个黑色的小型遮光筒,限制其视野,只对准蜡烛区域。
  3. 问题:FSR读数不稳定,阈值难以确定。

    • 排查:检查FSR与10kΩ电阻的分压电路连接是否正确、牢固。用手持续稳定按压,观察串口数值是否仍然跳动剧烈。
    • 解决:在Arduino代码中引入软件滤波。例如,连续读取10次FSR值,取平均值作为当前值,可以平滑掉大部分毛刺。
    int getAverageFSR(int pin) { int sum = 0; for (int i = 0; i < 10; i++) { sum += analogRead(pin); delay(5); } return sum / 10; }
  4. 问题:3D打印的抽屉过紧,无法推入。

    • 解决:如原项目所述,使用锉刀和砂纸仔细打磨抽屉的侧面和滑轨。这是一个精细活,需要边打磨边测试,避免打磨过度导致松动。可以在打磨后涂抹少许润滑油(如凡士林或干性润滑剂)以减少摩擦。
  5. 问题:亚克力板插入卡槽时太紧或开裂。

    • 解决:卡槽的宽度设计应比亚克力板厚度大0.1-0.2mm。如果已经打印好且过紧,可以用砂纸轻轻打磨卡槽内侧。切忌暴力插入,亚克力板很脆,容易开裂。如果过松,可以在卡槽内粘贴一层薄的双面胶或电工胶带来增加摩擦力。

5.2 项目的可优化方向与扩展思路

这个“无用灯笼”本身已经是一个完成度很高的作品,但它仍为我们留下了广阔的想象和改进空间:

  1. 供电系统升级:摆脱电源线的束缚,实现真正的便携。可以尝试使用大容量的18650锂电池组(如2S或3S),配合DC-DC降压模块为Arduino提供5V,同时直接为水泵提供12V。需要加入充电管理模块和电量指示。
  2. 水循环与过滤:目前的水箱是死水,长期使用可能滋生微生物。可以设计一个简单的水循环过滤系统,甚至加入微型水位传感器,当水位过低时通过LED闪烁提示加水。
  3. 增强交互与反馈:加入更多感官反馈。例如,检测到火焰时,可以先让一组RGB LED闪烁红光作为警告;灭火成功后,LED变为绿色。还可以加入蜂鸣器或MP3模块,播放提示音效。
  4. 结构优化与美学提升:如原项目反思,可以设计更紧凑、更优雅的外观。尝试使用镂空灯罩、磨砂亚克力,或在内部加入LED灯带,让它在不灭火的时候也是一个漂亮的氛围灯。结构上可以设计快拆式水箱,方便倒水和清洁。
  5. 智能化与联网:引入ESP8266或ESP32替代Arduino Uno,增加Wi-Fi功能。可以开发一个简单的手机App或网页,远程查看灯笼状态(是否检测到火、水箱水量),甚至远程手动触发灭火(虽然这听起来更“无用”了)。还可以将报警信息推送到手机。

回顾整个项目,从最初一个简单的想法,到最终捧在手里这个会“反抗”点燃的智能灯笼,其价值远超一个课程作业。它完整地串联了电子、编程、机械、制造多个环节,每一个踩过的坑——无论是电位器没调准、继电器接线搞反,还是3D打印公差算错、亚克力切不透——都变成了实实在在的经验。它教会我们的不仅是技术,更是一种“系统思维”:如何让感知、思考、行动三个环节可靠地协同工作,并把它塞进一个好看的壳子里。这,或许就是创客精神最迷人的地方。

http://www.cnnetsun.cn/news/2708245.html

相关文章:

  • Claude Code Harness 工程:数仓侧落地方案
  • 微信聊天记录解密终极指南:三步找回你的数字记忆宝库
  • Windows实时语音识别工具TMSpeech:完全离线的智能会议助手
  • NS-USBLoader终极指南:Switch游戏管理的完整解决方案
  • UE5 UI系统设计:告别硬编码,用PlayerController优雅管理你的商店界面
  • 学位论文认知篇 01
  • 别再只用重定向了!Linux tee命令的5个实用场景,从日志记录到管道调试
  • 免编程智能激光逗猫玩具:基于Micro Maestro的伺服控制方案
  • 【C++入门精讲16】 STL 四大核心容器实战教程(vector 缩容 /deque/list/map)
  • 【RT-DETR实战】 119、瑞芯微RKNN平台部署实战:从模型转换到板端推理的坑与经验
  • 魔兽争霸3性能优化终极指南:WarcraftHelper插件完整使用教程
  • TVA在电子元器件领域的创新应用(20)
  • 别再手动查漏洞了!用OWASP DependencyCheck给你的Maven项目做个自动化体检(附Jenkins流水线配置)
  • LED矩阵显示器的工业铝型材框架制作全攻略
  • AI没有复制互联网,它正在复制工业革命
  • 利用大语言模型生成数据增强仇恨言论检测模型的鲁棒性
  • 鸣潮自动化助手终极指南:5步实现智能挂机,解放双手轻松游戏
  • 机器人抓取新思路:为什么说6-DOF GraspNet的‘模块化’设计,是工业落地的关键?
  • Windows 10/11系统下,用vcpkg一键安装Tesseract C++库的避坑指南
  • 微信聊天记录解密终极指南:3分钟掌握WechatDecrypt工具
  • 从/lib到/libx32:一文看懂Linux多架构库目录的演变与设计哲学
  • AI漫剧创业冰火两重天:有人亏损近20万,有人小而美仍有得赚
  • TMSpeech:Windows本地实时语音转文字神器,让会议记录和内容创作效率翻倍
  • 告别‘炼丹’:手把手教你用Python复现经典跨模态哈希算法(附代码与避坑指南)
  • 3分钟把B站视频变文字稿:这个工具让你学习效率翻倍
  • 阴阳师自动化脚本OAS:5个高效技巧解放你的双手
  • MATLAB动态权重A*路径规划代码(含拐角平滑处理)
  • 智能手机改造乐器拾音器:低成本DIY方案与音频信号处理实践
  • 终极指南:如何让Windows任务栏变透明?TranslucentTB完全使用教程
  • Android MediaCodec解码到Surface的‘水管工’指南:搞懂BufferQueue、releaseOutputBuffer与SurfaceFlinger的协作流水线