资讯动态

基于Arduino与WS2812B的音频电平表制作:从信号调理到LED显示

发布时间:2026/8/19 13:40:53 来源:尧图企业网站定制
1. 项目概述当复古电视遇上音频电平表最近在工作室里翻出一台老旧的CRT电视显像管已经老化画面模糊不清但外壳和那种厚重的复古感依然让我着迷。直接扔掉太可惜改造成显示器又觉得技术门槛和成本不低。正好手头有几个闲置的Arduino开发板和一堆LED一个想法冒了出来能不能把这台“退役”的电视变成一个能实时显示音频信号电平的复古风格VU表再配上峰值指示灯这听起来就像给老物件注入新灵魂既有电子DIY的乐趣又能得到一件独一无二的桌面摆件或音乐监听设备。这个项目我们称之为“DIY复古电视VU表带峰值指示器”。它的核心功能是将一台废旧电视的显像管部分移除利用其原有的外壳和屏幕开口安装一个由LED灯条或点阵屏构成的显示面板。然后通过Arduino比如经典的Uno或更强大的ESP32来采集音频信号实时计算其音量电平即VU值并驱动LED以动态条形图或模拟指针的形式显示出来。同时我们还会加入峰值指示灯通常是一个独立的LED当音频信号瞬间超过设定的阈值时这个灯会亮起并保持几秒钟提醒你信号可能过载了。它适合谁呢首先当然是电子爱好者和Arduino玩家这是一个绝佳的练手项目涵盖了模拟信号采集、数字信号处理、LED驱动和创意外壳改造等多个环节。其次音乐制作人、DJ或音响发烧友可能会喜欢它作为一个别致的硬件VU表放在调音台旁边既实用又炫酷。甚至对于喜欢蒸汽朋克或复古科技风格的朋友来说这本身就是一件很棒的艺术装置。整个项目的关键在于几个部分如何安全地拆解和处理旧电视特别是高压部分如何设计并安装LED显示面板使其完美适配电视屏幕的开口如何用Arduino准确且美观地解析和显示音频电平以及如何实现灵敏且可靠的峰值检测与保持功能。接下来我会一步步拆解这个过程分享从构思到实现的完整细节以及我踩过的那些坑和总结出的技巧。2. 核心思路与方案选型为什么是“Arduino 复合视频信号”看到“复合信号”这个关键词可能有些朋友会疑惑我们不是做音频VU表吗怎么和视频信号扯上关系了这里有一个非常巧妙的思路转换。我们最终的目标是要在改造后的电视“屏幕”现在是LED面板上显示出动态的电平条和峰值指示。最直接的方式当然是Arduino直接控制LED。但如何让这个显示效果更有“复古电视”的神韵呢答案就是模拟老式电视的扫描线效果或者至少让显示内容的生成方式与电视有关联。一种经典的实现方法是利用Arduino生成一个简单的复合视频信号Composite Video Signal直接输出到电视的原始视频输入接口。在这个视频信号里我们不是绘制图像而是绘制VU表的条形图和峰值标记。这样理论上你甚至不需要拆除显像管电视本身就成了显示器。但这种方法对Arduino的时序要求极其苛刻需要精准控制且通常只能生成低分辨率的黑白或简单色信号视觉效果比较原始可能无法实现非常平滑的电平条动画。经过权衡我选择了更务实、效果也更容易控制的方案弃用电视的原生视频电路和显像管保留其外壳内置一个由Arduino直接控制的LED显示系统。而“复合信号”在这里扮演了另一个角色作为可选的、更专业的音频输入接口。很多老电视的AV输入端口那个黄色RCA接口接收的就是复合视频信号但旁边通常伴随着白色和红色的音频输入接口。我们可以利用这个音频输入接口作为外部音源的接入点。当然我们也可以直接使用3.5mm音频接口但保留并利用电视原有的RCA音频接口在改造完成后你依然可以用一根莲花头音频线连接设备这种“伪装”会让成品更具整体感和趣味性。所以本项目的方案可以概括为显示核心WS2812B LED灯条也称NeoPixel或常规LED点阵屏由Arduino控制。控制核心Arduino Uno入门首选或ESP32性能更强有Wi-Fi/蓝牙扩展潜力。音频输入通过一个简单的分压电路和电容耦合将音频信号接入Arduino的模拟输入引脚。同时保留电视原有的RCA音频接口作为输入端口之一实现“复古接口复用”。峰值检测在Arduino代码中实现软件峰值检测与保持算法并用一个独立的LED如5mm红色LED作为峰值指示灯。外壳废旧CRT电视外壳内部清空用于安装LED面板、Arduino和控制电路。选择WS2812B灯条是因为它易于控制只需要Arduino的一个数字引脚就能驱动上百个LED并且每个LED的颜色和亮度都可单独编程非常适合制作平滑的颜色渐变电平条。选择Arduino Uno是因为其资料丰富、社区支持强大对于处理音频采样和LED驱动足够用。如果希望显示更复杂的频谱而不仅仅是总体电平或者未来想通过网络传输音频数据那么ESP32是更好的选择。3. 安全拆解与外壳准备处理CRT电视的“第一课”这是整个项目中最需要谨慎对待的环节CRT阴极射线管电视内部有高压包即使在断电后很长时间其显像管阳极和电路板上的一些大电容里仍可能储存着致命的高压电可达数万伏。操作不当有严重触电风险。注意安全第一如果你对高压电器内部结构不熟悉或者没有电子维修基础强烈建议寻求有经验的朋友帮助或者直接跳过拆解显像管这一步只利用外壳。你可以尝试寻找一个已经损坏、内部被掏空的电视外壳或者用其他复古风格的箱子替代。我的操作流程如下仅供参考请务必小心3.1 放电与拆解步骤准备工具与防护准备一套绝缘良好的螺丝刀、尖嘴钳、万用表。戴上绝缘手套和护目镜。找一个宽敞、干燥、绝缘的工作台。充分放电将电视断电并拔掉电源线放置至少24小时让内部电路自然放电。为了确保安全需要进行主动放电。找到显像管锥体上的阳极帽一个连着粗电线、像橡皮碗一样扣在玻璃上的黑色部件。切勿直接用手触碰用一根绝缘导线一端可靠地连接到电视金属底盘接地另一端缠绕在一把绝缘良好的长柄螺丝刀金属杆上。手持螺丝刀的绝缘柄将金属杆慢慢滑入阳极帽与显像管玻璃之间听到或看到“啪”的放电声光为止。可以多次接触确保放完。同样对主板上的大型滤波电容通常是两个大圆柱体进行短路放电。用电阻或灯泡放电更温和但直接短路用导线连接电容两脚对于业余操作更常见会伴随“啪”一声请做好心理准备。拆除后盖与电路板卸下所有螺丝打开电视后盖。首先拔掉连接显像管颈部的偏转线圈插头、阳极高压线已放电和管座板。然后依次拆除主板、电源板、高压包等所有电子部件。只保留外壳、前面板、按键可选改造和扬声器可选利用。将拆下的电路板妥善处理电子垃圾回收。取出显像管这是最重、最危险的步骤。显像管非常沉重且易碎。需要先拆下固定它的金属框架或橡胶垫。通常需要两人协作平稳地将它从外壳中抬出。务必注意显像管颈部玻璃非常脆弱绝对不能磕碰。取出后将其安全放置最好用软布包裹并按照当地规定处理CRT玻璃含铅不能随意丢弃。3.2 外壳改造与显示面板安装清空内部后我们就得到了一个完美的“项目箱体”。清洁与规划彻底清洁外壳内部去除灰尘。从内部观察屏幕开口即原来显像管显示的区域测量其精确尺寸。制作显示面板根据屏幕开口尺寸裁剪一块亚克力板或磨砂半透明白色塑料板作为LED的漫射板。这能让LED光点变得柔和形成均匀的光带更像传统的VU表表盘。在漫射板背后固定你的LED灯条。如果你使用WS2812B软灯条可以将其紧密排列成所需的条形图形状。例如计划做一个10段电平表每段用3个LED那么就需要剪裁一段30颗LED的灯条并将其弯曲或固定在一条直线上。为了获得最佳效果可以在LED灯条和漫射板之间增加一层匀光纸或普通的白色绘图纸使光线扩散更均匀。将整个显示面板组件漫射板匀光纸LED灯条固定在外壳内部对准原来的屏幕开口。可以使用热熔胶、螺丝配合L型支架或3D打印的固定件来完成。接口保留与改造音频输入找到原电视的音频RCA输入接口通常是白色和红色的一对。将其从主板上焊接下来但保留接口本身安装在外壳上的部分。用导线将这两个接口的“信号端”引出连接到我们后续制作的音频输入电路。这样外壳上的原始接口就“复活”了成为我们VU表的音频输入口。电源开关可以利用电视原来的电源开关控制整个改造后设备的通断。其他按键/旋钮电视上的音量、频道等按键可以通过Arduino来读取改造为VU表的灵敏度调节、模式切换等功能这大大增加了项目的可玩性和复古交互感。4. 电路设计与核心模块解析完成外壳改造后我们进入电子部分。电路并不复杂但每个环节的设计都影响着最终效果。4.1 音频输入与调理电路Arduino的模拟输入引脚A0-A5只能读取0-5V的直流电压。而音频信号是交流信号其平均值约为0V波形在正负之间摆动。直接接入会损坏Arduino或得到错误读数。因此我们需要一个“音频调理电路”其核心任务有两个隔直和抬升电压基准。隔直使用一个串联电容阻止直流分量只允许交流的音频信号通过。抬升电压基准通过一个电阻分压网络将音频信号的整体电压“抬升”到以2.5V为基准即Arduino模拟参考电压5V的一半。这样无声时信号为0VArduino读到的是2.5V对应模拟值512当信号为正弦波正半周时电压高于2.5V负半周时电压低于2.5V。我们通过计算瞬时值与2.5V基准的绝对差值就能得到音频的振幅。一个典型且可靠的电路如下音频输入 (来自RCA接口) -- 10uF 电解电容 (正极接输入) -- 两个100kΩ电阻串联分压点 | --- 连接至 Arduino 模拟引脚 (如 A0) | GND10uF电解电容实现隔直。电容值不宜过小否则低频信号衰减严重。10uF-22uF是常用值。两个100kΩ电阻它们串联在Arduino的5V和GND之间中间连接点提供2.5V的稳定偏置电压。这个点同时连接到模拟输入引脚和隔直电容的负极。可选保护在模拟输入引脚对地之间可以并联一个5.1V的齐纳二极管或TVS二极管防止意外的高压冲击。再串联一个1kΩ的小电阻也能起到一定的限流保护作用。这个电路将音频信号“叠加”在了2.5V的直流电平上安全地送到了Arduino的ADC模数转换器。4.2 主控与显示驱动电路Arduino主控以Uno为例我们将使用A0引脚读取调理后的音频信号。一个数字引脚如D6用来控制WS2812B LED灯条的数据线。另一个数字引脚如D7用来控制独立的峰值指示灯LED记得串联一个220Ω的限流电阻。WS2812B连接连接非常简单。灯条的VCC接5V注意电流需求LED数量多时需要外接5V电源GND接GNDDIN数据输入接Arduino的D6引脚。如果灯条较长在VCC和GND之间靠近灯条输入端的地方并联一个100-1000uF的电解电容可以稳定电源防止上电时的电流冲击导致程序异常。电源整个系统需要稳定的5V电源。如果LED数量少于30个Arduino Uno的USB口或板载稳压器可能勉强够用。但为了稳定和亮度强烈建议使用外接的5V/2A以上的开关电源模块同时给Arduino和LED灯条供电。将电源的正负极分别接到电源模块的VIN或外部电源输入端子和GND。4.3 峰值指示电路峰值指示电路极其简单就是一个普通的LED驱动电路。将一颗高亮红色LED的阳极长脚通过一个220Ω电阻连接到Arduino的某个数字引脚如D7阴极短脚连接到GND。当Arduino检测到峰值时将该引脚设置为HIGHLED点亮。5. 软件实现Arduino代码核心解析代码是项目的灵魂它决定了VU表的响应速度、显示效果和准确性。我们将使用Arduino IDE进行开发。5.1 库文件准备首先需要安装控制WS2812B的库。最常用的是Adafruit_NeoPixel库。可以在Arduino IDE的“工具” - “管理库”中搜索并安装。5.2 核心算法与代码结构#include Adafruit_NeoPixel.h // 参数配置 #define PIN_AUDIO A0 // 音频输入引脚 #define PIN_LED_DATA 6 // WS2812B数据引脚 #define PIN_PEAK_LED 7 // 峰值指示灯引脚 #define NUM_LEDS 30 // LED总数 (例如10段每段3个LED) #define SAMPLE_WINDOW 50 // 采样窗口时长 (毫秒) #define PEAK_HOLD_TIME 2000 // 峰值保持时间 (毫秒) Adafruit_NeoPixel strip Adafruit_NeoPixel(NUM_LEDS, PIN_LED_DATA, NEO_GRB NEO_KHZ800); int ledPerSegment 3; // 每段电平使用的LED数量 int numSegments NUM_LEDS / ledPerSegment; // 总段数 unsigned int sample; // 单次采样值 float maxSample 0; // 采样窗口内的最大采样值 float volume 0; // 计算得到的音量值 (0-1) unsigned long peakTimer 0; // 峰值计时器 bool peakDetected false; // 峰值检测标志 void setup() { Serial.begin(9600); strip.begin(); strip.show(); // 初始化所有LED为关闭状态 pinMode(PIN_PEAK_LED, OUTPUT); // 设置模拟参考电压为默认的5V如果使用3.3V板子如ESP32需注意 // analogReference(DEFAULT); } void loop() { // --- 1. 音频采样与音量计算 --- unsigned long startMillis millis(); maxSample 0; unsigned int signalMax 0; unsigned int signalMin 1024; // 在固定的时间窗口内持续采样寻找波峰和波谷 while (millis() - startMillis SAMPLE_WINDOW) { sample analogRead(PIN_AUDIO); if (sample 1024) { // 忽略异常值 if (sample signalMax) { signalMax sample; } if (sample signalMin) { signalMin sample; } } } // 计算峰峰值 (Peak-to-Peak) unsigned int peakToPeak signalMax - signalMin; // 将ADC读数转换为电压再估算为音量。1024对应5V但我们的信号以512(2.5V)为中心。 // 更简单的做法是直接映射但为了更符合人耳感知可以做一些处理。 float voltage (peakToPeak * 5.0) / 1024.0; // 转换为电压值 volume voltage / 1.0; // 假设1.0V峰峰值对应最大音量可根据输入信号调整这个除数 // 限制音量值在0-1之间 volume constrain(volume, 0, 1); // --- 2. 峰值检测与保持 --- static float lastPeakVolume 0; float peakThreshold 0.85; // 峰值触发阈值设为最大音量的85% if (volume peakThreshold) { peakDetected true; peakTimer millis(); // 重置保持计时器 lastPeakVolume volume; // 记录峰值时的音量可用于显示峰值位置 } // 检查峰值保持时间是否结束 if (peakDetected (millis() - peakTimer PEAK_HOLD_TIME)) { peakDetected false; } // 控制峰值指示灯 digitalWrite(PIN_PEAK_LED, peakDetected ? HIGH : LOW); // --- 3. LED显示更新 --- // 根据音量计算点亮的LED段数 int ledsToLight volume * numSegments * ledPerSegment; ledsToLight constrain(ledsToLight, 0, NUM_LEDS); // 先关闭所有LED for (int i 0; i NUM_LEDS; i) { strip.setPixelColor(i, 0); // 黑色即关闭 } // 点亮对应数量的LED并设置颜色例如绿色-黄色-红色 for (int i 0; i ledsToLight; i) { int segmentIndex i / ledPerSegment; // 当前LED属于第几段 float segmentProgress (float)(i % ledPerSegment) / ledPerSegment; // 段内位置 // 根据段索引和位置计算颜色 uint32_t color getColorForSegment(segmentIndex, segmentProgress); strip.setPixelColor(i, color); } // 如果峰值被检测到并且我们想用最高段的LED闪烁来表示可以这样做 if (peakDetected) { // 例如让最顶端的几个LED闪烁白色 for (int i NUM_LEDS - 3; i NUM_LEDS; i) { strip.setPixelColor(i, strip.Color(150, 150, 150)); // 淡白色 } } strip.show(); // 更新LED显示 // 可选串口输出调试信息 // Serial.print(Volume: ); Serial.print(volume); // Serial.print(\tPeak: ); Serial.println(peakDetected); } // 辅助函数根据段索引和位置返回颜色 uint32_t getColorForSegment(int segment, float progress) { // 示例前60%的段为绿色中间30%为黄色最后10%为红色 float totalSegments numSegments; float segmentRatio (float)segment / totalSegments; if (segmentRatio 0.6) { // 绿色到黄绿色渐变 return strip.Color(0, 255 - (progress * 100), 0); } else if (segmentRatio 0.9) { // 黄色到橙色渐变 return strip.Color(255, 255 - (progress * 150), 0); } else { // 红色 return strip.Color(255, 0, 0); } }代码关键点解析采样窗口 (SAMPLE_WINDOW)我们不是在每个loop()循环中只读一次ADC值而是在一个固定时间段如50毫秒内连续采样找出这个时间段内的信号最大值和最小值。它们的差值峰峰值更能代表该时间段内的“音量”或“响度”。这种方法比读取瞬时值稳定得多避免了因音频波形过零点而误判为无声。音量标准化计算出的peakToPeak值范围取决于输入信号的强度。voltage (peakToPeak * 5.0) / 1024.0将其转换为电压值。除以一个经验值如1.0是为了将音量映射到0-1的范围。这个除数需要根据你的实际音源进行调整。可以通过串口监视器观察最大音量时的voltage值然后将其设为除数。峰值检测逻辑我们设定一个阈值如peakThreshold 0.85。当volume超过此阈值即认为检测到峰值。peakDetected标志置为true并启动计时器。在接下来的PEAK_HOLD_TIME如2秒内即使音量回落该标志也保持为真峰值指示灯常亮模拟硬件VU表峰值保持的功能。时间到后标志清除指示灯熄灭。LED显示与颜色映射getColorForSegment函数实现了经典的VU表颜色渐变低电平绿色中电平黄色高电平红色。通过segmentRatio判断当前LED属于哪个大区间再结合progress实现段内的平滑渐变视觉效果非常专业。性能优化strip.show()函数在更新大量LED时比较耗时。如果NUM_LEDS很多比如超过100且SAMPLE_WINDOW很短可能会影响采样率。可以考虑非阻塞式更新或者使用更快的库如FastLED。5.3 校准与调试技巧上传代码后很可能发现VU表要么不动要么一直顶格。这时就需要校准。静音校准在没有音频输入时读取A0的模拟值。理论上应该是512左右。如果偏差很大比如480或540说明你的2.5V偏置电路不准。可以微调两个分压电阻的阻值或者直接在代码中设置一个“零位”偏移量。int silentLevel 512; // 实测的静音值 sample analogRead(PIN_AUDIO) - silentLevel 512; // 软件补偿最大音量校准播放一段你知道音量很大的音乐注意别烧喇叭或耳机从串口监视器观察计算出的voltage值。记下这个最大值比如1.8V。然后将代码中volume voltage / 1.0;的除数1.0改为这个最大值如1.8。这样当播放这段音乐时VU表就应该刚好打满。响应速度调整SAMPLE_WINDOW的大小决定了VU表的响应速度。50ms是一个不错的折中值既能跟上音乐节奏又不会闪烁得太厉害。如果你想让它反应更快比如显示鼓点可以减小到20ms如果想更平滑像传统慢速VU表可以增加到100ms甚至200ms。峰值阈值调整peakThreshold决定了多强的信号会触发峰值灯。通常设为略低于最大音量0.85-0.95。你可以根据喜好和输入信号动态调整。6. 组装、调试与效果优化将Arduino、面包板或焊接好的电路板、电源模块等全部安装到电视外壳内部。合理布局确保散热并用扎带固定好线缆。上电测试先不接音频上电检查LED灯条是否正常初始化全灭峰值指示灯是否熄灭。音频连接用音频线将手机、电脑等音源连接到电视背板改造好的RCA接口或额外的3.5mm接口。播放音乐。观察与微调无反应检查音频调理电路连接用万用表测量A0引脚电压在播放音乐时应该在2.5V上下波动。检查代码中的引脚定义。一直满格音量除数太小按上述方法校准。反应迟钝减小SAMPLE_WINDOW值。峰值灯不亮提高peakThreshold或检查峰值LED电路连接。显示闪烁或错乱WS2812B对时序敏感。确保数据线连接可靠尽量短。在LED电源入口处并联一个大电容470uF以上。检查代码中LED数量NUM_LEDS定义是否正确。效果优化平滑处理为了让电平条移动更平滑可以对计算出的volume值进行一阶低通滤波软件实现。float smoothedVolume 0; float smoothingFactor 0.2; // 越小越平滑反应越慢 smoothedVolume (volume * smoothingFactor) (smoothedVolume * (1 - smoothingFactor)); // 然后用 smoothedVolume 去控制LED多种显示模式可以增加一个按钮切换显示模式。比如模式一经典单声道VU条模式二立体声VU表需要两个音频输入电路模式三频谱分析模式需要更复杂的FFT算法和ESP32等更强性能的主控。亮度调节增加一个电位器连接到另一个模拟引脚用来实时调节LED灯条的整体亮度strip.setBrightness()函数。7. 常见问题与排查实录在制作过程中你几乎一定会遇到下面这些问题。这里是我的排查笔记问题现象可能原因排查与解决步骤上电后LED灯条乱闪或颜色异常1. 电源功率不足。2. 数据线受到干扰。3. 第一个LED损坏。1.首要检查电源使用万用表测量灯条入口处的电压满载时不应低于4.8V。务必使用足额5V/3A以上的外接电源并确保导线足够粗。2.检查数据线数据线应尽量短50cm并远离电源线。可以在Arduino数据输出引脚和灯条数据输入引脚之间串联一个100-500Ω的电阻有助于抑制振铃。3.跳过第一个LED尝试将数据线接到灯条的第二个LED的DIN上如果后面都正常说明第一个LED可能已坏更换或剪掉它。VU表显示始终为0或极小值1. 音频信号未接入或调理电路故障。2. Arduino模拟引脚配置错误。3. 采样窗口内信号未变化。1.检查音频通路播放音乐用万用表交流电压档测量调理电路输出端A0引脚应有电压摆动。若无检查电容、电阻焊接和音频线。2.代码调试打开串口监视器查看signalMax和signalMin的原始值。无声时两者应接近且围绕512小幅波动。有声时差值应明显变大。如果值始终是0或1023检查引脚连接和analogRead语句。3.增大输入信号尝试提高音源音量。峰值指示灯常亮或不亮1. 阈值设置不当。2. 峰值保持逻辑错误。3. LED或电阻损坏。1.串口打印将volume和peakDetected状态打印出来观察音量达到多少时触发峰值。调整peakThreshold。2.检查计时逻辑确保peakTimer在检测到峰值时被正确更新peakTimer millis()并且判断条件(millis() - peakTimer PEAK_HOLD_TIME)正确。3.硬件检查用代码直接设置峰值引脚为HIGH看LED是否亮起。检查限流电阻值是否过大导致电流太小灯不亮或过小可能烧毁LED或IO口。电平条跳动过于剧烈1. 采样窗口太短。2. 未做平滑处理。3. 音频信号本身噪声大。1.增加SAMPLE_WINDOW从50ms逐步增加到100ms观察效果。2.加入软件滤波使用上述的低通滤波算法smoothingFactor从0.3开始尝试。3.优化硬件在音频输入端的2.5V偏置电压点对地并联一个10uF的电解电容可以进一步稳定直流偏置滤除噪声。使用电视原按键不灵敏1. 按键内部氧化接触不良。2. Arduino上拉电阻未启用或接线错误。1.清洁按键拆开按键用酒精清洗触点或直接更换新按键。2.正确配置引脚在setup()中将连接按键的引脚设置为INPUT_PULLUP模式。按键一端接该引脚另一端接GND。按下时引脚读到LOW释放时读到HIGH。一个关键的实操心得供电是王道。特别是驱动较长WS2812B灯条时瞬时电流很大。务必在灯条的首尾两端甚至中部都接入5V电源线称为“电源注入”避免因线路压降导致末端的LED颜色失真或无法驱动。计算总电流单颗WS2812B白色全亮时约60mA30颗就是1.8A选择电源时务必留有余量如3A。最后给改造完成的复古电视VU表装上一个合适的底座或者重新装上它的后盖。当接通电源播放音乐看着那些温暖的LED光芒随着节奏在昔日电视屏幕的窗口后跳动峰值红灯在强音处坚定地亮起那种将旧科技与新创意融合的满足感是任何成品设备都无法给予的。这个项目不仅是一个工具更是一个故事一个关于复活、创造和热爱的故事。你可以根据自己的喜好调整LED的颜色、显示模式甚至加入麦克风做成声控氛围灯。希望这份详细的指南能帮你少走弯路享受DIY的乐趣。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价