news 2026/9/28 1:35:08

Arduino声音采集实战:用MAX4466驻极体麦克风搭建可视化波形检测系统

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Arduino声音采集实战:用MAX4466驻极体麦克风搭建可视化波形检测系统

直接说结论:这个项目做起来比你想的简单,而且它真的是少数几个能让你在半小时内同时获得"看得见的物理量"和"听得见的反馈"的入门项目之一。我去年给社团新生带活动时用的就是这套方案——一块Arduino Uno、一个几块钱的驻极体麦克风模块、几根杜邦线,最后每个人都能在串口绘图器里看到自己说话声的波形起伏。文章会从器件原理讲到接线、代码、数据调理,再到我在实际带项目时踩过的几个典型的坑,全程按"从零开始"的节奏来,只要你有一块Arduino和基础动手能力,跟着一步步走就能复现。

1. 为什么用驻极体麦克风:器件原理与选型逻辑

1.1 驻极体麦克风到底是个什么东西

驻极体麦克风(Electret Condenser Microphone)本质上是电容麦克风的一种,核心结构是一片带有永久电荷的驻极体薄膜和一个背极板。声音让振膜振动时,两极板间距变化,电容容量跟着变化,而电荷量基本不变,于是两极板之间的电压就会发生变化。问题在于,这个电容式结构的输出阻抗非常高,高到没法直接接ADC引脚去读,所以封装时厂商标配在里面内置了一个JFET,当作阻抗变换器(源极跟随器),把高阻抗信号降下来。这也是为什么你在模块背面能看到一个三脚元件——它本质上是个场效应管,不是运放。

很多新手拿到模块后会问:为什么麦克风输出不是"没有声音就0V,有声音就3.3V"?因为驻极体模块的输出是交流性质的,没有声音时它稳定在直流偏置电压附近。比如MAX4466这类调理模块,静态输出通常被设计在VCC/2附近,声音再让这个值上下波动。这是个非常关键的理解点,后面写代码做音量检测时,你处理的其实是"偏离静态基线的大小",而不是"绝对电压高低"。

1.2 四种常见模块对比,别买错了

市面上能买到的驻极体相关模块大致有四类,很多新手第一次搜"Arduino 声音模块"会被这些名字搞晕,这里直接给你一个我实测过的对比表格。

模块类型输出形态适合做什么不适合做什么
裸驻极体麦克风头(圆柱形金属壳)依赖偏置电路,模拟小信号定制电路、拍PCB时自己搭直接接Arduino,信号太弱
MAX4466 驻极体模块模拟信号,静态偏置VCC/2,增益可调声音波形采集、音量检测、FFT输入高保真录音(带宽有限)
MAX9814 模块模拟信号,带AGC自动增益控制语音录音、声音忽大忽小的场景需要稳定幅值做阈值判断的场景
LM393 声音检测模块数字电平输出+模拟输出拍手开关、声控灯、触发类应用想看到真实声音波形?很难

这里多说一句MAX9814的AGC问题。自动增益控制听起来很高级,但它会把微弱声音放大、强声音压下,结果就是你的ADC数据几乎没有动态范围可言。我第一版方案用过MAX9814做音量计,结果发现轻声说话和用力拍手在数据上区别不大,反而很难设定阈值。所以如果是跟我一样做"声音采集系统"、想看到真实响度变化,MAX4466的固定增益更合适,它的电位器能让你手动调灵敏度,调整过程本身就是一种学习。

1.3 新人选型建议和购买提醒

我的建议是:第一套系统直接买MAX4466模块(模块上的标记通常是MAX4466,然后有三个引脚VCC、GND、OUT)。注意别买成Microphone Amplifier板子上焊的是MAX9814的那种,买前看商品描述里的芯片型号。

另外提一个很容易踩的坑:很多商家会把驻极体咪头俗称成"麦克风传感器",结果发过来是LM393的比较器小板,用起来倒是能响,但你读到的A0口电压基本是方波,完全没法还原声音强度变化。买的时候不要只看标题,要看实物图上的芯片丝印,MAX4466模块的板载电位器是蓝色的小方块,LM393模块则是两个蓝色电位器。

