前景描述:
在控制电机运动时,一方面需要从串口发出运动信号让电机转动,另一方面电机运动完成后应反馈一个信号告诉上位机运动已完成,可接收下一步的运动信号。如果没有此反馈信号的检测,会造成运动指令的丢失。因而,电机运动的控制算法应为:
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);                 //等待接收反馈信号
}
问题描述:
然而现实并未按照我所设想的,先发送运动指令,然后等待接收反馈信号,接收到后又发送运动指令,如此循环,使得电机不停向前运动。我想请教下,我该如何修改才能实现这样一种电机运动控制模式。

解决方案 »

  1.   

    首先将要发送的运行信号存到数组里,首先串口发送第一个运行信号,设置定时器,如果定时器时间里还没有收到反馈则(XXX),如果收到则发送下一条命令
    关于串口发送和接收可以参考这文章http://blog.csdn.net/cvbtvbwu/article/details/24694739,
      

  2.   

    问题的关键在于,如果将程序写为:
    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循环或者其他方法中实现这一个循环过程。
      

  3.   

    其实就是一个通信协议而已上位机采用完成端口来做;自己搜一下“完成端口”单片机就得用中断来实现。你不会是要弄G指令解析吧??CNC数控?据说有很多开源的。叫GBLR??还是GLBR 好像。ardnio上挺多。
      

  4.   

    来一个成员变量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));
            }
    }在来个按钮控制结束?