news 2026/9/27 1:08:35

Wokwi本地仿真:VS Code+Docker+Arduino CLI零成本搭建开发板环境

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Wokwi本地仿真:VS Code+Docker+Arduino CLI零成本搭建开发板环境

你是不是也以为,想学开发板就得先买一块板子?其实完全不用。Wokwi这个硬件仿真平台,能在浏览器里把Arduino、ESP32、树莓派Pico这些板卡连同LED、传感器、屏幕一起模拟出来,代码写对了,虚拟板卡立刻就能跑给你看。但我在实际用下来发现,在线版用起来还是有些别扭:每次都要开浏览器、等页面加载,跟本地工程来回切换很割裂,尤其当你同时在VS Code里改代码、查文档、看串口输出时,频繁在两个窗口之间跳,效率低得让人抓狂。

后来我仔细翻了一遍官方文档,确认Wokwi提供了完整的本地运行方案,能直接把仿真器塞进VS Code里,编译、仿真、串口监视器一条龙,全程不需要实体开发板,也不用买任何外设模块。这篇文章就是我当时从零搭环境的完整记录,里面改掉了之前网上很多教程里已经过时的写法,把踩过的坑和修正后的步骤都整理出来了。

如果你是想入坑嵌入式但还没买板子的新手,或者已经有了实体板但想在写代码阶段快速验证逻辑的老手,这篇文章都能帮你把仿真环境跑起来,真正实现0成本折腾开发板。整条路线里唯一需要用钱的地方,就是你电脑上已有的VS Code和Docker,其余全是免费工具。

1. 本地运行Wokwi的原理与方案选型

1.1 本地运行跑起来的到底是什么

先说清楚一件事:你本地跑的并不是一个精简网页,而是Wokwi仿真器的完整闭环。Wokwi的架构可以拆成三层——前端画布、仿真内核、固件工具链。

前端画布就是你看到的虚拟开发板、元件和连线,这一层在VS Code里由一个WebView面板承载;仿真内核负责模拟CPU指令、GPIO电平、定时器、串口等硬件行为,这层Wokwi没有开源,它被打包成Docker镜像,通过容器在本地运行;固件工具链则负责把你的C/C++代码编译成ELF可执行文件,这层可以是Arduino CLI,也可以是PlatformIO。

所以“本地运行”真正做的事情,是把在线版中跑在云端的仿真内核下载到你的电脑里,用Docker容器方式启动,再让VS Code扩展跟这个容器建立通信。你的代码在容器仿真器里执行,虚拟板卡的画面实时渲染在编辑器旁边,串口输出回传到面板里。

1.2 路线对比:VS Code扩展还是Wokwi CLI

官方给了两条本地运行路线,一条是VS Code扩展,另一条是命令行工具Wokwi CLI。我一开始也在这两者之间犹豫过,实际各用了一段时间之后,对它们的差异有了比较明确的判断。

VS Code扩展适合日常手工学习调试,非常适合新手。你把项目文件夹打开,按F1输入命令就能启动仿真,虚拟板卡出现在编辑器旁边的面板里,改完代码点一下重启按钮就能重新加载固件,串口监视器直接集成在底部面板。整个过程不需要手动敲命令,也不需要在浏览器和编辑器之间来回切换。

Wokwi CLI则更适合自动化场景,比如你跑完编译脚本后想自动拉起仿真做个冒烟测试,或者你想把仿真集成进CI流程。它的命令也很简单,wokwi sim就能启动一个仿真会话,同样依赖Docker,但操作上更接近传统的命令行工具。

两条路线底层用的仿真内核是一样的,区别只在于外壳。对绝大多数学习者来说,我的建议是直接选VS Code扩展,先把环境跑起来,把Arduino基础语法、传感器读写、断点思路练熟,等需要做批量验证时再回头研究CLI完全不迟。

1.3 为什么我推荐这套组合

我自己最终选用的组合是:VS Code写代码,Wokwi扩展做仿真,Arduino CLI负责编译,Docker跑仿真内核。

