Easy to use motion control card: IO configuration and zero return motion

Posted by unclebob on Mon, 08 Nov 2021 10:26:02 +0100

Today, positive motion technology will share with you how ECI3808 of motion control card uses C + + to write controller zero return motion and configure IO accordingly.

1, ECI3808 hardware introduction

1. Function introduction

ECI3808 series control card supports up to 12 axis linear interpolation, arbitrary arc interpolation, spatial arc interpolation, spiral interpolation, electronic cam, electronic gear, synchronous follow, virtual shaft, mechanical finger command, etc; The optimized network communication protocol can realize real-time motion control.

ECI3808 series motion control card supports Ethernet and RS232 communication interface to connect with the computer, receive the instructions of the computer, and connect each expansion module through CAN bus to expand the input and output points or motion axis.

The application program of ECI3808 series motion control card can be developed by using VC, VB, VS, C + +, c# and other software. The dynamic library zmotion.dll is required when the program runs. During debugging, ZDevelop software can be connected to the controller at the same time, so as to facilitate debugging and observation.

2. Hardware interface

Universal input circuit

Universal output circuit

AD/DA interface description


Local pulse axis description

3. Basic information of controller

2, C + + for motion control development

1. Create a new MFC project and add a function library

(1) In VS2015 menu "file" → "new" → "project", start the create project wizard.

(2) Select the development language as "Visual C + +" and the program type as "MFC application".

(3) Click next.

(4) Select "dialog based" as the type. Next or finish.

(5) Find the CD data provided by the manufacturer. The path is as follows (64 bit library as an example).

A. Enter the CD data provided by the manufacturer, find the "8.PC function" folder, and click to enter.

B. Select the function library 2.1 folder.

C. Select the Windows Platforms folder.

D. Select the corresponding function library as required. Here, select the 64 bit library.

E. Unzip the compressed package of C + +, which contains the corresponding function library of C + +.

F. The specific path of the function library is as follows.

(6) Copy the C + + library files and related header files provided by the manufacturer to the new project.

(7) Add static libraries and related header files to the project.

A. Right click the project file, and then select Add → existing item.

B. In the pop-up window, add the static library and related header files in turn.

(8) Declare the header file used and define the controller connection handle.

At this point, the new project is completed and MFC project development can be carried out.

2. Check the PC function manual and be familiar with relevant function interfaces.

(1) The PC function manual is also in the CD-ROM, and the specific path is as follows: "CD-ROM \ 8.PC function \ function library 2.1\ZMotion function library programming manual V2.1.pdf"

(2) Link controller to get the link handle.

ZAux_OpenEth() interface description:

(3) The function interfaces corresponding to IO signal points are configured as follows.

For a detailed description of the interface, please refer to the PC function manual.

The following is the calling interface for zero return movement and the detailed description of the zero return mode. Adding 10 means that after encountering the limit, it will not encounter the limit stop. For example, 13 = mode 3 + limit reverse finding 10 is used when the origin is in the middle.

3.MFC development controller hardware peripheral reading and writing routines.

(1) The routine interface is as follows.

(2) the interface function ZAux_ of the calling link controller in the event handling function of the link button. Openeth() links with the controller. After the link is successful, start timer 1 to monitor the controller status.

//Network interface link controller

void CSingle_move_Dlg::OnOpen()

{

    char   buffer[256]; 

    int32 iresult;

    //If already linked, disconnect the link first

    if(NULL != g_handle)

    {

        ZAux_Close(g_handle);

        g_handle = NULL;

    }

    //Select get IP address from the IP drop-down box

    GetDlgItemText(IDC_IPLIST,buffer,255);

    buffer[255] = '\0';

    //Start linking controller

    iresult = ZAux_OpenEth(buffer, &g_handle);

    if(ERR_SUCCESS != iresult)

    {

        g_handle = NULL;

        MessageBox(_T("link failure"));

        SetWindowText("Not linked");

        return;

    }

    //Link successfully started timer 1

    SetWindowText("Linked");

    SetTimer( 1, 100, NULL );  

}

