前景描述:
在控制電機運動時,一方面需要從串口發出運動信號讓電機轉動,另一方面電機運動完成后應反饋一個信號告訴上位機運動已完成,可接收下一步的運動信號。如果沒有此反饋信號的檢測,會造成運動指令的丟失。因而,電機運動的控制演算法應為:
1.發送運動指令;
2.接收反饋信號;
如此回圈,直至滿足停止條件。
目前,
第1步,我利用了MSCOMM控制元件用于串口通信,給電機發送指定運動信號:
m_mscomm.put_Output(COleVariant(hexdata)); //此處將運動資料hexdata輸入串口,從而電機運動
第2步,從串口接收反饋信號時,我利用了事件處理機制。首先定義了全域事件:
HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
當串口接收到電機反饋的信號時,設定事件為有信號:
SetEvent(hEvent);
并在程式中等待:
WaitForSingleObject(hEvent, INFINITE);
于是我的電機回圈控制為:
while(1)
{
m_mscomm.put_Output(COleVariant(hexdata)); //發送運動指令
WaitForSingleObject(hEvent, INFINITE); //等待接收反饋信號
}
問題描述:
然而現實并未按照我所設想的,先發送運動指令,然后等待接收反饋信號,接收到后又發送運動指令,如此回圈,使得電機不停向前運動。我想請教下,我該如何修改才能實作這樣一種電機運動控制模式。
uj5u.com熱心網友回復:
要創建手動重置的事件,多除錯多除錯uj5u.com熱心網友回復:
先看看你的命令有么有發送給串口,收到處理等。估計有死鎖uj5u.com熱心網友回復:
首先將要發送的運行信號存到陣列里,首先串口發送第一個運行信號,設定定時器,如果定時器時間里還沒有收到反饋則(XXX),如果收到則發送下一條命令關于串口發送和接收可以參考這文章http://blog.csdn.net/cvbtvbwu/article/details/24694739,
uj5u.com熱心網友回復:
你好!多謝你的解答!這個方法應該有一個不足在于定時器的時間是固定的,一旦程式讓電機走個大步子轉動時間超出定時器時長,會出現誤判;另一方面,如果電機走個小步子轉動時間小于定時器時長,則會出現電機運行一頓一頓的。
uj5u.com熱心網友回復:
不行設定定時器很小嗎?500毫秒檢測是否收到資料
uj5u.com熱心網友回復:
問題的關鍵在于,如果將程式寫為:m_mscomm.put_Output(COleVariant(hexdata)); //發送運動指令
WaitForSingleObject(hEvent, INFINITE); //等待接收反饋信號
發現程式會卡死在WaitForSingleObject(hEvent, INFINITE); 導致MSCOMM控制元件的訊息處理函式無法回應電機反饋信號
為此開辟執行緒,專門用于等待接收反饋信號:
hThread = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);
在執行緒處理函式中等待串口反饋信號,因而目前電機控制程式為:
void CautoDlg::OnBnClickedFrontButton()
{
// TODO: 在此添加控制元件通知處理程式代碼
m_mscomm.put_Output(COleVariant(hexdata));
hThread = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);
}
DWORD WINAPI ThreadProc(LPVOID lpParam)
{
DWORD dReturn = WaitForSingleObject(hEvent, INFINITE);
if (WAIT_OBJECT_0 == dReturn)
{
AfxMessageBox(_T("反饋信號已接收!"));
}
return 0;
}
程式運行正常,但只能按一次按鈕,電機轉動一次,但目前我不知道如何實作回圈發送呢?也就是回圈發送電機運動信號,并檢測反饋信號。有點不清楚,怎么在while回圈或者其他方法中實作這一個回圈程序。
uj5u.com熱心網友回復:
位置環 控制?uj5u.com熱心網友回復:
同問這一個問題,我找了很久,都沒有人關注這個東西。我原本的思路是開兩個執行緒,一個發送無限運動指令,然后死回圈等待,同時另一個執行緒監控串口的事件,一旦收到限位信號,則跳出第一個死回圈,但是容易造成程式假死……
都沒有人可以指點這個問題,好憂桑
uj5u.com熱心網友回復:
有應答的方式肯定需要個超時控制, 超時方式如果可以用阻塞方式反而會更好, 比如函式設計如下輸入引數: 輸入資料, 超時時間
回傳: 接收資料, 成功與否
uj5u.com熱心網友回復:
其實就是一個通信協議而已。。。上位機采用完成埠來做;自己搜一下“完成埠”。。。單片機就得用中斷來實作。
你不會是要弄G指令決議吧??CNC數控?據說有很多開源的。叫GBLR??還是GLBR 好像。ardnio上挺多。
uj5u.com熱心網友回復:
來一個成員變數Isrunning?void CautoDlg::OnBnClickedFrontButton()
{
// TODO: 在此添加控制元件通知處理程式代碼
m_mscomm.put_Output(COleVariant(hexdata));
hThread = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);
Isrunning=1;
while(Isrunning)
{
m_mscomm.put_Output(COleVariant(hexdata));
}
}
在來個按鈕控制結束?
uj5u.com熱心網友回復:
是不是需要沿信號
uj5u.com熱心網友回復:
"另一方面電機運動完成后應反饋一個信號告訴上位機運動已完成,"通過串口反饋的話,就是接受一個 字符 如 ‘OK’
uj5u.com熱心網友回復:
小心“慷訓誤差”轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/111012.html
標籤:基礎類