这个组合的核心优势在于,所有环节都在一个编辑器里完成。以前在线版的方式,你需要在代码编辑器和浏览器标签页之间来回切换,每改一行代码就要刷新页面重新编译,做多了手都累。本地版把这些整合在一起之后,整个实验节奏快了很多,也更接近后面接真实开发板的工作方式——只是把USB线换成一条Docker容器的虚拟通道。

至于为什么用Arduino CLI而不是Arduino IDE,说白了只有一点:IDE是个图形界面程序,很难跟其他工具链串联,也不方便在脚本里调用。而CLI可以一行命令完成编译并输出ELF文件,Wokwi仿真器需要的就是这个ELF文件。对零基础的人来说,命令行看起来可能有点劝退,但实际用到的命令就一两条,照着抄就能通。

2. 环境准备:本地仿真的四件套

2.1 安装Docker:本地仿真的地基

Wokwi仿真内核以Docker镜像方式分发,所以Docker是整条链路的硬性依赖,这一环不装好,后面所有操作都会卡死。

Windows用户建议直接用Docker Desktop,安装过程中记得选WSL2后端。WSL2比老旧的Hyper-V后端在内存占用和启动速度上都要好很多,而且Wokwi CLI跟WSL2后端通信更稳定。安装完成后启动Docker Desktop,等左下角图标变成绿色,就说明Docker daemon已经在运行了。

macOS用户同样装Docker Desktop,Apple Silicon芯片的机器选对应版本,安装后注意在设置里给Docker分配足够内存,至少2GB,否则跑ESP32仿真时可能因为内存不足被系统杀掉。

Linux用户稍微有点区别,除了装Docker引擎外,还有个容易忽略的步骤:默认情况下普通用户调用docker命令需要sudo权限,Wokwi CLI在启动仿真时并不会帮你提权,所以最好把当前用户加入docker组,然后重新登录终端。

验证Docker是否可用的命令是:

docker --version docker run hello-world

第二条命令如果能看到一段提示信息,说明Docker拉取镜像、创建容器都正常,可以进入下一步。

2.2 安装Arduino CLI并准备板卡支持

Arduino CLI是Wokwi本地版的编译引擎,负责把你的代码编译成仿真器能读的ELF文件。

安装方式很直接。Windows用户可以在GitHub上下载最新版的可执行文件放入PATH目录,或者用包管理器;macOS用户建议brew install arduino-cli;Linux用户可以用官方安装脚本,也可以直接下载二进制包。装好后执行arduino-cli version能输出版本号就说明成功。

安装完之后必须初始化配置并安装板卡支持,否则编译时不知道你的目标板是什么架构。先初始化配置文件:

arduino-cli config init

然后更新板卡索引:

arduino-cli core update-index

索引更新完成后,安装Arduino AVR板卡(Uno、Nano、Mega这些)支持:

arduino-cli core install arduino:avr

如果你打算仿真ESP32系列,还需要安装对应的板卡包,这个包比较大,包含交叉编译工具链,下载耗时比较长:

arduino-cli core install esp32:esp32

我建议不管你现在用的是Uno还是ESP32,把AVR和ESP32都装好,反正后面大概率都要用。

2.3 安装Wokwi CLI与VS Code扩展

Wokwi CLI要全局安装,它本身是Node.js工具,所以先要有Node.js环境。打开终端执行:

npm install -g wokwi

装完执行wokwi --help能看到Usage信息就没问题。

VS Code扩展这边,直接在扩展商店里搜“Wokwi”,认准发布者为wokwi的扩展(Wokwi for VS Code),安装后最好重启一次VS Code让扩展激活。

这里有个细节需要注意:VS Code扩展启动仿真时,实际上会在后台调用Wokwi CLI,而Wokwi CLI又会去找Docker。所以就算你完全不打算用命令行,CLI也得装,Docker也得跑着,这条依赖链缺一环就会报“Could not find a valid Docker installation”之类的错误。

2.4 环境自检清单

四件套装完之后,我建议做一个快速自检,别急着开干,免得后面出错时分不清是哪个环节造成的。

检查项命令 / 操作预期结果
Docker daemondocker info能输出系统信息,不报connection refused
Node.js环境node --version输出v18或更高版本号
Wokwi CLIwokwi --version输出版本号
Arduino CLIarduino-cli version输出版本号
Arduino板卡arduino-cli core list能看到 arduino:avr 和/或 esp32:esp32
VS Code扩展扩展面板搜Wokwi状态为已安装并已启用

