📄 新建 文本文档.txt
字号:
不同云台的协议可能不一样,我这里有一个,不知道合不合你用。
//类型定义
typedef struct _CAMERAINFO
{
CHAR Name[32];
BOOL bIsQuickBall; //快球标志
BOOL bHasPanTielt; //云台标志
BOOL bHasMicrophone; //麦克风标志
CHAR szComment[30];
int nQuickBallSpeed;
}CAMERAINFO,CAMERAINFOMATION;
基类:
头文件
// DecoderBase.h: interface for the CDecoderBase class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_DECODERBASE_H__9761EEC3_545E_4FC0_94F4_BAA0DC21AF3C__INCLUDED_)
#define AFX_DECODERBASE_H__9761EEC3_545E_4FC0_94F4_BAA0DC21AF3C__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class CMSComm;
class CDecoderBase
{
public:
CDecoderBase();
~CDecoderBase();
static CMSComm * m_spComm;
int * m_pDecoderID;
CAMERAINFO * m_pDecoderInfo;
public:
virtual VOID Initialize(int nBoardNo);
virtual VOID SetPanTielt(int nAction=0)=0; //设置云台,nAction:0表示自动,1向上,2向下,3向左,4向右
virtual VOID GetPreset(int nIndex,LPSTR szName=NULL)=0; //预置调用,nIndex表示第几个预置位
virtual VOID SetPreset(int nIndex=0,LPSTR szName=NULL)=0; //预置设置,nIndex表示第几个预置位
virtual VOID SetZoom(BOOL bIn=TRUE)=0; //设置镜头倍数,bIn=TRUE表示放大
virtual VOID SetAperture(BOOL bOpen=TRUE)=0; //设置光圈,bOpen表示打开
virtual VOID SetFocus(BOOL bFar=TRUE)=0; //设置焦距,bFar=TRUE表示将焦点调远
BYTE SumArr(LPBYTE pArr,int nCount=7);
};
#endif // !defined(AFX_DECODERBASE_H__9761EEC3_545E_4FC0_94F4_BAA0DC21AF3C__INCLUDED_)
//cpp文件
// DecoderBase.cpp: implementation of the CDecoderBase class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "client2.h"
#include "mscomm.h"
#include "DecoderBase.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CMSComm * CDecoderBase::m_spComm=NULL;
CDecoderBase::CDecoderBase()
{
}
CDecoderBase::~CDecoderBase()
{
}
VOID CDecoderBase::Initialize(int nBoardNo)
{
}
BYTE CDecoderBase::SumArr(LPBYTE pArr,int nCount)
{
BYTE sum=0;
for(int i=0;i<nCount;i++)
{
sum=sum+pArr[i];
}
return sum;
}
//具体的解码器(云台),此处为Alex快球
//头文件
// Alex.h: interface for the CAlex class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_ALEX_H__7DCEEB8B_3C82_4ED7_9BB7_409E63120296__INCLUDED_)
#define AFX_ALEX_H__7DCEEB8B_3C82_4ED7_9BB7_409E63120296__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "DecoderBase.h"
#include "mscomm.h"
class CAlex : public CDecoderBase
{
public:
VOID SetFocus(BOOL bFar=TRUE);
VOID SetAperture(BOOL bOpen=TRUE);
VOID SetZoom(BOOL bIn=TRUE);
VOID SetPanTielt(int nAction=0);
VOID GetPreset(int nIndex, LPSTR szName);
VOID SetPreset(int nIndex = -1, LPSTR szName=NULL);
VOID Initialize(int nBoardNo);
VOID ClearPreset();
CAlex();
CAlex(CMSComm* pComm,CDecoder* pParentDecoder);
virtual ~CAlex();
int m_nPresetCount;
BYTE m_byCmd[7];
CByteArray m_byArrCmd;
};
#endif // !defined(AFX_ALEX_H__7DCEEB8B_3C82_4ED7_9BB7_409E63120296__INCLUDED_)
//cpp文件
// Alex.cpp: implementation of the CAlex class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "client2.h"
#include "Alex.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
//建构函数,参数CMSComm* pComm用于向解码器发送数据,
//CDecoder* pParentDecoder用于取得已经保存好的设置信息,
//例如将快球的速度保存等等,具体保存内容见CAMERAINFO,对于一般的应用可以不要
CAlex::CAlex(CMSComm* pComm,CDecoder* pParentDecoder)
{
if(!m_spComm)
m_spComm=pComm;
if(!m_spComm->GetPortOpen())
{
m_spComm->SetCommPort(1);
m_spComm->SetSettings("4800,N,8,1");
m_spComm->SetPortOpen(TRUE);
}
m_pDecoderInfo=&pParentDecoder->m_DecoderInfo;
Initialize(pParentDecoder->m_nDecoderID );
ZeroMemory(m_byCmd,sizeof(m_byCmd));
m_nPresetCount=1;
}
CAlex::CAlex()
{
}
CAlex::~CAlex()
{
SetPanTielt(5); //先将云台停止动作再退出
}
VOID CAlex::Initialize(int nBoardNo) //初始化解码器,同时设置云台速度
{
//请对照协议填充命令位
m_byArrCmd.SetSize(6);
m_byCmd[0]=0x02;
m_byCmd[1]=0x01;
m_byCmd[2]=14;
m_byCmd[3]=m_pDecoderInfo->nQuickBallSpeed;
m_byCmd[4]=m_byCmd[3];
m_byCmd[5]=0;
m_byCmd[5]=SumArr(m_byCmd,6);
for(int j=0;j<m_byArrCmd.GetSize();j++)
{
m_byArrCmd.SetAt(j,m_byCmd[j]);
}
//利用串口向解码器发送数据
m_spComm->SetOutput(COleVariant(m_byArrCmd));
}
VOID CAlex::SetPreset(int nIndex, LPSTR szName) //设置预置位
{
m_byCmd[0]=0x02;
m_byCmd[1]=0x01;
m_byCmd[2]=0x05;
if(nIndex==-1)
m_byCmd[3]=m_nPresetCount;
else
m_byCmd[3]=nIndex;
m_byCmd[4]=0;
m_byCmd[4]=SumArr(m_byCmd,5);
m_byArrCmd.SetSize(5);
for(int j=0;j<m_byArrCmd.GetSize();j++)
{
m_byArrCmd.SetAt(j,m_byCmd[j]);
}
m_spComm->SetOutput(COleVariant(m_byArrCmd));
m_nPresetCount++;
}
VOID CAlex::GetPreset(int nIndex, LPSTR szName) //调用预置位
{
m_byCmd[0]=0x02;
m_byCmd[1]=0x01;
m_byCmd[2]=0x02;
m_byCmd[3]=nIndex;
m_byCmd[4]=0;
m_byCmd[4]=SumArr(m_byCmd,5);
if(m_byArrCmd.GetSize())
m_byArrCmd.RemoveAll();
m_byArrCmd.SetSize(5);
for(int j=0;j<m_byArrCmd.GetSize();j++)
{
m_byArrCmd.SetAt(j,m_byCmd[j]);
}
m_spComm->SetOutput(COleVariant(m_byArrCmd));
}
VOID CAlex::SetPanTielt(int nAction)
{
//设置云台,nAction:1向上,2向下,3向左,4向右,5停止动作
m_byCmd[0]=0x02;
m_byCmd[1]=0x01;
m_byCmd[2]=0x01;
m_byCmd[4]=0x00;
m_byCmd[5]=0;
switch(nAction)
{
case 1:
m_byCmd[3]=0X04;
m_byCmd[5]=SumArr(m_byCmd);
break;
case 2:
m_byCmd[3]=0X08;
m_byCmd[5]=SumArr(m_byCmd);
break;
case 3:
m_byCmd[3]=0X02;
m_byCmd[5]=SumArr(m_byCmd);
break;
case 4:
m_byCmd[3]=0X01;
m_byCmd[5]=SumArr(m_byCmd);
break;
case 5:
m_byCmd[3]=0X00;
m_byCmd[5]=SumArr(m_byCmd);
break;
}
if(m_byArrCmd.GetSize())
m_byArrCmd.RemoveAll();
m_byArrCmd.SetSize(6);
for(int j=0;j<m_byArrCmd.GetSize();j++)
{
m_byArrCmd.SetAt(j,m_byCmd[j]);
}
m_spComm->SetOutput(COleVariant(m_byArrCmd));
}
VOID CAlex::SetZoom(BOOL bIn) //设置倍数
{
m_byCmd[0]=0x02;
m_byCmd[1]=0x01;
m_byCmd[2]=0x01;
m_byCmd[4]=0x00;
m_byCmd[5]=0;
if(bIn)
{
m_byCmd[3]=32;
m_byCmd[5]=SumArr(m_byCmd);
}
else
{
m_byCmd[3]=16;
m_byCmd[5]=SumArr(m_byCmd);
}
if(m_byArrCmd.GetSize())
m_byArrCmd.RemoveAll();
m_byArrCmd.SetSize(6);
for(int j=0;j<m_byArrCmd.GetSize();j++)
{
m_byArrCmd.SetAt(j,m_byCmd[j]);
}
m_spComm->SetOutput(COleVariant(m_byArrCmd));
}
VOID CAlex::ClearPreset() //清除预置位
{
m_byCmd[0]=0x02;
m_byCmd[1]=0x01;
m_byCmd[2]=0x08;
m_byArrCmd.SetSize(5);
for(int i=0;i<100;i++)
{
m_byCmd[3]=i+1;
m_byCmd[4]=0;
m_byCmd[4]=SumArr(m_byCmd,5);
for(int j=0;j<m_byArrCmd.GetSize();j++)
{
m_byArrCmd.SetAt(j,m_byCmd[j]);
}
m_spComm->SetOutput(COleVariant(m_byArrCmd));
Sleep(50);
}
}
VOID CAlex::SetAperture(BOOL bOpen) //设置光圈(此Alex云台没有光圈)
{
}
VOID CAlex::SetFocus(BOOL bFar) //设置焦距
{
m_byCmd[0]=0x02;
m_byCmd[1]=0x01;
m_byCmd[2]=0x01;
m_byCmd[4]=0x00;
m_byCmd[5]=0;
if(bFar)
m_byCmd[3]=128;
else
m_byCmd[3]=64;
m_byCmd[5]=SumArr(m_byCmd);
if(m_byArrCmd.GetSize())
m_byArrCmd.RemoveAll();
m_byArrCmd.SetSize(6);
for(int j=0;j<m_byArrCmd.GetSize();j++)
{
我现在在写一个云台的控制程序~~通过串口控制它上下左右转动,现在我写好了,云台可以上、下、左、右、上左、下左,下右7个方向分别的转动了~~但是就是上右的方向不能转动,请问是怎么回事呢?以下是我的程序,(C写的):
enum Direct
{
STOP = 0x00,
RIGHT = 0x02,
LEFT = 0x04,
UP = 0x08,
DOWN = 0x10,
LEFTUP=0x0c,
LEFTDOWN=0x14,
RIGHTUP=0x0a,
RIGHTDOWN=0x12
};
void Running(int fd, char chCammerID, char chDir)
{
char strCommOut[7];
strCommOut[0] = 0xFF;
strCommOut[1] = chCammerID;
strCommOut[2] = 0x0;
strCommOut[3] = chDir;
strCommOut[4] = 0x20;
strCommOut[5] = 0x20;
int sum = 0;
for(int i=1; i<6; i++)
{
sum+=strCommOut;
}
if(sum > 0xFF)
strCommOut[6]=sum%0x100;
else
strCommOut[6]=sum;
write(fd,strCommOut,sizeof(strCommOut));
}
int main()
{
char *dev2 ="/dev/ttyS2";
int fd = OpenDev(dev2);
if (fd>0)
SetSpeed(fd,2400);//设置波特率
else
{
printf("Can't Open Serial Port '%s'\n",dev2);
return -1;
}
if (SetParity(fd,8,1,'N')== -1) //设置串口参数
{
printf("Set Parity Error\n");
return -1;
}
Running(fd,2,LEFT); //云台向左转
printf("press any key to stop.\n");
getchar();
Running(fd,2,STOP); //云台停止转动
return 0;
}
云台的控制协议是:PELCO-D:
数据格式:1位起始位、8位数据、1位停止位,无效验位。波特率:2400B/S
命令格式:
字节1 字节2 字节3 字节4 字节5 字节6 字节7
同步字节 地址码 指令码1 指令码2 数据码1 数据码2 校验码
字节4是控制转动方向的,
STOP = 0x00,
RIGHT = 0x02,
LEFT = 0x04,
UP = 0x08,
DOWN = 0x10,
LEFTUP=0x0c,
LEFTDOWN=0x14,
RIGHTUP=0x0a,
RIGHTDOWN=0x12
其他校验码这些都是对的~~那七个方向都能转~~就是右上不行~~我在网上直接下了个编译好了的控制云台的程序,8个方向都是可以运行的,说明云台是没问题的~~肯定是程序的问题~~请高手指点一下呀~~
PS:程序我是在linux下编的,linux是虚拟机FC8~~
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -