⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 新建 文本文档.txt

📁 pelco协议应用 你可以用在单片机控制云台的程序中
💻 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 + -