资讯动态

基于Arduino与Scilab的紫外反射计DIY:从光电检测到数据可视化

发布时间:2026/8/20 7:47:11 来源:尧图企业网站定制
1. 项目概述用Arduino Nano和Scilab搭建一台紫外反射计如果你对材料分析、表面涂层或者光学测量有点兴趣但又觉得专业设备太贵、太复杂那今天聊的这个项目可能正对你的胃口。我最近用一块Arduino Nano开发板和一款免费的数学软件Scilab捣鼓出了一台能测量紫外光反射率的简易设备我管它叫“桌面级紫外反射计”。这玩意儿听起来挺唬人其实核心思路就是把复杂的光学测量平民化、模块化。简单来说它的工作原理就是让一个紫外LED去照射样品表面然后用一个对紫外光敏感的光电传感器去接收反射回来的光信号。Arduino Nano负责控制LED的开关、读取传感器输出的模拟电压值并通过串口把数据实时发送到电脑。电脑端的Scilab软件则扮演“大脑”的角色它接收数据、进行必要的计算比如扣除环境光本底、做校准曲线拟合最后把反射率的结果用图表直观地显示出来。整个过程从硬件连接到软件编程再到数据可视化全部可以自己动手完成。这个项目最适合两类朋友一类是电子爱好者或创客想找个有点挑战又实用的项目练手另一类是相关专业的学生或研究人员比如材料、化学、物理领域需要低成本地做一些初步的定性或半定量光学表征。它当然比不上动辄几万、几十万的专业分光光度计但用来比较不同样品表面的紫外反射性能差异、监测涂层的老化过程或者作为教学演示仪器其精度和稳定性已经足够让人惊喜。接下来我就把从设计思路、硬件选型、电路搭建到软件编程、数据处理和实际调试的完整过程以及我踩过的那些坑毫无保留地分享给你。2. 核心思路与方案选型背后的考量为什么选择Arduino Nano加Scilab这个组合而不是用树莓派加Python或者直接用LabVIEW这里面的每一个选择都是基于成本、易用性、精度需求和开发效率的综合权衡。2.1 硬件平台为什么是Arduino Nano首先看微控制器。Arduino Nano的核心优势在于其极低的学习门槛和丰富的生态系统。对于这样一个以数据采集为核心的项目我们需要一个能稳定读取模拟信号、进行简单逻辑控制、并可靠进行串口通信的设备。Arduino Nano的ATmega328P芯片自带6路10位精度的ADC模数转换器对于测量光强产生的电压变化完全够用。它的体积小巧可以直接插在面包板或洞洞板上方便我们搭建紧凑的测量探头。市面上兼容板价格低廉资源丰富任何问题几乎都能找到现成的解决方案。我也考虑过ESP32它性能更强还有Wi-Fi但本项目对无线传输没有硬性需求ESP32的ADC非线性问题在某些情况下反而需要额外校准增加了复杂度。STM32系列性能强大但开发环境对新手不那么友好。因此Arduino Nano在满足功能需求的前提下提供了最佳的易用性和稳定性平衡。2.2 光学传感方案紫外LED与光电传感器的配对这是项目的核心。测量紫外反射率我们需要一个紫外光源和一个紫外探测器。对于光源我选择了波长在365nm附近的紫外LED。这个波长属于UVA波段相对安全且很多材料如防晒霜、某些塑料、老化后的涂层在这个波段有特征吸收或反射。选择LED而非激光或氙灯是因为LED驱动简单、寿命长、单色性好光谱带宽较窄、价格便宜。关键参数是视角和光强我选用的是5mm直插式、视角约15度的LED这样发出的光斑相对集中有利于提高信噪比。对于探测器我选择了光电二极管具体型号是滨松的S1227-66BR它是一个带有可见光截止滤光片的硅光电二极管对紫外光特别是200-400nm有较好的响应同时对可见光不敏感这能有效减少环境可见光的干扰。相比光敏电阻或光电池光电二极管的响应速度快、线性度好更适合做定量测量。它需要配合一个运放电路将微弱的光电流转换成电压信号这就是后续要讲的**跨阻放大器TIA**电路。为什么不直接用集成的光强度传感器模块如BH1750或TSL2591因为这些模块主要针对可见光优化其内置的光谱响应曲线在紫外区域通常不敏感或未标定无法准确测量紫外光强。2.3 软件平台为什么是Scilab数据处理和可视化需要在电脑上完成。Python配Matplotlib/NumPy当然是热门选择但我选择Scilab有以下几个原因专为科学计算设计Scilab内置了强大的矩阵运算、曲线拟合、信号处理工具箱进行数据滤波、多项式拟合、FFT分析等操作非常方便语法与MATLAB类似但完全免费开源。出色的图形能力它的绘图函数非常强大且易于使用能够轻松绘制实时数据流、拟合曲线、并添加复杂的标注生成出版级的图表。便捷的串口通信Scilab通过serial工具箱可以很方便地打开、读取、关闭串口实现与Arduino的实时数据交互。一体化环境不需要像Python那样安装和管理多个第三方库serial, numpy, matplotlib等对于不熟悉Python包管理的朋友更友好。当然这个项目的软件部分是开放的你用Python完全能实现一样的功能甚至更灵活。但Scilab提供了一条更直接、更“傻瓜式”的科学计算路径。3. 硬件电路设计与核心模块解析整个硬件部分可以分为三个核心模块紫外LED驱动电路、光电信号调理电路以及Arduino Nano最小系统。电路不复杂但每个环节的细节都决定了最终测量的稳定性和准确性。3.1 紫外LED恒流驱动与调制电路为了让LED发出稳定的光我们不能简单地用一个限流电阻接上PWM脉冲宽度调制就了事。因为LED的发光强度不仅与电流有关还受自身温度影响直接改变PWM占空比会导致电流波动进而引起光强波动。我的方案是采用恒流驱动。使用一个运算放大器如LM358搭建一个简单的恒流源电路。具体原理是利用一个精密参考电压可以从Arduino的5V经电阻分压得到或使用TL431等基准源加在运放的同相输入端运放输出驱动一个MOSFET如2N7000或三极管LED串联在MOSFET的漏极和地之间。在LED的阴极和地之间串联一个小的采样电阻例如10欧姆。采样电阻上的电压反馈到运放的反相输入端。运放会自动调整输出使采样电阻上的电压等于参考电压从而维持流过LED的电流恒定。计算公式很简单I_LED V_ref / R_sense。如果我需要20mA的驱动电流设定V_ref为0.2VR_sense用10欧姆即可。然后我再用Arduino Nano的一个数字引脚如D9输出一个低频方波比如1Hz来控制这个恒流源的使能。方波为高时LED恒流点亮为低时LED熄灭。这样做的巨大好处是实现了同步检测。在软件中我可以分别在LED亮和灭的两个阶段读取传感器值两者相减就能直接扣除环境光的本底信号极大地提高了抗干扰能力。这个技巧在微弱光信号检测中非常关键。3.2 光电信号调理跨阻放大器TIA设计光电二极管输出的信号是极其微弱的光电流通常在纳安到微安级别。我们需要一个电路将其线性地、低噪声地转换为电压信号。这就是跨阻放大器的任务。跨阻放大器的核心是一个运算放大器这里必须选用低偏置电流、低噪声的型号如OPA377或MCP6002将光电二极管反向偏置或零偏置连接在运放的反相输入端和输出端之间。光电二极管的阴极接反相输入端阳极接地或虚地。运放的同相输入端接地。在反相输入端和输出端之间并联一个反馈电阻R_f和一个反馈电容C_f。它的工作原理是光电流I_photo全部流过反馈电阻R_f根据运放“虚短”特性反相输入端电压为0因此输出电压V_out -I_photo * R_f。负号表示信号反相我们在软件中取绝对值即可。R_f的选择决定了放大倍数。假设最大光电流为10μA我们希望最大输出为2.5V在Arduino的ADC量程内那么R_f 2.5V / 10μA 250kΩ。我实际选用了一个1MΩ的可调电阻方便在实际调试中调整量程。反馈电容C_f的作用至关重要它用于抑制高频噪声和防止电路振荡。其值需要根据R_f和光电二极管的结电容C_j来计算以确保电路的稳定性。一个经验公式是C_f sqrt(C_j / (2π * R_f * GBW))其中GBW是运放的增益带宽积。如果不想复杂计算可以先不焊C_f用示波器观察输出如果出现高频振荡再并联一个几皮法到几十皮法的小电容通常就能解决。我最终用了22pF的瓷片电容。注意整个TIA电路必须精心布局。光电二极管到运放反相输入端的引线要尽可能短最好使用屏蔽线。反馈电阻R_f和电容C_f要紧贴运放引脚焊接。电路板要清洁避免漏电流。供电最好使用干净的线性稳压电源并在运放电源引脚附近加退耦电容0.1μF和10μF并联。3.3 Arduino Nano接口与电源管理Arduino Nano在这里主要承担三个任务数字控制一个引脚D9输出方波控制LED驱动电路的使能。模拟采集一个模拟输入引脚A0读取TIA电路输出的电压信号。串口通信将采集到的原始电压值发送给上位机Scilab。接线非常简单D9- LED驱动电路使能端。A0- TIA输出端V_out。GND- 与TIA电路、LED驱动电路共地。5V- 为LED驱动电路和TIA电路中的运放供电如果运放需要±电源则需额外设计负压产生电路本项目单电源运放即可。电源方面整个系统可以从电脑USB口取电但要注意USB口的噪声。如果追求更高稳定性建议给Arduino Nano和模拟电路部分单独用一个干净的5V线性稳压电源供电。数字部分和模拟部分的电源最好在入口处用磁珠或小电阻隔离并在靠近芯片处加大容量电解电容和小容量瓷片电容进行退耦。4. 固件编程Arduino的数据采集与同步策略Arduino的固件代码Sketch核心目标是实现精准的同步采集并将数据以格式化的方式通过串口发送。代码不长但逻辑要清晰。// 定义引脚 const int ledControlPin 9; // 控制LED的方波输出 const int sensorPin A0; // 读取TIA输出电压 const int sampleInterval 10; // 采样间隔毫秒 const int pulseWidth 500; // 方波高电平/低电平持续时间毫秒 unsigned long previousSampleTime 0; bool ledState HIGH; unsigned long previousPulseTime 0; void setup() { pinMode(ledControlPin, OUTPUT); digitalWrite(ledControlPin, ledState); // 初始状态 Serial.begin(115200); // 使用较高的波特率以保证实时性 previousPulseTime millis(); } void loop() { unsigned long currentTime millis(); // 1. 控制LED状态翻转实现1Hz方波周期2*pulseWidth if (currentTime - previousPulseTime pulseWidth) { ledState !ledState; digitalWrite(ledControlPin, ledState); previousPulseTime currentTime; // 每次状态变化时可以发送一个标记方便上位机同步可选 // Serial.println(STATE_CHANGE); } // 2. 定时采样传感器数据 if (currentTime - previousSampleTime sampleInterval) { int sensorValue analogRead(sensorPin); // 读取原始ADC值0-1023 float voltage sensorValue * (5.0 / 1023.0); // 转换为电压值0-5V // 打包数据当前时间戳(ms), LED状态, ADC原始值, 计算电压 Serial.print(currentTime); Serial.print(,); Serial.print(ledState); Serial.print(,); Serial.print(sensorValue); Serial.print(,); Serial.println(voltage, 4); // 电压值保留4位小数 previousSampleTime currentTime; } }这段代码的关键点同步机制ledState变量明确记录了采样瞬间LED是亮还是灭。上位机可以根据这个标志将数据流分离成“有光照”和“无光照”两组。数据打包将时间戳、状态、原始值、换算电压一并发送方便上位机进行后续处理和回溯。采样率sampleInterval设为10ms即100Hz的采样率对于1Hz的调制信号来说足够了一个周期内能采100个点。你可以根据信号变化速度调整。实时性使用millis()进行非阻塞定时避免使用delay()保证采样和控制的时序精准。实操心得串口通信的稳定性很重要。除了设置高波特率115200确保电脑端Scilab的串口设置与之匹配外在数据格式中加入逗号分隔和换行符能让Scilab的csvRead或fscanf函数更容易解析。另外首次上电时Arduino会复位可能会发送一些乱码Scilab程序最好有丢弃初始若干行数据的处理逻辑。5. Scilab上位机程序开发从数据接收到可视化分析Scilab程序是整个项目的大脑负责通信、数据处理、计算和显示。我将它分成几个功能模块来编写。5.1 串口通信与数据接收模块首先我们需要在Scilab中建立与Arduino的串口连接。Scilab的serial工具箱提供了相关函数。// 初始化串口 com_port COM3; // 根据你的实际端口修改Linux/Mac下可能是 /dev/ttyUSB0 baudrate 115200; timeout 10; // 超时时间秒 // 尝试打开串口 try h serial(com_port, baudrate, timeout); disp(串口打开成功: com_port); catch disp(无法打开串口: com_port); abort; end // 清空可能的缓冲区 serialflush(h); // 设置一个图形窗口用于实时显示 figure(1); clf(); ax gca(); ax.data_bounds [0, 0; 60, 5]; // 初始坐标轴范围60秒0-5V xtitle(实时紫外反射信号, 时间 (s), 传感器电压 (V)); plot_handle plot([], [], b-); // 创建空的绘图句柄5.2 实时数据绘图与信号处理接下来是主循环不断读取串口数据解析并实时绘图。同时我们需要分离LED亮/暗时的信号。// 初始化数据存储 time_list []; voltage_list []; led_state_list []; signal_on []; // 存储LED亮时的电压 signal_off []; // 存储LED灭时的电压 time_on []; time_off []; max_data_points 5000; // 最大存储数据点数防止内存溢出 read_interval 0.01; // 读取间隔约等于Arduino的采样间隔 disp(开始采集数据... (按ESC键停止)); while %t // 非阻塞检查按键按ESC退出循环 if xclick() ~ [] then c xget(lastkey); if c 27 then // ESC键 break; end end // 尝试读取一行数据 [num_read, data_str] mgetl(h, 1); // 读取一行 if num_read 0 then // 解析逗号分隔的数据 data_items strsplit(data_str, ,); if length(data_items) 4 then t evstr(data_items(1)); // 时间戳ms state evstr(data_items(2)); // LED状态 (1ON, 0OFF) voltage evstr(data_items(4)); // 电压值 // 转换为秒并从0开始计时 if length(time_list) 0 then t0 t; end t_rel (t - t0) / 1000.0; // 存储数据 time_list [time_list; t_rel]; voltage_list [voltage_list; voltage]; led_state_list [led_state_list; state]; // 根据状态分离信号 if state 0.5 then // LED亮 signal_on [signal_on; voltage]; time_on [time_on; t_rel]; else // LED灭 signal_off [signal_off; voltage]; time_off [time_off; t_rel]; end // 保持数据量不超过上限 if length(time_list) max_data_points then time_list(1) []; voltage_list(1) []; led_state_list(1) []; // 这里简化处理实际可能需要更精细的清理 end // 实时更新绘图每50个点更新一次以提高效率 if modulo(length(time_list), 50) 0 then plot_handle.data [time_list, voltage_list]; ax.data_bounds [min(time_list), min(voltage_list)-0.1; max(time_list)1, max(voltage_list)0.1]; replot(); // 重绘图形 end end end sleep(read_interval * 1000); // 短暂休眠模拟实时 end // 采集结束关闭串口 close(h); disp(数据采集停止。);5.3 反射率计算与校准采集到足够的数据后比如测量一个标准白板和一个样品我们需要计算反射率。反射率R定义为样品反射信号强度与参考标准反射信号强度之比。由于我们测量的是电压且已经通过同步检测扣除了本底所以R_sample (V_sample_on - V_sample_off) / (V_standard_on - V_standard_off)这里V_sample_on和V_sample_off是测量样品时LED亮和灭阶段的平均电压。V_standard_on和V_standard_off是测量标准白板通常认为其反射率接近100%时的平均电压。在Scilab中实现// 假设我们已经采集并存储了标准白板的数据 // std_on_voltages, std_off_voltages // 以及样品的数据 // sample_on_voltages, sample_off_voltages // 计算平均净信号电压 std_net_signal mean(std_on_voltages) - mean(std_off_voltages); sample_net_signal mean(sample_on_voltages) - mean(sample_off_voltages); // 计算反射率 reflectance sample_net_signal / std_net_signal; disp(计算出的反射率为: string(reflectance*100) %); // 绘制标准板和样品的信号对比图 figure(2); clf(); subplot(2,1,1); plot(time_std, std_on_voltages, g-, time_std, std_off_voltages, r--); xtitle(标准白板信号, 时间 (s), 电压 (V)); legend([LED ON, LED OFF]); subplot(2,1,2); plot(time_sample, sample_on_voltages, b-, time_sample, sample_off_voltages, k--); xtitle(样品信号, 时间 (s), 电压 (V)); legend([LED ON, LED OFF]); // 可以绘制反射率随时间的变化如果做动态监测 if length(reflectance_over_time) 1 then figure(3); plot(time_reflectance, reflectance_over_time, m-, LineWidth, 2); xtitle(反射率变化曲线, 时间 (s), 反射率); xgrid(); end注意事项标准白板的选择很重要。理想情况下应使用光谱级漫反射白板如硫酸钡或聚四氟乙烯板但成本很高。对于本项目的定性或半定量应用可以使用一块崭新的、平整的陶瓷片或高质量的打印白纸作为临时参考。但要记住这会在绝对反射率数值上引入系统误差不过对于比较不同样品的相对反射率差异影响不大。6. 系统集成、校准与性能测试硬件和软件都准备好后需要将它们集成起来并进行系统的校准和测试这是确保测量可信度的关键一步。6.1 机械结构与光路搭建一个稳定的测量环境至关重要。你需要制作一个简单的暗箱来隔绝环境光。可以用一个不透明的盒子如涂黑的纸盒或塑料盒在内部固定LED和光电二极管。两者的相对位置和角度需要仔细调整。角度问题标准的反射测量通常采用45°/0°或0°/45°几何条件前者指光源45度入射探测器垂直接收后者相反。这能避免镜面反射光进入探测器主要测量漫反射。我们可以将LED以45度角对准样品中心光电二极管垂直对准同一点。可以使用3D打印件、乐高积木或精心裁剪的泡沫板来固定角度。距离固定LED和探测器到样品表面的距离必须固定并且在不同测量间保持一致。任何距离变化都会导致光强按平方反比定律变化引入巨大误差。样品台需要一个平整的、可重复放置样品的平台。平台表面最好是黑色吸光材料以减少杂散光。6.2 系统校准流程校准的目的是建立ADC读数或电压值与实际光强或反射率之间的定量关系。暗噪声测量盖上暗箱关闭LED或设置LED状态为常灭采集一段时间如30秒的数据。计算输出电压的平均值和标准差。这个平均值就是系统的“暗电压”偏移标准差代表了系统的电噪声水平。理想情况下这个偏移值应该很小且稳定。我们可以在后续数据处理中统一减去这个暗电压。线性度测试由于我们使用了恒流驱动改变LED亮度比较麻烦。一个替代方法是使用已知不同反射率的标准灰度卡摄影用的那种。测量灰度卡上不同灰阶区域如黑、深灰、中灰、浅灰、白的净信号电压。以白色区域的信号为100%反射率参考绘制其他灰阶的理论反射率通常灰度卡会提供与测量信号电压的关系图。检查它们是否成良好的线性关系。如果线性度差可能是TIA电路饱和了或者光电二极管工作在非线性区需要调整R_f或LED驱动电流。重复性与稳定性测试对同一个样品如标准白板进行连续多次测量每次测量间隔几分钟中间重新放置样品。计算多次测量结果的反射率值的标准差和相对标准偏差RSD。一个好的系统RSD应该小于1-2%。这考验的是机械结构的稳定性、光源和探测器的热稳定性。6.3 实际样品测量演示我用自己的设备测试了几种常见材料A4打印纸作为临时参考白板。黑色电工胶布预期反射率极低。一片旧电路板阻焊层为绿色观察其紫外反射特性。涂抹了防晒霜的载玻片防晒霜应吸收UVA反射率应低于干净的载玻片。测量步骤将A4纸固定在样品台运行程序采集30秒数据保存为参考数据。依次更换为其他样品每个样品采集30秒数据。在Scilab中分别处理每个数据文件计算相对于A4纸的反射率。结果与预期基本相符黑色胶布反射率约3-5%绿色电路板反射率约15%干净载玻片反射率约8%主要是表面反射涂了防晒霜的载玻片反射率降至4%左右。这个趋势是合理的证明了设备的有效性。7. 常见问题、故障排查与优化技巧在实际搭建和调试过程中你肯定会遇到各种问题。下面是我总结的一些常见坑点和解决方案。7.1 信号噪声大、跳动严重可能原因1电源噪声。使用电脑USB或开关电源供电会引入大量高频噪声。排查用示波器观察TIA输出端和Arduino的5V、3.3V电源轨。解决为模拟电路部分尤其是TIA运放增加LC滤波或使用线性稳压器如LM7805单独供电。在运放电源引脚紧贴芯片处并联0.1μF和10μF电容。可能原因2电路布局不佳引入干扰。排查检查光电二极管到运放的引线是否过长是否靠近数字线路或电源线。解决使用屏蔽线连接光电二极管并尽量缩短走线。将TIA电路部分用铜箔或金属罩屏蔽起来。可能原因3环境光泄露。排查在LED熄灭状态下用手完全遮住暗箱观察信号是否显著下降。解决加强暗箱的密封所有接缝处用黑色电工胶布贴好。确保LED和探测器的安装孔大小刚好没有多余缝隙。可能原因4软件滤波不足。解决在Scilab数据处理中可以对采集到的电压序列进行滑动平均滤波或低通数字滤波。例如使用smooth函数进行移动平均。7.2 信号饱和或量程不足现象测量白板时电压输出接近5V或0V取决于TIA是反相还是同相或者测量黑色样品时电压变化极小。原因反馈电阻R_f选择不当。解决更换R_f。如果饱和减小R_f例如从1MΩ换为100kΩ如果信号太小增大R_f。最方便的方法是使用一个1MΩ的多圈电位器作为R_f调试到最佳点后用相同阻值的固定电阻替换。7.3 串口数据丢失或乱码可能原因1波特率不匹配。解决检查Arduino代码中的Serial.begin()速率与Scilab中serial()函数设置的波特率是否完全一致。可能原因2Scilab读取速度跟不上。解决增加Scilab程序中的read_interval或者减少Arduino的发送频率增大sampleInterval。也可以在Arduino端设置一个缓冲区只有当上位机请求时才发送一批数据而不是持续高速发送。可能原因3串口被其他程序占用。解决关闭Arduino IDE的串口监视器或其他可能占用COM口的软件。7.4 反射率计算结果不合理如大于1或为负可能原因1本底扣除错误。排查分别检查V_on和V_off的值。V_on应该始终大于V_off。如果V_off非常大可能是环境光泄露严重。解决确保同步检测机制工作正常ledState标志被正确解析。加强暗箱遮光。可能原因2标准白板选择不当或污染。解决使用新鲜、干净、平整的白板。如果使用白纸确保每次测量都用全新的区域因为纸张容易变黄或沾染灰尘。可能原因3样品放置位置或角度不一致。解决制作一个样品定位夹具确保每次样品都放在完全相同的位置和角度。7.5 高级优化技巧温度补偿LED的光输出和光电二极管的灵敏度都会随温度漂移。对于需要长时间高精度测量的场合可以在靠近LED和二极管的地方放置一个温度传感器如DS18B20Arduino同时读取温度数据并发送给Scilab。Scilab根据预先标定的温度-光强修正曲线对数据进行补偿。多波长测量如果你有兴趣可以购买不同波长的紫外LED如295nm, 310nm, 340nm, 365nm, 385nm。通过Arduino控制一个多路开关轮流点亮它们配合宽带紫外探测器就能构建一个简易的多波长紫外反射计获得粗糙的“光谱”信息。自动量程切换在TIA电路中使用多个不同阻值的反馈电阻并通过模拟开关如CD4051由Arduino控制切换。当信号太强时自动切换到小电阻档位信号太弱时切到大电阻档位从而扩展动态范围。使用外部基准提升ADC精度Arduino Nano的ADC默认使用系统5V作为参考电压噪声较大。可以接入一个外部精密基准电压源如REF50252.5V到AREF引脚并在代码中设置analogReference(EXTERNAL)。这能显著提高ADC的稳定性和精度。这个项目从构思到实现最深的体会就是“细节决定成败”。一个不起眼的电源噪声、一丝环境光的泄露、一个不稳定的机械结构都会在最终的信号上被放大。它不仅仅是一个电子制作项目更是一次完整的测量系统实践涵盖了传感器技术、模拟电路设计、数字采集、信号处理和软件编程。当你看到屏幕上那条随着样品更换而跳动的曲线并计算出有意义的反射率数值时那种成就感是无可替代的。希望这份详细的指南能帮你少走弯路成功搭建起你自己的紫外反射计。如果在实践中遇到新的问题欢迎随时交流讨论很多巧妙的解决方案都是在解决具体问题中诞生的。

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

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

免费获取报价