12.06.2013 Views

How to make a GUI for USBCNC with Qt4 - Femtotech

How to make a GUI for USBCNC with Qt4 - Femtotech

How to make a GUI for USBCNC with Qt4 - Femtotech

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

<strong>How</strong> <strong>to</strong> <strong>make</strong> a <strong>GUI</strong> <strong>for</strong> <strong>USBCNC</strong> <strong>with</strong> <strong>Qt4</strong><br />

Summary<br />

Fem<strong>to</strong>tech di Marco Trapanese Via Ripamonti, 14 – 22044 Inverigo (CO) tel. 031 5481112 / 347 9431074 fax 031 2280476<br />

info@fem<strong>to</strong>tech.it www.fem<strong>to</strong>tech.it C.F. TRP MRC 81S13 B639G P.IVA 03041740139<br />

1<br />

fem<strong>to</strong>tu<strong>to</strong>rial<br />

Summary .................................................................................................................................................................... 1<br />

1 Preface ................................................................................................................................................................ 2<br />

2 Getting started .................................................................................................................................................... 3<br />

2.1 Prerequisites ............................................................................................................................................... 3<br />

2.2 First steps .................................................................................................................................................... 3<br />

3 The <strong>USBCNC</strong> SDK ................................................................................................................................................. 5<br />

3.1 Adding the library <strong>to</strong> the project .................................................................................................................. 5<br />

3.2 Including headers ........................................................................................................................................ 5<br />

3.3 The <strong>USBCNC</strong> Server...................................................................................................................................... 6<br />

3.4 Useful functions........................................................................................................................................... 7<br />

4 A complete example............................................................................................................................................ 9<br />

4.1 Design the <strong>GUI</strong> ............................................................................................................................................. 9<br />

4.2 Do it yourself ............................................................................................................................................. 11<br />

5 Deploy your application .................................................................................................................................... 12<br />

6 Links .................................................................................................................................................................. 12<br />

Revision A, 05-feb-2012


1 Preface<br />

This tu<strong>to</strong>rial will guide you through all the steps needed <strong>to</strong> setup the developing environment, configure the project<br />

and write a small <strong>GUI</strong> <strong>for</strong> the <strong>USBCNC</strong> software. Using <strong>GUI</strong>s is a powerful way <strong>to</strong> extend the functionality of your CNC<br />

machine. You should cus<strong>to</strong>mise your preferred tasks or create a user interface that meets some unusual<br />

requirements.<br />

As we will see later, interfacing <strong>with</strong> <strong>USBCNC</strong> is very easy and requires only some basic knowledge of C++<br />

programming and of the <strong>Qt4</strong> environment. Anyway, at the end of the document there are a couple of links <strong>to</strong> generic<br />

tu<strong>to</strong>rials about <strong>Qt4</strong>.<br />

Fem<strong>to</strong>tech di Marco Trapanese Via Ripamonti, 14 – 22044 Inverigo (CO) tel. 031 5481112 / 347 9431074 fax 031 2280476<br />

info@fem<strong>to</strong>tech.it www.fem<strong>to</strong>tech.it C.F. TRP MRC 81S13 B639G P.IVA 03041740139<br />

2


2 Getting started<br />

2.1 Prerequisites<br />

To develop our applications <strong>for</strong> <strong>USBCNC</strong> we need some prerequisites:<br />

A computer <strong>with</strong> a Windows O.S. (here Windows 7)<br />