2. 硬件接线与那些不讲清楚就会翻车的细节

2.1 物料清单

这是整套系统的最低配置清单,全部加起来成本能控制在几十块钱以内:

元件规格/型号数量备注
开发板Arduino Uno R31块兼容板即可
麦克风模块MAX4466 驻极体模块1块核心采集器件
LED5mm任意颜色3~5个做音量指示
电阻220Ω3~5个LED限流
面包板400孔1块方便扩展
杜邦线公对公/公对母若干若干推荐多买几种

如果你手头只有裸的驻极体麦克风,也可以搭一个最简单的偏置电路:咪头一端接VCC,另一端通过10kΩ电阻接到GND,然后把这一端同时用一根线接到Arduino的A0口,再在咪头和A0之间接一个1μF左右的电容也可以工作,但效果和稳定性不如MAX4466模块。建议第一版别省这十几块钱。

2.2 接线图,逐脚对照

把MAX4466模块和Arduino Uno R3接起来非常直接:

  • VCC→ Arduino的5V
  • GND→ Arduino的GND
  • OUT→ Arduino的A0

LED部分如果想顺便做音量指示,可以这样接:每个LED正极串联220Ω电阻,然后分别接到D3、D4、D5等引脚,负极统一接GND。这里注意:LED的阳极(长脚)接数字引脚,阴极(短脚)通过电阻接地,不要接反。

提示:Arduino Uno的模拟引脚A0到A5都是可以作为数字引脚使用的,但反过来不行。如果你本来想把OUT接在D0上——不行,D0/D1是串口通信引脚,接了会导致上传程序时报错或输出数据异常。

2.3 供电、共地和信号完整性

河豚原则:一切电信号,参考的都是自己的地。如果麦克风模块和Arduino没有共地,OUT引脚就是一个悬空的电压,读出来的模拟量只能是噪声乱跳。这句话听起来像废话,但我在社团活动时至少见过三次因为"明明接了VCC和OUT,忘了接GND"导致串口输出一直恒定的同学。检查顺序永远先看共地。

再说供电。MAX4466的供电范围是2.4V到5.5V,吃的是Arduino的5V输出,一般情况下没问题。但要留意一个极端情况:如果你用USB口的电流已经同时给ESP8266、舵机、多个传感器供电,5V线的压降可能会让模块实际电压掉到4V以下,这种时候模块输出的静态偏置点会漂移——静态值不再是512附近,而是更低或更高。表现在串口绘图器里就是你对着它喊话,波形能变但整体基线忽高忽低。排查方法很简单:用万用表量模块VCC和GND之间的电压,如果比5V低太多,换个独立供电口再试。

另一个常被忽视的细节是:面包板和杜邦线的接触电阻。麦克风信号电平虽然是模拟的,但它在模块里已经过了放大,幅度并不小,所以对线路噪声没那么敏感;但如果你用的杜邦线内部已经折断了,引脚接触不良会导致信号时断时续——这在后面踩坑部分我会具体讲排查思路,这里先提醒一句:插杜邦线时不要只捏线头,要捏住插针部分插到底,线松没松用指头轻轻拨一下就知道。

3. 从模拟电压到稳定读数:代码实现线程

3.1 最基础的读取代码长什么样

先别想着滤波、FFT、音量柱这些花活儿,第一步要做的只有一件事:把A0口的模拟电压读进电脑,用串口打印出来,然后用串口绘图器看看波形。代码如下:

void setup() { Serial.begin(9600); } void loop() { int sensorValue = analogRead(A0); Serial.println(sensorValue); delay(10); }

上传后打开"工具 → 串口绘图器"(注意是绘图器,不是串口监视器),然后对着麦克风吹口气或者说话。你会看到一条在512上下抖动的曲线,说话时抖动幅度变大。如果你看到的是4095这种数字,说明你用了ESP32然后看的是12位ADC,等下再说这个;如果看到的是恒定512左右没有任何反应,大概率是接线或模块问题,跳到第5章排查。

