简介组合信号GO/GI应用说明是一份面向ABB机器人工程技术人员与自动化集成工程师的PDF文档重在解决多路数字量输入输出与PLC通信时常见的程序冗长、状态误判问题。文档从组合信号的定义讲起指出组输出和组输入可将多个DO/DI合并管理随后详细演示了在Signal配置界面创建GO信号、绑定IO单元、填写Device Mapping地址的完整流程并分别说明了连续地址例如1-3与不连续地址例如1,4,6的填写要点。针对GO输出值的计算文档以二进制映射关系展开举例说明当需要DO1与DO3同时置1时应向GO输入数值5GI的配置和计算思路与GO相反。资源包整体为1个PDF文件压缩后约1.16MB便于下载后离线阅读。目前已有928人学习使用适合需要提升机器人-PLC交互效率、降低信号配置错误概率的中级及以上自动化工程师。1. 组合信号不是银弹但能让 PLC 接线少掉一半当机器人需要告诉 PLC 一个三段式状态时三个 DO 信号就得一一置位当 PLC 想告诉机器人去拿几号物料三个 DI 信号也得逐一等待。这个场景在柔性产线上几乎天天出现。用单点数字信号逐个写程序很快就变成一坨“信号瀑布”而且信号不是同时翻转的PLC 那边极容易读到中间状态造成误判。某品牌机器人提供的组输入输出GO/GI就是为一个 IO 通道塞进多个二进制位一次传出一个“状态值”。这篇内容围绕组信号展开适合正在调试机器人对接 PLC 的电气工程师和现场维护人员配置过一次后改地址、补位、查值的方式就都清楚了。2. 为什么单点 DO/DI 会误判组信号的位宽与编码逻辑2.1 单点数字信号通信的核心痛点非原子性用过某品牌机器人的 RAPID 程序的人都知道SetDO 是一条一条执行的。假设我们想让 DO11、DO20、DO31 同时出现在输出端实际执行顺序却是SetDO DO1, 1; SetDO DO2, 0; SetDO DO3, 1;这三条指令在 PLC 看来不是一个瞬间完成的动作而是一个变化过程。PLC 的扫描周期如果是 10ms机器人两条指令之间的间隔可能只有 2ms但 PLC 完全有可能在 DO1 刚翻成 1、DO3 还是 0 的那个窗口期扫到一次然后就把这个中间状态当成真实信号记录下来。这类问题在单步调试时根本看不出来一旦产线跑起来偶尔报警一下查起来非常耗时间。组信号解决的就是这个问题。GO 一旦写入一个数值控制器底层会在同一个 IO 刷新周期内把绑定的所有 DO 同时置位不会出现“先置了 DO1DO3 还没变”的中间状态。理解这一点是后面配置的正确姿势也是判断“该不该用 GO”的准绳。2.2 组信号的本质一块二进制的“并行总线”某品牌机器人的 GO/GI 信号不依赖标志位本质上是一个映射器你在 Device Mapping 里写了地址范围控制器就把这些地址上的数字输入或输出打包成一个整数。对 DO 来说打包起来的整数的二进制形式就是每个 DO 的实际电平。可以这样看一个 GO 信号占用一个 32 位整数的寄存器窗口。如果地址是 1-3那么 bit 0、bit 1、bit 2 分别对应 DO1、DO2、DO3写入值 5 即二进制 101DO1 和 DO3 同时置 1。这样的设计有三个直接好处代码量少一“写”代替多“置位”通信动作是原子的PLC 侧读到的任何时刻的状态都完整信号含义可集中定义维护时看 GO 号比查一排 DO 容易得多。选型上我一般这样判断两三个状态量、对实时性要求不高单点 DO 足够超过三个数字量并且它们有明确的“组合含义”时就该上 GO/GI。并不是所有场景都适合组信号有的 PLC 程序老没法把 DI 字读成整型那还是要走单点。3. 在 Signal 界面配置 GO/GI地址映射是全部关键3.1 添加 GO 信号的完整操作顺序某品牌机器人的配置入口在示教器的“控制面板”里路径一般是控制面板 → 配置 → I/O 系统 → Signal。新建一个信号注意以下几步不能乱1. Name: GO1 2. Type of Signal: Group Output 3. Assigned to Device: 选择与 DO 相同的 IO 单元 4. Device Mapping: 填地址如 1-3 5. 确定后重启机器人控制器这里最容易踩坑的是 Assigned to Device。如果你之前填写的 DO1 挂在 d10 这个 IO 单元下那这个 GO1 的 Assigned to Device 也必须是 d10而不是别的单元。有些现场做过 IO 迁移DO 已经重新分配过了但人没记住新建 GO 时仍然按旧记忆选设备最终结果就是重启后报地址冲突。Device Mapping 的格式我见过不少新手上手就填错。记住一句话这里的地址填的是“被绑定的 DO 信号的地址”不是 GO 自己的编号。比如你之前人为定义了 DO1 → Address 1DO2 → Address 2DO3 → Address 3那么这里就写 1-3。如果地址跳着编DO1 在 1、DO4 在 4、DO6 在 6就写 1,4,6。注意逗号是英文半角逗号全角会导致解析失败。3.2 地址连续与离散时的映射写法对照很多项目现场地址编号是设计院定的不一定连续。下表是三个常见场景的映射方式绑定信号地址分布Device Mapping 写法DO1, DO2, DO31、2、31-3DO1, DO4, DO61、4、61,4,6DO1, DO2, DO4, DO51、2、4、51-2, 4-5第三个写法很多人不知道其实某品牌机器人支持用短横线表示连续区间、逗号分隔多个区间。如果你想把 DO2 留作手动调试用不想打进组里就可以把地址写成 1, 3, 4中间的 2 不参与。这样既保留了组信号又给调试留了后门。3.3 GI 配置与 GO 对称但读法有一个反直觉GIGroup Input的配置界面和 GO 几乎完全一样类型选择 Group InputDevice Mapping 写 DI 的地址。但有一个小陷阱GI 的数值读出来每一位对应的是绑定的 DI 的实时电平但位序是按地址的数值大小从低到高排列的不是按你输入映射表时的书写顺序。举个例子如果你绑定的是 DI5地址 5和 DI1地址 1映射表写“1,5”那 GI 值的二进制中地址 1 永远对应低位地址 5 对应高位而不是按“1,5”这个书写顺序硬排。这个反直觉点会让很多人第一次读值时直接懵掉后面第 5 章会专门展开。4. 组信号值怎么算从需求到十六进制的一条龙推导4.1 把 DO 组合翻译成整数的两个方法有了组信号代码不再是一行一个 SetDO而是一次 SetGO。核心问题是给定“DO11、DO20、DO31”GO 应该写多少方法一直接按位手动算。DO1 对应 2 的 0 次方DO2 对应 2 的 1 次方DO3 对应 2 的 2 次方。要置位的位取 1不置位的取 0求和即可。未完继续阅读rapid ! 需要 DO11, DO20, DO31 ! 1 对应二进制 001DO1 置位 ! 2 对应二进制 010DO2 不置位 ! 4 对应二进制 100DO3 置位 ! 求和 1 4 5 SetGO GO1, 5;方法二十六进制换算。当组信号超过 8 位时用十六进制更直观。举例DO1 到 DO8 全部为 1二进制是 1111 1111十六进制是 0xFF所以 SetGO GO1, 255 和 SetGO GO1, 0xFF 等效。现场调试时我习惯先在纸上写出二进制再转成十进制填入示教器避免算错。 ### 4.2 用 GO 向 PLC 发送“取料完成”的标准写法 回到最开始的场景。以前是先置三个单点 DO现在变成了 rapid ! 取料完成状态DO11, DO20, DO31 SetGO GO1, 5; ! 等待 PLC 给出“允许放料”的组合信号 WaitGI GI1, 5;这几行程序比原来的六条简洁得多而且 PLC 侧收到的状态变化是同一时刻发生的不会读到中间值。WaitGI 的第二个参数就是期望 GI 的十进制值等于 5 时允许程序往下走否则一直等。如果你希望 PLC 给的值“大于等于某个值”就继续RAPID 里没办法直接在 WaitGI 里写不等式得先读出来再判断IF GI1 5 THEN ! 继续执行 ELSE ! 报警或等待 ENDIF要注意WaitGI 是等一个精确值而 IF 判断适合边界范围。产线上“大于等于”的场景更多因为 PLC 那边可能额外加了一个工件在位信号导致组合值比你预期大这时用精确匹配就会卡死。4.3 值为 0 和“所有 DO 都低”是两个不同的故事初学者常犯一个认知错误认为 GO 值为 0 就等于“没有信号”。在组信号层面GO0 意味着绑定的所有 DO 全部输出 0这是一个有效状态PLC 可以拿它做“空”判断。当你需要表达“什么都没发生”时直接 SetGO GO1, 0 是干净利落的。但反过来有一个坑重启后组信号默认值是 0。这意味着如果机器人刚启动还没来得及执行初始化程序PLC 就已经读到“所有 DO 为 0”了。如果 PLC 的逻辑把“0”解释成“取料完成”就会产生危险动作。我在项目里一般会在机器人启动的第一行强制写入一个非工作状态值比如 SetGO GO1, 0xFF告诉 PLC“机器人刚启动不要参考当前输出”等逻辑准备好再写入实际状态。5. 避坑地址重叠、重启顺序与位序错乱的三个典型案例5.1 配置完重启机器人直接被拒绝启动现象在 Signal 界面添加完 GO1点击确定后机器人提示需要重启重启过程中报“AS or DS 系统错误”启动中断。原因检查发现 GO1 的 Device Mapping 写了一部分 DO 的地址但其中一个地址同时也被另一个组信号占用。比如 DI 或 DO 之间没有冲突但另一个 GO2 已经绑定了地址 4GO1 也写了 4导致两个信号争同一个 IO 位。解决把其中一个组信号的映射地址挪开或者取消旧的组信号。我处理这类问题时的顺序是先打开已有信号列表看所有组信号的 Device Mapping 是否有交集再用地址范围逐一核对确认不重叠后再重启。这是一个纯配置层面的死锁代码写得没问题也救不了。5.2 地址连续但程序里读出来的值总差一个现象GO1 绑定 DO1(地址1)、DO2(地址2)、DO3(地址3)配置完全正确。程序里写 SetGO GO1, 4结果 DO2 没高DO3 却高了或者反过来。PLC 侧读到状态错乱。原因把地址号当成了二进制位号。地址 1 对应的是位 0地址 2 对应位 1地址 3 对应位 2。SetGO GO1, 4二进制 100置位的是位 2也就是地址 3对应 DO3。如果你想置位 DO2应该写 2二进制 010。这个换算关系是纯数学关系地址号减 1 才是位序号。解决建议先在纸上列一张换算表地址 1 → 位 0 → 权重 1地址 2 → 位 1 → 权重 2地址 3 → 位 2 → 权重 4。然后每次 SetGO 前都按这个表算。如果程序里已经写了不少魔法数字建议加注释注明每个值的二进制含义避免后面维护的人再踩同一个坑。5.3 GI 读出来的数和自己绑定的 DI 顺序对不上现象GI1 绑定了 DI5地址5、DI1地址1映射表按“1,5”填写。实际运行时 DI51、DI11读 GI1 等于 17二进制 10001而不是 3二进制 11或者是 33二进制 100001。原因GI 每位的顺序只由地址数值大小决定与写入映射表的顺序无关。地址 1 是最低位地址 2 是第二位依此类推。同一时刻地址 5 的那一位已经是位 4 的权重16所以 DI51 就要贡献 16地址 1 贡献 1加起来就是 17。这是最容易翻车的点因为直觉上“我按顺序写的就按顺序读”实际完全不是这样。解决把映射表按地址从低到高重新排序然后再计算。如果你希望 DI5 对应 DB 里的第 1 位第 2 位留给 DI1那最直接的办法是改 IO 地址定义让它们按位重要性排列否则就只能硬算偏移。我在项目中会把所有 IO 点表和组信号位序一一对应后存档纯用手算太容易错存档至少能让人复核。6. 进阶技巧把组信号值用在状态机里而不是散落在主程序里组信号的配置一次搞定后真正拉开效率差距的是怎么用。我见过很多人的程序里到处是 SetGO GO1, 5SetGO GO1, 2状态一变就修改数值代码写得像乱七八糟的贴纸。其实组信号非常适合做状态机的翻译器定义一个枚举把每个状态和 GO 值一一对应程序里只传状态名不传魔法数字。! 定义状态枚举 CONST int STATE_IDLE : 0; ! 待机全 DO 为 0 CONST int STATE_FETCHED : 5; ! 取料完成DO11, DO31 CONST int STATE_PLACED : 2; ! 放料完成DO21 ! 状态机主循环 PROC main() WHILE TRUE DO SetGO GO1, curState; WaitGI GI1, plcAck; ! 根据 GI 的返回值跳转状态 ENDWHILE END PROC这样做有两个好处一是代码可读性强看 STATE_FETCHED 不用回翻二进制表二是后续增加状态只加一行枚举不用改任何逻辑代码。某品牌机器人支持在 RAPID 里定义常量数组把状态名作为下标去索引 GO 值VAR int stateValue{3} : [0, 5, 2]; SetGO GO1, stateValue{curStateIndex};这样多余的重复判断也能省掉。不过要注意如果你在离线编程软件里做了这套下载到真实控制器时信号地址必须完全一致否则就会出现第 5 章说到的“值对、设备不对”的问题。还有一个小技巧现场有时候需要临时把某个 DO 从组信号中摘出去调试不用修改映射表直接给那个 DO 加一条手动 SetDO 就会覆盖组信号的输出但前提是程序里不能同时写 SetGO。不然同一个扫描周期里两条指令互相打架PLC 侧看着就像信号在抖动。这时候我会在手动模式下把组输出屏蔽等自动运行了再恢复比反复改配置省事很多。从那以后我每次接手机器人项目第一件事不是写动作而是先梳理 IO 表把要参与状态交互的信号统统归到组信号里排好位序再做状态机映射。这套流程救过我不少回至少省掉了当初反复查“为什么少一个位”的时间。希望帮到你。本文还有配套的精品资源点击获取