欧姆龙FINS协议从原理到实操:帧结构、通信机制与故障排查
做自动化项目的工程师估计都遇到过这种场景现场用的是欧姆龙PLC上位机或产线MES要采集数据结果对面工程师丢过来一句“走FINS协议”。你要是平时主要玩Modbus第一次听到FINS协议大概率是懵的——报文字节该怎么填连不上怎么排查这篇文章我就把欧姆龙FINS协议从原理到实操完整拆一遍。FINS是欧姆龙自家设备之间、设备与上位机之间的标准通信协议在数据采集、设备监控、机器人联动这些自动化场景里非常常见。不管你是做上位机开发的、搞PLC程序的还是负责现场维护的只要项目里出现过“欧姆龙”三个字FINS就值得你花半小时弄明白。1. 先弄清楚FINS协议是什么解决什么问题1.1 一个冷知识FINS其实是一套网络体系FINS的全称是Factory Interface Network Service很多人只把它当成“欧姆龙PLC的一种通信方式”其实它远不止一个报文格式那么简单——它是一整套覆盖从物理链路到应用接口的FA网络体系。在欧姆龙的生态里PLC、触摸屏、伺服驱动器、传感器之间都能通过FINS交换数据而且FINS不挑链路以太网、控制网络、RS-232C串口都有对应的实现方式。常见的落地形态有三种跑在以太网TCP上的FINS/TCP、跑在以太网UDP上的FINS/UDP以及串口上的FINS协议。这对开发者的好处是显而易见的不管底层是网线还是串口命令代码、地址模型、响应结构基本都是一套。也就是说你学会了以太网版本的FINS报文怎么组串口版本也就会了七七八八。这也是为什么我建议新手直接学FINS/TCP——它最容易抓包、最容易验证学完再迁移到其他链路几乎没有成本。FINS另一个核心设计是“网络-节点-单元”三层寻址。它不像Modbus那样只有从站地址一个维度而是把目标分成网络地址、节点地址、单元号三层来定位。这个设计的工程意义在于FINS天然支持跨网络通信也就是通过网关把多个子网串起来上层应用甚至可以访问另一个网络里的PLC。当然绝大多数项目用不到跨网络我们只要把“本地网络目标节点PLC节点号目标单元CPU单元”这三个关键参数填对通信就已经通了。1.2 用对比的方式理解FINS与Modbus TCP的差别对于只接触过Modbus的工程师用对比的方式理解FINS会非常快。Modbus TCP的核心是功能码03读保持寄存器、06写单个寄存器、16写多个寄存器报文结构极短一个请求可能就12个字节。它做的是“寄存器”层面的读写不关心你的数据在PLC里到底属于哪个内存区域。FINS则完全不同它把PLC内存按功能区分成DM区、CIO区、WR区、HR区等命令直接面向这些区域开发者不用自己去做“地址映射表”。举一个生产中的例子某项目X里用Modbus TCP去读欧姆龙PLC的数据你就得在PLC程序里把工程值一点一点挪到Modbus映射区比如40001地址这种做法相当于给PLC增加额外的程序负担。但用FINS读DM区D100就是直接一条命令的事不需要在PLC侧做任何搬运。这个差别在实际维护中很关键——用Modbus那套坏了要查PLC程序里的搬运逻辑用FINS只要协议地址对直接就能拿到原始数据。不过Modbus也不是没优势。它的好处是通用性极强西门子、三菱、AB的PLC全支持而且报文简单是一个非常成熟的业界标准。FINS的优势在欧姆龙生态内部要读取的数据类型越贴近PLC原生内存区效率越高。所以我的建议是如果你的上位机只对接欧姆龙PLC直接用FINS如果现场设备品牌很杂、需要和第三方控制器互通那Modbus TCP仍然是避不开的底线方案。2. FINS协议核心机制帧结构、命令码与地址模型2.1 帧头那10个字节一个一个拆给你看FINS的命令帧除了前导的TCP/UDP封装之外本体部分核心结构是“10字节帧头 2字节命令码 参数区”。那10个帧头字节是理解整个协议的钥匙我建议直接背下来因为不管是读、写、强制置位还是其他扩展命令这个帧头都是完全一样的。下面用一个实际读D100的FINS/TCP命令帧来逐字节拆解。完整报文含TCP封装头是00 00 00 16 | 00 00 | 00 00 | 80 00 02 00 01 00 00 0F 00 01 | 01 01 | 82 00 64 00 00 01前面4字节00 00 00 16是报文长度不参与FINS帧本身再往后2字节00 00是FINS头一般是固定零再往后2字节00 00是握手码这是FINS/TCP封装层的东西下面实操部分再细说。真正核心的是从80开始的FINS帧。字段值含义ICF80信息控制字段。80表示这是一条需要响应的命令帧响应帧这里通常会变成00RSV00保留字段固定填0GCT02网关连续计数。本地网络内通信保持02不要乱改DNA00目标网络地址。00表示本地网络DA101目标节点地址。就是PLC的FINS节点号DA200目标单元号。00表示PLC的CPU单元SNA00源网络地址。上位机所在的网络本地网络为00SA10F源节点地址。即上位机的FINS节点号SA200源单元号。上位机软件一般填00SID01服务标识符。用来匹配请求和响应随便取00~FF同一个请求最好保持固定很多人一上来就卡在这10个字节上其实只需要抓住关键目的字段DA1是“去谁那”SA1是“我是谁”。这两个节点号在配置阶段确认好其他字节照抄就行。2.2 命令码与地址映射规则怎么找到PLC里的数据帧头后面跟着2字节命令码。最常用的就两个0101H是内存区读0102H是内存区写。注意FINS协议里所有多字节数值都以大端方式表达0101H就是字节01 01不是01 01反过来。FINS和Modbus一个特别大的差异是它可以直接用PLC原生内存区进行IO。常用区域代码字单位二进制模式如下内存区代码二进制/字地址范围举例DM区82D0 ~ D32767CIO区B0CIO 0 ~ CIO 6143WR工作区B1W0 ~ W511HR保持区B2H0 ~ H1535DR数据寄存器A0D0 ~ D32767注意与DM区分开比如要读D100这一个字读命令0101的参数部分是82 00 64 00 00 01。这里面第一个字节82是DM区代码后面3个字节00 64 00就是地址。这个地址的排列方式是小节号(bit号) 地址低字节 地址高字节。D100换算成十六进制是0x0064所以低字节是64高字节是00。00 64 00就是“bit编号00地址0x0064”。最后两个字节00 01表示读取1个字。这是FINS最容易踩坑的地方地址是按“低字节在前”排的跟命令码的大端排列正好相反。我见过不少人在这一步翻车把D100的地址写成00 00 64结果PLC直接回错误码1103也就是地址超范围。如果你要读D400十六进制0x0190地址就是00 90 01。2.3 FINS/TCP与FINS/UDP的选型逻辑FINS在以太网上有两种玩法FINS/TCP和FINS/UDP。虽然命令帧本身几乎一样但传输层的差异直接决定了你的程序怎么写。FINS/TCP走的是TCP协议默认端口9600通信前需要建立连接而且有一个特殊的软件握手过程——PLC连上之后会先向客户端发一个握手帧客户端必须回一个握手帧双方确认节点信息后才能正常收发命令。这样做的好处是连接状态可靠、命令有保障PLC侧也知道是哪个上位机节点在跟它通信适合频繁读写、实时性要求高的采集场景。大多数上位机项目选这个方案。FINS/UDP就简单粗暴了直接把FINS命令帧封装进UDP数据报发给PLC的9600端口PLC回的响应也是UDP数据报。它不需要握手、不需要维护连接适合“问一下答一下”的轻量通信比如设备心跳检测、简单状态读取。代价是UDP丢包了不会自动重传、通信状态不可靠同时PLC需要预先在以太网配置里把上位机的节点注册进去否则很可能不回包。从实践角度我个人的建议是正式项目优先选FINS/TCP。这不是因为UDP不能用而是TCP的握手机制能帮你省掉一大半“为什么PLC不理我”的排查时间。一旦TCP能连上、握手成功后面命令收发基本就是水到渠成的事。UDP更适合做测试原型或者你明确知道通信量小、丢包无所谓的场景。3. 手写FINS/TCP客户端从握手到读写一通到底3.1 通信环境准备搞清楚你手上有哪些参数开始写代码之前先确认几个关键参数。没有这些参数下面的代码全白搭PLC的IP地址比如192.168.1.10。PLC的FINS节点号。这个在PLC的以太网端口设置里能看到出厂默认一般是1。上位机的FINS节点号。自己在PLC允许的范围内随便选一个别跟PLC节点号重复就行。我习惯用150x0F方便在抓包里快速辨认。端口号。FINS/TCP是9600FINS/UDP也是9600一般不用改。没有真实PLC也能学。你可以先用网络调试助手模拟PLC侧监听9600端口自己给自己发FINS响应帧来联调也可以参考某些开源PLC模拟器的实现方式先把客户端代码写熟再上真机验证。我第一次练FINS就是在没有PLC的情况下用调试助手手动回了几个响应帧把整个协议流程跑通的。3.2 FINS/TCP的软件握手这是最容易漏的一步TCP连接建立后千万别急着发命令。FINS/TCP有一个“连接握手”机制PLC作为服务端连接一建立就主动给客户端发一帧握手数据。这个握手帧的结构是4字节长度 2字节FINS头0000 2字节PLC节点号。客户端收到后必须回复同样结构的握手帧其中最后2字节要填上位机节点号。用Python写出来就是这样import socket import struct def connect(plc_ip, src_node0x0F, port9600, timeout5): sock socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(timeout) sock.connect((plc_ip, port)) # 接收PLC发来的连接握手帧 handshake recv_exact(sock, 8) print(PLC handshake:, handshake.hex()) # handshake结构: 4字节长度 2字节FINS头 2字节节点号 plc_node handshake[7] print(PLC node:, plc_node) # 回复连接握手帧 resp struct.pack(I, 4) b\x00\x00 struct.pack(H, src_node) sock.send(resp) return sock, plc_node注意recv_exact是一次收满N字节的辅助函数因为TCP是流式传输一次recv不一定能收全8个字节。这个辅助函数在后面的循环读取响应里也会反复用到建议这样实现def recv_exact(sock, n): data b while len(data) n: chunk sock.recv(n - len(data)) if not chunk: raise ConnectionError(connection closed) data chunk return data握手完成后后面的每条FINS命令都走同样的封装格式4字节长度 2字节FINS头(0000) 2字节握手码(可填0000) FINS帧。注意握手码这个字段在后续命令里可以填0因为FINS帧头里的DA1和SA1已经明确了通信双方抓包验证时我看到很多实现都是这么处理的。3.3 读内存区命令把D100的数据抓回来握手完成后我们来构造一条读D100的请求。完整帧应该是长度(4字节) 0000 0000 FINS帧 FINS帧 80 00 02 00 01 00 00 0F 00 01 01 01 82 00 64 00 00 01计算一下长度FINS头2字节 握手码2字节 FINS帧18字节 22字节也就是0x16和前面抓包示例一致。Python实现def build_read_request(plc_node, src_node, memory_code0x82, address100, count1, sid1): # 10字节FINS帧头 fins bytes([ 0x80, 0x00, 0x02, # ICF, RSV, GCT 0x00, plc_node, 0x00, # DNA, DA1, DA2 0x00, src_node, 0x00, # SNA, SA1, SA2 sid ]) # 命令码0101H: 内存区读 body bytes([0x01, 0x01]) # 参数: 内存区代码(1) 地址(3) 个数(2) addr_low address 0xFF addr_high (address 8) 0xFF body bytes([memory_code, 0x00, addr_low, addr_high]) body struct.pack(H, count) frame fins body packet struct.pack(I, len(frame) 4) b\x00\x00\x00\x00 frame return packet收到响应后先读4字节长度再按长度读取剩下的“长度值”个字节。然后从第5个字节开始解析FINS响应帧第1个字节是ICF正常响应会是0x00第11个字节开始是命令码正常是01 01命令码后面是2字节结束码00 00代表成功结束码再往后才是真正读出来的数据每2字节一个字大端排列。def read_dm(sock, plc_node, src_node, address, count1): req build_read_request(plc_node, src_node, 0x82, address, count) sock.send(req) head recv_exact(sock, 4) resp_len struct.unpack(I, head)[0] resp_body recv_exact(sock, resp_len) # 跳过FINS头2字节握手码2字节得到FINS帧 fins_resp resp_body[4:] end_code int.from_bytes(fins_resp[12:14], big) if end_code ! 0x0000: raise RuntimeError(fFINS error code: 0x{end_code:04X}) data_bytes fins_resp[14:] return data_bytes注意响应帧里命令码的位置FINS帧本身10字节帧头从resp_body第4字节开始计算命令码在FINS帧的第11、12字节对应整个响应体的第14字节偏移不对从FINS响应帧的10字节帧头后是2字节命令码然后2字节结束码所以结束码在FINS响应帧偏移为10212。但resp_body从第5个字节开始才是FINS帧前4字节是长度所以fins_resp[102]fins_resp[12]正好是结束码高字节。这里我代码里写fins_resp[12:14]但fins_resp是从第4字节开始取。验证一下resp_body 4字节长度 2字节FINS头 2字节握手码 FINS帧所以resp_body[4:]正是FINS帧那么FINS帧[10]为命令码高字节FINS帧[12]为结束码高字节。对代码没问题。3.4 写内存区命令把数据写进D区写命令0102H的参数比读多一步在地址和个数后面直接跟要写入的数据。比如向D100写一个字内容是0x1234那么参数区就是82 00 64 00 00 01 12 34。注意数据字是大端排列0x1234就是字节12 34不要写反了。def build_write_request(plc_node, src_node, memory_code, address, data_words, sid2): fins bytes([ 0x80, 0x00, 0x02, 0x00, plc_node, 0x00, 0x00, src_node, 0x00, sid ]) body bytes([0x01, 0x02]) # 0102H: 内存区写 addr_low address 0xFF addr_high (address 8) 0xFF body bytes([memory_code, 0x00, addr_low, addr_high]) body struct.pack(H, len(data_words)) for w in data_words: body struct.pack(H, w) frame fins body packet struct.pack(I, len(frame) 4) b\x00\x00\x00\x00 frame return packet写命令的正常响应没有数据区结束码是0000就算成功。如果命令码返回的最高位变成1比如8102那就说明写入被拒绝紧跟在后面的2字节错误码能告诉我们具体原因。在实际写操作里我还建议你在写之前先用读命令把当前值读出来看看尤其是写入对象是CIO区或者有外部设备在控制的区域时。这不算多余有一次我在某项目里向W区写工作模式字一上来就写结果发现之前已经有别的工作站把数据改掉了我那一条写命令把之前的配置覆盖了——正确的做法是读改写先读当前值按位修改目标位再整体写回。4. 实战避坑常见通信故障与错误码速查4.1 连接不上PLC时按顺序查这5个地方FINS/TCP连不上八成不是协议本身的问题而是基础网络或配置问题。我一般按下面的顺序排查每次都能快速定位第一IP通不通。直接在电脑上ping PLC的IP地址。如果不通查网线、交换机、电脑本机IP是否在同一个网段。这一步能排除掉一半问题。第二端口通不通。ping通不代表9600端口是开着的可用系统自带的telnet命令测试telnet 192.168.1.10 9600。如果端口不通去PLC的网络设置里确认FINS/TCP服务是否启用、端口号是否被改过。第三是否真的收到了握手帧。这一步最容易被忽略。很多人在socket建立后直接发命令结果PLC根本不回。FINS/TCP要求先完成前面说的握手过程PLC给你发节点信息、你回复自己的节点信息之后才开始正常命令交互。抓包时看一眼有没有完成这一步没握手的直接补上。第四节点号是否冲突。上位机节点号不能和PLC节点号一样也不能和其他上位机节点重复。工业现场如果有多台上位机同时连PLC节点号规划混乱是常见坑。第五防火墙是否拦截。Windows自带的防火墙偶尔会拦截TCP 9600端口入站连接开发期临时关闭防火墙试试或者给防火墙加一条放行规则。这个原因排查起来最隐蔽但出现频率不低。4.2 数据读出来了但结果完全不对多半是这3个原因能读到数据却读不对比连不上还折磨人。我遇到最多的情况有以下三种。第一种是地址编码写反了。FINS的3字节地址是“小节号 地址低字节 地址高字节”如果你把D100的地址写成00 00 64PLC要么报1103错误要么读出来的不是你想要的那个字。解决办法很简单翻译成十六进制以后把高低字节调换再填进去。第二种是字节序问题。FINS一个字是2字节大端传输也就是值0x1234在报文里是12 34。但有些上位机或者三方库在解析时按小端处理导致你读出来的数值变成0x3412。这种问题在调试工具里一眼就能看到原始字节和预期反了就调一下。多字数据比如浮点数更麻烦FINS里32位浮点数通常按“高字在前低字在后”排列解析时得先拼回完整的32位再转float。第三种是区域代码用错。DM区和DR区都是D开头但代码完全不同一个是82一个是A0。CIO区在有些PLC型号里还分“CIO”和“内部分区”写错代码后PLC不是报错就是读到另外一块内存的内容。我建议在代码里把每个区域代码定义成常量不要散落在业务代码里。4.3 FINS错误码速查表遇到异常响应不用慌响应帧的结束码不是0000时就是通信被拒了。我整理了项目里最常见的几个错误码遇到时优先对照错误码含义常见原因与解决办法0x0105目标节点无响应目标PLC不存在或未工作检查IP和节点号0x1101内存区代码错误服务请求中指定的内存区代码不对检查区域代码0x1103地址超范围地址编码或范围超出该区域上限重点检查低高字节顺序0x110B请求数据个数超限一次读写的字数超过协议上限减少单帧数据量0x2001命令代码不支持当前PLC单元不支持该命令码检查命令版本0x2101数据长度错误写入数据长度与参数区指定数量不一致检查数据区这组错误码不用死记抓包看到响应帧里命令码最高位被置1后面跟的2字节就是错误码。把错误码表存在手边排查效率会高很多。我自己在电脑上就存了一份某次在项目现场遇到1103同事还在对着文档翻半天我一看地址字段就知道是高低字节写反了。4.4 一次真实排查实录FINS/TCP握手成功后依然通信超时最后分享一个印象很深的排查案例。某项目X里我用Python写好的FINS/TCP客户端连PLC时握手已经完成了但每次发读命令都会超时。反复检查了IP、节点号、命令帧字节全部看起来正常PLC端也没报任何错误。后来我抓了一把报文才发现问题PLC回握手帧之后我的客户端读响应帧时只recv了一次结果把PLC的握手帧和第一条响应帧的一部分粘连在一起解析了。因为PLC发送时序比较快两个包几乎同时到达而TCP是字节流没有天然的消息边界。那次之后我把所有响应读取都改成基于长度字段的精确读取再也没有出过这类问题。还有一条经验FINS/TCP的安全超时设置建议放在3~5秒之间。PLC扫描周期慢、或者网络上有交换机缓存时响应超过1秒并不罕见。超时太短会导致误判通信故障超时太长又会让故障发现变慢。3秒是经验值既能覆盖大多数PLC的响应延迟又不会让现场排查等太久。最后再说一点实操体会FINS协议本身并不难它真正考验人的地方是细节——握手有没有做、地址的高低字节有没有写反、错误码有没有看懂。我刚开始调FINS的时候也曾在握手这一块栽过跟头那时候以为TCP连上就能发命令直到抓包对比才发现少了软件握手的流程。后来我把这篇文章里这套代码封装成了公共组件再对接新项目里的欧姆龙PLC基本就是填IP、填节点号、调用读写接口的事省心很多。如果你正准备开始搞FINS我的建议是先别急着写业务逻辑拿一个网络调试助手把“握手、读D区、写D区”三步手动走通看一眼真实报文长什么样再写代码。这样一通百通后续不管是改地址还是加命令码都不会再被协议细节绊住。