<strong>USBCNC</strong> Software by Bert Eding (http://www.edingcnc.com/index.php?pagina=8_download)<br />

<strong>USBCNC</strong> SDK, included in the <strong>USBCNC</strong> folder<br />

QtSDK <strong>for</strong> Windows by Nokia (http://qt.nokia.com/downloads)<br />

Some C++ programming experience and a minimum knowledge of <strong>Qt4</strong><br />

Download and install both software.<br />

For this tu<strong>to</strong>rial let’s assume that QtSDK was installed in<strong>to</strong> C:\QtSDK and <strong>USBCNC</strong> in<strong>to</strong> C:\Program Files<br />

(x86)\<strong>USBCNC</strong>4. Please, mind the difference between your actual installation paths.<br />

2.2 First steps<br />

Now we are going <strong>to</strong> check the functionality of the software we have just installed. Launch <strong>USBCNC</strong>4 and click on the<br />

START but<strong>to</strong>n in the middle of the screen. If you have not purchased the <strong>USBCNC</strong> CPU board yet, the application will<br />

run in Simulation mode:<br />

It is enough <strong>for</strong> testing purposes. Press F1 <strong>to</strong> enable drives and try <strong>to</strong> move around the screen using cursor keys. You<br />

should see the coordinates changing. Leave the <strong>USBCNC</strong>4 open, we need it in a while.<br />

Ok, now launch Qt Crea<strong>to</strong>r so that we can create a<br />

test project. In the Welcome window click on<br />

Create Project, then select Qt Widget Project > Qt<br />

Gui Application:<br />

Fem<strong>to</strong>tech di Marco Trapanese Via Ripamonti, 14 – 22044 Inverigo (CO) tel. 031 5481112 / 347 9431074 fax 031 2280476<br />

info@fem<strong>to</strong>tech.it www.fem<strong>to</strong>tech.it C.F. TRP MRC 81S13 B639G P.IVA 03041740139<br />

3


The next window will ask <strong>for</strong> a project name and the location path. At this point, we need <strong>to</strong> check the Target Setup:<br />

Usually, there is no need <strong>to</strong> change default values. Qt Crea<strong>to</strong>r will compile <strong>with</strong> the latest Qt Version and will place<br />

the executable files in either debug or release subfolder. Click Next on subsequent windows until the wizard ends.<br />

You should see the mainwindow.cpp default code:<br />

Please take time <strong>to</strong> become familiar <strong>with</strong> the environment. In the left lower side of the screen there are two play<br />

but<strong>to</strong>ns. Click on one of them 1 and our empty application should run <strong>with</strong>out problems. Close the application<br />

window using the X but<strong>to</strong>n.<br />

We are ready <strong>to</strong> develop new <strong>GUI</strong>s <strong>for</strong> <strong>USBCNC</strong>!<br />

1 The play but<strong>to</strong>n <strong>with</strong> a bug on the <strong>to</strong>p is used <strong>to</strong> start debugging.<br />

Fem<strong>to</strong>tech di Marco Trapanese Via Ripamonti, 14 – 22044 Inverigo (CO) tel. 031 5481112 / 347 9431074 fax 031 2280476<br />

info@fem<strong>to</strong>tech.it www.fem<strong>to</strong>tech.it C.F. TRP MRC 81S13 B639G P.IVA 03041740139<br />

4


3 The <strong>USBCNC</strong> SDK<br />

The <strong>USBCNC</strong> SDK is provided <strong>with</strong> the <strong>USBCNC</strong> software. In the installation path there is a cncapi folder which<br />

contains all the necessary files: the library and the related headers.<br />

3.1 Adding the library <strong>to</strong> the project<br />

The first operation we have <strong>to</strong> do is <strong>to</strong> convey <strong>to</strong> Qt Crea<strong>to</strong>r that we want <strong>to</strong> use the <strong>USBCNC</strong> SDK. Double-click on<br />

the .pro file and edit according <strong>to</strong> the following picture:<br />

3.2 Including headers<br />

We have just configured our project <strong>to</strong> link the cncapi library. If we want <strong>to</strong> use the functions provided, we also need<br />

<strong>to</strong> include the header files. Open the mainwindow.h file and add at the beginning the #include instruction <strong>for</strong><br />

cncapi.h:<br />

Fem<strong>to</strong>tech di Marco Trapanese Via Ripamonti, 14 – 22044 Inverigo (CO) tel. 031 5481112 / 347 9431074 fax 031 2280476<br />

info@fem<strong>to</strong>tech.it www.fem<strong>to</strong>tech.it C.F. TRP MRC 81S13 B639G P.IVA 03041740139<br />

5


The typedef is needed because the cncapi uses the integer type _int64 which <strong>Qt4</strong> does not know. Now build the<br />

project (Ctrl + B or click on the hammer icon in the lower left). You should get no errors but a lot of warnings which<br />

are due <strong>to</strong> the syntax used by the cncapi. <strong>How</strong>ever, we may ignore them.<br />

Now let’s see how <strong>to</strong> do something useful <strong>with</strong> the <strong>USBCNC</strong> SDK.<br />

3.3 The <strong>USBCNC</strong> Server<br />

On launching the <strong>USBCNC</strong> software (this standard can be called <strong>GUI</strong>), a process will run in background: it is the<br />

CncServer.exe. In order <strong>to</strong> work properly, the standard <strong>GUI</strong> and all other <strong>GUI</strong>s, that we can build, have <strong>to</strong> be<br />

connected <strong>to</strong> this server.<br />

Open the mainwindow.ui <strong>for</strong>m, drag and drop a Pushbut<strong>to</strong>n and a Line Edit widgets and set the following properties:<br />

Pushbut<strong>to</strong>n<br />

objectName btnConnect<br />

text CONNECT<br />

Line Edit<br />

objectName txtServerStatus<br />

readOnly true<br />

At the moment we do not use any layout, but we will come back <strong>to</strong> this <strong>to</strong>pic later.<br />

Open the mainwindow.h and add the following code in the class definition:<br />

private slots:<br />

void on_btnConnect_clicked();<br />

At this point, add the implementation in the mainwindow.cpp:<br />

void MainWindow::on_btnConnect_clicked()<br />

{<br />

CNC_RC rc = CncConnectServer("");<br />

ui->txtServerStatus->setText(CncGetRCText(rc));<br />

}<br />

The “on_” prefix allows <strong>to</strong> connect au<strong>to</strong>matically a signal (clicked() in the example) <strong>to</strong> the slot declared. In this way<br />

on clicking the pushbut<strong>to</strong>n, the on_btnConnect_clicked() function is called.<br />

CncConnectServer() is the first cncapi function that we use. In order <strong>to</strong> know something more about any cncapi items<br />

just place the cursor on and press F2. The edi<strong>to</strong>r will show the definition in the header file. CncConnectServer() takes<br />

one optional argument: the .ini file name. You should pass this parameter only <strong>for</strong> stand-alone applications which<br />

will run <strong>with</strong>out <strong>USBCNC</strong>4 software. In our example we have already the server running because the <strong>USBCNC</strong>4<br />

Fem<strong>to</strong>tech di Marco Trapanese Via Ripamonti, 14 – 22044 Inverigo (CO) tel. 031 5481112 / 347 9431074 fax 031 2280476<br />

info@fem<strong>to</strong>tech.it www.fem<strong>to</strong>tech.it C.F. TRP MRC 81S13 B639G P.IVA 03041740139<br />

6


software is still open, so we pass an empty string.<br />

As this is a key point, I have decided <strong>to</strong> summarise the options we have:<br />

If you want <strong>to</strong> create a stand-alone application:<br />

Call CncConnectServer(“cnc.ini”)<br />

Do not launch <strong>USBCNC</strong>4 but only your application<br />

If you want <strong>to</strong> create an additional <strong>GUI</strong> that runs beside the standard <strong>GUI</strong>:<br />

Call CncConnectServer(“”) <strong>with</strong> an empty string<br />

Launch <strong>USBCNC</strong>4 be<strong>for</strong>e your application<br />

Call CncDisconnectServer() be<strong>for</strong>e exiting<br />

In order <strong>to</strong> see the differences, you should try both ways <strong>with</strong> our simple example. The text box will show the<br />

messages returned from the function.<br />

3.4 Useful functions<br />

In order <strong>to</strong> learn more about the api provided by the SDK, you should explore yourself the cncapi.h. <strong>How</strong>ever, here is<br />

provided a list of the more common functions.<br />

CNC_RC CncConnectServer(char *iniFileName);<br />

As I have already said, this is the first function you have <strong>to</strong> call when connecting <strong>to</strong> the server. If no valid<br />

argument is passed, the server is already running; otherwise, it will be started.<br />

CNC_RC CncDisConnectServer(void);<br />

Call this function only in case you have started the server (you passed the “cnc.ini” <strong>to</strong> CncConnectServer).<br />

CNC_IE_STATE CncGetState(void);<br />

This is useful in order <strong>to</strong> know the state of the machine: ready, running a job, etc.<br />

CNC_RC CncPauseJob(void);<br />

This is useful <strong>to</strong> pause a job <strong>with</strong>out abort. In this way, the mo<strong>to</strong>rs do not lose steps and homing is not<br />

required.<br />

CNC_RC CncRunOrResumeJob(void);<br />

This is used <strong>to</strong> start a job or resume the paused one.<br />

CNC_RC CncRewindJob(void);<br />

This is used <strong>to</strong> rewind the job <strong>to</strong> the beginning.<br />

Fem<strong>to</strong>tech di Marco Trapanese Via Ripamonti, 14 – 22044 Inverigo (CO) tel. 031 5481112 / 347 9431074 fax 031 2280476<br />

info@fem<strong>to</strong>tech.it www.fem<strong>to</strong>tech.it C.F. TRP MRC 81S13 B639G P.IVA 03041740139<br />

7


CNC_RC CncReset(void);<br />

This function recovers from errors, exits from a paused state, establishes a connection <strong>with</strong> the server in<br />

case this has not been done yet.<br />

CNC_RC CncLoadJob(const char *fileName,<br />

int *jobFileLength,<br />

int *macroFileLength,<br />

int *isLongJob,<br />

int *isSuperLongJob,<br />

__int64 *sizeInBytes);<br />

Loads the job specified by the first parameters. All the others are output arguments, so pass the pointers <strong>to</strong><br />

the local variables. If your application runs beside the standard <strong>GUI</strong>, call CncStartRenderGraph() <strong>to</strong> update the<br />

rendering window.<br />

CNC_RC CncRunSingleLine(char *text);<br />

Runs a line of G-Code or calls a subroutine contained in<strong>to</strong> the macro.cnc file.<br />

double CncGetWorkPos2(int axis);<br />

Returns the position of the axis specified. Axes are defined in the cnc_types.h as CNC_X_AXIS, CNC_Y_AXIS<br />

and so on. Thus, <strong>to</strong> get the position of the Z axis simply call: CncGetWorkPos2(CNC_Z_AXIS).<br />

Fem<strong>to</strong>tech di Marco Trapanese Via Ripamonti, 14 – 22044 Inverigo (CO) tel. 031 5481112 / 347 9431074 fax 031 2280476<br />

info@fem<strong>to</strong>tech.it www.fem<strong>to</strong>tech.it C.F. TRP MRC 81S13 B639G P.IVA 03041740139<br />

8


4 A complete example<br />

Now we are ready <strong>to</strong> develop a complete application that provides basic features like the following ones:<br />

Displaying current coordinates<br />

Homing the machine<br />

Loading a job<br />

Starting / resuming / rewinding the job<br />

4.1 Design the <strong>GUI</strong><br />

Open the mainwindow.ui <strong>for</strong>m and add the necessary widgets:<br />

Play <strong>with</strong> the properties <strong>to</strong> see their effects.<br />

Now let’s write some codes. In order <strong>to</strong> read the current position, we need a timer that periodically calls the<br />

CncGetWorkPos2() function. To load a job we use the standard file dialog. For this first test I recommend you <strong>to</strong> run<br />

the application beside <strong>USBCNC</strong>4 so that you can see what is going <strong>to</strong> happen.<br />

To layout properly the widgets, put them first in<strong>to</strong> a container (e.g. Group Box), then use the Lay Out on a Grid<br />

command. The same applies <strong>to</strong> lay out the containers in the <strong>for</strong>m.<br />

This is the mainwindow.h code:<br />

#ifndef MAINWINDOW_H<br />

#define MAINWINDOW_H<br />

#include <br />

#include <br />

#include <br />

typedef qint64 _int64;<br />

#include "cncapi.h"<br />

namespace Ui {<br />

class MainWindow;<br />

}<br />

Fem<strong>to</strong>tech di Marco Trapanese Via Ripamonti, 14 – 22044 Inverigo (CO) tel. 031 5481112 / 347 9431074 fax 031 2280476<br />

info@fem<strong>to</strong>tech.it www.fem<strong>to</strong>tech.it C.F. TRP MRC 81S13 B639G P.IVA 03041740139<br />

9


class MainWindow : public QMainWindow<br />

{<br />

Q_OBJECT<br />

public:<br />

explicit MainWindow(QWidget *parent = 0);<br />

~MainWindow();<br />

private:<br />

Ui::MainWindow *ui;<br />

QTimer *timer;<br />

private slots:<br />

void on_btnConnect_clicked();<br />

void on_btnLoadJob_clicked();<br />

void on_btnStartJob_clicked();<br />

void on_btnRewindJob_clicked();<br />

void on_btnHomeAll_clicked();<br />

void on_btnPause_clicked();<br />

void on_btnReset_clicked();<br />

void timer_ovf();<br />

};<br />

#endif // MAINWINDOW_H<br />

This is the mainwindow.cpp code:<br />

#include "mainwindow.h"<br />

#include "ui_mainwindow.h"<br />

MainWindow::MainWindow(QWidget *parent) :<br />

QMainWindow(parent),<br />

ui(new Ui::MainWindow)<br />

{<br />

ui->setupUi(this);<br />

timer = new QTimer(this);<br />

timer->setInterval(100);<br />

connect(timer, SIGNAL(timeout()), this, SLOT(timer_ovf()));<br />

}<br />

MainWindow::~MainWindow()<br />

{<br />

//CncDisConnectServer();<br />

delete ui;<br />

}<br />

void MainWindow::on_btnConnect_clicked()<br />

{<br />

CNC_RC rc = CncConnectServer(""); // ("cnc.ini");<br />

ui->txtServerStatus->setText(CncGetRCText(rc));<br />

if (rc == CNC_RC_OK || rc == CNC_RC_ALREADY_RUNS) timer->start();<br />

}<br />

void MainWindow::on_btnLoadJob_clicked()<br />

{<br />

QFileDialog *dialog = new QFileDialog();<br />

QString file = dialog->getOpenFileName(this, "Select job", "", "CNC Files (*.nc *.cnc *.ngc *.gc *.iso<br />

*.tap)");<br />

if (file.isEmpty()) return;<br />

int jobFileLength, macroFileLength, isLongJob, isSuperLongJob;<br />

qint64 sizeInBytes;<br />

QByteArray fileName = file.<strong>to</strong>Local8Bit();<br />

CNC_RC rc = CncLoadJob(fileName.data(), &jobFileLength, &macroFileLength, &isLongJob, &isSuperLongJob,<br />

&sizeInBytes);<br />

ui->txtServerStatus->setText(CncGetRCText(rc));<br />

CncStartRenderGraph(1, 1);<br />

}<br />

void MainWindow::on_btnHomeAll_clicked()<br />

{<br />

CNC_RC rc = CncRunSingleLine("gosub home_all");<br />

ui->txtServerStatus->setText(CncGetRCText(rc));<br />

}<br />

void MainWindow::on_btnRewindJob_clicked()<br />

Fem<strong>to</strong>tech di Marco Trapanese Via Ripamonti, 14 – 22044 Inverigo (CO) tel. 031 5481112 / 347 9431074 fax 031 2280476<br />

info@fem<strong>to</strong>tech.it www.fem<strong>to</strong>tech.it C.F. TRP MRC 81S13 B639G P.IVA 03041740139<br />

10


{<br />

}<br />

CNC_RC rc = CncRewindJob();<br />

ui->txtServerStatus->setText(CncGetRCText(rc));<br />

void MainWindow::on_btnStartJob_clicked()<br />

{<br />

CNC_RC rc = CncRunOrResumeJob();<br />

ui->txtServerStatus->setText(CncGetRCText(rc));<br />

}<br />

void MainWindow::on_btnPause_clicked()<br />

{<br />

CNC_RC rc = CncPauseJob();<br />

ui->txtServerStatus->setText(CncGetRCText(rc));<br />

}<br />

void MainWindow::on_btnReset_clicked()<br />

{<br />

CNC_RC rc = CncReset();<br />

ui->txtServerStatus->setText(CncGetRCText(rc));<br />

}<br />

void MainWindow::timer_ovf() {<br />

ui->txtX->setText(QString::number(CncGetWorkPos2(CNC_X_AXIS), 'f', 3));<br />

ui->txtY->setText(QString::number(CncGetWorkPos2(CNC_Y_AXIS), 'f', 3));<br />

ui->txtZ->setText(QString::number(CncGetWorkPos2(CNC_Z_AXIS), 'f', 3));<br />

}<br />

4.2 Do it yourself<br />

The application we have just built is very simple and does not have all the features you can require. Try <strong>to</strong> add them<br />

yourself. For example, extending the moni<strong>to</strong>ring of the position <strong>to</strong> all 5 axes, providing a function in order <strong>to</strong> move<br />

the <strong>to</strong>ol <strong>to</strong> a known and safe position (hint: use CncRunSingleLine() using G0 code), etc.<br />

Fem<strong>to</strong>tech di Marco Trapanese Via Ripamonti, 14 – 22044 Inverigo (CO) tel. 031 5481112 / 347 9431074 fax 031 2280476<br />

info@fem<strong>to</strong>tech.it www.fem<strong>to</strong>tech.it C.F. TRP MRC 81S13 B639G P.IVA 03041740139<br />

11


5 Deploy your application<br />

The Qt Crea<strong>to</strong>r environment takes care of all the dependencies needed <strong>to</strong> run our application. When we want <strong>to</strong><br />

launch the executable outside the Qt Crea<strong>to</strong>r, we have <strong>to</strong> copy them <strong>to</strong> the output folder or set the environment<br />

PATH variable.<br />

Be<strong>for</strong>e starting <strong>to</strong> deploy the application, we recompile it in Release mode. You find this option just above the two<br />

green play but<strong>to</strong>ns. Run the application <strong>to</strong> check that everything works again.<br />

Now we can close Qt Crea<strong>to</strong>r and open the source folder, in our example C:/Tu<strong>to</strong>rial/Test01. You see two folders<br />

called Debug and Release. Open the latter and you find the Test01.exe. If you try <strong>to</strong> execute it, it is likely you will get<br />

some errors about missing dlls. This is because the executable does not know where they are placed.<br />

I prefer <strong>to</strong> copy the dlls in<strong>to</strong> this folder rather than set an environment variable. You need the following files:<br />

C:/QtSDK/Desk<strong>to</strong>p/Qt/4.7.4/mingw/bin/QtGui4.dll<br />

C:/QtSDK/Desk<strong>to</strong>p/Qt/4.7.4/mingw/bin/QtCore4.dll<br />

C:/QtSDK/Desk<strong>to</strong>p/Qt/4.7.4/mingw/bin/libgcc_s_dw2-1.dll<br />

C:/QtSDK/Desk<strong>to</strong>p/Qt/4.7.4/mingw/bin/mingwm10.dll<br />

C:/Program Files (x86)/<strong>USBCNC</strong>4/cncapi.dll<br />

Now the exe should run <strong>with</strong>out problems.<br />

6 Links<br />

http://qt.nokia.com/learning<br />

http://zetcode.com/tu<strong>to</strong>rials/qt4tu<strong>to</strong>rial/<br />

Fem<strong>to</strong>tech di Marco Trapanese Via Ripamonti, 14 – 22044 Inverigo (CO) tel. 031 5481112 / 347 9431074 fax 031 2280476<br />

info@fem<strong>to</strong>tech.it www.fem<strong>to</strong>tech.it C.F. TRP MRC 81S13 B639G P.IVA 03041740139<br />

12

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!