这段代码看似简单,但里面藏了一个关键点:delay(10)决定了采样频率。10ms一个点,大约100Hz的采样率,对于"音量检测"来说勉强够用,但你不可能还原出说话声的细节,因为语音的基频一般在100到300Hz,想采集完整语音至少需要几kHz的采样率。所以请提前想清楚:你的系统是用来做“响度检测”还是“波形录音”。前者,delay(10)够了;后者,你需要把delay去掉或换用定时器中断,后面进阶部分会展开。

3.2 为什么要校准基线,不能直接拿原始值当音量

你现在看到的是500多、600多这样波动的绝对值。但不同板子、不同模块、不同供电电压下,静态基线可能不是512,而是498、530,甚至460。如果直接把原始值拿来做"超过700就触发",你的系统在另一块板子上可能完全不敏感,或者还没说话就误触发。

我常用的做法是动态基线校准。读取程序启动后先花500毫秒采集50个点,取平均值作为静态基线baseline:

int baseline = 0; void setup() { Serial.begin(9600); for (int i = 0; i < 50; i++) { baseline += analogRead(A0); delay(10); } baseline /= 50; } void loop() { int raw = analogRead(A0); int level = abs(raw - baseline); Serial.println(level); delay(10); }

这个level就是"偏离基线的大小",代表当前声音的幅度。没有声音时它接近0,有声音时变大。这个值比原始ADC值好用得多,因为它消除了直流偏置的影响。

3.3 加一点峰值检测和阈值判断

要让它变成能真正触发动作的"声音采集系统",还需加一个判断逻辑:在滑动窗口内检测最大偏移量,超过阈值就做某个动作。这个动作可以是点亮LED、串口协议上报、控制舵机。

int threshold = 50; // 根据实测调整 int peak = 0; void setup() { Serial.begin(9600); for (int i = 0; i < 50; i++) { baseline += analogRead(A0); delay(10); } baseline /= 50; pinMode(LED_BUILTIN, OUTPUT); } void loop() { int raw = analogRead(A0); int[] window[10]; // 每10个采样取一个最大值 for (int i = 0; i < 10; i++) { window[i] = abs(analogRead(A0) - baseline); delay(2); } peak = window[0]; for (int i = 1; i < 10; i++) { if (window[i] > peak) peak = window[i]; } if (peak > threshold) { digitalWrite(LED_BUILTIN, HIGH); delay(100); digitalWrite(LED_BUILTIN, LOW); } Serial.println(peak); }

这个滑动窗口的思路很朴素,但它解决了一个实际问题:单次采样很容易被环境噪声的尖峰干扰。试想一下,你拍手产生的声压到麦克风后,模块输出一路大偏移,紧接着还有反射声波造成的尾音,但如果你正好在两次拍手的间隙某一次采样时值很大,等于每次都各管各的,就会造成"同样拍手,有时触发有时不触发"。窗口取峰值就好比"你听一个人说话,不会因为他一句话里的一个字顿了一下就判听不到"——你取的是整句话的响度包络。

注意:上面代码里的threshold需要根据你的环境实测。我拿到的MAX4466模块,默认增益下,安静房间的底噪偏移大约在10到20之间,正常说话在40到80之间,拍手能到200以上。夜间实验室开着空调可能把底噪顶到50以上,阈值自然也得往上调。

3.4 关于随机数热词里"上传项目出错"和"1.8.6如何下载调试"的顺带说明

排查过程中肯定有人会遇到上传失败。Arduino IDE上传出错时,先看最底部的错误日志,最常见的两种:一种提示avrdude: stk500_recv(): programmer is not responding,另一个是port busy。前者大概率是板子型号选错或者串口端口没选对,后者是串口被串口监视器占用着导致上传不进去——IDE默认上传前会关掉监视器,但如果你同时开了多个窗口占用同一个端口就会出现。所以先关掉串口监视器,再重新拔插板子,再检查工具→端口里选的是不是"COM3 (Arduino/Genuino Uno)"这种带板子名的选项而不是蓝牙设备,这基本能解决九成问题。

"Arduino 1.8.6 如何下载调试"这个搜索词提示很多人还在用老版本IDE,其实是没必要的,直接去arduino.cc官网下最新的2.x系列即可,目前最新版本在代码补全、中文显示、串口监视器体验上比1.8.x好很多。不过要提醒:2.x的图形界面变化很大,很多人搜"arduino 2.3为什么没有代码补全"其实就是没找到设置入口——新版默认需要等索引加载完,代码补全才生效,刚装的软件第一次打开会有个初始化过程,放一会儿就好,不是软件坏了。

