news 2026/5/30 15:09:16

从电路原理到智能硬件:Arduino环境监测终端全流程实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从电路原理到智能硬件:Arduino环境监测终端全流程实战

1. 项目概述:从零开始的电子世界探索

很多朋友对电子制作感兴趣,但往往被复杂的电路图和一堆元器件吓退。其实,电路设计就像搭积木,理解了最基础的几块“积木”和它们之间的连接规则,你就能创造出无限可能。无论是想让一个LED灯闪烁,还是想做一个能感知环境温度并自动控制风扇的智能设备,其核心都离不开电路。电路是电子设备的骨架和血管,电流、电压、电阻这些概念就是它的“物理语言”。掌握这门语言,你就能与硬件对话,将脑海中的创意,无论是简单的互动玩具还是复杂的物联网节点,一步步变为现实。本文旨在为你拆解这层神秘面纱,通过一个完整的、从原理到实物的项目流程,带你亲手制作一个基于Arduino的智能环境监测终端。这个项目会串联起电路基础、元器件认知、原理图绘制、面包板实验、焊接实操乃至简单的PCB设计概念,让你在动手实践中,真正理解电流如何流淌,信号如何传递,代码如何驱动硬件。

2. 核心原理与基础元器件解析

2.1 电路分析的基石:欧姆定律与基尔霍夫定律

一切复杂的电路分析都始于几个最基础的定律。首先是欧姆定律,它描述了电压(V)、电流(I)和电阻(R)三者之间最简单直接的关系:V = I × R。你可以把它想象成水管系统:电压好比水压,是推动水流的动力;电流好比水流量,是单位时间内流过某截面的水量;电阻则好比水管的粗细或阀门,阻碍水流通过。对于一个固定电阻的元件,增加电压,电流就会成比例增大。在设计电路时,我们经常用这个定律来计算需要串联多大的电阻来保护一个发光二极管(LED),防止过大的电流将其烧毁。

比欧姆定律更进一步的是基尔霍夫定律,它包含电流定律(KCL)和电压定律(KVL)。KCL指出,流入一个电路节点的电流之和等于流出该节点的电流之和。这就像交通路口,开进去的车流量总和一定等于开出来的车流量总和,电荷不会在节点处凭空堆积或消失。KVL则指出,沿着闭合回路一周,所有元器件的电压降(电势差)之和等于零,或者说所有电源提供的电压等于所有负载消耗的电压之和。这确保了能量守恒。理解这两个定律,你就能分析稍微复杂一点的串并联电路,计算各支路的电流和电压,这是设计任何功能电路的前提。

2.2 关键被动元器件:电阻、电容与电感

认识了电路的“交通规则”,接下来要认识路上的“车辆”和“设施”。电阻是最基本的元件,它的核心作用就是限制电流、分配电压。除了阻值,我们还需要关注其功率额定值。一个1/4瓦的电阻,如果通过的电流过大导致实际消耗功率(P = I² × R)超过0.25W,它就会发热甚至烧毁。在给LED限流时,我们不仅要算出阻值,还要核算功率。

电容像一个微型的蓄电池,能够储存和释放电荷。它在电路中的角色多样:滤波(平滑电源电压,去除毛刺)、耦合(允许交流信号通过,隔断直流)、定时(与电阻组成RC电路,决定时间常数)。电解电容有正负极之分,接反了可能导致鼓包甚至爆炸。瓷片电容无极性,常用在高频旁路场合。

电感则是利用电磁感应原理,抵抗电流变化的元件。它通直流、阻交流,特性与电容相反。在直流电源电路中,电感常与电容组合形成LC滤波器,能更有效地滤除噪声。对于初学者,电阻和电容的应用频率远高于电感,因此前期可以重点掌握前两者。

2.3 核心主动元器件:二极管与三极管

主动元器件是指能够对电信号进行放大、开关等操作的器件,它们需要电源才能工作。二极管具有单向导电性,电流只能从正极(阳极)流向负极(阴极)。最常见的应用是整流(将交流电变为直流电)和防止电源反接保护电路。发光二极管(LED)是一种特殊的二极管,当电流正向通过时会发光,使用时必须串联限流电阻。

三极管是模拟电路和简单数字开关电路的核心,可以看作一个电流控制的开关或电流放大器。它有三个引脚:基极(B)、集电极(C)、发射极(E)。对于常用的NPN型三极管,当基极有较小的电流流入时,就允许一个较大的电流从集电极流向发射极。利用这个特性,我们可以用Arduino单片机IO口(仅能提供约20mA电流)通过一个小三极管,去控制一个需要数百mA电流的电机或继电器,这就是所谓的“驱动”。理解三极管的开关状态(饱和与截止)是设计控制电路的关键。

注意:在初次使用三极管时,务必查阅其数据手册(Datasheet),确认引脚排列(E、B、C的位置可能因封装而异)和最大允许的集电极电流(Ic),避免过载损坏。

3. 项目实战:智能环境监测终端制作

3.1 功能定义与系统框图设计

我们的目标是制作一个能够测量环境温湿度、光照强度,并通过OLED屏幕显示,同时在数据异常(如温度过高)时能发出声光报警的终端设备。它还可以通过Wi-Fi模块将数据上传到本地服务器或物联网平台(为简化,本文先实现本地显示与报警,网络功能作为扩展思路)。

首先,我们用系统框图来规划整个项目的“架构”。这能让你在动手前理清思路:

  1. 感知层:由DHT11温湿度传感器和光敏电阻模块组成,负责采集物理世界的数据。
  2. 控制核心:采用Arduino Uno开发板,负责读取传感器数据、进行逻辑判断、控制输出设备。
  3. 人机交互层:包括0.96英寸OLED显示屏(用于显示信息)和一个有源蜂鸣器及LED(用于报警)。
  4. 执行层(可选扩展):可以预留一个三极管驱动电路,未来用于控制风扇或加湿器等设备。
  5. 通信层(可选扩展):预留ESP-01s Wi-Fi模块接口,用于网络连接。

这个框图明确了各模块之间的数据流向:传感器→Arduino→显示屏/报警器。基于这个框图,我们就可以开始进行具体的电路设计了。

3.2 原理图绘制与元器件选型

有了框图,下一步就是绘制详细的电路原理图,它定义了所有元器件如何精确连接。我们使用免费的EDA工具KiCad来完成这一步。首先,需要为每个元器件创建或调用符号(Symbol)。

核心控制器:Arduino Uno。在原理图中,我们通常不会绘制完整的Uno板,而是将其视为一个“黑盒”,聚焦于我们使用的引脚。我们需要用到:

  • 数字引脚 D2: 连接DHT11数据线。
  • 模拟引脚 A0: 连接光敏电阻模块的模拟输出。
  • 数字引脚 D8, D9: 通过三极管驱动蜂鸣器和LED。
  • I2C引脚 A4 (SDA), A5 (SCL): 连接OLED显示屏。

传感器选型与连接

  • DHT11:这是一款数字温湿度复合传感器,精度对于入门项目足够(温度±2°C,湿度±5%RH)。它有三根线:VCC(接5V)、GND、DATA(接Arduino D2,并需要上拉一个4.7kΩ~10kΩ的电阻到VCC)。上拉电阻的作用是确保数据线在空闲时处于稳定的高电平状态,这是许多数字通信协议的要求。
  • 光敏电阻模块:为简化设计,我们直接使用市面上常见的模块。它通常已将光敏电阻与分压电阻集成,并带有LM393比较器,同时提供数字和模拟输出。我们使用模拟输出(AO引脚)接A0,这样可以读取连续的光照强度变化值。模块的VCC和GND分别接5V和地。

输出设备驱动设计

  • OLED显示屏 (SSD1306):采用I2C接口的版本,仅需4根线(VCC, GND, SDA, SCL)。在原理图中,它是一个标准的I2C设备符号。
  • 蜂鸣器与LED驱动:Arduino的IO口驱动能力有限。为了驱动蜂鸣器(工作电流可能几十mA)并实现电气隔离,我们使用NPN三极管(如常见的S8050)作为开关。以蜂鸣器为例:蜂鸣器正极接一个独立的5V电源(可与Arduino共用),负极接三极管的集电极(C);三极管的发射极(E)接地;基极(B)通过一个1kΩ的限流电阻连接到Arduino的D8引脚。当D8输出高电平(5V)时,三极管导通,蜂鸣器形成回路而鸣响;D8输出低电平时,三极管截止,蜂鸣器静音。LED的驱动电路类似,但LED自身需要串联一个220Ω-1kΩ的限流电阻。