(3) Monitor the controller status through the timer.

void CFuncWrapperDlg::OnTimer(UINT_PTR nIDEvent)

{

    // TODO: add message handler code here and / or call default values

    if(NULL == g_handle)

    {

        MessageBox(_T("Link broken"));

        return ;

    }

    if(1 == nIDEvent)

    {

        CString string;

        float position[4] = {0};

        int status[4] = {0}; 

        int nAxisStatus[4] = {0};

        for (int i = 0;i< 4; i++)

        {

            ZAux_Direct_GetDpos( g_handle,i,&position[i]);          //Gets the current axis position

            ZAux_Direct_GetIfIdle(g_handle,i,&status[i]);           //Judge the current axis state

            ZAux_Direct_GetAxisStatus(g_handle, i, &nAxisStatus[i]);

        }

        if (status[0] == -1)

        {

            if (nAxisStatus[0] == 0 || (nAxisStatus[0] & 0x000040) == 64)

            {

                string.Format("X  stop it  %.2f   The shaft status is normal", position[0]);

                GetDlgItem(IDC_STATE_X)->SetWindowText(string);

            }

            if ((nAxisStatus[0] & 0x000010) == 16)

            {

                string.Format("X  stop it  %.2f   Shaft positive hard limit alarm", position[0]);

                GetDlgItem(IDC_STATE_X)->SetWindowText(string);

            }

            if ((nAxisStatus[0] & 0x000020) == 32)

            {

                string.Format("X  stop it  %.2f   Shaft reverse hard limit alarm", position[0]);

                GetDlgItem(IDC_STATE_X)->SetWindowText(string);

             }

        

        }

        else

        {

             if (nAxisStatus[0] == 0 || (nAxisStatus[0] & 0x000040) == 64)

             {

                string.Format("X  In operation  %.2f   The shaft status is normal", position[0]);

                GetDlgItem(IDC_STATE_X)->SetWindowText(string);

             }

             if ((nAxisStatus[0] & 0x000010) == 16)

             {

                string.Format("X  In operation  %.2f   Shaft positive hard limit alarm", position[0]);

                GetDlgItem(IDC_STATE_X)->SetWindowText(string);

             }

             if ((nAxisStatus[0] & 0x000020) == 32)

             {

                string.Format("X  In operation  %.2f   Shaft reverse hard limit alarm", position[0]);

                GetDlgItem(IDC_STATE_X)->SetWindowText(string);

             }

        }

        if (status[1] == -1)

        {

            if (nAxisStatus[1] == 0 || (nAxisStatus[1] & 0x000040) == 64)

            {

                string.Format("Y  stop it  %.2f   The shaft status is normal", position[1]);

                GetDlgItem(IDC_STATE_Y)->SetWindowText(string);

            }

            if ((nAxisStatus[1] & 0x000010) == 16)

            {

                string.Format("Y  stop it  %.2f   Shaft positive hard limit alarm", position[1]);

                GetDlgItem(IDC_STATE_Y)->SetWindowText(string);

            }

            if ((nAxisStatus[1] & 0x000020) == 32)

            {

                string.Format("Y  stop it  %.2f   Shaft reverse hard limit alarm", position[1]);

                GetDlgItem(IDC_STATE_Y)->SetWindowText(string);

            }

        }

        else

        {

            if (nAxisStatus[1] == 0 || (nAxisStatus[1] & 0x000040) == 64)

            {

                string.Format("Y  In operation  %.2f   The shaft status is normal", position[1]);

                GetDlgItem(IDC_STATE_Y)->SetWindowText(string);

            }

            if ((nAxisStatus[1] & 0x000010) == 16)

            {

                string.Format("Y  In operation  %.2f   Shaft positive hard limit alarm", position[1]);

                GetDlgItem(IDC_STATE_Y)->SetWindowText(string);

            }

            if ((nAxisStatus[1] & 0x000020) == 32)

            {

                string.Format("Y  In operation  %.2f   Shaft reverse hard limit alarm", position[1]);

                GetDlgItem(IDC_STATE_Y)->SetWindowText(string);

            }

        }    

        if (status[2] == -1)

        {

            if (nAxisStatus[2] == 0 || (nAxisStatus[2] & 0x000040) == 64)

            {

                string.Format("Z  stop it  %.2f   The shaft status is normal", position[2]);

                GetDlgItem(IDC_STATE_Z)->SetWindowText(string);

            }

            if ((nAxisStatus[2] & 0x000010) == 16)

            {

                string.Format("Z  stop it  %.2f   Shaft positive hard limit alarm", position[2]);

                GetDlgItem(IDC_STATE_Z)->SetWindowText(string);

            }

            if ((nAxisStatus[2] & 0x000020) == 32)

            {

                string.Format("Z  stop it  %.2f   Shaft reverse hard limit alarm", position[2]);

                GetDlgItem(IDC_STATE_Z)->SetWindowText(string);

            }

        }

        else

        {

            if (nAxisStatus[2] == 0 || (nAxisStatus[2] & 0x000040) == 64)

            {

                string.Format("Z  In operation  %.2f   The shaft status is normal", position[2]);

                GetDlgItem(IDC_STATE_Z)->SetWindowText(string);

            }

            if ((nAxisStatus[2] & 0x000010) == 16)

            {

                string.Format("Z  In operation  %.2f   Shaft positive hard limit alarm", position[2]);

                GetDlgItem(IDC_STATE_Z)->SetWindowText(string);

            }

            if ((nAxisStatus[2] & 0x000020) == 32)

            {

                string.Format("Z  In operation  %.2f   Shaft reverse hard limit alarm", position[2]);

                GetDlgItem(IDC_STATE_Z)->SetWindowText(string);

            }

        } 

        if (status[3] == -1)

        {

            if (nAxisStatus[3] == 0 || (nAxisStatus[3] & 0x000040) == 64)

            {

                string.Format("R  stop it  %.2f   The shaft status is normal", position[3]);

                GetDlgItem(IDC_STATE_R)->SetWindowText(string);

            }

            if ((nAxisStatus[3] & 0x000010) == 16)

            {

                string.Format("R  stop it  %.2f   Shaft positive hard limit alarm", position[3]);

                GetDlgItem(IDC_STATE_R)->SetWindowText(string);

            }

            if ((nAxisStatus[3] & 0x000020) == 32)

            {

                string.Format("R  stop it  %.2f   Shaft reverse hard limit alarm", position[3]);

                GetDlgItem(IDC_STATE_R)->SetWindowText(string);

            }

        }

        else

        {

            if (nAxisStatus[3] == 0 || (nAxisStatus[3] & 0x000040) == 64)

            {

                string.Format("R  In operation  %.2f   The shaft status is normal", position[3]);

                GetDlgItem(IDC_STATE_R)->SetWindowText(string);

            }

            if ((nAxisStatus[3] & 0x000010) == 16)

            {

                string.Format("R  In operation  %.2f   Shaft positive hard limit alarm", position[3]);

                GetDlgItem(IDC_STATE_R)->SetWindowText(string);

            }

            if ((nAxisStatus[3] & 0x000020) == 32)

            {

                string.Format("R  In operation  %.2f   Shaft reverse hard limit alarm", position[3]);

                GetDlgItem(IDC_STATE_R)->SetWindowText(string);

            }

        }     

    }

    CDialog::OnTimer(nIDEvent);

}