相关新闻

JavaScript生命游戏边界处理:从LeetCode 289到工程落地

JavaScript生命游戏边界处理:从LeetCode 289到工程落地

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

2026/10/13 9:11:24 阅读更多 →
索洛模型弹性与收敛速度:从公式推导到半程期计算

索洛模型弹性与收敛速度:从公式推导到半程期计算

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

2026/10/13 9:10:21 阅读更多 →
二叉树叶子结点统计:从递归到Morris遍历与工程优化

二叉树叶子结点统计:从递归到Morris遍历与工程优化

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

2026/10/13 9:10:21 阅读更多 →

最新新闻

PowerContext挂接MiniMax Code:终结跨会话与跨Agent上下文断裂

PowerContext挂接MiniMax Code:终结跨会话与跨Agent上下文断裂

大约两个星期前,我把手头的项目从“上下文完全靠每次手动贴”的方式,切到了 PowerContext 挂接 MiniMax Code 的方式。困扰我很久的一个问题终于不再是问题:跨会话和跨 Agent 之间的项目上下文,不再断裂了。起因很简单。我开一个新…

2026/10/13 10:00:16 阅读更多 →
领域模型进化:GRPO 强化学习与 Post-training Engineering

领域模型进化:GRPO 强化学习与 Post-training Engineering

通用大模型(base model)是个通才。它在万亿 token 上做过 next-token prediction,把世界知识压缩进了权重,但你让它写一段符合你公司合规规范的代码、审一份你领域的合同、跑通你内部系统的 SQL,它大概率会给你一个&qu…

2026/10/13 10:00:16 阅读更多 →
t3code 深度拆解:编码工具核心原理与实操避坑指南

t3code 深度拆解:编码工具核心原理与实操避坑指南

1. 从“t3code”这个标题说起:它到底是什么,能解决什么问题第一次看到“t3code”这个标题,很多人会一头雾水。它不像“Python爬虫实战”那样直白,也不像“家庭咖啡烘焙指南”那样有明确场景。但恰恰是这种模糊性,给了我…

2026/10/13 10:00:16 阅读更多 →
Seldon Core Pipeline 就绪状态检查实战:从 tfsimples 示例到 ready 接口的源码解析

Seldon Core Pipeline 就绪状态检查实战:从 tfsimples 示例到 ready 接口的源码解析

人工智能大模型MLOpsLLMOps模型推理服务云原生后端 【免费下载链接】seldon-core An MLOps framework to package, deploy, monitor and manage thousands of production machine learning models 项目地址: https://gitcode.com/gh_mirrors/se/seldon-core 点击查看…

2026/10/13 10:00:16 阅读更多 →
Oracle到达梦迁移实战:数据类型、SQL语法与存储过程避坑指南

Oracle到达梦迁移实战:数据类型、SQL语法与存储过程避坑指南

1. 迁移之前,先把两边的“家底”摸清楚1.1 为什么Oracle到达梦的迁移总在“意料之外”翻车做过数据库迁移的人都有一个共识:迁移本身不难,难的是迁移之后业务跑不起来。Oracle到达梦的迁移尤其如此,因为这两套数据库虽然都支持SQL…

2026/10/13 10:00:16 阅读更多 →
Java垃圾分类系统:树形分类建模与时间窗调度实战

Java垃圾分类系统:树形分类建模与时间窗调度实战

简介:这是一套已高分通过的Java毕业设计项目源码,面向计算机专业本科生及Java初学者,聚焦城市垃圾分类回收管理场景,提供从用户注册登录、垃圾类型分类录入、回收点信息维护、预约回收申请到后台数据统计的完整业务闭环&#xff0…

2026/10/13 9:59:14 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

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

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

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

2026/10/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

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

2026/10/12 18:11:17 阅读更多 →