4. 让声音可见:串口绘图与LED指示

4.1 串口绘图器就是你的临时示波器

Arduino IDE自带的串口绘图器可能是最被低估的调试工具。它不是万用表那种冷冰冰的数字列表,而是实时把数据画成波形,就像一台简易示波器。你写完第三节的代码,打开串口绘图器(在"工具"菜单里),对着麦克风说话,就能看到一条波线在上下伸缩。很多人第一次看到自己说话带来的波形时都会觉得挺神奇——这其实就是最简单的"把声音可视化"的成果。

串口绘图器支持绘制逗号分隔的多条线,比如同时打印原始值和偏移值,可以这样:

Serial.print(raw); Serial.print(","); Serial.println(level);

然后绘图器上会出现两条不同颜色的线。这招在调试时特别有用:你可以一眼看出原始值的基线在不在512附近,偏移值有没有正常响应,不用手动换算就能定位是模块的问题还是代码逻辑的问题。

4.2 做一个三档LED音量计

有了稳定的level值,做LED音量计就很简单了。把3个LED接在D5、D6、D7上,设定两个阈值,声音超过低阈值亮一盏灯,超过中阈值亮两盏,超过高阈值亮三盏:

int ledPins[] = {5, 6, 7}; int low = 30, mid = 60, high = 120; void setup() { Serial.begin(9600); for (int i = 0; i < 50; i++) { baseline += analogRead(A0); delay(10); } baseline /= 50; for (int i = 0; i < 3; i++) { pinMode(ledPins[i], OUTPUT); } } void loop() { int raw = analogRead(A0); int level = abs(raw - baseline); int count = 0; if (level > low) count = 1; if (level > mid) count = 2; if (level > high) count = 3; for (int i = 0; i < 3; i++) { digitalWrite(ledPins[i], i < count ? HIGH : LOW); } Serial.println(level); delay(5); }

因为这个循环本身就跑得很快(每次约5毫秒),LED会跟着你的语音动态闪动,亮度变化响应很直接。这里有个小技巧:delay(5)替代了之前用的delay(10),LED的亮灭更跟手;但如果数据太跳,反而会显得闪得杂乱,建议从delay(10)开始试。

4.3 阈值调校的实操方法

阈值不是一次就能定准的。我建议这样调:先串口打印level值,在安静环境下读10秒,取能看到的最大值加一点余量作为low;然后正常说话,读说话时能达到的平均值附近作为mid;拍手能达到的值,再略低一点,作为high。这样三个阈值就是有梯度的,不是拍脑袋设的。

如果你调完发现"拍手灯都不亮":先看是不是阈值太高了,把high降到80甚至50试试;如果"安静时灯也亮",那就是level的底噪太大了,要么把阈值调高,要么换个更高增益的模块。说到底,环境噪声是没法完全滤掉的,做声音触发类应用本身就是"平衡灵敏度与误触发的艺术"。

5. 踩坑实录:三个典型现象的完整排查链路

5.1 现象一:串口数据恒为0或恒为1023,说话没有任何反应

这是我见过最多的问题,没有之一。完整链路是这样的:

一位同学报错说串口输出一直是1023,动嘴完全没变化。我的排查顺序是:

  1. 先问他OUT接在哪个引脚,他说A0。好,排除引脚问题。
  2. 让他把手放在模块上,触摸咪头外壳(注意是金属壳),如果读数变化,说明信号链路是通的——他反馈"有反应但很小",说明模拟通道OK。
  3. 既然信号链路通,再问供电。他说用的是面包板的5V排,我让他万用表量VCC和GND之间电压——只有3.2V。原因找到了:他的面包板电源轨从一根杜邦线接到Arduino 5V,但那根杜邦线内部折断了,接触电阻大,一接负载电压就掉到3.2V。而MAX4466虽然能在2.4V工作,但输出摆幅严重受限,几乎顶在VCC附近。换一根杜邦线后问题消失。

