Today, Zheng Motion Assistant will share with you how to use C# to run and control real-time programs using the EtherCAT motion control card ECI2828.
ECI2828 Motion Control Card Hardware Introduction
The ECI2828 series motion control card supports up to 16-axis linear interpolation, arbitrary circular interpolation, spatial circular interpolation, helical interpolation, electronic cams, electronic gears, synchronous following, virtual axes, and robot commands; it uses an optimized network communication protocol to achieve real-time motion control.
The ECI2828 series motion control card supports Ethernet and a RS-232 communication interface to connect to a computer, receive commands from the computer, and can connect to various expansion modules via EtherCAT and CAN buses to expand the number of input/output points or motion axes.
Applications for the ECI2828 series motion control card can be developed using software such as VC, VB, VS, C++, and C#. The program requires the dynamic library zmotion.dll to run. During debugging, the ZDevelop software can be connected to the controller simultaneously for easier debugging and observation.
Typical connection configuration diagram of ECI2828 series
Motion control development using C# language
01 Create a new WinForm project and add function libraries
1. In VS2015, 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 (for a 64-bit library):
A. Locate the "8.PC Functions" folder in the CD-ROM provided by the manufacturer and click to enter.
B. Select the "Function Library 2.1" folder.
C. Select the "Windows Platform" folder.
D. Select the appropriate function library as needed; here, we choose the 64-bit library.
E. Unzip the C# compressed file, which contains the corresponding C# function library.
F. 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.
A. Copy the zmcaux.cs file into the newly created project.
B. 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". 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.
The project is now complete and ready for C# development.
02. Check the PC function manual
The A.PC function manual is also included in the CD-ROM materials. The specific path is as follows: "CD-ROM materials\8.PC functions\Function library 2.1\ZMotion function library programming manual V2.1.pdf".
In B.PC programming, a common practice is to connect the controller and the industrial PC via the network port. The network port connection function interface is ZAux_OpenEth(); if the connection is successful, this interface will return a connection handle. By manipulating this connection handle, control of the controller can be achieved.
ZAux_OpenEth() Interface Description:
C. Use the instruction to operate on the lower-level machine registers to operate the link handle "g_handle", retrieve the register contents of the controller, and perform real-time control of the lower-level machine. The relevant instructions are as follows.
Real-time global variable directives:
After the ZAux_Direct_HwPswitch2 hardware compares and outputs the instruction to the desired location, the hardware automatically triggers the op output signal.
The ZAux_Direct_HwTimer hardware timer outputs a level that is restored shortly after the hardware compare.
Latch-related instructions:
ZAux_Direct_Regist immediately latches the current position record after receiving the specified signal input. Inputs R0 and R1 generally correspond to input ports 0 and 1.
ZAux_Direct_GetMark determines whether a latch mark has been generated:
ZAux_Direct_GetMarkB determines whether latched markB has been generated:
Feedback location when the ZAux_Direct_GetRegPos latch signal is triggered:
ZAux_Direct_GetRegPosB retrieves the encoder position fed back from the R1 type latch:
Hardware comparison output related functions:
Single point trigger
Multi-point triggering
The motion controller has a position comparison unit. The hardware comparison output is operated by comparing whether the axis has reached the set position. In general use, the encoder position is compared with the set position. When the encoder position reaches a set comparison position, the corresponding output port level is triggered to flip once.
As shown in the figure below, when the set position 1 is reached, the level flips. When the set position 2 is reached, the level flips again. When the set position 3 is reached, the level flips again. After all the points have been compared, the level remains in the state after the last flip.
03. Develop real-time program execution and read/write control using C#
1. The human-computer interaction interface for real-time program execution and read/write control is as follows.
2. Routine Function Introduction
Position comparison output function implementation:
The following data is transmitted to the controller's table. The hardware compare output function will select the position to flip the corresponding signal to achieve the purpose of hardware compare output.
Position comparison output parameter settings
By setting the axis number and corresponding output port number for comparison, the action is performed. The data is moved from the starting point table register number to the ending point number. When the movement reaches each corresponding data position, the level will be flipped.
Hardware timer operation
After the hardware comparison output function is activated, the hardware timer function can be used to restore the op port signal within the corresponding set period, ensuring that the op port does not output signals for extended periods.
Status display
The PC timer refreshes the currently acquired controller coordinates and the status of the op output port, displays them on the interface, and records the number of latch triggers.
Movement part
Select the movement distance and ensure that the coordinate data points output by the position comparison are within the movement range so that the corresponding signal point can be triggered and the action can be performed.
Encoder latch
Specify the latching mode and latching axis. When the movement reaches the comparison output position, the op output signal is sent to the in port, triggering the corresponding rising or falling edge to latch the current position, record the position, and display it on the current interface.
3. Simplified flowchart of the routine.
4. Call the interface ZAux_OpenEth() in the constructor of Form1 to automatically link the controller during system initialization.
private void C_Open_Eth_Click(object sender, EventArgs e) // Ethernet connection controller { if (g_handle == (IntPtr)0) { C_Close_Card_Click(sender, e); // Disconnect the previous connection } zmcaux.ZAux_OpenEth(C_Ip_Address.Text, out g_handle); // Ethernet port connection controller if (g_handle != (IntPtr)0) { this.Text = "Connected"; timer1.Enabled = true; // C_Move_Axis_TextChanged(sender, e); }}
5. Update the controller axis status via timer: current coordinate, OP output status, etc.
private void timer1_Tick(object sender, EventArgs e) // Refresh status display { float AxisDpos = 0; int iret = 0; UInt32 Op_status = 0;
`updata_value(); if (RadioButton1.Checked == true) // Enable position comparison m_POS_IfOpen = false; if (RadioButton2.Checked == true) m_POS_IfOpen = true; if (RadioButton4.Checked == true) // Enable timer output inversion m_Timer_IfOpen = false; if (RadioButton3.Checked == true) m_Timer_IfOpen = true; iret = zmcaux.ZAux_Direct_GetDpos(g_handle, m_AxisNum, ref AxisDpos); iret = zmcaux.ZAux_Direct_GetOp(g_handle, m_POS_out, ref Op_status); label_dpos.Text = "Axis" + m_AxisNum.ToString() + "Coordinates: " + AxisDpos.ToString(); op.BackColor = Color.Red; if (Op_status == 1) op.BackColor` = Color.LimeGreen;
}
6. Set the comparison point position, enable hardware comparison output and hardware timer, and start the motion:
private void Button2_Click(object sender, EventArgs e) //Motion { if (g_handle == (IntPtr)0) { MessageBox.Show("Not linked to controller!", "Prompt"); return; } int iret = 0; iret = zmcaux.ZAux_Direct_SetUnits(g_handle, m_AxisNum, 100); iret = zmcaux.ZAux_Direct_SetSpeed(g_handle, m_AxisNum, 100); iret = zmcaux.ZAux_Direct_SetAccel(g_handle, m_AxisNum, 2000); iret = zmcaux.ZAux_Direct_HwPswitch2(g_handle, m_AxisNum, 2, 0, 0, 0, 0, 0, 0); //Clear the preceding comparison output command if (m_POS_IfOpen == false) // HwPswitch needs to be called again after one comparison is completed { iret = zmcaux.ZAux_Direct_SetTable(g_handle, m_POS_StartTable, m_POS_EndTable, fPointPos); // Fill the comparison point into the TABLE if (iret != 0) { string tempstr; tempstr = "SetTable failed, return value: " + iret.ToString(); MessageBox.Show(tempstr, "Prompt"); return; } iret = zmcaux.ZAux_Direct_HwPswitch2(g_handle, m_AxisNum, 1, m_POS_out, m_POS_OutStatus, m_POS_StartTable, m_POS_EndTable, m_PSO_dir, 0); if (iret != 0) { string tempstr; tempstr = "HwPswitch2 failed, return value: " + iret.ToString(); MessageBox.Show(tempstr, "Prompt"); return; } } else { iret = 0; iret = zmcaux.ZAux_Direct_HwPswitch2(g_handle, m_AxisNum, 2, 0, 0, 0, 0, 0, 0); // Clear comparison output instructions if (iret != 0) { string tempstr; tempstr = "HwPswitch2 failed and returned value: " + iret.ToString(); MessageBox.Show(tempstr, "Prompt"); return; } }
int tempoutstatus = 0; if (m_POS_OutStatus == 0) tempoutstatus = 1; else tempoutstatus = 0; if (m_Timer_IfOpen == false) { iret = zmcaux.ZAux_Direct_HwTimer(g_handle, 2, m_Timer_Cycle, m_Timer_Valid, m_Timer_Num, tempoutstatus, m_POS_out); if (iret != 0) { string tempstr; tempstr = "HwTimer failure return value:" + iret.ToString(); MessageBox.Show(tempstr, "Prompt"); //return; } } else { iret = zmcaux.ZAux_Direct_HwTimer(g_handle, 0, m_Timer_Cycle, m_Timer_Valid, m_Timer_Num, tempoutstatus, m_POS_out); if (iret != 0) { string tempstr; tempstr = "HwTimer failure return value:" + iret.ToString(); MessageBox.Show(tempstr, "Prompt"); //return; } } zmcaux.ZAux_Trigger(g_handle); iret = zmcaux.ZAux_Direct_SetDpos(g_handle, m_AxisNum, 0); iret = zmcaux.ZAux_Direct_Single_MoveAbs(g_handle, m_AxisNum, m_Start_Pos); iret = zmcaux.ZAux_Direct_Single_MoveAbs(g_handle, m_AxisNum, m_End_Pos);
}
7. Select the latching mode and latching axis position to enable latching.
private void Button1_Click(object sender, EventArgs e) //Activate latch { if (g_handle == (IntPtr)0) { MessageBox.Show("Not linked to controller!", "Prompt"); return; } int iret = 0; if (m_Regist_IfOpen == false) { m_RegistCount = 0; iret = zmcaux.ZAux_Direct_SetAtype(g_handle, m_RegistAxis, 4); //Must be an encoder axis int ReglistListSel = ComboBox1.SelectedIndex; if (ReglistListSel >= 0 && ReglistListSel <= 3) { RegistMode = ReglistListSel + 1; } else if (ReglistListSel == 4 || ReglistListSel == 5) { RegistMode = 10 + ReglistListSel; } else if (ReglistListSel > 0) { ReglistListSel = 0; } else if (ReglistListSel > 0) { ReglistListSel = 0; } 5 || ReglistListSel < 9) { RegistMode = 12 + ReglistListSel; } iret = zmcaux.ZAux_Direct_Regist(g_handle, m_RegistAxis, RegistMode); timer2.Start();
m_Regist_IfOpen = true; ComboBox1.Enabled = false; Button1.Text = "Stop latching";
} else { timer2.Stop(); m_Regist_IfOpen = false; ComboBox1.Enabled = true; Button1.Text = "Starting latching"; DataGridView2.Rows.Clear(); }}
8. The timer periodically checks whether the latching state has been triggered, reads the latching position, and displays it on the interface.
private void timer2_Tick(object sender, EventArgs e) //Timer refresh { int iret = 0; int MarkStatus = 0; float RegistPos=0; if(RegistMode >= 0 && RegistMode <= 4) { iret = zmcaux.ZAux_Direct_GetMark(g_handle,m_RegistAxis,ref MarkStatus); } else if(RegistMode >= 14 || RegistMode < 16) { iret = zmcaux.ZAux_Direct_GetMarkB(g_handle, m_RegistAxis, ref MarkStatus); } else if(RegistMode >= 18 || RegistMode < 20) { float tempc=0; iret = zmcaux.ZAux_Direct_GetParam(g_handle, "MARKC", m_RegistAxis, ref tempc); MarkStatus = (int)tempc; } else if(RegistMode >= 20 || RegistMode < 22) { float tempd=0; iret = zmcaux.ZAux_Direct_GetParam(g_handle, "MARKD", m_RegistAxis, ref tempd); MarkStatus = (int)tempd; }
if (MarkStatus == -1) { if (RegistMode >= 0 && RegistMode <= 4) { iret = zmcaux.ZAux_Direct_GetRegPos(g_handle, m_RegistAxis, ref RegistPos); //Get the latch position} else if (RegistMode >= 14 || RegistMode < 16) { iret = zmcaux.ZAux_Direct_GetRegPosB(g_handle, m_RegistAxis, ref RegistPos); } else if (RegistMode >= 18 || RegistMode < 20) { iret = zmcaux.ZAux_Direct_GetParam(g_handle, "REG_POSC", m_RegistAxis, ref RegistPos); } else if (RegistMode >= 20 || RegistMode < 22) { iret = zmcaux.ZAux_Direct_GetParam(g_handle, "REG_POSD", m_RegistAxis, ref RegistPos); } string[] tempstr = new string[2]; tempstr[0] = m_RegistCount.ToString(); tempstr[1] = RegistPos.ToString(); DataGridView2.Rows.Add(tempstr); m_RegistCount = m_RegistCount + 1; iret = zmcaux.ZAux_Direct_Regist(g_handle, m_RegistAxis, RegistMode); //Re-trigger latch} string temps; temps = "Latch trigger status: " + MarkStatus.ToString() + " Count: " + m_RegistCount.ToString(); Label3.Text = temps; }
}
04 Debugging and Monitoring
Compile and run the routines, and connect to the ZDevelop software for debugging, monitoring the axis parameters and motion status of the motion control.
1. Location comparison function
Using the position comparison output function on the interface and the corresponding position table, the signal port level will be flipped at the specified position, as shown in the waveform display.
2. Hardware timer function
Hardware timers are mainly used to restore the level after a certain period of time after a hardware comparison output. They can be used to ensure the output port status output time and control the output duration.
3. Encoder latching function
When the latch function is enabled, the current mpos value will be latched when the corresponding input port receives a signal, and the corresponding content will be displayed on the interface.
Latch mode 3: R0 rising edge triggered (default RO signal port is in0)
As shown in the figure: the external input port IN is triggered the instant it changes from the on state to the off state, and the position is recorded and displayed in the table.
Latch mode 4: R0 falling edge triggered (default RO signal port is in0)
As shown in the figure: the position is recorded and displayed in the table the instant the external input port changes from the cut-off state to the conduction state.
Demo video
That concludes our discussion on the synchronization of I/O actions and motion control in the EtherCAT motion control card.
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.