ZMC406R-V2 Hardware Introduction
The ZMC406R-V2 is a multi-axis, high-performance EtherCAT bus motion controller launched by Zheng Motion. It has communication interfaces such as EtherCAT, EtherNET, RS232, CAN and USB flash drive. The ZMC series motion controllers can be used in various occasions that require offline or online operation.
The ZMC406R-V2 supports 6-axis motion control, expandable to a maximum of 32 axes, and supports linear interpolation, arbitrary circular interpolation, spatial circular interpolation, helical interpolation, electronic cam, electronic gear, synchronous following and other functions.
The ZMC406R-V2 can download edited programs to the controller offline, allowing users to edit desired motion trajectories via touchscreen teaching. It can also be operated using PC API function calls or real-time command transmission, enabling the development of Delta parallel robot applications on a PC using languages such as C#, C++, LabVIEW, and Python.
The ZMC406R-V2 supports 6-axis motion control and can use pulse axes (with encoder feedback) or EtherCAT bus axes. The general-purpose I/O includes 24 input ports and 12 output ports, two analog AD/DA channels, and an EtherCAT refresh cycle of up to 125us.
Hardware Wiring Reference
1. Wiring reference diagram for general input port
2. General output port wiring reference diagram
Development of Delta parallel robotic arms using C#
1. In VS2010, go to "File" → "New" → "Project" to start the Project Creation Wizard.
2. Select "Visual C#" as the development language and .NET Framework 4 as the Windows Forms application.
3. Locate the C# function library in the CD-ROM provided by the manufacturer. The path is as follows (taking the 32-bit library as an example).
1) Go to the CD-ROM provided by the manufacturer, find the "04PC Functions" folder, and click to enter.
2) Select the "Function Library 2.1" folder.
3) Select the "Windows Platform" folder.
4) Select the corresponding function library as needed; here, we choose the 32-bit library.
5) Unzip the C# compressed package, which contains the corresponding C# function library.
6) The specific path to the function library is as follows.
4. Copy the C# library files and related files provided by the vendor into the newly created project.
1) Copy the zmcaux.cs file into the newly created project.
2) Place the zaux.dll and zmotion.dll files into the bin\debug folder.
5. Open the newly created project file in Visual Studio. In the Solution Explorer on the right, click "Show all files," then right-click the zmcaux.cs file and click "Include in project."
6. Double-click Form1 in Form1.cs to open the code editing interface. At the beginning of the file, write "using cszmcaux" and declare the controller handle g_handle.
PC function introduction
1. The PC function manual can be viewed on the CD-ROM. The specific path is as follows.
2. Connect to the controller and obtain the connection handle.
3. Establishment of the forward solution for the robot model.
4. Establishment of the inverse solution of the robot model.
5. Rotate the robot's coordinate system to obtain the user's coordinate system.
1. Axial direction requirements
Using the Delta parallel manipulator model with forward motion, it is necessary to ensure that the three joint axes rotate downwards in the positive direction, and the end-effector rotation axis rotates counterclockwise in the positive direction (top view).
2. Structural parameters (the structural parameters are provided by the robot manufacturer) The structural parameters of the robot need to be written into the TABLE register of the controller before the interface can be called to establish the forward and inverse kinematics of the robot.
3. Definition of Origin A. When all the connecting rods L1 of each joint axis are in a horizontal position, it is considered to be the zero point position of the joint. (Generally, the main body will provide a positioning pin. If not, you can use a level to ensure that L1 is in a horizontal position at the zero point.) B. At this time, the direction of the line connecting axis 0 and axis 1 is the X direction of the rectangular coordinate system, and the zero point of the rectangular coordinate system is located at the center of the horizontal plane of connecting rod L1.
4. Joint Axes and Virtual Axes: Joint axes are actual motor axes. Delta has joint axis 0 motor, joint axis 1 motor, joint axis 2 motor, and end-rotation axis motor. The pulse equivalent settings for these shutdown axes need to be set to the number of pulses required for the corresponding joint axis to rotate 1 degree, such as: (Units = number of pulses per motor revolution * reduction ratio / 360). Virtual axes are virtual rectangular coordinate systems with X, Y, and Z axes and a rotation axis RZ. The recommended pulse equivalent for the X, Y, and Z axes is set to 1000, and the pulse equivalent for the rotation axis RZ is set to the number of pulses required for the rotation axis to rotate 1 degree.
Related routine demonstrations
1. The controller handle is obtained by linking the controller, and the host computer operates the controller by using the obtained handle.
·
// Connect to the controller, the default IP address is 192.168.0.11 ZauxErr = zmcaux.ZAux_OpenEth("192.168.0.11", out g_Handle); if (0 != ZauxErr){AlmInifFile.Write(DateTime.Now.ToString("F"), "ZAux_OpenEth execution error, error code: " + ZauxErr.ToString(), "Error code information");}
2. Delta parallel robot parameter settings.
3. Establishment of forward and inverse kinematics for the robotic arm.
·
/************************************************************************************'Task Number: None'Function: Establishing forward and inverse kinematics of the robot'Input: Mode=0 Disconnect the robot; 1 Establish the inverse kinematics of the robot; 2 Establish the forward kinematics of the robot'Output: None'Return Value: 0: Indicates successful robot establishment; -1: Indicates failed robot establishment'Remarks: 1. Only controllers with the suffix "R" support this robot model'2. In forward kinematics mode, the MTYPE of the virtual axis is 34'3. In inverse kinematics mode, the MTYPE of the joint axis is 33'4. Do not disconnect the robot when it is in inverse kinematics mode, otherwise improper operation may cause it to run away. **************************************************************************************/public int ScaraEstab(int Mode){ // Update the Delta parameter of the UI interface ScaraParaWindows.DeltaParaSave(); // Set the mechanical parameters to the controller SetControPara(); // Save the Delta parameter to the Ini file WriteIniFile(); // Clear the controller alarm ZauxErr = zmcaux.ZAux_Direct_Single_Datum(g_Handle, 0, 0); // Update the axis list The axis order for establishing forward and inverse solutions is J1, J2, Ju, Jz (joint axes) Vx, Vy, Vr, Vz (virtual axes) int[] mJScaraAxisList = new int[4]; // Joint axis list int[] mVScaraAxisList = new int[4]; // Virtual axis list for (int i = 0; i < 4; i++) { mJScaraAxisList[i] = gDeltaAxisList[i]; mVScaraAxisList[i] = gVAxisList[i]; } // Check if the robot parameters are set correctly if ((DeltaR <= 0) || (DeltaR <= 0) || (DeltaL1 <= 0) || (DeltaL2 <= 0)) { MessageBox.Show("There is a problem with the Delta robot parameters, please confirm!"); return -1; } // The robot's structural parameters must be written into the controller's TABLE register before the interface can be called to establish the robot's forward and inverse kinematics // Update the robot parameters to the controller's TABLE register float[] ScaraParaList = new float[11] { DeltaR, Deltar, DeltaL1, DeltaL2, gMotorPulNum[0] * gReducRatio[0], gMotorPulNum[1] * gReducRatio[1], gMotorPulNum[2] * gReducRatio[2], 0, 0, 0, gMotorPulNum[3] * gReducRatio[3] }; ZauxErr = zmcaux.ZAux_Direct_SetTable(g_Handle, TableStaraId, 11, ScaraParaList); if (0 != ZauxErr) { return -1; } if ((1 == Mode) && (0 == ZauxErr)) // Establish the inverse solution of the robot (if the robot parameters are successfully updated) { // Establish the Scara inverse solution ZauxErr = zmcaux.ZAux_Direct_Connframe(g_Handle, 4, mJScaraAxisList, 14, TableStaraId, 4, mVScaraAxisList); if (0 != ZauxErr) { ProceWindows.WriteLog("Failed to switch to inverse solution mode"); return -1; } ProceWindows.WriteLog("Switched to reverse solution mode"); } else if ((2 == Mode) && (0 == ZauxErr)) //Build the forward solution for the robotic arm (assuming the robotic arm parameters are successfully updated) { //Build the Scara forward solution ZauxErr = zmcaux.ZAux_Direct_Connreframe(g_Handle, 4, mVScaraAxisList, 14, TableStaraId, 4, mJScaraAxisList); if (0 != ZauxErr) { ProceWindows.WriteLog("Failed to switch to forward solution mode"); return -1; } ProceWindows.WriteLog("Switched to forward solution mode"); } } return 0;}
4. Manual motion interface
The image below shows the interface for manual motion in the example program. The "Manual Control of Joint Coordinate System" button performs manual motion of the joint axes; pressing it automatically establishes the forward traversal algorithm for the robot. The "Manual Control of Cartesian Coordinate System" button performs manual motion of the virtual axes XYZ; pressing it automatically establishes the inverse traversal algorithm for the robot. When the manual speed decreases to a certain value, it automatically switches to inching mode.
5. Manual joint axis movement /****************************************************************************************'Task number: None'Function function: Manual movement of the joint axis in the negative direction. Called when the negative jog button is pressed.'Input: None'Output: None'Return value: None'Remarks: None ******************************************************************************************/private void JHandDirRev0_MouseDown(object sender, MouseEventArgs e){ //Check if it is locked. Movement is only allowed if it is locked int EnableState = 0; cszmcaux.zmcaux.ZAux_Direct_GetAxisEnable(MainWindows.g_Handle, MainWindows.gDeltaAxisList[0], ref EnableState); //If enabled if ((1 == EnableState) || (MainWindows.IsDebug)) { int Vmtype = 0;//Virtual axis MTYPE cszmcaux.zmcaux.ZAux_Direct_GetMtype(MainWindows.g_Handle, MainWindows.gVAxisList[0], ref Vmtype); // If not the correct solution if (Vmtype != 34) { // Correct solution for establishing the robotic arm if (0 != MainWindows.ScaraEstab(2)) { // Robotic arm not successfully established return; } } // Which button is pressed int Id = 0; for (int i = 0; i < 4; i++) { if (((Button)sender).Name == ("JHandDirRev" + i)) { Id = i; } } int TempAxis = 0; TempAxis = MainWindows.gDeltaAxisList[Id]; // Manual speed less than 5 is in inch motion mode if (5 <= MainWindows.HnadSpeedPerc) { // Set jog speed cszmcaux.zmcaux.ZAux_Direct_SetSpeed(MainWindows.g_Handle, TempAxis, MainWindows.HnadSpeedPerc * MainWindows.gAxisHandSpeed[Id] / 100); // Send negative motion command cszmcaux.zmcaux.ZAux_Direct_Single_Vmove(MainWindows.g_Handle, TempAxis, -1); } else { // Set inch speed cszmcaux.zmcaux.ZAux_Direct_SetSpeed(MainWindows.g_Handle, TempAxis, MainWindows.gAxisHandSpeed[Id] / 10); // Send inch motion command cszmcaux.zmcaux.ZAux_Direct_Single_Move(MainWindows.g_Handle, TempAxis, -1 * MainWindows.HnadSpeedPerc); } }}/****************************************************************************************'Task Number: None'Function Function: Manual movement of the joint axis in the forward direction, called when the forward jog button is pressed'Input: None'Output: None'Return Value: None'Remarks: None**************************************************************************************/private void JHandDirFwd0_MouseDown(object sender, MouseEventArgs e){ //Check if it is locked, it can only move if it is locked int EnableState = 0; cszmcaux.zmcaux.ZAux_Direct_GetAxisEnable(MainWindows.g_Handle, MainWindows.gDeltaAxisList[0], ref EnableState); //If enabled if ((1 == EnableState) || (MainWindows.IsDebug)) { int Vmtype = 0;//Virtual axis MTYPE cszmcaux.zmcaux.ZAux_Direct_GetMtype(MainWindows.g_Handle, MainWindows.gVAxisList[0], ref Vmtype); //If it's not the correct solution if (Vmtype != 34) { //The correct solution for building the robot if (0 != MainWindows.ScaraEstab(2)) { //The robot was not successfully built return; } } //Which button was pressed int Id = 0; for (int i = 0; i < 4; i++) { if (((Button)sender).Name == ("JHandDirFwd" + i)) { Id = i; } } int TempAxis = 0; TempAxis = MainWindows.gDeltaAxisList[Id]; //Manual speed less than 5 is in inch motion mode if (5 <= MainWindows.HnadSpeedPerc) { // Set jog speed cszmcaux.zmcaux.ZAux_Direct_SetSpeed(MainWindows.g_Handle, TempAxis, MainWindows.HandSpeedPerc * MainWindows.gAxisHandSpeed[Id] / 100); // Send forward motion command cszmcaux.zmcaux.ZAux_Direct_Single_Vmove(MainWindows.g_Handle, TempAxis, 1); } else { // Set inch speed cszmcaux.zmcaux.ZAux_Direct_SetSpeed(MainWindows.g_Handle, TempAxis, MainWindows.gAxisHandSpeed[Id] / 10); // Send inch motion command cszmcaux.zmcaux.ZAux_Direct_Single_Move(MainWindows.g_Handle, TempAxis, 1 * MainWindows.HnadSpeedPerc); } }}/****************************************************************************************'Task Number: None'Function Function: Stops manual movement of the joint axis; called when the jog button is released. 'Input: None' Output: None' Return value: None' Remarks: None **************************************************************************************/private void JHandDirRev0_MouseUp(object sender, MouseEventArgs e){ //Which button is pressed int Id = 0; for (int i = 0; i < 4; i++) { if (((Button)sender).Name == ("JHandDirRev" + i)) { Id = i; } } int TempAxis = 0; TempAxis = MainWindows.gDeltaAxisList[Id]; //Manual speed less than 5 is in inching mode if (5 <= MainWindows.HnadSpeedPerc) { MainWindows.ZauxErr = cszmcaux.zmcaux.ZAux_Direct_Single_Cancel(MainWindows.g_Handle, TempAxis, 2); }}
Joint axis manual movement demonstration
6. Manual movement of virtual axis
·
/************************************************************************************'Task Number: None'Function Function: Manual movement of the virtual axis in the negative direction, called when the negative jog button is pressed'Input: None'Output: None'Return Value: None'Remarks: None ******************************************************************************************/private void VHandDirRev0_MouseDown(object sender, MouseEventArgs e){ //Check if it is locked, it can only move if it is locked int EnableState = 0; cszmcaux.zmcaux.ZAux_Direct_GetAxisEnable(MainWindows.g_Handle, MainWindows.gDeltaAxisList[0], ref EnableState); //If enabled if ((1 == EnableState) || (MainWindows.IsDebug)) { int Jmtype = 0;//Joint axis Mtype cszmcaux.zmcaux.ZAux_Direct_GetMtype(MainWindows.g_Handle, gDeltaAxisList[0], ref Jmtype); // If it is not in reverse engineering state if (Jmtype != 33) { // Establish the reverse engineering of the robotic arm if (0 != MainWindows.ScaraEstab(1)) { // The robotic arm was not successfully established return; } } // Which button was pressed int Id = 0; for (int i = 0; i < 5; i++) { if (((Button)sender).Name == ("VHandDirRev" + i)) { Id = i; } } int TempAxis = 0; // Update the current robotic arm state TempAxis = MainWindows.gVAxisList[Id]; // Manual speed less than 5 is in inch motion mode if (5 <= MainWindows.HnadSpeedPerc) { // Set jog speed cszmcaux.zmcaux.ZAux_Direct_SetSpeed(MainWindows.g_Handle, TempAxis, MainWindows.HnadSpeedPerc * MainWindows.gAxisHandSpeed[Id] / 100); // Send negative motion command cszmcaux.zmcaux.ZAux_Direct_Single_Vmove(MainWindows.g_Handle, TempAxis, -1); } else { // Set inch speed cszmcaux.zmcaux.ZAux_Direct_SetSpeed(MainWindows.g_Handle, TempAxis, MainWindows.gAxisHandSpeed[Id] / 10); // Send inch motion command cszmcaux.zmcaux.ZAux_Direct_Single_Move(MainWindows.g_Handle, TempAxis, -1 * MainWindows.HnadSpeedPerc); } }}/****************************************************************************************'Task Number: None'Function Function: Manual movement of the virtual axis in the negative direction, called when the negative jog button is pressed'Input: None'Output: None'Return Value: None'Remarks: None******************************************************************************************/private void VHandDirFwd0_MouseDown(object sender, MouseEventArgs e){ //Check if it is locked, it can only move if it is locked int EnableState = 0; cszmcaux.zmcaux.ZAux_Direct_GetAxisEnable(MainWindows.g_Handle, MainWindows.gDeltaAxisList[0], ref EnableState); //If enabled if ((1 == EnableState) || (MainWindows.IsDebug)) { int Jmtype = 0;//Joint axis Mtype cszmcaux.zmcaux.ZAux_Direct_GetMtype(MainWindows.g_Handle, gDeltaAxisList[0], ref Jmtype); //If it is not in the reverse engineering state if (Jmtype != 33) { //Build the reverse engineering of the robot if (0 != MainWindows.ScaraEstab(1)) { //The robot was not successfully built return; } } //Which button was pressed int Id = 0; for (int i = 0; i < 5; i++) { if (((Button)sender).Name == ("VHandDirFwd" + i)) { Id = i; } } int TempAxis = 0; //Update the current robot state TempAxis = MainWindows.gVAxisList[Id]; //Manual speed less than 5 is the inching mode if (5 <= MainWindows.HnadSpeedPerc) { // Set jog speed cszmcaux.zmcaux.ZAux_Direct_SetSpeed(MainWindows.g_Handle, TempAxis, MainWindows.HandSpeedPerc * MainWindows.gAxisHandSpeed[Id] / 100); // Send forward motion command cszmcaux.zmcaux.ZAux_Direct_Single_Vmove(MainWindows.g_Handle, TempAxis, 1); } else { // Set inch speed cszmcaux.zmcaux.ZAux_Direct_SetSpeed(MainWindows.g_Handle, TempAxis, MainWindows.gAxisHandSpeed[Id] / 10); // Send inch motion command cszmcaux.zmcaux.ZAux_Direct_Single_Move(MainWindows.g_Handle, TempAxis, 1 * MainWindows.HnadSpeedPerc); } }}/****************************************************************************************'Task Number: None'Function Function: Stops the virtual axis movement, called when the jog button is released'Input: None'Output: None'Return Value: None'Remarks: None ******************************************************************************************///Stop Movement private void VHandDirRev0_MouseUp(object sender, MouseEventArgs e){ //Which button is pressed int Id = 0; for (int i = 0; i < 5; i++) { if (((Button)sender).Name == ("VHandDirRev" + i)) { Id = i; } } int TempAxis = 0; TempAxis = MainWindows.gVAxisList[Id]; //Manual speed less than 5 is jog mode if (5 <= MainWindows.HnadSpeedPerc) { cszmcaux.zmcaux.ZAux_Direct_Single_Cancel(MainWindows.g_Handle, TempAxis, 2); }}
Virtual axis manual motion demonstration
7. Using the robot simulation tool: Open the ZRobotView software, click Connect, enter the controller's IP address (default IP: 192.168.0.11), click Connect, and after successful connection, click Switch to simulate the robot's movement in 3D.
This concludes our sharing of the forward and inverse kinematics of the Delta parallel robot in C# and its manual motion.
For more exciting content, please follow the "Zheng Motion Assistant" WeChat official account. For related development environment and example code, please contact Zheng Motion's technical sales engineer: 400-089-8936.
This article is original content from Zheng Motion Technology. We welcome everyone to reprint it for mutual learning and to jointly improve China's intelligent manufacturing level. Copyright belongs to Zheng Motion Technology. Please indicate the source if you reprint this article.