从这个案例能提炼出一个排查方法论:模电问题先查供电,再查信号链路,最后才怀疑代码。逻辑其实很朴素——单片机只要代码烧进去了基本就不会"错",哪怕逻辑差,它仍然在忠心执行,输出不符合预期十有八九是硬件没给到它正确输入。如果你一上来就怀疑代码、反复改阈值,大概率是白费功夫。

另一种"恒为0"的情况更隐蔽:之前提过,A0口不是0号数字口,很多人把OUT接到了标着"D0"的引脚上。D0和D1是串口收发引脚,不能用来做模拟输入,接了之后不但读不到数据,还把上传程序都搞乱了。检查方法就是看到接在D0/D1上就先换掉。

5.2 现象二:波形有反应但毛刺和跳变特别大

这个问题多出现在环境干扰强的实验室。表现为:安静时level原本应该在20附近,但总出现无视规律的大尖峰,串口绘图器上能看到一条细细的线突然冲到120又掉回去。

排查链路:

  1. 先关掉附近的开关电源、手机充电器,看波形成不变化。
  2. 把USB线从电脑换到充电宝供电试试。你会发现读数稳定很多——电脑USB口的地和实验室大功率设备的零线之间有干扰电压,通过USB屏蔽层串进了Arduino的GND,最后在A0口体现出来了。
  3. 如果换供电还是不行,就在MAX4466模块的VCC和GND之间并一个100μF电解电容和0.1μF瓷片电容,做电源去耦。

这个问题给我们的教训是:模拟采集系统的"干扰"很多时候不是电磁波直接打到信号线上,而是从电源线进来的。所以给模块单独滤波、单独供电,比在代码里写一百行滤波算法更治本。

5.3 现象三:能触发但总是慢半拍

代码是"检测到声音→点灯→灭灯",但总觉得反应有300毫秒左右的延迟。这种问题就纯在代码层了。常见原因有两种:

第一种是故意保留的delay过多。比如你在loop里先delay(100)处理别的逻辑,导致声音信号需要等待循环运行到读麦克风那一步才能被读到。解决方法是尽量减小delay,非阻塞编程用millis()代替delay。第二种是我自己犯过的错:在循环里用了Serial.begin(9600),波特率低,打印一条数据就要花很长时间,后来把波特率提到115200,明显感觉响应变快了。

第二种是滤波窗口太长,滑动平均数组设了50个点,每个点delay(10),那我实际看到的就是0.5秒前的平均结果,反应当然慢。改成10个点甚至5个点,牺牲一点稳定度换取响应速度。

5.4 几个"看起来没用但很值钱"的调试习惯

除上述排查,我再分享三个在带项目时积累的调试习惯。第一,串口打印别打印所有数据,只打印核心变量,否则会降低采样频率。第二,调试时把阈值、采样窗口长度等参数定义成常量,改参数时只改一处,不用到处翻代码。第三,如果你调完一段功能就把串口监视器关了,下次打开会停留在上次的Serial.begin波特率而出现乱码——这个坑每次都能坑到人,开了监视器显示乱码,先检查波特率,不是代码坏了。

6. 更进一步:从采集到应用

6.1 声音控制舵机,做一个"声控小玩意儿"

基础采集跑通之后,下一步最自然的方向就是拿声音去控制执行器。比如结合热词里常见的"arduino控制舵机"——用拍手控制SG90舵机转动一个角度。代码不需要改太多,把第3节里的触发动作从点LED换成转动舵机就行:

#include <Servo.h> Servo myServo; int threshold = 120; int pos = 0; void setup() { myServo.attach(9); // ... 其他初始化不变 } void loop() { // ... 采集和峰值检测逻辑 if (peak > threshold) { pos = (pos == 0) ? 90 : 0; myServo.write(pos); } }

舵机的意义在于让你直观感受到"声音采集系统"不只是显示数据,而是一个能对外界声音作出反应的交互系统。如果加上一定延时和状态机,还能做出"拍两次手前后移动"之类的玩法,网上这类创意作品很多,完全可以挑一个来复刻。

6.2 用ESP32替换Uno,把声音数据传到局域网

