How to make a GUI for USBCNC with Qt4 Summary femtotutorial

How to make a GUI for USBCNC with Qt4
femtotutorial
Summary
Summary .................................................................................................................................................................... 1
1
Preface................................................................................................................................................................ 2
2
Getting started .................................................................................................................................................... 3
3
4
2.1
Prerequisites ............................................................................................................................................... 3
2.2
First steps .................................................................................................................................................... 3
The USBCNC SDK ................................................................................................................................................. 5
3.1
Adding the library to the project .................................................................................................................. 5
3.2
Including headers ........................................................................................................................................ 5
3.3
The USBCNC Server...................................................................................................................................... 6
3.4
Useful functions........................................................................................................................................... 7
A complete example............................................................................................................................................ 9
4.1
Design the GUI............................................................................................................................................. 9
4.2
Do it yourself ............................................................................................................................................. 11
5
Deploy your application .................................................................................................................................... 12
6
Links.................................................................................................................................................................. 12
Revision A, 05-feb-2012
Femtotech di Marco Trapanese  Via Ripamonti, 14 – 22044 Inverigo (CO)  tel. 031 5481112 / 347 9431074  fax 031 2280476
[email protected]  www.femtotech.it  C.F. TRP MRC 81S13 B639G  P.IVA 03041740139
1
1 Preface
This tutorial will guide you through all the steps needed to setup the developing environment, configure the project
and write a small GUI for the USBCNC software. Using GUIs is a powerful way to extend the functionality of your CNC
machine. You should customise your preferred tasks or create a user interface that meets some unusual
requirements.
As we will see later, interfacing with USBCNC is very easy and requires only some basic knowledge of C++
programming and of the Qt4 environment. Anyway, at the end of the document there are a couple of links to generic
tutorials about Qt4.
Femtotech di Marco Trapanese  Via Ripamonti, 14 – 22044 Inverigo (CO)  tel. 031 5481112 / 347 9431074  fax 031 2280476
[email protected]  www.femtotech.it  C.F. TRP MRC 81S13 B639G  P.IVA 03041740139
2
2 Getting started
2.1 Prerequisites
To develop our applications for USBCNC we need some prerequisites:





