PDA

View Full Version : QT and Libmodbus



hoan_do_van
2nd March 2015, 06:26
hi!
I view the source code of QModMaster and now want to build a Qt GUI application server using libmodbus .
my application is run on raspberry pi.
when i run my application, GUI appears only when there is a connection.
anyone have any examples of this application can send t it? please!

code:
tcp.h:


#ifndef TCP_H
#define TCP_H

#include <QObject>
#include <modbus/modbus.h>
#include <modbus/modbus-tcp.h>
#include <QDebug>
#include <QEventLoop>

QT_BEGIN_NAMESPACE

//static int NB_CONNECTION;

class TcpPrivate;

class Q_NETWORK_EXPORT Tcp : public QObject
{
Q_OBJECT
public:
explicit Tcp(QObject *parent = 0);
~Tcp();

bool listen(const char* address, int port,int NB);

modbus_t *server;
int ser;


Q_SIGNALS:
void newconnection();
void accepterror();

protected:
virtual void incomingConnection(int handle);
void addPendingConnection(int socket);

Tcp(TcpPrivate &dd, QObject *parent = 0);

public slots:

private:
Q_DISABLE_COPY(Tcp)
Q_DECLARE_PRIVATE(Tcp)
};

QT_END_NAMESPACE

#endif // TCP_H

tcp_p.h:


#ifndef TCP_P_H
#define TCP_P_H

#include "tcp.h"
#include "object_p.h"
#include <QtCore/QList>
#include <QDebug>
//#include <winsock2.h>
#include <sys/socket.h>
#include <netinet/in.h>

QT_BEGIN_NAMESPACE

class TcpPrivate: public QObjectPrivate
{
Q_DECLARE_PUBLIC(Tcp)
public:
TcpPrivate();
~TcpPrivate();

QList<int *> pendingConnections;

quint16 port;
const char* address;
int maxConnections;

void readNotification();
void setreadNotification(bool enable);
};

QT_END_NAMESPACE

#endif // TCP_P_H

tcp.cpp:


#include "tcp.h"
#include "tcp_p.h"
#include <qlist.h>

QT_BEGIN_NAMESPACE

/*! \internal
*/
TcpPrivate::TcpPrivate()
: port(0)
, maxConnections(30)
{
}

/*! \internal
*/

TcpPrivate::~TcpPrivate()
{
}

void TcpPrivate::readNotification()
{
Q_Q(Tcp);
qDebug() << "dang o for";
if(pendingConnections.count() > maxConnections)
{
qDebug() << "too many connections";
return;
}

socklen_t addrlen;
struct sockaddr_in clientaddr;
int descriptor;

qDebug() << "ser" << q->ser;
descriptor = accept(q->ser,(struct sockaddr*)&clientaddr,&addrlen);
qDebug() << "descriptor " << descriptor;
if(descriptor == -1)
{
//q->pauseaccepting();
qDebug() << "accept connection failed";
emit q->accepterror();
return;

}

qDebug("TcpPrivate::processIncomingConnection() accepted socket %i", descriptor);

q->incomingConnection(descriptor);

emit q->newconnection();

qDebug() << "emit newconnection";
//return;
}

/*! \internal
*/

void TcpPrivate::setreadNotification(bool enable)
{
if(enable)
readNotification();
}

/*! \internal
*/

Tcp::Tcp(TcpPrivate &dd, QObject *parent)
: QObject(dd, parent)
{
}

Tcp::Tcp(QObject *parent) : QObject(*new TcpPrivate, parent)
{
}

Tcp::~Tcp()
{

}

bool Tcp::listen(const char* address, int port,int NB)
{
Q_D(Tcp);
modbus_t *mb_tcp;
mb_tcp = modbus_new_tcp(address,port);
ser = modbus_tcp_listen(mb_tcp,NB);
if(ser == -1)
{
qDebug() << "listen fail";
return false;
}

qDebug() << "listenning on socket "<<ser;

d->setreadNotification(true);
}

void Tcp::incomingConnection(int handler)
{
qDebug("QTcpServer::incomingConnection(%i)", handler);

int socket;
socket = handler;
// socket->setSocketDescriptor(handler);
addPendingConnection(socket);
}

void Tcp::addPendingConnection(int socket)
{
d_func()->pendingConnections.append(&socket);
}


mainwindow.cpp:


#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
const char * host = "192.168.0.140";
int port = 1502;
ui->setupUi(this);
new_tcp = new Tcp(this);
connect(new_tcp,SIGNAL(newconnection()),this,SLOT( newconnection()));

//connect(this,SIGNAL(newconnection()),&loop,SLOT(quit()));
connect(new_tcp,SIGNAL(accepterror()),this,SLOT(ac cepterror()));
new_tcp->listen(host,port,5);
//loop.exec();

}

anda_skoa
2nd March 2015, 12:22
Maybe Tcp::listen() blocks?

Cheers,
_

hoan_do_van
2nd March 2015, 13:39
thank for reply!
I tried to non block non listen socket created by the command deposits,
fcntl ( socket , F_SETFL , 0 ) However it is still not effective , you have examples of this application does not , sent me ? please!

anda_skoa
2nd March 2015, 20:05
I've not used modbus or its Qt wrapper before so I don't have any examples.
If you can't make the listen call non-blocking like e.g. QTcpServer's, then you'll have to use a separate thread.

Cheers,
_

hoan_do_van
4th March 2015, 05:21
It has been solved.
Thank you!