把这趟流程走完,你的电脑就具备本地仿真开发板的能力了。我刚开始搭的时候,就是少了Docker没启动这一环,导致仿真一直起不来,浪费了大半天查问题,后来学会先做自检,基本五分钟内就能定位环境问题。

3. 从零跑通一个Arduino Uno点灯仿真

3.1 创建项目文件:三个文件缺一不可

Wokwi本地仿真项目最少需要三个文件:源码文件(.ino)、电路定义文件(diagram.json)、固件路径配置(wokwi.toml)。

先在工作目录里新建一个文件夹,命名为wokwi-blink,然后在文件夹里新建wokwi-blink.ino文件。注意Arduino CLI要求.ino文件名跟所在文件夹名一致,否则编译时找不到主文件。

在.ino文件里写入代码:

void setup() { pinMode(13, OUTPUT); Serial.begin(9600); } void loop() { digitalWrite(13, HIGH); Serial.println("LED ON"); delay(500); digitalWrite(13, LOW); Serial.println("LED OFF"); delay(500); }

这段代码会让Uno板载的D13引脚输出高电平半秒、低电平半秒,同时在串口打印状态。之所以加上串口打印,是为了后面能在仿真器里看到真实的串口输出效果,而不是只干等着看LED闪烁。

接着创建diagram.json,这个文件描述虚拟电路板上有哪些元件、怎么连线。一个Uno加一颗LED的配置如下:

{ "version": 1, "author": "Learning", "editor": "wokwi", "parts": [ { "type": "wokwi-arduino-uno", "id": "uno", "top": 0, "left": 0, "attrs": {} }, { "type": "wokwi-led", "id": "led1", "top": 120, "left": 120, "attrs": { "color": "red" } } ], "connections": [ [ "uno:13", "led1:1", "red", [] ], [ "led1:2", "uno:gnd.1", "black", [] ] ] }

接线表里三要素缺一不可:源引脚、目标引脚、连线颜色。LED的1脚是阳极,2脚是阴极,所以1脚接Uno的D13,2脚接GND。[]里可以填额外的电气属性,比如弯折点,新手阶段留空就行。

最后创建wokwi.toml,这是Wokwi的配置文件,核心功能是告诉仿真器去哪个路径读固件。我修正后的写法是同时保留firmware和elf两个字段,兼容不同版本:

[wokwi] version = 1 firmware = 'build/wokwi-blink.ino.elf' elf = 'build/wokwi-blink.ino.elf'

这里有个很重要的变化后面会详细说,就是旧版Wokwi只认firmware字段,新版则强调elf字段。如果你在别的教程里只看到firmware一个字段,并且你的Wokwi版本比较新,仿真可能启动后完全没反应,原因就在这。

3.2 编译固件:arduino-cli命令解析

三个文件就绪后,打开终端进入项目文件夹,执行编译命令:

cd wokwi-blink arduino-cli compile --fqbn arduino:avr:uno --output-dir build wokwi-blink.ino

--fqbn参数是“Fully Qualified Board Name”,即目标板卡的完整标识。arduino:avr:uno的意思是:来自arduino厂商的avr平台下的Uno板型,这个标识必须跟你arduino-cli core install时装的板卡包一致。

--output-dir build指定编译产物输出到build子目录。编译成功的标志是终端最后出现“Used platform”和“Used library”之类的汇总信息,并且build目录下能找到一个名为wokwi-blink.ino.elf的文件。

在实际编译中你可能会遇到编译报错的情况,比如头文件找不到。一个比较常见的坑是:你用了ESP32的库,但fqbn还写着arduino:avr:uno,AVR平台当然没有ESP32的库。遇到这类问题,先确认fqbn是否跟你的目标板卡匹配,再确认对应的core是否已经安装,大多数报错都能在这两步里定位。

3.3 启动仿真:让虚拟Uno跑起来

编译完成后回到VS Code,确认当前打开的是项目文件夹,按Ctrl+Shift+P调出命令面板,输入Wokwi: Start Simulation,回车。如果是第一次启动,扩展会询问你使用哪种编译方式,选择Arduino CLI。

