Here's my "final" implementation. It uses a thread to read data from the serial port, and sends a signal to a GUI class to slot update the value to the screen. The CPU load on this is 0-1% as the Serial Port Read is a true blocking function call.
There are 2 remarks about this:
1) I notice that as time goes on, the program's memory keeps increasing (I checked from Windows task manager. Not a lot, about 4 KB per minute. I couldnt think of anything that could cause this. I tried taking out the serial port Read code, and the program's size still kept increasing. Can it be because of signal/slot?
2) I'm currently passing signal/slot by value. If somebody knows a better way of passing the QString and could show it to me, that'd be great.
That was fun though, now I start to get a hang of it, and I'm going to start adding features.
SerialPortReader.hpp
#pragma once
#include "CSerial.hpp"
#include <QString>
#include <QStringList>
#include <QThread>
class SerialPortReader
: public QThread{
Q_OBJECT
public:
SerialPortReader();
void run();
signals:
private:
CSerial* port;
};
#pragma once
#include "CSerial.hpp"
#include <QString>
#include <QStringList>
#include <QThread>
class SerialPortReader : public QThread
{
Q_OBJECT
public:
SerialPortReader();
void run();
signals:
void newString( QString string );
private:
QString* str;
QStringList* list;
CSerial* port;
};
To copy to clipboard, switch view to plain text mode
SerialPortReader.cpp
#include "SerialPortReader.hpp"
#include <tchar.h>
#include <assert.h>
SerialPortReader::SerialPortReader()
{
port = new CSerial;
LONG stat;
stat = port->Open( _T("COM1"), 0, 0, true );
assert( stat == ERROR_SUCCESS );
stat = port->Setup( CSerial::EBaud115200,
CSerial::EData8,
CSerial::EParNone,
CSerial::EStop1 );
assert( stat == ERROR_SUCCESS );
stat = port->SetupHandshaking( CSerial::EHandshakeOff );
assert( stat == ERROR_SUCCESS );
stat = port->SetupReadTimeouts( CSerial::EReadTimeoutBlocking );
assert( stat == ERROR_SUCCESS );
}
void SerialPortReader::run()
{
char data[100] = "Hey man how are you?";
while(1)
{
int charIdx = 0;
DWORD bytesRead;
//
// Find sync word
do
{
data[charIdx] = 'A';
port->Read( &data[charIdx],
1,
&bytesRead );
} while( data[charIdx] != '$' );
charIdx++;
//
// Read the rest of the data
do
{
port->Read( &data[charIdx],
1,
&bytesRead );
charIdx++;
} while( data[charIdx-1] != '*' );
//
// Read check sum
port->Read( &data[charIdx],
2,
&bytesRead );
charIdx += 2;
data[charIdx] = '\0';
//
// Copy buffer to QString
*str = data;
//
// Indicate there's a new string
emit newString( *str );
}
}
#include "SerialPortReader.hpp"
#include <tchar.h>
#include <assert.h>
SerialPortReader::SerialPortReader()
{
str = new QString;
list = new QStringList;
port = new CSerial;
LONG stat;
stat = port->Open( _T("COM1"), 0, 0, true );
assert( stat == ERROR_SUCCESS );
stat = port->Setup( CSerial::EBaud115200,
CSerial::EData8,
CSerial::EParNone,
CSerial::EStop1 );
assert( stat == ERROR_SUCCESS );
stat = port->SetupHandshaking( CSerial::EHandshakeOff );
assert( stat == ERROR_SUCCESS );
stat = port->SetupReadTimeouts( CSerial::EReadTimeoutBlocking );
assert( stat == ERROR_SUCCESS );
}
void SerialPortReader::run()
{
char data[100] = "Hey man how are you?";
while(1)
{
int charIdx = 0;
DWORD bytesRead;
//
// Find sync word
do
{
data[charIdx] = 'A';
port->Read( &data[charIdx],
1,
&bytesRead );
} while( data[charIdx] != '$' );
charIdx++;
//
// Read the rest of the data
do
{
port->Read( &data[charIdx],
1,
&bytesRead );
charIdx++;
} while( data[charIdx-1] != '*' );
//
// Read check sum
port->Read( &data[charIdx],
2,
&bytesRead );
charIdx += 2;
data[charIdx] = '\0';
//
// Copy buffer to QString
*str = data;
//
// Indicate there's a new string
emit newString( *str );
}
}
To copy to clipboard, switch view to plain text mode
GUI.hpp
#ifndef QTAPP_H
#define QTAPP_H
#include <QtGui/QMainWindow>
#include "ui_qtapp.h"
#include <QLabel>
#include <QString>
#include "SerialPortReader.hpp"
{
Q_OBJECT
public:
QtApp
(QWidget *parent
= 0, Qt
::WFlags flags
= 0);
private:
Ui::QtAppClass ui;
SerialPortReader* portThread;
public slots:
void DisplayString
( QString string
);
};
#endif // QTAPP_H
#ifndef QTAPP_H
#define QTAPP_H
#include <QtGui/QMainWindow>
#include "ui_qtapp.h"
#include <QLabel>
#include <QString>
#include "SerialPortReader.hpp"
class QtApp : public QMainWindow
{
Q_OBJECT
public:
QtApp(QWidget *parent = 0, Qt::WFlags flags = 0);
private:
Ui::QtAppClass ui;
SerialPortReader* portThread;
public slots:
void DisplayString( QString string );
};
#endif // QTAPP_H
To copy to clipboard, switch view to plain text mode
GUI.cpp
#include "qtapp.h"
QtApp
::QtApp(QWidget *parent, Qt
::WFlags flags
){
ui.setupUi(this);
// Start a new thread
portThread = new SerialPortReader;
connect( portThread,
SIGNAL(newString
(QString)),
this,
SLOT(DisplayString
(QString)) );
portThread->start();
}
void QtApp
::DisplayString( QString string
) {
ui.mLabel->setText( string );
}
#include "qtapp.h"
QtApp::QtApp(QWidget *parent, Qt::WFlags flags)
: QMainWindow(parent, flags)
{
ui.setupUi(this);
// Start a new thread
portThread = new SerialPortReader;
connect( portThread, SIGNAL(newString(QString)),
this, SLOT(DisplayString(QString)) );
portThread->start();
}
void QtApp::DisplayString( QString string )
{
ui.mLabel->setText( string );
}
To copy to clipboard, switch view to plain text mode
UI Generated by Designer
class Ui_QtAppClass
{
public:
//....
}
class Ui_QtAppClass
{
public:
QWidget *centralWidget;
QLabel *mLabel;
QStatusBar *statusBar;
//....
}
To copy to clipboard, switch view to plain text mode
Bookmarks