A computer with a Windows O.S. (here Windows 7)
USBCNC Software by Bert Eding (http://www.edingcnc.com/index.php?pagina=8_download)
USBCNC SDK, included in the USBCNC folder
QtSDK for Windows by Nokia (http://qt.nokia.com/downloads)
Some C++ programming experience and a minimum knowledge of Qt4
Download and install both software.
For this tutorial let’s assume that QtSDK was installed into C:\QtSDK and USBCNC into C:\Program Files
(x86)\USBCNC4. Please, mind the difference between your actual installation paths.
2.2 First steps
Now we are going to check the functionality of the software we have just installed. Launch USBCNC4 and click on the
START button in the middle of the screen. If you have not purchased the USBCNC CPU board yet, the application will
run in Simulation mode:
It is enough for testing purposes. Press F1 to enable drives and try to move around the screen using cursor keys. You
should see the coordinates changing. Leave the USBCNC4 open, we need it in a while.
Ok, now launch Qt Creator so that we can create a
test project. In the Welcome window click on
Create Project, then select Qt Widget Project > Qt
Gui Application:
Femtotech di Marco Trapanese  Via Ripamonti, 14 – 22044 Inverigo (CO)  tel. 031 5481112 / 347 9431074  fax 031 2280476
[email protected]  www.femtotech.it  C.F. TRP MRC 81S13 B639G  P.IVA 03041740139
3
The next window will ask for a project name and the location path. At this point, we need to check the Target Setup:
Usually, there is no need to change default values. Qt Creator will compile with the latest Qt Version and will place
the executable files in either debug or release subfolder. Click Next on subsequent windows until the wizard ends.
You should see the mainwindow.cpp default code:
Please take time to become familiar with the environment. In the left lower side of the screen there are two play
buttons. Click on one of them1 and our empty application should run without problems. Close the application
window using the X button.
We are ready to develop new GUIs for USBCNC!
1
The play button with a bug on the top is used to start debugging.
Femtotech di Marco Trapanese  Via Ripamonti, 14 – 22044 Inverigo (CO)  tel. 031 5481112 / 347 9431074  fax 031 2280476
[email protected]  www.femtotech.it  C.F. TRP MRC 81S13 B639G  P.IVA 03041740139
4
3 The USBCNC SDK
The USBCNC SDK is provided with the USBCNC software. In the installation path there is a cncapi folder which
contains all the necessary files: the library and the related headers.
3.1
Adding the library to the project
The first operation we have to do is to convey to Qt Creator that we want to use the USBCNC SDK. Double-click on
the .pro file and edit according to the following picture:
3.2 Including headers
We have just configured our project to link the cncapi library. If we want to use the functions provided, we also need
to include the header files. Open the mainwindow.h file and add at the beginning the #include instruction for
cncapi.h:
Femtotech di Marco Trapanese  Via Ripamonti, 14 – 22044 Inverigo (CO)  tel. 031 5481112 / 347 9431074  fax 031 2280476
[email protected]  www.femtotech.it  C.F. TRP MRC 81S13 B639G  P.IVA 03041740139
5
The typedef is needed because the cncapi uses the integer type _int64 which Qt4 does not know. Now build the
project (Ctrl + B or click on the hammer icon in the lower left). You should get no errors but a lot of warnings which
are due to the syntax used by the cncapi. However, we may ignore them.
Now let’s see how to do something useful with the USBCNC SDK.
3.3 The USBCNC Server
On launching the USBCNC software (this standard can be called GUI), a process will run in background: it is the
CncServer.exe. In order to work properly, the standard GUI and all other GUIs, that we can build, have to be
connected to this server.
Open the mainwindow.ui form, drag and drop a Pushbutton and a Line Edit widgets and set the following properties:
Pushbutton
objectName
text
btnConnect
CONNECT
Line Edit
objectName
readOnly
txtServerStatus
true
At the moment we do not use any layout, but we will come back to this topic later.
Open the mainwindow.h and add the following code in the class definition:
private slots:
void on_btnConnect_clicked();
At this point, add the implementation in the mainwindow.cpp:
void MainWindow::on_btnConnect_clicked()
{
CNC_RC rc = CncConnectServer("");
ui->txtServerStatus->setText(CncGetRCText(rc));
}
The “on_” prefix allows to connect automatically a signal (clicked() in the example) to the slot declared. In this way
on clicking the pushbutton, the on_btnConnect_clicked() function is called.
CncConnectServer() is the first cncapi function that we use. In order to know something more about any cncapi items
just place the cursor on and press F2. The editor will show the definition in the header file. CncConnectServer() takes
one optional argument: the .ini file name. You should pass this parameter only for stand-alone applications which
will run without USBCNC4 software. In our example we have already the server running because the USBCNC4
Femtotech di Marco Trapanese  Via Ripamonti, 14 – 22044 Inverigo (CO)  tel. 031 5481112 / 347 9431074  fax 031 2280476
[email protected]  www.femtotech.it  C.F. TRP MRC 81S13 B639G  P.IVA 03041740139
6
software is still open, so we pass an empty string.
As this is a key point, I have decided to summarise the options we have:
If you want to create a stand-alone application:


Call CncConnectServer(“cnc.ini”)
Do not launch USBCNC4 but only your application
If you want to create an additional GUI that runs beside the standard GUI:



Call CncConnectServer(“”) with an empty string
Launch USBCNC4 before your application
Call CncDisconnectServer() before exiting
In order to see the differences, you should try both ways with our simple example. The text box will show the
messages returned from the function.
3.4 Useful functions
In order to learn more about the api provided by the SDK, you should explore yourself the cncapi.h. However, here is
provided a list of the more common functions.
CNC_RC CncConnectServer(char *iniFileName);
As I have already said, this is the first function you have to call when connecting to the server. If no valid
argument is passed, the server is already running; otherwise, it will be started.
CNC_RC CncDisConnectServer(void);
Call this function only in case you have started the server (you passed the “cnc.ini” to CncConnectServer).
CNC_IE_STATE CncGetState(void);
This is useful in order to know the state of the machine: ready, running a job, etc.
CNC_RC CncPauseJob(void);
This is useful to pause a job without abort. In this way, the motors do not lose steps and homing is not
required.
CNC_RC CncRunOrResumeJob(void);
This is used to start a job or resume the paused one.
CNC_RC CncRewindJob(void);
This is used to rewind the job to the beginning.
Femtotech di Marco Trapanese  Via Ripamonti, 14 – 22044 Inverigo (CO)  tel. 031 5481112 / 347 9431074  fax 031 2280476
[email protected]  www.femtotech.it  C.F. TRP MRC 81S13 B639G  P.IVA 03041740139
7
CNC_RC CncReset(void);
This function recovers from errors, exits from a paused state, establishes a connection with the server in
case this has not been done yet.
CNC_RC CncLoadJob(const char *fileName,
int
*jobFileLength,
int
*macroFileLength,
int
*isLongJob,
int
*isSuperLongJob,
__int64 *sizeInBytes);
Loads the job specified by the first parameters. All the others are output arguments, so pass the pointers to
the local variables. If your application runs beside the standard GUI, call CncStartRenderGraph() to update the
rendering window.
CNC_RC CncRunSingleLine(char *text);
Runs a line of G-Code or calls a subroutine contained into the macro.cnc file.
double CncGetWorkPos2(int axis);
Returns the position of the axis specified. Axes are defined in the cnc_types.h as CNC_X_AXIS, CNC_Y_AXIS
and so on. Thus, to get the position of the Z axis simply call: CncGetWorkPos2(CNC_Z_AXIS).
Femtotech di Marco Trapanese  Via Ripamonti, 14 – 22044 Inverigo (CO)  tel. 031 5481112 / 347 9431074  fax 031 2280476
[email protected]  www.femtotech.it  C.F. TRP MRC 81S13 B639G  P.IVA 03041740139
8
4 A complete example
Now we are ready to develop a complete application that provides basic features like the following ones:




Displaying current coordinates
Homing the machine
Loading a job
Starting / resuming / rewinding the job
4.1 Design the GUI
Open the mainwindow.ui form and add the necessary widgets:
Play with the properties to see their effects.
Now let’s write some codes. In order to read the current position, we need a timer that periodically calls the
CncGetWorkPos2() function. To load a job we use the standard file dialog. For this first test I recommend you to run
the application beside USBCNC4 so that you can see what is going to happen.
To layout properly the widgets, put them first into a container (e.g. Group Box), then use the Lay Out on a Grid
command. The same applies to lay out the containers in the form.
This is the mainwindow.h code:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QFileDialog>
#include <QTimer>
typedef qint64 _int64;
#include "cncapi.h"
namespace Ui {
class MainWindow;
}
Femtotech di Marco Trapanese  Via Ripamonti, 14 – 22044 Inverigo (CO)  tel. 031 5481112 / 347 9431074  fax 031 2280476
[email protected]  www.femtotech.it  C.F. TRP MRC 81S13 B639G  P.IVA 03041740139
9
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
QTimer *timer;
private slots:
void on_btnConnect_clicked();
void on_btnLoadJob_clicked();
void on_btnStartJob_clicked();
void on_btnRewindJob_clicked();
void on_btnHomeAll_clicked();
void on_btnPause_clicked();
void on_btnReset_clicked();
void timer_ovf();
};
#endif // MAINWINDOW_H
This is the mainwindow.cpp code:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
timer = new QTimer(this);
timer->setInterval(100);
connect(timer, SIGNAL(timeout()), this, SLOT(timer_ovf()));
}
MainWindow::~MainWindow()
{
//CncDisConnectServer();
delete ui;
}
void MainWindow::on_btnConnect_clicked()
{
CNC_RC rc = CncConnectServer(""); // ("cnc.ini");
ui->txtServerStatus->setText(CncGetRCText(rc));
if (rc == CNC_RC_OK || rc == CNC_RC_ALREADY_RUNS) timer->start();
}
void MainWindow::on_btnLoadJob_clicked()
{
QFileDialog *dialog = new QFileDialog();
QString file = dialog->getOpenFileName(this, "Select job", "", "CNC Files (*.nc *.cnc *.ngc *.gc *.iso
*.tap)");
if (file.isEmpty()) return;
int jobFileLength, macroFileLength, isLongJob, isSuperLongJob;
qint64 sizeInBytes;
QByteArray fileName = file.toLocal8Bit();
CNC_RC rc = CncLoadJob(fileName.data(), &jobFileLength, &macroFileLength, &isLongJob, &isSuperLongJob,
&sizeInBytes);
ui->txtServerStatus->setText(CncGetRCText(rc));
CncStartRenderGraph(1, 1);
}
void MainWindow::on_btnHomeAll_clicked()
{
CNC_RC rc = CncRunSingleLine("gosub home_all");
ui->txtServerStatus->setText(CncGetRCText(rc));
}
void MainWindow::on_btnRewindJob_clicked()
Femtotech di Marco Trapanese  Via Ripamonti, 14 – 22044 Inverigo (CO)  tel. 031 5481112 / 347 9431074  fax 031 2280476
[email protected]  www.femtotech.it  C.F. TRP MRC 81S13 B639G  P.IVA 03041740139
10
{
CNC_RC rc = CncRewindJob();
ui->txtServerStatus->setText(CncGetRCText(rc));
}
void MainWindow::on_btnStartJob_clicked()
{
CNC_RC rc = CncRunOrResumeJob();
ui->txtServerStatus->setText(CncGetRCText(rc));
}
void MainWindow::on_btnPause_clicked()
{
CNC_RC rc = CncPauseJob();
ui->txtServerStatus->setText(CncGetRCText(rc));
}
void MainWindow::on_btnReset_clicked()
{
CNC_RC rc = CncReset();
ui->txtServerStatus->setText(CncGetRCText(rc));
}
void MainWindow::timer_ovf() {
ui->txtX->setText(QString::number(CncGetWorkPos2(CNC_X_AXIS), 'f', 3));
ui->txtY->setText(QString::number(CncGetWorkPos2(CNC_Y_AXIS), 'f', 3));
ui->txtZ->setText(QString::number(CncGetWorkPos2(CNC_Z_AXIS), 'f', 3));
}
4.2 Do it yourself
The application we have just built is very simple and does not have all the features you can require. Try to add them
yourself. For example, extending the monitoring of the position to all 5 axes, providing a function in order to move
the tool to a known and safe position (hint: use CncRunSingleLine() using G0 code), etc.
Femtotech di Marco Trapanese  Via Ripamonti, 14 – 22044 Inverigo (CO)  tel. 031 5481112 / 347 9431074  fax 031 2280476
[email protected]  www.femtotech.it  C.F. TRP MRC 81S13 B639G  P.IVA 03041740139
11
5 Deploy your application
The Qt Creator environment takes care of all the dependencies needed to run our application. When we want to
launch the executable outside the Qt Creator, we have to copy them to the output folder or set the environment
PATH variable.
Before starting to deploy the application, we recompile it in Release mode. You find this option just above the two
green play buttons. Run the application to check that everything works again.
Now we can close Qt Creator and open the source folder, in our example C:/Tutorial/Test01. You see two folders
called Debug and Release. Open the latter and you find the Test01.exe. If you try to execute it, it is likely you will get
some errors about missing dlls. This is because the executable does not know where they are placed.
I prefer to copy the dlls into this folder rather than set an environment variable. You need the following files:





C:/QtSDK/Desktop/Qt/4.7.4/mingw/bin/QtGui4.dll
C:/QtSDK/Desktop/Qt/4.7.4/mingw/bin/QtCore4.dll
C:/QtSDK/Desktop/Qt/4.7.4/mingw/bin/libgcc_s_dw2-1.dll
C:/QtSDK/Desktop/Qt/4.7.4/mingw/bin/mingwm10.dll
C:/Program Files (x86)/USBCNC4/cncapi.dll
Now the exe should run without problems.
6 Links
http://qt.nokia.com/learning
http://zetcode.com/tutorials/qt4tutorial/
Femtotech di Marco Trapanese  Via Ripamonti, 14 – 22044 Inverigo (CO)  tel. 031 5481112 / 347 9431074  fax 031 2280476
[email protected]  www.femtotech.it  C.F. TRP MRC 81S13 B639G  P.IVA 03041740139
12