简介:组合信号(GO/GI)应用说明是一份面向ABB机器人工程技术人员与自动化集成工程师的PDF文档,重在解决多路数字量输入输出与PLC通信时常见的程序冗长、状态误判问题。文档从组合信号的定义讲起,指出组输出和组输入可将多个DO/DI合并管理,随后详细演示了在Signal配置界面创建GO信号、绑定IO单元、填写Device Mapping地址的完整流程,并分别说明了连续地址(例如1-3)与不连续地址(例如1,4,6)的填写要点。针对GO输出值的计算,文档以二进制映射关系展开,举例说明当需要DO1与DO3同时置1时,应向GO输入数值5,GI的配置和计算思路与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 是一条一条执行的。假设我们想让 DO1=1、DO2=0、DO3=1 同时出现在输出端,实际执行顺序却是:
SetDO DO1, 1; SetDO DO2, 0; SetDO DO3, 1;这三条指令在 PLC 看来不是一个瞬间完成的动作,而是一个变化过程。PLC 的扫描周期如果是 10ms,机器人两条指令之间的间隔可能只有 2ms,但 PLC 完全有可能在 DO1 刚翻成 1、DO3 还是 0 的那个窗口期扫到一次,然后就把这个中间状态当成真实信号记录下来。这类问题在单步调试时根本看不出来,一旦产线跑起来,偶尔报警一下,查起来非常耗时间。
组信号解决的就是这个问题。GO 一旦写入一个数值,控制器底层会在同一个 IO 刷新周期内把绑定的所有 DO 同时置位,不会出现“先置了 DO1,DO3 还没变”的中间状态。理解这一点,是后面配置的正确姿势,也是判断“该不该用 GO”的准绳。
2.2 组信号的本质:一块二进制的“并行总线”
某品牌机器人的 GO/GI 信号不依赖标志位,本质上是一个映射器:你在 Device Mapping 里写了地址范围,控制器就把这些地址上的数字输入或输出打包成一个整数。对 DO 来说,打包起来的整数的二进制形式就是每个 DO 的实际电平。
可以这样看:一个 GO 信号占用一个 32 位整数的寄存器窗口。如果地址是 1-3,那么 bit 0、bit 1、bit 2 分别对应 DO1、DO2、DO3,写入值 5 即二进制 101,DO1 和 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 1,DO2 → Address 2,DO3 → Address 3,那么这里就写 1-3。如果地址跳着编,DO1 在 1、DO4 在 4、DO6 在 6,就写 1,4,6。注意逗号是英文半角逗号,全角会导致解析失败。
3.2 地址连续与离散时的映射写法对照
很多项目现场地址编号是设计院定的,不一定连续。下表是三个常见场景的映射方式:
| 绑定信号 | 地址分布 | Device Mapping 写法 |
|---|---|---|
| DO1, DO2, DO3 | 1、2、3 | 1-3 |
| DO1, DO4, DO6 | 1、4、6 | 1,4,6 |
| DO1, DO2, DO4, DO5 | 1、2、4、5 | 1-2, 4-5 |
第三个写法很多人不知道,其实某品牌机器人支持用短横线表示连续区间、逗号分隔多个区间。如果你想把 DO2 留作手动调试用,不想打进组里,就可以把地址写成 1, 3, 4,中间的 2 不参与。这样既保留了组信号,又给调试留了后门。
3.3 GI 配置:与 GO 对称,但读法有一个反直觉
GI(Group Input)的配置界面和 GO 几乎完全一样,类型选择 Group Input,Device Mapping 写 DI 的地址。但有一个小陷阱:GI 的数值读出来,每一位对应的是绑定的 DI 的实时电平,但位序是按地址的数值大小从低到高排列的,不是按你输入映射表时的书写顺序。
举个例子,如果你绑定的是 DI5(地址 5)和 DI1(地址 1),映射表写“1,5”,那 GI 值的二进制中,地址 1 永远对应低位,地址 5 对应高位,而不是按“1,5”这个书写顺序硬排。这个反直觉点会让很多人第一次读值时直接懵掉,后面第 5 章会专门展开。
4. 组信号值怎么算:从需求到十六进制的一条龙推导
4.1 把 DO 组合翻译成整数的两个方法
有了组信号,代码不再是一行一个 SetDO,而是一次 SetGO。核心问题是:给定“DO1=1、DO2=0、DO3=1”,GO 应该写多少?
方法一:直接按位手动算。DO1 对应 2 的 0 次方,DO2 对应 2 的 1 次方,DO3 对应 2 的 2 次方。要置位的位取 1,不置位的取 0,求和即可。未完,继续阅读```rapid ! 需要 DO1=1, DO2=0, DO3=1 ! 1 对应二进制 001,DO1 置位 ! 2 对应二进制 010,DO2 不置位 ! 4 对应二进制 100,DO3 置位 ! 求和 = 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 ! 取料完成状态:DO1=1, DO2=0, DO3=1 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 就等于“没有信号”。在组信号层面,GO=0 意味着绑定的所有 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 已经绑定了地址 4,GO1 也写了 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”填写。实际运行时 DI5=1、DI1=1,读 GI1 等于 17(二进制 10001),而不是 3(二进制 11),或者是 33(二进制 100001)。
原因:GI 每位的顺序只由地址数值大小决定,与写入映射表的顺序无关。地址 1 是最低位,地址 2 是第二位,依此类推。同一时刻地址 5 的那一位已经是位 4 的权重(16),所以 DI5=1 就要贡献 16;地址 1 贡献 1,加起来就是 17。这是最容易翻车的点,因为直觉上“我按顺序写的就按顺序读”,实际完全不是这样。
解决:把映射表按地址从低到高重新排序,然后再计算。如果你希望 DI5 对应 DB 里的第 1 位,第 2 位留给 DI1,那最直接的办法是改 IO 地址定义,让它们按位重要性排列,否则就只能硬算偏移。我在项目中会把所有 IO 点表和组信号位序一一对应后存档,纯用手算太容易错,存档至少能让人复核。
6. 进阶技巧:把组信号值用在状态机里,而不是散落在主程序里
组信号的配置一次搞定后,真正拉开效率差距的是怎么用。我见过很多人的程序里到处是 SetGO GO1, 5,SetGO GO1, 2,状态一变就修改数值,代码写得像乱七八糟的贴纸。其实组信号非常适合做状态机的翻译器:定义一个枚举,把每个状态和 GO 值一一对应,程序里只传状态名,不传魔法数字。
! 定义状态枚举 CONST int STATE_IDLE := 0; ! 待机,全 DO 为 0 CONST int STATE_FETCHED := 5; ! 取料完成,DO1=1, DO3=1 CONST int STATE_PLACED := 2; ! 放料完成,DO2=1 ! 状态机主循环 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 表,把要参与状态交互的信号统统归到组信号里,排好位序,再做状态机映射。这套流程救过我不少回,至少省掉了当初反复查“为什么少一个位”的时间。希望帮到你。
本文还有配套的精品资源,点击获取