美文网首页
史丹利扭力枪

史丹利扭力枪

作者: ioufev | 来源:发表于2022-02-05 17:41 被阅读0次
    img img

    手工具,汽保工具,工具箱,卷尺,螺丝刀,套筒,老虎钳,工具组套,工业手工具—史丹利STANLEY:

    https://www.stanleytools.com/
    http://www.stanleytools.cn

    1 介绍

    开放协议是用于构建控制器远程控制或数据订阅应用程序的接口。它是独立于平台的,可以在Linux、PLC、打印机和所有Windows平台上实现。

    开放协议支持串行和以太网连接。

    img

    1.3 术语

    术语 定义
    控制器 开放协议支持 Power Focus 和 PowerMACS 控制器。看到:PF60001 .5 表99的限制。
    集成器 例如,集成器硬件可以是PC、PLC或打印机。集成器应用程序在集成器硬件中使用开放协议。
    消息 信息由三部分组成:标头、数据字段和消息结束,如"消息结构"部分所述。根据通信类型的不同,发送或接收的包包括消息之前和之后的消息和封装,如通信部分所述。
    MID 由四位数字表示的消息的消息ID,例如0052。MID0052是指车辆Id号上传。该ID始终包含在消息中。
    MID修订版本 MID可以有多个修订。如果未设置修订版本,则应用修订版1。MID通常会进行修订以包括更多数据,从而增加消息的长度。添加MID修订版本以确保向后兼容性。
    订阅 订阅是控制器在每次生成特定数据时向集成器发送时使用的术语。
    取消订阅 取消订阅是订阅取消订阅时使用的术语。数据将不再从控制器发送。

    2.1 通信

    使用开放协议

    可以使用以太网或串行通信运行开放协议。
    开放协议是全双工协议,这意味着可以同时发送和接收数据。每个通信伙伴必须能够同时操作发送和接收。

    • Power Focus 控制器一次最多可接受5个连接,在串行和以太网之间共享。
    • Power MACS 控制器一次可以为每个站接受两个以太网连接。没有支持用于串行连接。

    2.1.1 以太网协议

    集成器连接到控制器,控制器接受连接。
    控制器是服务器,集成器应用程序是客户端。
    使用的协议是TCP/IP。用于的默认端口通讯是4545。

    2.2 消息结构

    通过通信链路发送的所有信息都是ASCII格式。
    消息由三部分组成; 标题,数据字段和消息结束。
    以下部分描述了每个部分 部分详细。

    2.2.2 数据字段

    数据字段是表示数据的ASCII数据。 数据包含一系列参数,具体取决于 MID。 每个参数都用ID和参数值表示。 请注意,ID始终为2 字节。 数据字段可以为空或包含最多9979个字节。

    表2数据字段内容

    消息部分 字节 参数
    数据字段 21-22 01 参数ID(00 ... 99),长度为两个字节。 参数 ID在左侧填充,用ASCII字符为“0”。
    数据字段 23- 参数01值 参数值由参数选择定义(固定字节数)。 ASCII数字(“0”...“9”)或0x20之间的ASCII字符 和0x7F十六进制。 如果是数字, 左边填充“0”。 如果是字符, 右边填充space 。 如果不支持参数值,则为整体参数字段填充空格。
    数据字段 n- 02 参数02

    2.2.3数据字段实施规则

    • 必须发送数据字段的所有参数
    • 每条消息的数据字段都需要通过添加MID来处理 修订。 新版本可以包括新参数或增加数据字段的长度。
    • 在实现具有多个版本的现有MID时,所有版本必须是 支持的
    • 不支持的参数必须填充空格(hex 020)。 这特别适用于重用MID来购买新产品。
    • 如果可以确定不支持的参数从不支持 ,则使用新的MID 必须定义这些参数被排除,从长远来看,这将给予更清洁 接口。 被发送到Open Protocol comitte。
    • 所有MIDs描述都没有定义的“不支持”colomn 得到充分实施和支持。
    • 数据部件中发送的所有扭矩和角度值均以Nm和度为单位发送,没有其他指定。 对于度数,转弯表示360度。

    2.2.4消息结束

    消息结束为空。

    表3 消息结束内容

    消息部分 字节 参数
    消息结束 0 消息结束 所有消息都是NUL终止的。 NUL 终止不包括在消息长度中。 在这手册用NUL,ASCII 0x00说明。

    3.1建立联系

    通讯实例,本节介绍如何设置通信

    3.1.1 以太网连接

    先决条件:控制器具有IP地址并侦听端口4545。

    图9以太网连接示例

    img
    1. 控制器监听端口 4545。
    2. 集成器连接到 控制器。
    3. 控制器接受连接。
    4. 集成器发送 MID 0001 沟通开始 。
    5. 控制器回答 MID 0002通讯开始,用Cell ID 0001 确认,通道ID 04和控制器 名为安全气囊

    4 消息类别

    大多数(但不是全部)消息可以分为两大类。 MID 0001通讯开始 或 MID 0003通讯停止,不属于任何这些类别。

    类别是:

    • 请求消息
    • 活动消息

    4.1 请求和请求回复消息

    集成器向控制器发送请求,控制器以肯定或否定的答复者来响应请求 。
    如果在响应超时之前未收到对请求的答复,则集成器应该重新发送请求最多三次。三次之后,连接被视为丢失并且是必须建立新的连接。

    某些请求消息可用作Open Protocol命令禁用。这些命令是如果数字输入开放协议命令禁用数字输入有效,则拒绝。命令是表4中标记了可用消息。有关更多信息,另请参见禁用打开协议命令部分信息。

    请求和请求回复消息的示例:

    • 集成器发送MID 0018选择参数集
    • 控制器应答MID 0005命令已接受或MID 0004命令错误

    4.2 事件消息

    事件消息可以分为三类:

    • 事件订阅 - 取消订阅消息
    • 活动消息
    • 事件确认消息

    事件订阅 - 取消订阅消息

    订阅是使用subscribe - unsubscribe消息进行的。 订阅可以在取消 任何时候集成器通过发送取消订阅消息。

    事件消息

    控制器可以在诸如收紧或紧固等事件后自发地向集成器发送消息报警。此服务仅在订阅事件消息后启用。

    事件消息确认

    集成器应通过发送相应的确认MID来确认事件消息。如果在响应超时之前没有收到确认,则控制器将重新发送消息 三次。在三次尝试之后,控制器将认为连接丢失。

    4.3 编程控制

    某些命令MID需要对称为“编程控制”的控制器进行独占访问。可以将编程控制与执行编程任务所需的常规锁进行比较。

    有关的MID要求编程控制可用(即锁定应解锁)为了执行,在执行命令期间进行编程控制(即它们锁定锁定),然后自动释放编程控制(即自动解锁)。

    如果在发送这样的MID时没有编程控制(即锁已经锁定),则控制器以MID0004命令回答命令错误,未授予编程控制。

    当命令MID需要编程控制时,这在MID中表示为警告规格。

    4.4 消息列表

    该部分列出了表4中的所有可用消息。看到PF60001.5
    表99产品MID/Revision支持列表,其中MID在每个控制器中实现。

    表 4可用消息

    ID 描述 由谁发送 请求信息 请求相应信息 事件订阅 事件 事件确认 开放协议命令
    0001 通讯开始 集成器
    0002 通讯开始确认 控制器
    0003 通讯停止 集成器
    0004 命令错误 控制器
    0005 命令被接受 控制器
    0010 参数设置ID上传请求 集成器
    0011 参数设置ID上传回复 控制器
    0012 参数设置数据上传请求 集成器
    0013 参数设置数据上传回复 控制器
    0014 参数设置选择订阅 集成器
    0015 选择参数组 控制器
    0016 参数组选择确认 集成器
    0017 参数设置选择取消订阅 集成器
    0018 选择参数设置 集成器
    0019 设置参数设置批量大小 集成器
    0020 复位参数设置批处理计数器 集成器
    0021 批量完成订阅锁定 集成器
    0022 批量完成上传锁定 控制器
    0023 批量锁定完成上传确认 集成器
    0024 批量锁定完成取消订阅 集成器
    0025 保留给福特 集成器
    0030 作业ID上传请求 集成器
    0031 作业ID上传回复 控制器
    0032 作业数据上传请求 集成器
    0033 作业数据上传回复 控制器
    0034 工作信息订阅 集成器
    0035 工作信息 控制器
    0036 工作信息确认 集成器
    0037 工作信息取消订阅 集成器
    0038 选择作业 集成器
    0039 作业重启 集成器
    0040 工具数据上传请求 集成器
    0041 工具数据上传回复 控制器
    0042 禁用工具 集成器
    0043 启用工具 集成器
    0044 断开工具请求 集成器
    0045 设置校准值请求 集成器
    0046 设置主要工具请求 集成器
    0047 配对处理 集成器
    0048 配对状态 控制器
    0049 配对状态确认 集成器
    0050 车辆ID号下载请求 集成器
    0051 车辆ID号订阅 集成器
    0052 车辆ID号 控制器
    0053 车辆ID号确认 集成器
    0054 车辆ID号取消订阅 集成器
    0060 最后收紧结果数据订阅 集成器
    0061 最后收紧结果数据 控制器
    0062 最后收紧结果数据确认 集成器
    0063 最后收紧结果数据取消订阅 集成器
    0064 旧收紧结果上传请求 集成器
    0065 旧收紧结果上传回复 控制器
    0070 报警订阅 集成器
    0071 报警 控制器
    0072 报警确认 集成器
    0073 报警取消订阅 集成器
    0074 控制器上确认报警 控制器
    0075 控制器确认时确认报警 集成器
    0076 报警状态 控制器
    0077 报警状态确认 集成器
    0078 在控制器上远程确认报警 集成器
    0080 读取时间上传请求 集成器
    0081 读取时间上传回复 控制器
    0082 设定时间 集成器
    0090 多轴状态订阅 集成器
    0091 多轴状态 控制器
    0092 多轴状态确认 集成器
    0093 多轴状态取消订阅 集成器
    0100 多轴结果订阅 集成器
    0101 多轴结果 控制器
    0102 多轴结果确认 集成器
    0103 多轴结果取消订阅 集成器
    0105 最后的PowerMACS拧紧结果数据订阅 集成器
    0106 最后的PowerMACS拧紧结果站数据 控制器
    0107 最后的PowerMACS拧紧结果螺栓数据 控制器
    0108 最后的PowerMACS拧紧结果数据确认 集成器
    0109 最后的PowerMACS拧紧结果数据取消订阅 集成器
    0110 在compact上显示用户文本 集成器
    0111 在图表上显示用户文本 集成器
    0113 工具上闪烁绿灯 集成器
    0120 作业行控制信息订阅 集成器
    0121 作业线控制已开始 控制器
    0122 作业线控制警报1 控制器
    0123 作业线控制警报2 控制器
    0124 完成作业线控制 控制器
    0125 作业线控制信息确认 集成器
    0126 作业行控制信息取消订阅 集成器
    0127 中止工作 集成器
    0128 作业批量增量 集成器
    0129 作业批量减少 集成器
    0130 工作休息 集成器
    0131 设置作业线控制开始 集成器
    0132 设置作业线控制警报1 集成器
    0133 设置作业线控制警报2 集成器
    0140 执行动态作业请求 集成器
    0150 标识符下载请求 集成器
    0151 多个标识符工作订单订阅 集成器
    0152 多个标识符工单 控制器
    0153 多个标识符工作单确认 集成器
    0154 多个标识符工作订单取消订阅 集成器
    0155 旁路标识符 集成器
    0156 重置最新标识符 集成器
    0157 重置所有标识符 集成器
    0200 设置外部受控继电器 集成器
    0210 状态外部监控输入订阅 集成器
    0211 状态外部监控输入 控制器
    0212 状态外部监控输入确认 集成器
    0213 状态外部监控输入取消订阅 集成器
    0214 IO设备状态请求 集成器
    0215 IO设备状态回复 控制器
    0216 继电器功能订阅 集成器
    0217 继电器功能 控制器
    0218 继电器功能确认 集成器
    0219 继电器功能取消订阅 集成器
    0220 数字输入功能订阅 集成器
    0221 数字输入功能 控制器
    0222 数字输入功能确认 集成器
    0223 Digin功能取消订阅 集成器
    0224 设置数字输入功能 集成器
    0225 复位数字输入功能 集成器
    0240 用户数据下载 集成器
    0241 订阅用户数据 集成器
    0242 用户数据 控制器
    0243 用户数据确认 集成器
    0244 用户数据取消订阅 集成器
    0250 选择器套接字信息订阅 集成器
    0251 选择器插座信息 控制器
    0252 选择器套接字信息确认 集成器
    0253 选择器套接字信息取消订阅 集成器
    0254 选择器控制绿灯 集成器
    0255 选择器控制红灯 集成器
    0260 工具标签ID请求 集成器
    0261 工具标签ID订阅 集成器
    0262 工具标签ID 控制器
    0263 工具标签ID确认 集成器
    0264 工具标签ID取消订阅 集成器
    0270 控制器重启请求 集成器
    0300 直方图上传请求 集成器
    0301 直方图上传回复 控制器
    0400 自动/手动模式订阅 集成器
    0401 自动/手动模式 控制器
    0402 自动/手动模式确认 集成器
    0403 自动/手动模式取消订阅 集成器
    0410 AutoDisable设置请求 集成器
    0411 AutoDisable设置回复 控制器
    0420 开放协议命令已禁用订阅 集成器
    0421 禁用开放协议命令 控制器
    0422 开放协议命令禁用确认 集成器
    0423 禁用取消订阅开放协议命令 集成器
    0500 电机调谐结果数据订阅 集成器
    0501 电机调谐结果数据 控制器
    0502 电机调谐结果数据确认 集成器
    0503 电机调谐结果数据取消订阅 集成器
    0504 电机调谐请求 集成器
    8000 奥迪紧急状态订阅 集成器
    8001 奥迪紧急状态 控制器
    8002 奥迪紧急状态确认 集成器
    8003 奥迪紧急状态取消订阅 集成器
    9999 保持开放的协议通信 集成器

    实际使用

    消息ID这么多,其实用到的就是几个

    消息ID(MID,发送) 含义 消息ID(MID,接收) 含义
    0001 开始 0002 收到开始
    9999 保持连接
    0060 订阅 0062 收到订阅的消息

    0001

    img

    发送

    00200001003 NUL

    • 0020表示是20个字节
    • 0001表示MID 0001(消息ID 0001)含义是通信开始
    • 003表示MID 0002(消息ID 0002)的修订版本是003,不同修订版回复数据的结构不一样
    • NUL是ASCII码的字符0,在Java中表示是"\0"
            String start = "00200001003         ";
            ctx.writeAndFlush(start + "\0");
    

    接收

        if("0002".equals(msg.toString().substring(4, 8))){
            // 表示成功
        }
        
            if("0004".equals(msg.toString().substring(4, 8))){
            // 表示错误
        }
    

    0002

    img img

    0003

    img

    0004

    img

    0005

    img

    0060

    img

    0061

    img img

    结果数据

    img img img img img img

    代码

    TorqueGunClient

    import java.net.InetSocketAddress;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    
    import io.netty.bootstrap.Bootstrap;
    import io.netty.channel.Channel;
    import io.netty.channel.ChannelInitializer;
    import io.netty.channel.ChannelPipeline;
    import io.netty.channel.nio.NioEventLoopGroup;
    import io.netty.channel.socket.nio.NioSocketChannel;
    import io.netty.handler.codec.DelimiterBasedFrameDecoder;
    import io.netty.handler.codec.Delimiters;
    import io.netty.handler.codec.string.StringDecoder;
    import io.netty.handler.codec.string.StringEncoder;
    
    @Component
    public class TorqueGunClient {
        private static Logger logger = LoggerFactory.getLogger(TorqueGunClient.class);
        
        @Autowired
        TorqueGunConfig torqueGunConfig;
        
        public void start() {
            logger.debug("开始,扭力枪通信");
            // Bootstrap,且构造函数变化很大,这里用无参构造。
            Bootstrap bootstrap = new Bootstrap();
            // 指定channel[通道]类型
            bootstrap.channel(NioSocketChannel.class);
            // 指定Handler [操纵者]
            bootstrap.handler(new ChannelInitializer<Channel>() {
    
                @Override
                protected void initChannel(Channel ch) throws Exception {
                    ChannelPipeline pipeline = ch.pipeline();
    
                    /*
                     * 这个地方的 必须和服务端对应上。否则无法正常解码和编码
                     * 
                     */
                    pipeline.addLast("framer", new DelimiterBasedFrameDecoder(8192, Delimiters.nulDelimiter()));
                    pipeline.addLast("decoder", new StringDecoder());
                    pipeline.addLast("encoder", new StringEncoder());
    
                    // 客户端的逻辑,自己对数据处理
                    pipeline.addLast(new TorqueGunClientHandler());
                }
            });
            // 指定EventLoopGroup [事件组]
            bootstrap.group(new NioEventLoopGroup());
    
            // 连接到本地的8000端口的服务端
            bootstrap.connect(new InetSocketAddress(torqueGunConfig.getIp(), torqueGunConfig.getPort()));
        }
    }
    

    类TorqueGunClientHandler

    import java.util.Timer;
    import java.util.TimerTask;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import cn.com.tcb.uavpcs.datacenter.comm.desktop.process.WorkplaceClientInvotor;
    import io.netty.channel.ChannelHandlerContext;
    import io.netty.channel.ChannelInboundHandlerAdapter;
    
    public class TorqueGunClientHandler extends ChannelInboundHandlerAdapter {
        private static Logger logger = LoggerFactory.getLogger(TorqueGunClientHandler.class);
        private String keepAlive = "00209999000         " + "\0";
        private String start = "00200001003         " + "\0";
        private String subscribe01 = "002000600031  01    " + "\0";
        private String subscribe02 = "002000600031  02    " + "\0";
        private String subscribe03 = "002000600031  03    " + "\0";
        private String subscribe04 = "002000600031  04    " + "\0";
        private String subscribe05 = "002000600031  05    " + "\0";
        private String subscribe06 = "002000600031  06    " + "\0";
        private String subscribe07 = "002000600031  07    " + "\0";
        private String subscribe08 = "002000600031  08    " + "\0";
        
        /*
         * 监听 服务器 发送来的数据
         */
        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
            logger.debug("say:" + msg);
            if ("0002".equals(msg.toString().substring(4, 8))) {
                // 握手成功,主动发送一次心跳消息
                ctx.writeAndFlush(keepAlive);
            } else if ("9999".equals(msg.toString().substring(4, 8))) {
                Timer timer = new Timer();
                timer.schedule(new TimerTask() {
                    @Override
                    public void run() {
                        ctx.writeAndFlush(keepAlive);
                        timer.cancel();
                    }
                },10000);
            } else if ("0061".equals(msg.toString().substring(4, 8))) {
                logger.debug(msg.toString());
                String val = msg.toString();
                if(val.length()>57) {
                    String clientID = val.substring(55, 57).trim();             
                    if(!clientID.equals("")) {
                        WorkplaceClientInvotor workplaceClientInvotor = new WorkplaceClientInvotor();
                        workplaceClientInvotor.reportTorqueData(msg.toString(), clientID);
                    }
                }
            }
        }
    
        /*
         * 启动客户端 时触发
         */
        @Override
        public void channelActive(ChannelHandlerContext ctx) throws Exception {
            logger.debug("Client active ");
            ctx.writeAndFlush(start);
            ctx.writeAndFlush(subscribe01);
            ctx.writeAndFlush(subscribe02);
            ctx.writeAndFlush(subscribe03);
            ctx.writeAndFlush(subscribe04);
            ctx.writeAndFlush(subscribe05);
            ctx.writeAndFlush(subscribe06);
            ctx.writeAndFlush(subscribe07);
            ctx.writeAndFlush(subscribe08);
            super.channelActive(ctx);
        }
    
        /*
         * 关闭 客户端 触发
         */
        @Override
        public void channelInactive(ChannelHandlerContext ctx) throws Exception {
            logger.debug("Client close ");
            super.channelInactive(ctx);
        }
    }
    

    相关文章

      网友评论

          本文标题:史丹利扭力枪

          本文链接:https://www.haomeiwen.com/subject/qmqykrtx.html