visca是索尼公司搞出来的,用来控制相机的协议,一般通过rs232来通信(看了些资料,也有用rs485的)。

一、命令格式

命令通信的基本单元称为包(Packet)。一个包的长度为3到16字节,由头部、消息体和结束符三部分组成。命令包的第一个字节称为命令头(Header)。高半字节由1 (最高位,固定为1)和发送方(控制者)地址(地址一般为0)组成,低半字节由0和设备(相机)地址(或称“编号”)组成,从组成格式看,可以外接的相机最多有7台,如向1号相机发送命令,则命令头为0x81。命令包最后一个字节为终结符号,固定为0xff。中间部分字节称为消息体。协议说明文档中将命令头写成“8x”,其中x表示相机地址。

命令共2类:普通命令(Command)及查询命令(Inquiry)。前者是直接发送命令到相机,后者是从相机获取到数据。
具体的命令包格式如下:
8X QQ RR … FF
其中QQ为命令分类,01表示普通命令,09表示查询命令。RR为类别码(Category code)。X表示相机地址。范围1~7。

二、响应

每个命令均有响应包,格式如下:
X0 … … FF
其中X范围为9~F,数值为相机编号+8。以FF结束。发送普通命令时,相机会返回ACK响应,但查询命令不会返回ACK。

ACK响应包格式:X0 41 FF
普通命令响应包格式:X0 51 FF
查询命令响应包格式:X0 51 ... FF
其中,X范围为9~F,是相机地址值+8。查询命令的响应包中带有数据,每种数据均不相同,可以询查协议文档。

错误信息格式如下:
语法错误:X0 61 02 FF
命令取消:X0 61 04 FF
没有socket:X0 61 05 FF
命令没有执行:X0 61 41 FF
其中X的值和上面的一样。“socket”的范围暂时还不太了解。这些值就是代码做出判断的依据。

三、协议文档备注
对于协议文档中qprs这类的描述方式,直接将其放到16位的十六进制数据的各项(十六进制格式为0xAAAA)中即可。比如一个命令的响应包格式为“y0  50  0p 0q  0r  0s  FF”,则实际得到的数据是0xpqrs。如“01 02 03 04”,对应数据为0x1234。反之亦然。在代码中用移位来实现即可。下面看几个经典的命令格式。

1、不带参数的命令
相机上电CAM_Power命令格式: 8x  01  04  00  02  FF
“8x”中的“x”表示相机编号。此类命令,直接按命令字段来组装即可。

2、带参数的命令
变焦CAM_Zoom命令格式为:8x  01  04  47  0p 0q  0r  0s  FF。
“0p 0q 0r 0s”中的pqrs组成focus position参数。组装命令时,要将这个参数依次移位到对应的字段。假设参数值为0x1234,则对应的字段为“01 02 03 04”。
CAM_AFMode命令可以设置Active/Interval Time两个值,格式为:8x  01  04  27  0p 0q  0r  0s  FF
“0p 0q”对应于movement time,“0r 0s”对应于Interval,组装命令时,要分别进行组装。方式见上。

3、查询类命令,不带参数
像CAM_PowerInq查询命令,发送8x  09  04  00  FF,直接返回y0  50  02  FF或y0  50  03  FF
其中“y0  50  02  FF”是返回的数据,y值为相机编号+8。对于此类命令,直接读取第3个字节即可得到对应的状态。

4、查询类命令,带参数
像CAM_ZoomPosInq命令,发送8x  09  04  47  FF,返回y0  50  0p 0q  0r  0s  FF
在查询命令中,有大部分的命令是带有可变数据的,“y0  50  0p 0q  0r  0s  FF”中的“0p 0q 0r 0s”需要移位后才能知道确切的值,对应的值为0xpqrs。

四、实现

很庆幸,关于visca,已经有libvisca开源项目了(见参考资源)。下面参考这个项目,做了一些小修改,写一下关键的实现代码。

关于串口的打开、读写、关闭,在此不再多说。下面说一下命令的封装:

[cpp] view plain copy
  1. void _visca_append_byte(VISCAPacket_t *packet, unsigned char byte)
  2. {
  3. packet->bytes[packet->length]=byte;
  4. (packet->length)++;
  5. }
  6. void _visca_init_packet(VISCAPacket_t *packet)
  7. {
  8. // set it to null
  9. memset(packet->bytes, '\0', sizeof(packet->bytes));
  10. // we start writing at byte 1, the first byte will be filled by the
  11. // packet sending function(_visca_send_packet). This function will also append a terminator.
  12. packet->length=1;
  13. }
[cpp] view plain copy
  1. void _visca_append_byte(VISCAPacket_t *packet, unsigned char byte)
  2. {
  3. packet->bytes[packet->length]=byte;
  4. (packet->length)++;
  5. }
  6. void _visca_init_packet(VISCAPacket_t *packet)
  7. {
  8. // set it to null
  9. memset(packet->bytes, '\0', sizeof(packet->bytes));
  10. // we start writing at byte 1, the first byte will be filled by the
  11. // packet sending function(_visca_send_packet). This function will also append a terminator.
  12. packet->length=1;
  13. }

这两个函数是命令的填充,每次调用_visca_append_byte就填充一个字符,在未填充前,要调用_visca_init_packet来初始化包的长度。当然,实现上也可以直接用数组形式把每个命令合到一起发送出去。_visca_send_packet是填充头部和尾部数据,无须调用者进行考虑,调用者只需关注实际的命令数据即可。这也是使用了VISCAInterface_t的好处(后面写pelco实现的将会看到)。

[cpp] view plain copy
  1. int32_t _visca_send_packet(VISCAInterface_t *iface, VISCACamera_t *camera, VISCAPacket_t *packet)
  2. {
  3. // check data:
  4. if ((iface->address>7)||(camera->address>7)||(iface->broadcast>1))
  5. {
  6. com_print("(%s): Invalid header parameters\n",__FILE__);
  7. com_print("addr: %d %d broadcast: %d(0x%x)\n",iface->address,camera->address,
  8. iface->broadcast,iface->broadcast);
  9. return VISCA_FAILURE;
  10. }
  11. // build header:
  12. packet->bytes[0]=0x80;
  13. packet->bytes[0]|=(iface->address << 4);
  14. if (iface->broadcast>0)
  15. {
  16. packet->bytes[0]|=(iface->broadcast << 3);
  17. packet->bytes[0]&=0xF8;
  18. }
  19. else
  20. {
  21. packet->bytes[0]|=camera->address;
  22. }
  23. // append footer(0xff)
  24. _visca_append_byte(packet,VISCA_TERMINATOR);
  25. return _visca_write_packet_data(iface,packet);
  26. }
[cpp] view plain copy
  1. int32_t _visca_send_packet(VISCAInterface_t *iface, VISCACamera_t *camera, VISCAPacket_t *packet)
  2. {
  3. // check data:
  4. if ((iface->address>7)||(camera->address>7)||(iface->broadcast>1))
  5. {
  6. com_print("(%s): Invalid header parameters\n",__FILE__);
  7. com_print("addr: %d %d broadcast: %d(0x%x)\n",iface->address,camera->address,
  8. iface->broadcast,iface->broadcast);
  9. return VISCA_FAILURE;
  10. }
  11. // build header:
  12. packet->bytes[0]=0x80;
  13. packet->bytes[0]|=(iface->address << 4);
  14. if (iface->broadcast>0)
  15. {
  16. packet->bytes[0]|=(iface->broadcast << 3);
  17. packet->bytes[0]&=0xF8;
  18. }
  19. else
  20. {
  21. packet->bytes[0]|=camera->address;
  22. }
  23. // append footer(0xff)
  24. _visca_append_byte(packet,VISCA_TERMINATOR);
  25. return _visca_write_packet_data(iface,packet);
  26. }

命令响应包函数如下:

[cpp] view plain copy
  1. int32_t _visca_get_reply(VISCAInterface_t *iface, VISCACamera_t *camera)
  2. {
  3. // first message: -------------------
  4. if (_visca_get_packet(iface)!= VISCA_SUCCESS)
  5. return VISCA_FAILURE;
  6. iface->type=iface->ibuf[1]&0xF0;
  7. // skip ack messages
  8. while (iface->type==VISCA_RESPONSE_ACK)
  9. {
  10. if (_visca_get_packet(iface)!=VISCA_SUCCESS)
  11. return VISCA_FAILURE;
  12. iface->type=iface->ibuf[1]&0xF0;
  13. }
  14. switch (iface->type)
  15. {
  16. case VISCA_RESPONSE_CLEAR:
  17. return VISCA_SUCCESS;
  18. break;
  19. case VISCA_RESPONSE_ADDRESS:
  20. return VISCA_SUCCESS;
  21. break;
  22. case VISCA_RESPONSE_COMPLETED:
  23. return VISCA_SUCCESS;
  24. break;
  25. case VISCA_RESPONSE_ERROR:
  26. return VISCA_CMDERROR;
  27. break;
  28. }
  29. return VISCA_FAILURE;
  30. }
[cpp] view plain copy
  1. int32_t _visca_get_reply(VISCAInterface_t *iface, VISCACamera_t *camera)
  2. {
  3. // first message: -------------------
  4. if (_visca_get_packet(iface)!= VISCA_SUCCESS)
  5. return VISCA_FAILURE;
  6. iface->type=iface->ibuf[1]&0xF0;
  7. // skip ack messages
  8. while (iface->type==VISCA_RESPONSE_ACK)
  9. {
  10. if (_visca_get_packet(iface)!=VISCA_SUCCESS)
  11. return VISCA_FAILURE;
  12. iface->type=iface->ibuf[1]&0xF0;
  13. }
  14. switch (iface->type)
  15. {
  16. case VISCA_RESPONSE_CLEAR:
  17. return VISCA_SUCCESS;
  18. break;
  19. case VISCA_RESPONSE_ADDRESS:
  20. return VISCA_SUCCESS;
  21. break;
  22. case VISCA_RESPONSE_COMPLETED:
  23. return VISCA_SUCCESS;
  24. break;
  25. case VISCA_RESPONSE_ERROR:
  26. return VISCA_CMDERROR;
  27. break;
  28. }
  29. return VISCA_FAILURE;
  30. }

里面一些宏定义如下:

[cpp] view plain copy
  1. /* response types */
  2. #define VISCA_RESPONSE_CLEAR             0x40
  3. #define VISCA_RESPONSE_ADDRESS           0x30
  4. #define VISCA_RESPONSE_ACK               0x40
  5. #define VISCA_RESPONSE_COMPLETED         0x50
  6. #define VISCA_RESPONSE_ERROR             0x60
[cpp] view plain copy
  1. /* response types */
  2. #define VISCA_RESPONSE_CLEAR             0x40
  3. #define VISCA_RESPONSE_ADDRESS           0x30
  4. #define VISCA_RESPONSE_ACK               0x40
  5. #define VISCA_RESPONSE_COMPLETED         0x50
  6. #define VISCA_RESPONSE_ERROR             0x60

其实判断也十分简单,就是根据协议给出的错误码来一一判断。
其它的代码,直接参考libvisca即可,不在这里列出。

参考资源:

1、开源的visca协议库:libvisca: http://damien.douxchamps.net/libvisca/
2、visca协议的wiki介绍:http://en.wikipedia.org/wiki/VISCA_Protocol

后记:截止本文编写时,手上还没有得到硬件资源,文章是根据libvisca和visca协议文档中的描述来写的,应该不具有实践价值。

李迟记于2014年6月30日