将所有符号用导线(Wire)按照上述逻辑连接起来,并放置电源符号(5V, 3.3V)和接地符号(GND),就构成了完整的原理图。绘制过程中,为每个网络(导线)取一个清晰的名称(如SENSOR_DATA,BUZZER_CTRL),会让后续的PCB设计更轻松。

3.3 面包板原型验证

在将电路焊死或制作PCB之前,强烈建议在面包板上搭建原型进行验证。面包板内部是金属条连接,可以让你无需焊接,快速插拔元器件来测试电路。

搭建步骤

  1. 电源分布:用跳线将面包板两侧的长条电源轨分别连接到Arduino的5V和GND。这样,整个面包板就都有了电源和地。
  2. 放置核心控制器:将Arduino Uno跨坐在面包板的中部分隔槽上,其引脚就分别接入了两侧的孔排。
  3. 连接DHT11:将DHT11的VCC、GND插入电源轨。DATA引脚用杜邦线连接到Arduino D2,并在这条线路上,在面包板上插一个10kΩ电阻,一端接DATA线,另一端接5V电源轨(实现上拉)。
  4. 连接光敏模块:模块的VCC、GND接电源轨,AO引脚接Arduino A0。
  5. 搭建驱动电路:在面包板上插入S8050三极管。小心识别引脚(平面朝向自己,从左至右通常是E, B, C)。按照原理图,用跳线和电阻连接蜂鸣器、LED和三极管、Arduino。
  6. 连接OLED:将OLED的4个引脚(VCC, GND, SDA, SCL)分别对应接入电源轨和Arduino的A4、A5。

编写测试代码: 在Arduino IDE中,分别安装DHT sensor libraryAdafruit SSD1306等库。然后分段编写测试程序:

  • 先单独测试DHT11,读取并串口打印温湿度值。
  • 再测试光敏电阻,打印模拟输入值。
  • 然后测试OLED,显示一段固定文字。
  • 最后测试蜂鸣器和LED,控制其鸣响和闪烁。
  • 将所有功能整合,实现最终逻辑:读取传感器数据→OLED显示→若温度超过阈值,则触发声光报警。

通过面包板验证,你可以确保电路逻辑正确,代码运行正常,所有元器件完好无损。这是将错误成本降到最低的关键一步。

实操心得:面包板连接时,杜邦线容易松动,导致接触不良。如果遇到传感器数据时有时无或设备工作不稳定,第一个要检查的就是所有连接点是否牢固。可以用手轻轻按压各个连接处试试。

4. 从原型到成品:焊接与PCB入门

4.1 焊接基础与洞洞板制作

面包板验证成功后,我们可以制作一个更稳固的版本。对于单件或小批量,万用板(洞洞板)是理想选择。你需要准备电烙铁、焊锡丝、松香或助焊膏、吸锡器、镊子等工具。

焊接技巧

  1. 准备:将电烙铁加热到适宜温度(约350°C)。用湿润的海绵清洁烙铁头,并上一层薄薄的锡(吃锡),使其保持良好的导热性。
  2. 焊接过程:将元器件引脚穿过洞洞板,在背面固定。焊接时,同时加热焊盘和元器件引脚约1-2秒,然后将焊锡丝送到加热点,而不是送到烙铁头上。待焊锡熔化并自然流满焊盘形成光滑的圆锥形后,先移开焊锡丝,再迅速移开烙铁头。整个过程应在2-4秒内完成,时间过长会烫坏元器件或导致焊盘脱落。
  3. 检查:一个良好的焊点应该像光滑的小山丘,呈现亮银色。如果呈灰暗、粗糙的球状(冷焊),说明热量不足或焊锡质量不好,需要重新焊接。

在洞洞板上布局时,可以参照原理图,尽量使走线简洁。电源和地线可以用较粗的导线或铜柱作为“总线”。焊接顺序建议先焊矮小的元件(如电阻、IC座),再焊较高的元件(如电容、连接器)。为Arduino和OLED显示屏使用排母,方便插拔。

4.2 PCB设计概念与入门

如果想获得更专业、可靠且易于复制的电路板,就需要设计印刷电路板(PCB)。我们继续使用KiCad。

  1. 从原理图到PCB:在KiCad中完成原理图后,进行电气规则检查(ERC),确保没有未连接的引脚或电源冲突。然后通过“标注”工具为所有元器件分配唯一的标识符(如R1, C1, U1),再通过“导出网表”或“使用原理图更新PCB”功能,将元器件和连接关系导入PCB编辑器。
  2. 元器件布局:所有元器件会出现在PCB框外。布局是PCB设计中最具艺术性的环节,核心原则是:
    • 信号流导向:按照系统框图的信号流向(输入->处理->输出)放置元器件,减少走线交叉和长度。
    • 模块化:将相关功能的元器件(如传感器及其滤波电路)聚集在一起。
    • 考虑散热与干扰:大功率器件(如未来可能加的电机驱动芯片)应靠近板边并预留散热空间;模拟部分(传感器输入)和数字部分(单片机、开关信号)尽量分开,避免数字噪声干扰敏感的模拟信号。
    • 预留接口:电源接口、编程接口、扩展引脚应放在板子边缘便于插拔的位置。
  3. 布线:布局完成后,用“布线工具”将具有电气连接的飞线(细灰线)变成实际的铜走线。
    • 线宽:电源线(尤其是5V、3.3V主干)和地线要加粗(如0.5mm-1mm),以承载更大电流、减小压降。普通信号线0.2mm-0.3mm即可。
    • 过孔:当走线需要从顶层切换到底层时,使用过孔。不要滥用,过多的过孔会增加制板成本和潜在故障点。
    • 接地:对于简单的双面板,通常采用“接地覆铜”的方式。即在布线完成后,在顶层和底层没有走线的空白区域全部填充接地铜皮,并通过多个过孔将两层地连接起来,这能提供稳定的地参考和一定的屏蔽效果。
  4. 设计规则检查(DRC):布线完成后,必须运行DRC。它会根据你设定的规则(如最小线间距、最小线宽、焊盘与走线间距等)检查整个PCB,确保设计符合PCB制造厂的工艺要求,避免出现短路、断路等无法生产的问题。

完成DRC后,就可以导出Gerber文件(一种包含各层信息的标准制板文件),发送给PCB打样厂家(如嘉立创、捷配等)进行生产了。通常入门级的简单板子,5-10块钱就能打样5-10片。

5. 软件编程与系统调试

5.1 Arduino程序架构与关键库使用

硬件就绪后,我们需要赋予它“灵魂”。Arduino程序的基本架构非常简单,包含setup()loop()两个函数。

#include <Wire.h> #include <Adafruit_Sensor.h> #include <DHT.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> // 引脚定义与对象初始化 #define DHTPIN 2 #define DHTTYPE DHT11 #define LIGHT_SENSOR_PIN A0 #define BUZZER_PIN 8 #define LED_PIN 9 #define TEMP_THRESHOLD 28.0 // 温度报警阈值 DHT dht(DHTPIN, DHTTYPE); Adafruit_SSD1306 display(128, 64, &Wire, -1); void setup() { Serial.begin(9600); pinMode(BUZZER_PIN, OUTPUT); pinMode(LED_PIN, OUTPUT); digitalWrite(BUZZER_PIN, LOW); // 初始关闭蜂鸣器 digitalWrite(LED_PIN, LOW); // 初始关闭LED dht.begin(); // 初始化OLED if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { Serial.println(F("SSD1306 allocation failed")); for(;;); // 死循环,阻止程序继续 } display.clearDisplay(); display.setTextSize(1); display.setTextColor(SSD1306_WHITE); } void loop() { delay(2000); // DHT11采样间隔至少2秒 float humidity = dht.readHumidity(); float temperature = dht.readTemperature(); // 读取摄氏温度 // 检查传感器读数是否有效 if (isnan(humidity) || isnan(temperature)) { Serial.println("Failed to read from DHT sensor!"); display.clearDisplay(); display.setCursor(0,0); display.println("Sensor Error!"); display.display(); return; } int lightValue = analogRead(LIGHT_SENSOR_PIN); // 在串口监视器打印数据 Serial.print("Humidity: "); Serial.print(humidity); Serial.print(" %\t"); Serial.print("Temperature: "); Serial.print(temperature); Serial.print(" *C\t"); Serial.print("Light: "); Serial.println(lightValue); // 在OLED上显示数据 display.clearDisplay(); display.setCursor(0,0); display.print("Temp: "); display.print(temperature); display.println(" C"); display.print("Hum: "); display.print(humidity); display.println(" %"); display.print("Light:"); display.println(lightValue); display.display(); // 报警逻辑 if(temperature > TEMP_THRESHOLD) { digitalWrite(BUZZER_PIN, HIGH); digitalWrite(LED_PIN, HIGH); display.setCursor(0, 40); display.println("! TOO HOT !"); display.display(); } else { digitalWrite(BUZZER_PIN, LOW); digitalWrite(LED_PIN, LOW); } }

