Today, we will explain the Qt tutorial for developing motion control card applications using positive motion technology.
Previously, we shared information about "XPLC516E Open Linux Platform Controller and its Qt Development under Linux". We know that the motion controller supports the Linux system and embedded Qt development.
Positive motion technology supports the powerful Qt dynamic link library and has easy-to-read motion control library function manuals. The code is highly portable, making it very convenient to get started with motion control development and greatly shortening the development time cycle of intelligent equipment.
Before we begin our formal learning, let's first understand the motion control cards ECI2418 and ECI2618 from Zheng Motion Technology. These two products are 4-axis and 6-axis motion control cards, respectively.
The ECI2418 supports 4-axis pulse input and encoder feedback, with 24 onboard inputs, 16 onboard outputs, 2 AD, 2 DA, and a handwheel interface. Some outputs support high-speed PWM control.
The ECI2618 supports 6-axis pulse input and encoder feedback, with 24 onboard inputs, 16 onboard outputs, 2 AD converters, 2 DA converters, and a handwheel interface. Some outputs support high-speed PWM control.
Both ECI2418 and ECI2618 use the same set of API functions and support development languages such as C, C++, C#, LabVIEW, Python, and Delphi. They also support platforms such as VC6.0, VB6.0, Qt, and .Net, and operating systems such as Windows, Linux, WinCE, and iMac.
I. Qt Development Process for Motion Control Card Applications
1. Create a new Qt project using Qt software.
2. Copy the dynamic library and related files "libzmotion.so, zaux.cpp, zaux.h, zmotion.h" into the newly created Qt project.
Download the four files circled in the image above from the CD-ROM, and copy them to your newly created Qt project via the terminal.
3. Add the dynamic library "libzmotion.so" to your Qt project.
A. First, right-click the project and click Add Library.
B. Select an external library and click Next.
C. Click Browse Library Files, select the dynamic library you just copied, and click Next.
D. Finally, click finish to complete adding the dynamic library.
Note: In a Linux environment, dynamic library names must begin with "lib" to be recognized.
4. Add the header files "zmotion.h" and "zaux.h" to your Qt project.
A. First, right-click Headers and click Add Existing Files...
B. Locate the zmotion.h file that you just copied and put into the project, and double-click zmotion.h to add the header file zmotion.h to the project.
C. Repeat the above two steps to add the zaux.h file to the project as well.
5. Add the cpp source file "zaux.cpp" to the Qt project.
A. First, right-click Sources and click Add Existing Files...
B. Locate the zaux.cpp file that you just copied and put into the project, and double-click the zaux.cpp file to add the source file zaux.cpp to the project.
6. Add `#include "zmotion.h"`, `#include "zaux.h"`, and define the controller's connection handle `g_handle` in `mainwindow.h`.
7. Use the slot function of the link button to connect the controller via Ethernet.
A. In the Qt UI design interface, add a button and rename it to Link. Right-click the Link button and click Go to slot... to jump to the slot function of the button.
B. Consult the ZMotion PC programming manual to understand how to use the Ethernet connection controller interface functions.
C. Refer to the PC programming manual in the CD-ROM to learn how to use the ZAux_OpenEth function and write code in the slot function to implement the function.
8. The controller implements interpolation motion, and the code implementation process.
A. In the Qt UI design interface, add a button and rename it to move. Right-click the move button and click Go to slot... to jump to the slot function of the button.
B. Consult the ZMotion PC programming manual to understand the usage of the interpolation motion interface functions.
C. Based on the usage of the ZAux_Direct_Move function in the PC programming manual, write code in the slot function to implement the function.
9. Once the motion program is designed, click the Run button.
Note: When the host computer connects to the controller via Ethernet, the controller and the PC must be on the same network segment for the connection to be successful.
II. Qt Example Explanation of Motion Control Card Application
1. The CD-ROM documentation for forward motion technology contains many Qt examples, which can make it easier to get started with the forward motion controller. Below is a detailed explanation of one example.
2. Functional description of the single-axis motion routine
a. A controller connected to a specified IP address via Ethernet;
b. Set the motion axis parameters;
c. Select the motion axis object;
d. Select the movement mode to achieve continuous movement and inching motion;
3. Specific implementation of single-axis motion in the routine
(1) Implement network port connection to the controller
A. Manually add IP address from the drop-down list: Enter the UI design interface and double-click the drop-down list to add the controller IP address, as follows.
B. Refer to the ZMotion PC function programming manual to familiarize yourself with the usage of the ZAux_OpenEth() interface.
C. By using the slot function of the Open button (on_pushButton_OpenEth_clicked()), the link controller interface (ZAux_OpenEth()) provided by the dynamic library (zmotion.so) is called to establish a link with the controller.
Ethernet connectivity controller
void MainWindow::on_pushButton_OpenEth_clicked()
{
int32 iresult;
char * tmp_buff = new char[16];
QString str, str_title;
/* Get IP from the dropdown list */
str = ui->comboBox_IP->currentText();
QByteArray ba = str.toLatin1();
tmp_buff = ba.data();
/*Link controller*/
iresult = ZAux_OpenEth(tmp_buff,&g_handle);
if(0 == iresult)
{
str_title = ("linked:");
str_title += tmp_buff;
setWindowTitle(str_title);
/* Start the timer */
m_nTimerId = startTimer(10);
}
else
{
setWindowTitle("no link!");
}
}
D. Refer to the ZMotion PC function programming manual to familiarize yourself with the usage of the ZAux_OpenEth() interface.
E. By using the slot function of the Close button (on_pushButton_CloseEth_clicked()), the interface for disconnecting the controller provided by the dynamic library (zmotion.so) (ZAux_Close()) is called to disconnect the connection with the controller.
Disconnect network port connection
void MainWindow::on_pushButton_CloseEth_clicked()
{
if (0 != g_handle)
{
/* Disconnect*/
ZAux_Close(g_handle);
g_handle = NULL;
setWindowTitle("no line");
/* Turn off the timer */
killTimer(m_nTimerId);
m_nTimerId=-1;
}
}
(2) Obtain information on axis motion and input/output ports.
A. Set the X, Y, Z, and R radio buttons to the same button group for axis selection.
B. By using the timer timeout handling function, the interface provided by the dynamic library "zmotion.so" to obtain axis dpos, vpspeed, idle information and input/output port status information is called to realize the monitoring of the controller status.
//Timer timeout handling function
void MainWindow::timerEvent(QTimerEvent *event)
{
if(m_nTimerId == event->timerId())
{
int idle;
float fdpos, fvspeed;
QString str_tmp;
/* Get axis status */
ZAux_Direct_GetIfIdle(g_handle,AxisGroup->checkedId(),&idle);
str_tmp = QString("Idle : %1").arg(idle?"stop":"run");
ui->label_statue->setText(str_tmp);
/* Get dpos */
ZAux_Direct_GetDpos(g_handle,AxisGroup->checkedId(),&fdpos);
str_tmp = QString("Dpos : %1").arg(fdpos);
ui->label_dpos->setText(str_tmp);
/* Get vspeed */
ZAux_Direct_GetVpSpeed(g_handle,AxisGroup->checkedId(),&fvspeed);
str_tmp = QString("Vspeed : %1").arg(fvspeed);
ui->label_vspeed->setText(str_tmp);
uint8 in, out, i=0,j=0,k=0;
char buff[128]={0};
/* Get input port status */
ZAux_GetModbusIn(g_handle, 0, 7, &in); // Get the states in0-in7
/* Get output port status */
ZAux_GetModbusOut(g_handle, 0, 7, &out); // Get the status of out0-out7
/* Decimal to binary conversion */
for(i=0; i<8; i++)
{
buff[i] = in%2;
in = in/2;
if(1 >= in)
{
buff[i+1]=in;
break
}
}
/* Update UI information */
buff[0]? ui->checkBox_IN0->setChecked(true):ui->checkBox_IN0->setChecked(false);
buff[1]? ui->checkBox_IN1->setChecked(true):ui->checkBox_IN1->setChecked(false);
buff[2]? ui->checkBox_IN2->setChecked(true):ui->checkBox_IN2->setChecked(false);
buff[3]? ui->checkBox_IN3->setChecked(true):ui->checkBox_IN3->setChecked(false);
buff[4]? ui->checkBox_IN4->setChecked(true):ui->checkBox_IN4->setChecked(false);
buff[5]? ui->checkBox_IN5->setChecked(true):ui->checkBox_IN5->setChecked(false);
buff[6]? ui->checkBox_IN6->setChecked(true):ui->checkBox_IN6->setChecked(false);
buff[7]? ui->checkBox_IN7->setChecked(true):ui->checkBox_IN7->setChecked(false);
memset(buff, 0, 8);
/* Decimal to binary conversion */
for(i=0; i<8; i++)
{
buff[i] = out%2;
out = out/2;
if(1 >= out)
{
buff[i+1]=out;
break
}
}
/* Update UI information */
buff[0]? ui->checkBox_OUT0->setChecked(true):ui->checkBox_OUT0->setChecked(false);
buff[1]? ui->checkBox_OUT1->setChecked(true):ui->checkBox_OUT1->setChecked(false);
buff[2]? ui->checkBox_OUT2->setChecked(true):ui->checkBox_OUT2->setChecked(false);
buff[3]? ui->checkBox_OUT3->setChecked(true):ui->checkBox_OUT3->setChecked(false);
buff[4]? ui->checkBox_OUT4->setChecked(true):ui->checkBox_OUT4->setChecked(false);
buff[5]? ui->checkBox_OUT5->setChecked(true):ui->checkBox_OUT5->setChecked(false);
buff[6]? ui->checkBox_OUT6->setChecked(true):ui->checkBox_OUT6->setChecked(false);
buff[7]? ui->checkBox_OUT7->setChecked(true):ui->checkBox_OUT7->setChecked(false);
}
}
(3) Shaft parameter settings
The "on_ParaSet_clicked()" function of the parameter activation button calls the axis parameter setting interface provided by the dynamic library (zmotion.so) to set the axis parameters.
//Parameter settings
void MainWindow::on_ParaSet_clicked()
{
QString str_tmp;
float float_tmp;
int isidle = 0;
/* Get axis number */
axis_num = AxisGroup->checkedId();
/*The axis is running and cannot move*/
ZAux_Direct_GetIfIdle(g_handle,axis_num,&isidle);
if(!isidle)
{
return;
}
/*Set units */
str_tmp = ui->lineEdit_Units->text();
float_tmp = str_tmp.toFloat();
ZAux_Direct_SetUnits(g_handle, axis_num, float_tmp);
/* Set speed */
str_tmp = ui->lineEdit_Speed->text();
float_tmp = str_tmp.toFloat();
ZAux_Direct_SetSpeed(g_handle,axis_num,float_tmp);
/*Set Accel */
str_tmp = ui->lineEdit_Accel->text();
float_tmp = str_tmp.toFloat();
ZAux_Direct_SetAccel(g_handle,axis_num,float_tmp);
/* Set DECEL */
str_tmp = ui->lineEdit_Decel->text();
float_tmp = str_tmp.toFloat();
ZAux_Direct_SetDecel(g_handle,axis_num,float_tmp);
/* Set sramp */
str_tmp = ui->lineEdit_Sramp->text();
float_tmp = str_tmp.toFloat();
ZAux_Direct_SetSramp(g_handle,axis_num,float_tmp);
}
(4) Single-axis inching/continuous motion
A. By using the slot function "on_pushButton_Run_clicked()" of the Run button, the relevant interface functions provided by the dynamic library "zmotion.so" are called to control the motion of the axis.
// Slot function for the Run button
void MainWindow::on_pushButton_Run_clicked()
{
QString str_tmp;
float float_tmp;
int isidle = 0;
ZAux_Direct_GetIfIdle(g_handle,axis_num,&isidle);
if(!isidle)
{
qDebug()<<"not stop";
return;
}
/*Oscilloscope trigger*/
ZAux_Trigger(g_handle);
/*Single-axis motion*/
if(1 == RunModeGroup->checkedId())//inch
{
str_tmp = ui->lineEdit_inchdis->text();
float_tmp = str_tmp.toFloat();
ZAux_Direct_Singl_Move(g_handle,axis_num,ui->checkBox_dir->checkState()?-float_tmp:float_tmp);
}
else if(0 == RunModeGroup->checkedId())//continue
{
ZAux_Direct_Singl_Vmove(g_handle,axis_num,ui->checkBox_dir->checkState()?-1:1);
}
}
B. The function of stopping the axis movement is implemented by calling the relevant interface through the slot function "on_pushButton_Stop_clicked()" of the Stop button.
//Slot function for the Stop button
void MainWindow::on_pushButton_Stop_clicked()
{
int isidle = 0;
ZAux_Direct_GetIfIdle(g_handle,AxisGroup->checkedId(),&isidle);
if (is idle) return;
/*Single-axis stop*/
ZAux_Direct_Singl_Cancel(g_handle,AxisGroup->checkedId(),2);
}
(5) Compile, run, and debug
While developing your own application for connection, you can also use ZDevelop to debug and diagnose the controller's status.
When used in conjunction with ZDevelop software for debugging, the controller's status can be monitored more intuitively through tools such as axis parameters, input ports, output ports, and oscilloscopes.
You can see a graph of a single-axis movement of 300 user units in the oscilloscope window.
That concludes today's tutorial on developing motion control card applications using Qt from Zhengdong Technology. For more great content, please follow our official WeChat account.
This article was originally created by Zheng Motion Assistant. We welcome everyone to reprint it for mutual learning and to improve China's intelligent manufacturing capabilities. Copyright belongs to Zheng Motion Technology. Please indicate the source if you reprint this article.