SONY VISCA协议及其简单认识相关推荐

  1. visca协议c语言,VISCA协议控制键盘 SONY VISCA协议会议摄像机控制键盘NK-EVI603K

    SONYVISCA协议视频会议摄像机控制键盘NK-EVI603KC 概述: 派尼珂三位维矢量变速摇杆SONYVISCA协议控制键盘,兼容SONY全系列摄像机模拟及高清会议摄像机控制:EVI-D70P. ...

  2. visca协议及其实现的简单认识

    转载自:https://latelee.blog.csdn.net/article/details/35811777 visca协议及其实现的简单认识 李迟 2014-06-30 14:09:01 7 ...

  3. Android Visca 协议控制电子云镜(Android ndk)

    项目是个教学类TV应用,有一个功能是要控制摄像机的云台控制,就是控制跟踪摄像机的方向(上,下,左,右): 摄像机的焦距(远和近),预制位调用等功能.与跟踪摄像机的通信基于sony 的visca协议,v ...

  4. TCP/IP 协议标准简单描述

    TCP/IP 协议标准简单描述 说明 分为三部分:中文名称.缩写.说明. 应用层 DNS 域名服务 (DNS) 功能: 将域名转化为IP地址 BOOTP 引导程序协议 (BOOTP) 功能: 允许无盘 ...

  5. Qt TCP协议 传输简单字符串实例

    TCP协议的程序使用的是客户端/服务器模式,在Qt中提供了QTcpSocket类来编写客户端程序,使用QTcpServer类编写服务器端程序. A 转载:http://mobile.51cto.com ...

  6. SIP协议及其简单介绍

    SIP协议及其简单介绍 概述 流程 SIP流程 两台设备建立会话 原理 使用场景 概述 SIP(Session Initiation Protocol,会话初始化协议)是一个应用层协议,用于在互联网上 ...

  7. 【网络】tftp协议、简单实用tftpd32工具在主机和虚拟机之间传输文件

    TFTP协议的简单了解学习以及使用 一.前言 在公司里,给设备进行升级的时候使用了一个tftp传输文件工具(Tftpd32),笔记本接上和设备在同一网络下的网线(使二者在同一个局域网下),然后配置Tf ...

  8. 串口RS232 RS485最本质的区别!-!I2C通讯协议 最简单的总线通讯!-深入理解SPi通讯协议!

    5分钟看懂!串口RS232 RS485最本质的区别!-4分钟看懂!I2C通讯协议 最简单的总线通讯!-深入理解SPi通讯协议,5分钟看懂! 一.5分钟看懂!串口RS232 RS485最本质的区别! 二 ...

  9. UDP协议的简单概述

    1.UDP协议概述 UDP是User Datagram Protocol(用户数据协议)的简称,是一种无连接的协议,该协议工作在OSI模型中的第四层(传输层),处于IP协议的上一层.传输层的功能就是建 ...

最新文章

  1. 架构师之前,请先进阶,不要只会 Spring
  2. [UVa10296]Jogging Trails
  3. (转)输入pipt提示:AttributeError: 'module' object has no attribute 'HTTPSConnection'
  4. c语言程序转换成单片机语言,单片机编程常用到的类型转换 C语言程序实现
  5. C++ 简单的语音合成(TTS,即文字转语音)类
  6. java中的命令行参数_Java中的命令行参数
  7. HCIA-IoT V2.5物联网初级考试总结(附题库,历年真题,刷题软件)
  8. PanguVR获得400万种子轮融资,提供高效的VR家装解决方案
  9. c++ 应输入表达式_【C语言编程入门系列】—— 第五章,C语言基本运算和表达式(一)...
  10. Java后端Controller层解析Json数组转对象
  11. SOEM报文数据结构介绍
  12. HTML5+CSS3基础
  13. 龙讯3号 龙芯电脑即将店面销售
  14. 【数据结构与算法】之深入解析“1比特与2比特字符”的求解思路与算法示例
  15. 【无机纳米材料科研制图——OriginLab 0209】Origin散点图线性拟合与非线性拟合
  16. java tapestry_Tapestry简介- 转载 (转自java-cn)
  17. 科研伦理与学术规范 期末考试2(40题)
  18. 什么是老生代的标记算法
  19. 史上全面伊玛尔项目简介大全
  20. 高德地图2016清明出行交通预测报告(完整版)

热门文章

  1. ERROR 2002 (HY00O) : Can‘t connect to local MySQL server through socket ‘ /var/ tib/ mysqL /mysgL.s
  2. Windows环境下msysgit安装git flow
  3. 【收藏】UltraISO制作U盘启动安装CentOS 7.4
  4. ASEMI快恢复二极管型号大全,快恢复常见封装型号
  5. 龙格库塔法求解微分方程
  6. 微软批量许可服务中心注册指南
  7. c# emgucv 切图_(转载)C#下的openCV(Emgu CV)
  8. vue2 打印二维码功能
  9. 佳能打印技术推动艺术品拍卖业务创新高;iQOO 9系列手机搭载Pixelworks X5 Pro视觉处理器 | 全球TMT...
  10. 中小企业 数量 e-mail_采购订单管理——中小企业采购容易忽视的环节