随后Wokwi会调用CLI,CLI去检查Docker并启动仿真内核容器,再读取diagram.json里的电路定义,把虚拟Uno渲染出来。整个过程大概几秒钟到十几秒,主要看Docker镜像是否已经拉取过。

仿真窗口打开后,你应该能看到一个虚拟的Arduino Uno板卡,上面还立着一个LED模块。程序启动后,LED以1Hz的频率闪烁,同时底部“Wokwi Serial Monitor”面板会交替输出“LED ON”和“LED OFF”。

这里要留意一个细节:仿真器里的Uno默认自带一个D13的LED,但你diagram.json里另外接的那个LED是独立元件,两者都会闪。如果你只想看自己接的外设LED,可以改代码让D13之外的引脚输出,比如D12,然后改diagram.json里的连线。

3.4 修改代码与重启仿真

本地仿真最大的优势之一就是迭代速度快。你改完代码,不需要重新启动容器,只要让Wokwi重新编译并加载固件即可。

最简单的做法是点仿真窗口工具栏上的重启按钮,扩展会重新执行编译并刷新仿真。也可以再用命令面板输入Wokwi: Restart Simulation,效果一样。

我在实际操作中的体验是:改一行delay参数,从500改成100,点重启,整个过程大概两三秒,虚拟板卡立刻按新参数闪烁。这种即时反馈感,对学习循环来说非常关键。你写代码、看结果、再修正的频率变高了,对知识的吸收效率自然也会高很多。

4. 进阶玩法:仿真ESP32和外部器件

4.1 从Uno换成ESP32,需要改什么

跑通Uno之后,马上可以往前迈一步:仿真ESP32。ESP32是当前学习物联网和WiFi应用的主流板卡,而Wokwi对ESP32的仿真也很成熟。

把项目里三处地方改掉就行。diagram.json里的parts部分,把板卡换成ESP32 DevKit:

{ "type": "wokwi-esp32-devkit-v1", "id": "esp32", "top": 0, "left": 0, "attrs": {} }

源码文件不用改,ESP32完全兼容Arduino语法。wokwi.toml里的elf路径保持不变,只要重新编译时的fqbn换掉即可:

arduino-cli compile --fqbn esp32:esp32:esp32 --output-dir build wokwi-blink.ino

这里注意:编译ESP32之前必须先执行过arduino-cli core install esp32:esp32,并且这个板卡包体积大,首次安装会比较久。装好之后同样用arduino-cli compile编译,生成的ELF文件位置不变,仿真启动方式也不变。

换成ESP32之后你会发现,仿真窗口里的板卡接口、布局都变了,这对学习不同芯片的引脚资源也很有帮助。

4.2 常用外围器件的仿真写法

在实际学习中,LED点灯只是起步,传感器、屏幕、按键这些外设的仿真才是省钱的大头。Wokwi的元件库已提供了大量常用虚拟器件,我列几个最常用的。

DHT22温湿度传感器在代码里正常用DHT库读数据,diagram.json里这样声明:

{ "type": "wokwi-dht22", "id": "dht", "top": 0, "left": 0, "attrs": {} }

DHT22的Data引脚接开发板的某个数字引脚,VCC接5V,GND接GND,然后代码里正常初始化dht.begin(),读温度湿度,仿真器会按你设定的模拟值返回数据。

LCD1602字符屏幕也很常用,代码里用LiquidCrystal库操作,diagram.json里声明wokwi-lcd1602元件,并按接线定义连好RS、EN、D4-D7引脚即可。仿真效果会真实地把字符显示在小屏幕上。

还有按键、舵机、蜂鸣器、超声波测距模块等,类型名称基本是wokwi-按键名的格式,比如wokwi-button、wokwi-servo、wokwi-buzzer、wokwi-hc-sr04。

我自己的体会是,在本地仿真里把传感器读值、屏幕显示、串口输出这三个环节一起跑通,基本就能覆盖绝大多数入门实验了。

4.3 仿真平台做不到的事

这部分必须说清楚,避免你产生误解。Wokwi能做很多事,但跟真实硬件还是有差距的。

