曾經覺得手柄來遙控玩具小車不明覺厲,現在我也能呵呵了。不過用無線來遙控機器人的話,一般要用ZigBee或者無線串口來實現通信了,無線串口還試了一下,和有線的是差不多的,實驗室用的是ZigBee,這一塊不是我做的,不過也基本只是一個收發功能了,用的代碼好像是官方提供的代碼,這就不是我的重點了。
首先,你得有一個遊戲手柄,不過不是用來打遊戲的啦!當然,在我來實驗室之際,師兄就把手柄的接口和庫交給我了,這裏我們需要使用它們,如果你沒有這東西,我可以共享一下,不過在csdn上似乎不行,因爲有100多M,如下.cpp和.h爲接口,使用的時候要添加進工程,其他爲一些庫之類的,在工程中設置到這個目錄就可以了。
轉載請註明:來自xzyfeixiang的專欄http://blog.csdn.net/xzyiverson
我之前做的筆記已經放在csdn的資源上了http://download.csdn.net/detail/xzyfeixiang/6601501
原理如下:
我在上一篇博客http://blog.csdn.net/xzyiverson/article/details/16908179實現了串口收發,接下來在那個工程的基礎上進行手柄的界面的設計。本人水平確實不高,也不是專業搞這個的,會有很多錯誤和漏洞,希望大家指教,誤導之處還望海涵。
1.我已經建好了工程和添加好了串口,這樣,我們將DIJoystick.cpp和DIJoystick.h添加到工程(project)
DIJoystick.h: interface for the CDIJoystick class.
DIJoystick.cpp: implementation of the CDIJoystick class.
2.工具 選項選擇 目錄 include 和lib目錄,這個是提到的庫支持的頭文件和lib文件的目錄設置
3.在Dialog中使用 組框 和複選框,ID修改成IDC_Up等這種,一看就知道這個是Up這個按鈕,標題就修改成Up等,看下圖這樣:
4.爲剛剛這些按鈕的ID添加成員變量,這樣掃描到這各按鈕時,我們就可以將成員變量變成TRUE,否則就爲False,然後根據這些成員變量的值來執行一些相應的函數,大致的原理就是這樣,上面也有原理圖。
View-Classwizard,添加成員變量:
5.在如Dlg.cpp中添加#include"DIJoystick.h"
在// CAboutDlgdialog used for App About後加入
CDIJoystickmyJoystick1;//定義了一個類對象(這個是在Dlg.Cpp中定義
6.我們在使用串口的時候要初始化,在使用手柄的時候也是這樣,初始化代碼寫在OnInitDialog()裏面:
//================遊戲機手柄初始化====================
//設置遊戲機手柄的的窗口句柄
CWnd *jb=this;
myJoystick1.SetHWND(jb->m_hWnd);
LPCDIDEVICEINSTANCE lpddi=NULL;
GUID myguid;
// 獲取手柄的Id,並??????
lpddi=myJoystick1.GetFirstJoystickID();
memcpy(&myguid,&(lpddi->guidInstance),sizeof(GUID));
myJoystick1.SetPreferredDevice(&myguid);
if(!lpddi)
{
MessageBox("I have not been able to find a joystick on your system.","No Joystick Detected",MB_ICONHAND|MB_OK);
OnCancel();
}
//設置採樣間隔
SetTimer(1,300,NULL);
7.添加和編寫Ontime消息函數
注意必須要使用查看-類嚮導來添加這個消息函數。
然後就是編寫這個函數了,
myJoystick1.PollDevice();
if (myJoystick1.IsJoystickFire(0))
{
if (m_1==false)
m_1=true;
else
m_1=false;
}
if (myJoystick1.IsJoystickFire(1))
{
if (m_2==false)
m_2=true;
else
m_2=false;
}
if (myJoystick1.IsJoystickFire(2))
{
if (m_3==false)
m_3=true;
else
m_3=false;
}
if (myJoystick1.IsJoystickFire(3))
{
if (m_4==false)
m_4=true;
else
m_4=false;
}
if (myJoystick1.IsJoystickFire(8))
{
if (m_Select==false)
m_Select=true;
else
m_Select=false;
}
//判斷是否按下了 左鍵
if(myJoystick1.IsJoystickLeft()) m_Left=true; else m_Left=false;
//判斷是否按下 右鍵
if(myJoystick1.IsJoystickRight()) m_Right=true; else m_Right=false;
//判斷是否按下 上鍵
if(myJoystick1.IsJoystickUp()) m_Up=true; else m_Up=false;
//判斷是否按下 下鍵
if(myJoystick1.IsJoystickDown()) m_Down=true; else m_Down=false;
//判斷是否按下 張開鍵
if (myJoystick1.IsJoystickFire(5)) m_R1=true; else m_R1=false;
//判斷是否按下 閉合鍵
if (myJoystick1.IsJoystickFire(7)) m_R2=true; else m_R2=false;
//判斷是否按下 加速鍵
if (myJoystick1.IsJoystickFire(4)) m_L1=true; else m_L1=false;
//判斷是否按下 減速鍵
if (myJoystick1.IsJoystickFire(6))m_L2=true; else m_L2=false;
//速度加減
UpdateData(false);
if(!m_Select) //Control the motor
{
if(m_1)
AllMotorStop();
else
{
if(m_R1) TailUp();
else if(m_R2) TailDown();
else TailStop();
if(m_L1) HeadUp();
else if(m_L2) HeadDown();
else HeadStop();
if(m_Up) MoveForward(m_2); //2鍵按下都會6機聯動
else if(m_Down) MoveBackward(m_2);
else if(m_Left) TurnLeft();
else if(m_Right) TurnRight();
else MoveStop();
// if(m_R1) TailUp();
// else if(m_R2) TailDown();
// else TailStop();
}
說明:UpdateDate(false)之前是掃描獲取鍵值,後面是根據鍵值執行不同的函數。添加和編寫上述的成員函數就可以了。以我下面的爲例:
void CRobotDlg::HeadDown()//3號電機
{
if(robot3_state!=0xf2)
{
CByteArray bytOutArr1;
bytOutArr1.Add(0xAA);
bytOutArr1.Add(0x78);
bytOutArr1.Add(0x04); //長度4
bytOutArr1.Add(0x02); //命令02
bytOutArr1.Add(0x90); //3號電機參數
bytOutArr1.Add(0xF0); //3號電機參數
bytOutArr1.Add(0xf2); //增加一個字節,爲機器人的運動狀態,爲下位機好判斷
bytOutArr1.Add(0xCC);
bytOutArr1.Add(0x33);
bytOutArr1.Add(0xC3);
bytOutArr1.Add(0x3C);
m_CtrlComm.SetOutput(COleVariant(bytOutArr1));
}
}
之前不懂vc(現在也不太懂),上面的東西還倒騰了蠻久的,這個是發送一串數據,先添加到字節數組裏面,然後後面那句你應該熟悉,上個博客也用到了,就是發送出去,你也可以用串口助手來測試一下。
測試結果如下面
我這裏因爲沒有收到電機的反饋值,會一直髮,反正大致思路我應該是說清楚了。這個就是用手柄來做界面了。