关键点解析

  • 库管理#include引入了所需库。务必通过库管理器安装正确版本。
  • 传感器读取:DHT11读取需要至少2秒的间隔,否则会读取失败。isnan()函数用于判断读数是否有效,这是非常必要的健壮性检查。
  • OLED显示:显示内容前先clearDisplay()清屏,所有内容绘制在内存中,最后调用display()才会一次性刷新到屏幕上,避免闪烁。
  • 报警逻辑:判断温度是否超过阈值,并控制数字引脚输出高/低电平来驱动三极管开关电路。

5.2 系统集成调试与问题排查

将程序上传至Arduino后,系统可能不会一次就完美运行。以下是常见的排查步骤:

问题1:OLED屏幕不亮或显示乱码。

  • 检查接线:确认SDA、SCL是否接反(分别对应A4和A5)。
  • 检查地址:I2C设备有地址。SSD1306常见地址是0x3C0x3D。可以使用Arduino的I2C Scanner示例代码扫描确认地址。
  • 检查电源:确认OLED的VCC接的是5V还是3.3V,有些模块只支持3.3V。

问题2:DHT11读取总是失败(返回NaN)。

  • 检查接线与上拉电阻:这是最常见的原因。确保DATA线连接正确,并且上拉电阻(4.7kΩ-10kΩ)已可靠连接在DATA和5V之间。
  • 检查供电:DHT11供电不足也会导致失败,确保其VCC引脚电压稳定在5V。
  • 检查时序:确保两次读取间隔大于2秒,并且不要在loop()中不加延迟地快速连续读取。

问题3:蜂鸣器不响或LED不亮。

  • 检查三极管电路:用万用表测量,当Arduino输出高电平时,三极管基极电压是否在0.7V左右(表明基极电流已形成)。测量集电极对地电压,导通时应接近0V(蜂鸣器负极被拉低)。
  • 检查元件极性:确认蜂鸣器(有源蜂鸣器分正负)、LED(长脚为正)、三极管引脚是否接对。
  • 检查代码:确认控制的引脚编号与定义一致,输出的是HIGH

问题4:光敏电阻读数变化不明显或异常。

  • 检查模块模式:确认使用的是模拟输出(AO)引脚,而不是数字输出(DO)引脚。DO引脚只在光照超过设定阈值时跳变,不输出连续值。
  • 测试供电:测量光敏电阻模块的VCC引脚电压是否为稳定的5V。

调试是一个“假设-验证”的过程。从电源开始,用万用表逐步测量关键点的电压,结合串口打印的调试信息,能快速定位大部分问题。养成在代码中添加调试输出(Serial.print)的习惯,是硬件开发中最重要的技能之一。

6. 扩展思路与项目优化

基础功能实现后,这个项目还有巨大的优化和扩展空间,这能让你学到更多。

硬件扩展

  1. 添加执行机构:利用一个额外的三极管或电机驱动芯片(如L298N),连接一个小型直流风扇。修改代码,当温度超过阈值时,不仅报警,同时启动风扇散热。
  2. 集成Wi-Fi:添加一个ESP-01s模块(基于ESP8266)。这需要修改硬件连接(接至Arduino的软串口引脚,如D10, D11),并编写复杂的网络通信代码(可使用AT指令或直接为ESP8266编程)。这样数据就能上传到Thingspeak、Blynk等物联网平台,或在手机APP上查看。
  3. 提高精度:将DHT11升级为DHT22或BME280,后者还能测量大气压,精度也更高。
  4. 增加交互:加入一个按键或旋转编码器,用于切换OLED显示内容(如显示温湿度曲线)或设置报警阈值。

软件优化

  1. 状态机编程:将系统的不同状态(如正常显示、报警、设置菜单)用状态机模式管理,使程序逻辑更清晰,易于维护和扩展。
  2. 低功耗设计:如果希望设备电池供电,可以优化代码,让单片机大部分时间处于睡眠模式,定时唤醒读取传感器和刷新显示,显著延长续航。
  3. 数据平滑滤波:传感器读数可能有微小波动。可以在软件中对连续几次的采样值进行平均(滑动平均滤波)或取中值(中值滤波),使显示数据更稳定。
  4. 使用中断:对于按键等需要即时响应的输入,可以配置为外部中断,而不是在loop()中轮询,提高响应效率。

结构与外观: 为你的电路板设计一个3D打印的外壳,将OLED屏幕、传感器探头露出来,把蜂鸣器开孔。这不仅让作品更美观、坚固,也体现了从内部电路到完整产品的全流程实践。

从理解欧姆定律到亲手做出一个能交互、能思考的智能设备,这个过程充满了挑战与乐趣。每一次调试成功,每一次功能实现,都是对你理论知识和动手能力的双重肯定。电路设计与制作没有想象的那么高深,它需要的是一份好奇心、一点耐心和一种“动手试试看”的勇气。这个环境监测终端只是一个起点,它的电路框架和设计思想,可以迁移到无数其他的项目中。当你掌握了这些基础,你会发现,用电路和代码去构建一个符合自己想象的物理世界,是一件极其自由且富有成就感的事。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/29 13:03:33

从零开始学电路设计:从原理图到PCB的完整实战指南

1. 项目概述&#xff1a;从想法到实物的电子之旅电路&#xff0c;这个听起来有点技术门槛的词&#xff0c;其实离我们并不遥远。你手上正在看这篇文章的手机&#xff0c;家里调节温度的空调&#xff0c;甚至那个一闪一闪的玩具&#xff0c;它们的“心脏”都是一块精心设计的电路…

作者头像 李华
网站建设 2026/5/29 13:03:29

PySide6多线程避坑指南:为什么你的线程暂停/恢复后数据错乱了?

PySide6多线程开发中的线程控制陷阱与工业级解决方案1. 问题现象&#xff1a;线程暂停/恢复为何导致数据错乱&#xff1f;在PySide6多线程开发中&#xff0c;许多开发者会遇到这样的场景&#xff1a;当尝试暂停一个正在运行的线程&#xff0c;然后恢复执行时&#xff0c;进度显…

作者头像 李华
网站建设 2026/5/29 13:03:17

量子计算传感:原理、优势与应用场景解析

## 1. 量子计算传感的革命性突破&#xff1a;原理与实现路径量子计算传感&#xff08;Quantum Computational Sensing, QCS&#xff09;正在重新定义测量科学的边界。这项技术巧妙融合了量子传感的灵敏度与量子计算的并行处理能力&#xff0c;其核心突破在于&#xff1a;传统量…

作者头像 李华
网站建设 2026/5/29 13:03:15

搜索引擎规模下的实时语法检查:架构、模型与工程实践

1. 项目概述&#xff1a;当语法检查遇上搜索引擎的庞大规模 “在谷歌搜索的规模下进行语法检查”&#xff0c;这个标题听起来像是一个纯粹的技术挑战&#xff0c;但背后涉及的&#xff0c;其实是每个普通用户都可能遇到的需求。想象一下&#xff0c;你正在用搜索引擎查询一个复…

作者头像 李华
网站建设 2026/5/29 13:02:55

3分钟搞定微博PDF备份:Speechless终极指南,让数字记忆永不消失

3分钟搞定微博PDF备份&#xff1a;Speechless终极指南&#xff0c;让数字记忆永不消失 【免费下载链接】Speechless 把新浪微博的内容&#xff0c;导出成 PDF 文件进行备份的 Chrome Extension。 项目地址: https://gitcode.com/gh_mirrors/sp/Speechless 你是一个文章写…

作者头像 李华