第一,它模拟的是数字逻辑层面的行为,不精确模拟模拟电路细节。比如你想研究RC滤波电路的充放电波形,或者运放电路的增益特性,这不是Wokwi的强项,得用专业电路仿真工具。

第二,时序精度不是绝对的。虽然它的核心仿真基于真实指令模拟,但受Docker容器调度影响,严格的时间测量不能作为依据。如果代码里有毫秒级精度的时序要求,拿到真实板卡上必须重新验证。

第三,不是所有真实外设都有仿真模型。Wokwi的元件库在持续增长,但不可能覆盖所有传感器和模块。用到一个没有虚拟模型的器件时,只能先用跳线把引脚电平模拟出来。

第四,仿真器里WiFi网络的模型是虚拟化的。ESP32的WiFi可以仿真连接,但网络环境是Wokwi模拟出来的,跟真实路由器环境存在差异。

这些局限不是坏事,反而能帮你把注意力聚焦在程序逻辑上。逻辑对了,硬件差异的坑可以在拿到真实板卡后再排查。

4.4 从仿真到真实开发板的迁移流程

很多零件装上真实板子后才发现写的代码是对的,接线或者引脚却对不上。在仿真里提前把引脚规划好,能少踩很多坑。

迁移流程其实很简单。第一步,在仿真里确保所有引脚编号和接线与真实板卡的连接完全一致,这是最重要的一步。第二步,把代码里的库和引脚定义原封不动保留,真实板卡烧录时用Arduino IDE或arduino-cli直接编译烧录即可。第三步,真实板卡上电后,用串口监视器对比仿真时的输出,如果两者一致,恭喜你的逻辑已经通过了验证。

我经历过一次印象很深的迁移:早前写一个温湿度加LCD显示的项目,在仿真里跑得好好的,真实板卡上LCD完全不亮,排查到最后就是虚拟仿真里LCD对比度引脚默认不需要处理,但真实LCD模块需要接电位器调整对比度。这类问题只能在真实硬件上遇到,但至少仿真帮我排除了代码逻辑和接线错误,把问题范围缩小到了单点。

5. 已修正:这些坑我替你踩过了

5.1 Docker缺失或没启动,仿真直接报错

Wokwi启动仿真时,CLI会调用Docker创建仿真容器。如果Docker Desktop没启动,或者Linux下docker daemon没跑,你会看到类似Could not find a valid Docker installation或Error: connect ECONNREFUSED /var/run/docker.sock的错误。

排查方式很简单:先执行docker info,能输出信息就说明daemon正常;不能就先把Docker Desktop打开,等它完全进入运行状态再重试。Linux用户还要检查当前用户是否有权限访问docker socket,没有权限就执行sudo usermod -aG docker $USER,然后重新登录。

一个很容易忽略的点是Windows上Docker Desktop开机后不会自动启动,你重启电脑后满心欢喜打开仿真,却看到一连串报错。把Docker Desktop设为开机自启,或者养成“先启动Docker再开仿真”的习惯,能省下很多眼泪。

5.2 wokwi.toml里firmware和elf到底写哪个

这个问题是网上教程最容易出错的地方,我最初搭建时也在这里翻过车。旧版Wokwi使用firmware字段指定固件文件路径,后面改版后官方文档开始推荐elf字段。

你如果按老教程只写firmware,在新版本下仿真实例可能能启动,但虚拟机上的程序不跑,或者扩展一直提示找不到固件。

我的修正方案是:两个字段都写,指向同一个ELF文件。这样不管Wokwi内部按哪个字段读取,都能正确加载固件。这是经过实际检验的稳妥做法。

5.3 Arduino CLI下载板卡索引和工具链超时

arduino-cli core update-index和arduino-cli core install时,需要从官方源下载索引和工具链,这些下载在某些网络环境下速度很慢,甚至直接超时失败。

常规思路是用包管理器检查是否有新版,或在网络环境更稳定时重试。有些用户会选择手动下载离线包,然后放到Arduino CLI的缓存目录里,再用arduino-cli core install时带上本地包路径。这个方法虽然多几个步骤,但一劳永逸——装好之后,后面的编译和仿真就都不需要再联网了。