(4) Use the event handler function of the return to zero button to initialize the parameters before the return to zero movement and call the corresponding return to zero mode to operate the return to zero movement.

void CSingle_homeDlg::OnHome()          //Zero return motion

{

    // TODO: Add your control notification handler code here

    UpdateData(true);//Refresh parameters

    int status = 0; 

    ZAux_Direct_GetIfIdle(g_handle, m_nAxis,&status);           //Judge the current axis state

    if (status == 0) //Already in motion

    {

        return; 

    }

    //Set axis type 7 - pulse axis type + encoder Z signal can also be set to 1 without EZ zeroing  

    ZAux_Direct_SetAtype(g_handle, m_nAxis, 7);

    //Set pulse mode and logic direction (pulse + direction)  

    ZAux_Direct_SetInvertStep(g_handle, m_nAxis, 0);  

    //Set pulse equivalent 1 represents the number of pulses set to 1MM in one pulse, and the measurement unit is MM

    ZAux_Direct_SetUnits(g_handle, m_nAxis, m_units);

    //Set speed, acceleration and deceleration

    ZAux_Direct_SetLspeed(g_handle, m_nAxis, m_lspeed);

    ZAux_Direct_SetSpeed(g_handle, m_nAxis, m_speed);

    ZAux_Direct_SetAccel(g_handle, m_nAxis, m_acc);

    ZAux_Direct_SetDecel(g_handle, m_nAxis, m_dec);

    ZAux_Direct_SetCreep(g_handle, m_nAxis, m_creep);

    //Set the zero point input port signal of the corresponding axis

    ZAux_Direct_SetDatumIn(g_handle, m_nAxis, m_datumin);

    //ZMC series thinks that it encounters the origin signal (normally closed) when OFF. If it is a normally open sensor, it needs to reverse the input port, and ECI series does not need to reverse

    ZAux_Direct_SetInvertIn(g_handle, m_datumin, 1);  

    //Set the zero point input port signal of the corresponding axis

    ZAux_Direct_SetFwdIn(g_handle, m_nAxis, m_FwdIn);

    //ZMC series thinks that it encounters the origin signal (normally closed) when OFF. If it is a normally open sensor, it needs to reverse the input port, and ECI series does not need to reverse

    ZAux_Direct_SetInvertIn(g_handle, m_FwdIn, 1);

    //Set the zero point input port signal of the corresponding axis

    ZAux_Direct_SetRevIn(g_handle, m_nAxis, m_RevIn);

    //ZMC series thinks that it encounters the origin signal (normally closed) when OFF. If it is a normally open sensor, it needs to reverse the input port, and ECI series does not need to reverse

    ZAux_Direct_SetInvertIn(g_handle, m_RevIn, 1);

    //Return to zero

    if( m_datummode < 4) 

    {

        ZAux_Direct_Single_Datum(g_handle, m_nAxis, m_datummode + 1);  //Mode 1-4  

    }

    else

    {

        ZAux_Direct_Single_Datum(g_handle, m_nAxis, m_datummode + 4 ); //Mode 8, 9

    }

    UpdateData(false);  

}

(5) Stop the current motion by the event handler of the stop motion button.

void CSingle_homeDlg::OnStop()          //Stop movement

{

    // TODO: Add your control notification handler code here

    if(NULL == g_handle)

    {

        MessageBox(_T("Link broken status"));

        return ;

    }

    ZAux_Direct_Single_Cancel(g_handle,m_nAxis,2);        //

}

(6) The coordinates of the current axis are correspondingly cleared through the event processing function of the coordinate reset button.

void CSingle_homeDlg::OnZero()          //Coordinate reset

{

    if(NULL == g_handle)

    {

        MessageBox(_T("Link broken status"));

        return ;

    }

    // TODO: Add your control notification handler code here

    for (int i=0;i<4;i++) 

    {

        ZAux_Direct_SetDpos(g_handle,i,0);        //Set zero

    }

}

3, Commissioning and monitoring

Compile and run the routine, and connect the controller through ZDevelop software to monitor the controller status.

1. Connect ZDevelop software and click "view" → "oscilloscope" to open the oscilloscope to monitor the shaft movement.

2.ZDevelop software debugging video.

Easy to use motion control card (V) IO configuration and zero return motion

This time, the simple and easy-to-use motion control card of positive motion technology (V): IO configuration and zero return motion, which is shared here.

For more interesting content, please pay attention to the "public assistant" official account, and you need the relevant development environment and routine code. Please consult the sales engineer of the sports technology.

This article is original by positive motion technology. You are welcome to reprint it and learn together to improve China's intelligent manufacturing level. The copyright of this article belongs to rightmovement technology. If you reprint it, please indicate the source of the article.

Topics: software testing