Uno的处理能力对声音采集来说是够用的,但它的硬伤是没有网络能力。热词里频繁出现"arduino esp32"和"esp32 arduino",说明很多人在采集到数据之后,下一步就是想远程看数据。ESP32的ADC是12位(0到4095),而且引脚定义和Uno不同,接线时要注意几件事:

  • 不要接在GPIO 34-39上,这些引脚是纯输入引脚,没有内部上拉,但读取没问题;
  • ESP32的ADC在电压超过约3.1V时会失真,虽然模块输出可能到3.3V,但最好用分压或者选择衰减比合适的ADC引脚(在代码里用analogSetPinAttenuation设置);
  • 代码里的baseline、level、阈值都要重新校准,因为12位ADC的分辨率比Uno高了一倍,同样的声音对应的数值范围完全不同。

配一个最简单的HTTP服务器,ESP32开热点或连局域网,手机浏览器访问IP就能看到实时的声音波形数据,这样你手里的"简易声音采集系统"就从玩具变成了一个微型环境监测节点。

6.3 不着急买硬件的验证方式:Wokwi仿真

如果你暂时手里没有板子,或者想边写代码边验证逻辑,Wokwi平台是很好的选择。它支持在浏览器里拖一个Arduino Uno、拖一个麦克风模块(有现成的驻极体麦克风组件),连上代码就能跑。我用它给远程的同学讲过课,体验下来最大的优点是:接线错了可以随便改,不用担心烧板子;而且它的仿真里可以直接模拟声音信号变化,省去拿嘴吹麦克风的尴尬。不过要提醒:仿真终归是仿真,ADC的实际噪声、供电波动这些问题它是模拟不出来的,所以真机调试那一步还是不能省。

6.4 如果你想把方案做成正式产品

做完小样之后,如果你想把麦克风模块和主控整合到一块板子上,就需要画PCB了。热词里"arduino 立创实战派s3"指向的就是国产主控板和立创EDA这个画板工具。画板时驻极体麦克风周围要注意几个点:麦克风拾音孔要朝外,不要被电池或外壳挡住;MAX4466的反馈电阻和电容要靠近芯片;模拟部分和数字部分地线单点接地。这些是从模块搭跳到自制板最可能遇到的问题,第一版打板回来先别急着焊模块,把板子的供电和地网络用万用表测一遍再动手。

另外如果你想要更高保真的"录音"功能,Uno的ADC采样率是个硬瓶颈。这边给个思路:用I2S接口的麦克风模块(如INMP441)配合ESP32,采样率能到44.1kHz,SD卡存储或WiFi上传后就能做真正的语音记录装置,往语音识别方向扩展。这已经超出入门范畴,但方向值得明确——声音采集系统往下走的路径很宽,从"检测"到"录音"再到"识别",每一步都对应不同的硬件选型。

在我自己折腾这个项目的过程中,最有成就感的一刻不是代码跑通的时候,而是把LED音量计放在桌上,放一段音乐,看着三个灯跟着节奏跳动,旁边放着串口绘图器的实时波形。那种把空气中看不见的振动变成一个可观察、可控制、可反馈的过程,真的很有魔力。希望这篇文章能帮你少走点弯路,顺利把第一版声音采集系统跑起来。

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

STM32F407用DCMI接口驱动12位并口ADC,配合DMA双缓冲实现高速采集

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/28 1:34:27

DoCAN到DoIP迁移:车载UDS诊断协议栈重构实战解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/28 1:33:59

拆解16.8元蓝牙音乐灯音箱:一颗CK6865L主控如何扛下所有

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/28 1:33:58

KettleWeb 实战:从零搭建 Web 版 Kettle 数据集成平台

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/28 1:33:58

Kubeedge 1.13.1 部署实践:CentOS 7.9 + K8s 1.22.17 + MetalLB 全流程

简介&#xff1a;面向 Kubeedge 初学者的完整部署资源包&#xff0c;聚焦 Centos7.9 系统上基于 kubeadm 搭建的 Kubernetes v1.22.17 集群&#xff0c;安装 Kubeedge v1.13.1 并借助 MetalLB 负载均衡器实现组件对外访问。资源共 15 个文件&#xff0c;压缩包约 474.64MB&…

作者头像 李华