PELCO-D

https://blog.csdn.net/subfate/article/details/36644419

在搞visca的同时顺便也搞了pelco。这里再做个笔记。

pelco,中文翻译为“派尔高”,在行文和写代码过程,写pelco比写“派尔高”快很多,所以一般就写pelco。这个协议在云台控制中用得比较多,比较出名的有PTZ,用rs232或rs485来通信。pelco有两种协议,D协议和P协议,两者命令封装不太一样,网上有协议的说明文档,也有实现的代码,我找到一个C#写的,某搜索引擎上找得到的介绍派尔高协议的,基本上都是直接把每个命令的数据一一写成数组来调用,个人认为这样不太方便。

本文所讲的是pelco D协议。

一、命令格式

文档中说pelco D协议的命令都是7个字节的(实际上,有些不是),命令格式如下图:


说明:

字节1:D协议同步头为0xFF。
字节2:相机编号(或称地址),范围为1~0xFF,0x01表示相机1。
字节3:CMND1,命令1。
字节4:CMND2,命令2。作为扩展命令,命令数值为奇数。
字节5:数据字节1,作为motion命令,其表示pan的速度。
字节6:数据字节2,作为motion命令,其表示tilt的速度。
字节7:检验码,计算公式:(字节2+字节3+字节4+字节5+字节6)% 0x100。注:检验码是除了同步头及本身(CKSM)字节外的所有字节的的和,再除以265,取余数(用“%”即可)。

命令共2大类,motion命令,和非motion命令(注:可以称为基本命令和扩展命令/高级命令)。其中motion命令,在CMND2中Bit0始终为0。反之,该比特为1表示非motion命令。
motion命令包含了水平移动、垂直移动、光圈、变焦、对焦等功能。这类命令是由命令1和命令2的各个位来表示的。如下图:

要实现某一项功能,只要在对应的位置设为1即可,有些命令是可以同时设置的,但有些是不行的,比如,可以同时实现左(右)转和向上(下)转动,但不能同时左转及右转(两者是互斥的)。

Bit7含义为“sense bit”(sense一词,在linux内核中使用比较多,我其实也搞不明白这个词中文该怎么表达),它决定了Bit4和Bit3的含义。如下图所示:

其实说白了,就是这3个比特的哪些组合可以控制相机上断电,自动扫描,哪些无效,等等。说到这里,想起来了公司某部门发的一个邮件,说某客户想接入云台,是用派尔高协议来控制的,然后还顺带一个中文的协议文档,这个文档翻译得不伦不类,应该是机器翻译的,把“sense bit”翻译成“感觉字节”,一开始看中文文档时,完全一头雾水,后面经过努力,上网上查了英文原版,才有点理解。所以,有时候,看英文原版获取的资源更通俗,更准确。

二、响应

相机返回的响应包有4种,0字节、4字节、7字节、18字节。除了第一种外,其它每种都和上面给出的命令格式相似,同步头+相机地址+信息体+检验码。文档中有每种响应包的具体格式的描述,如果格式来解析即可得到想要的数据。文档中说大部分命令是有返回值的——像上面的motion命令,也有响应包,但我实际测试的结果,串口是没有返回什么数据的,或者是我拿到的那个东西本身就是这样的。

三、协议文档备注

协议文档中每条命令都讲得比较细,不过,有部分命令是厂家自己实现的,比如,有些命令超过7个字节,这跟协议上讲的有冲突,但实际上却是可以的。这个主要是看厂家提供的协议文档了。说到这,不得不提现在我接手的这个任务,厂家提供的文档惜墨如金,不肯多写一点字,文档又不规范,东写一点,西写一点,给的文档也不全,有些命令还要问人家才知道。

四、实现

为了方便,专门为pelco通信定义了PELCOPacket_t结构体(其实它和上一篇文章的visca那个结构体是同一个东西),命令封装如下:

    void _pelco_append_byte(PELCOPacket_t *packet, unsigned char byte)
    {
        packet->bytes[packet->length]=byte;
        (packet->length)++;
    }
     
    void _pelco_init_packet(PELCOPacket_t *packet)
    {
        // set it to null
        memset(packet->bytes, '\0', sizeof(packet->bytes));
        // we start writing at byte 2, the first byte and the second will be filled by the
        // packet sending function(_pelco_send_packet). This function will also append a cksm.
        packet->length = 2;
    }

注意,初始化时,命令包的长度是2,因为pelco协议的真正数据是从第2个字节开始的,这让调用者关注的是真正的数据,而不用理会同步头、相机地址等信息。命令发送如下:

    // All commands are 7 bytes long in D Protocol
    int _pelco_send_packet(PELCOInterface_t *iface, PELCOPacket_t *packet)
    {
        int cksm = 0;
        int i = 0;
     
        // check data:
        if (iface->address>0xff)
        {
            return PELCO_FAILURE;
        }
     
        // build header:
        packet->bytes[0] = 0xff;
        packet->bytes[1] = iface->address;
     
        // see spec, some cmd has 7 bytes, some has 9 bytes
        for (i = 0; i < packet->length; i++)
        {
            cksm += packet->bytes[1+i];
        }
        cksm  = cksm % 0x100;
     
        /*
        cksm = (packet->bytes[1] + packet->bytes[2] + packet->bytes[3] +
                packet->bytes[4] + packet->bytes[5]) % 0x100;
        */
        // append footer(cksm)
        _pelco_append_byte(packet,cksm);
     
        return _pelco_write_packet_data(iface,packet);
        
        
    }

因为有些命令不只有7个字节,所以这里用for循环计算每个需要计算的字节,而不是指定哪一些字节被计算。

命令的封装接口比较简单,基本上和visca一样,比如,像stop命令,就是所有的信息体都搞成0就行了。

    int pelco_camera_stop(PELCOInterface_t *iface)
    {
        PELCOPacket_t packet;
     
        _pelco_init_packet(&packet);
        _pelco_append_byte(&packet,0x00);
        _pelco_append_byte(&packet,0x00);
        _pelco_append_byte(&packet,0x00);
        _pelco_append_byte(&packet,0x00);
     
        return _pelco_send_packet_no_reply(iface, &packet);
    }


参考资源:

1、一个C#实现的工程:http://www.codeproject.com/Articles/8034/Pelco-P-and-D-protocol-implementation-in-C

2、一个图文并茂的示例:http://www.commfront.com/RS232_Examples/CCTV/Pelco_D_Pelco_P_Examples_Tutorial.HTM

后记:本文出现很多次“搞”,近来的确是东搞西搞,人在公司,身不由己。本文仅对协议进行描述,不贴出实际的实现代码。
https://blog.csdn.net/subfate/article/details/36644419

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值