另外,第一次装ESP32板卡的时候,建议留出充足时间,别以为卡住了就强退。它的工具链包含编译器、链接器、烧录工具,体积比AVR大很多,耐心等它跑完就好。

5.4 仿真窗口黑屏或模型不动

仿真窗口打开后,有时会看到板卡图像出来了,但程序不跑,LED不闪,串口也没有输出。

遇到这种情况,先检查串口监视器是否有报错信息,错误信息往往比现象本身更有指向性。最常见的根因是wokwi.toml里的固件路径不对,或者ELF文件不存在。你需要重新确认build目录下有wokwi-blink.ino.elf这个文件,再确认既firmware后elf字段指向的就是它。

另一个常见根因是diagram.json语法错误。JSON格式不允许注释,代码里如果用了类似//的注释,或者多了逗号,整个文件会被解析失败。可以在命令行用arduino-cli无关的JSON校验工具,或者直接把内容粘贴到任意JSON格式化网站上检查一遍再放回来。

5.5 版本不一致导致扩展报错

Wokwi一直在迭代,扩展版本、CLI版本、Docker镜像版本之间如果跨得太大,可能出现一些奇怪的兼容性问题。比如扩展编译好了固件,但仿真内核不识别新ELF格式;或者CLI新版本要求特定的Docker镜像版本,本地拉到的却是旧版。

这类问题比较难直接定位,我的处理策略是先把所有组件更新到最新版:VS Code扩展在扩展页面更新、npm install -g wokwi重装CLI、docker pull相关镜像看版本、Arduino CLI用包管理器升级。大部分跨版本问题在全部更新后都会消失。

如果更新后问题还在,可以在项目目录下删除Wokwi扩展的缓存目录重新来一遍。这个方法成功率不高,但成本也很低,值得一试。

5.6 问题排查速查表

最后给你一份直接可对照的速查表,比我上面每个问题单独描述更直观。

错误现象可能原因解决方法
Could not find a valid Docker installationDocker未启动或未安装启动Docker Desktop,执行docker info验证
Permission denied / docker.sock连接失败Linux用户无docker权限sudo usermod -aG docker $USER后重新登录
仿真窗口能开但程序不跑wokwi.toml固件路径错误确认build目录中有elf文件,且firmware/elf字段指向正确
串口无输出未在代码中初始化Serial或波特率不匹配在setup里加Serial.begin(9600),面板波特率保持一致
编译报错找不到板卡对应的core未安装arduino-cli core list检查,缺什么装什么
JSON解析失败diagram.json语法错误用JSON校验工具检查格式
编译成功但仿真画面没有外设diagram.json为空或缺parts字段确认parts里声明了元件,connections里有连线定义
扩展启动后一直转圈VS Code扩展与CLI版本不兼容更新扩展和CLI到最新版,重启VS Code

我在搭建这套环境的过程中,最深的体会是:仿真平台对面真正的价值不是省掉买板子的几十块钱,而是给了你一个可以随便折腾、随便炸、没有任何心理负担的虚拟实验台。你可以故意把延时函数去掉让串口刷屏,可以故意反接LED看它不亮,可以在代码里写明显越界的数组然后观察仿真器怎么表现——这些在真实板卡上要么让人心疼板子,要么排查起来很费劲,在仿真里则完全没有任何顾虑。

Wokwi本地环境跑通之后,整个学习闭环就彻底转起来了:打开VS Code,改代码,点重启,看结果,不满意再改。等你真拿到一块实体板卡,其实做的事情跟仿真里一模一样,只是把Docker容器换成了USB线连接的真实芯片。这种无缝衔接让“先用仿真学逻辑、再上真板调硬件”成为一条很适合自学的路线。

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

埃夫特ER_Factory_Trail工业机器人仿真:从安装到工作站搭建全攻略

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

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

STM32软解码EV1527:从波形到按键码的完整实现

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

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

基于STM32的智能鸽子驯养系统:从电路设计到实物调试的完整方案

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

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

YOLOv5橘子成熟度检测:数据集训练与树莓派部署实战

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

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

QSV转MP4全攻略:专用工具、录屏与FFmpeg方案详解

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

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

SAP Fiori OData服务本质:从SEGW拖拽到生产级契约的四层穿透

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

作者头像 李华