Daten aus einer Klasse in mehreren Klassen verfügbar halten



  • Daten aus einer Klasse in mehreren Klassen verfügbar halten

    Beitragvon Bohnsopp » Do Mär 05, 2015 15:42
    Hallo,

    ich habe ein kleines Verständigungsproblem.
    Ich komme eigentlich aus der Mikrocontroller Ecke und kann diese Dinger auch mit C programmieren.

    Aus Interesse arbeite ich mich in C++ inkl. QT und Boos ein.

    Ich habe ein Messgerät, welches ich per serieller Schnittstelle per RS232 anspreche. Die Kommunikation sowie das Zurücklesen und verarbeiten der Daten funktioniert dank QT und Boos auch schon sehr gut.
    Jetzt würde ich gerne hierfür eine Windows-DLL für Matlab erstellen. Einfache DLLs kann ich auch schon mittels "Extern _C" erstellen.

    Ich habe jetzt aber ein kleines C++ Projekt mittels Klassen in denen die
    (1). RS232 konfiguriert wird (settings.cpp)
    (2). Die RS232 geöffnet wird (serial.cpp)
    (3). Eine Abfrage generiert wird und an das Messgerät gesendet wird (console.cpp)
    (4). Die empfangenen Daten in einem Ringpuffer mittels Boost gespeichert und sortiert werden (console.cpp)
    (5). Die Daten nach seinem Protokoll zerschnitten werden

    Über meine Main Funktion (main.c) kann ich auch via Matlab die Kommunikation mit RS232 aufbauen (prüfe ich mit Portmon.exe) und empfange Daten.

    Nun meine Frage,
    wie kann ich in der main.c auf die Messdaten die in der Klasse "Protocol" gespeichert sind zugreifen?
    Ein Rückgabewert bekomme ich nicht, da die RS232 mittels Signal/Slots die empfangenen Daten verarbeitet?

    Über die Rückgabe nach Matlab habe ich mir noch nicht wirklich Gedanken gemacht, aber mittels Callib und Pointer habe ich schon ein Array zurücklesen können. Ich denke die Messwerte müsste ich auf ähnliche Weise zurücklesen können.

    Gruß

    Auszug aus protocol.h

    class Protocol
    {
    public:
     ....
        struct Messwerte {
            int status_x;
            int status_y;
            QString d_x;
            QString d_y;
        };
        // Memberfunction
        Messwerte localmw() const;
    
        Protocol *protocol;
    
    private:
        Messwerte currentMW;
        void updateMesswerte(QString dx, QString dy, int status_x, int status_y);
    
    };
    

    Auszug aus main.cpp

    int main(int argc, char *argv[])
        {
            QCoreApplication a(argc, argv);
    
            int i;
            Seriel messgeraet;
    
            int status_x=0;
            int status_y=0;
    
            i = messgeraet.AskHardware();
            //i = fb.AskHardware(status_x, status_y);
    
            a.exec();
    
            qDebug() << "zurück zu Main";
    
            // wie komme ich an die Werte aus der Klasse
            // protocol.h??
    
            return i;
        }
    

    protocol.h (komplett)

    #ifndef PROTOCOL_H
    #define PROTOCOL_H
    
    #include <QPlainTextEdit>
    #include <QString>
    
    class Protocol
    {
    public:
        Protocol();
        ~Protocol();
    
        static void GMD(QString data);
    
        struct Messwerte {
            int status_x;
            int status_y;
            QString d_x;
            QString d_y;
        };
    
        // Memberfunction
        Messwerte localmw() const;
    
        Protocol *protocol;
    
    private:
        Messwerte currentMW;
        void updateMesswerte(QString dx, QString dy, int status_x, int status_y);
    
    };
    
    #endif // PROTOCOL_H
    

    protcol.cpp

    #include <QtCore/QDebug>
    #include <QtCore/QString>
    #include "protocol.h"
    #include "main.h"
    
    Protocol::Protocol()
    {
        currentMW.status_x = 0;
        currentMW.status_y = 0;
        currentMW.d_x = "+-0";
        currentMW.d_y = "-+0";
    }
    
    Protocol::~Protocol() { }
    
    void Protocol::GMD(QString data){
        qDebug() << "Befehl" << data.mid(0,3);
    
        qDebug() << "Pos X" << data.mid(3,8);
        qDebug() << "Dim X" << data.mid(11,7);
        qDebug() << "Status X" << data.mid(18,3);
    
        qDebug() << "Pos Y" << data.mid(32,8);
        qDebug() << "Dim Y" << data.mid(40,7);
        qDebug() << "Status Y" << data.mid(47,3);
    
        qDebug() << "--------------------";
    
        Protocol *alpha;
        alpha = new Protocol;
        Messwerte p = alpha->localmw();
        alpha->updateMesswerte(data.mid(03,8), data.mid(32,8), data.mid(18,3).toInt(), data.mid(47,3).toInt());
        p = alpha->localmw();
    
        qDebug() << "/////////////////////////";
        qDebug() << "p.d_x" << p.d_x;
        qDebug() << "p.d_y" << p.d_y;
        qDebug() << "status_x" << p.status_x;
        qDebug() << "status_y" << p.status_y;
        qDebug() << "/////////////////////////";
    }
    
    void Protocol::updateMesswerte(QString dx, QString dy, int status_x, int status_y)
    {
        currentMW.d_x = dx;
        currentMW.d_y = dy;
        currentMW.status_x = status_x;
        currentMW.status_y = status_y;
    }
    
    Protocol::Messwerte Protocol::localmw() const
    {
        return currentMW;
    }
    

    serial.h

    #ifndef SERIEL_H
    #define SERIEL_H
    
    #include <QtCore/QtGlobal>
    #include <QtSerialPort/QSerialPort>
    
    #ifndef MY_API
    //#define MY_API extern "C" __declspec(dllexport)
    #define MY_API__declspec(dllexport)
    #endif
    
    #define MATHFUNCSDLL_EXPORTS
    
    #ifdef MATHFUNCSDLL_EXPORTS
    //#define MATHFUNCSDLL_API __declspec(dllexport)
    #define MATHFUNCSDLL_API extern "C" __declspec(dllexport)
    #else
    #define MATHFUNCSDLL_API __declspec(dllimport)
    #endif
    
    class Console;
    class Settings;
    class Protocol;
    
    class Seriel: public QObject
    {
        Q_OBJECT
    
    signals:
        void getData(const QByteArray &data);
    
    public:
        explicit Seriel(QObject *parent = 0);
        ~Seriel();
    
    private slots:
        void writeData(const QByteArray &data);
    
    public slots:
        void openSerialPort();
        void closeSerialPort();
        void readData();
    
        void handleError(QSerialPort::SerialPortError error);
        int AskHardware(void);
    
    private:
        Console *console;
        QSerialPort *serial;
        Settings *setting;
        Protocol *protocol;
    };
    
    #endif // SERIEL_H
    

    serial.cpp

    #include <QtSerialPort/QSerialPort>
    #include <QDebug>
    
    #include "console.h"
    #include "settings.h"
    #include "protocol.h"
    #include "serial.h"
    #include "protocol.h"
    
    Seriel::Seriel(QObject *parent) : QObject(parent)
    {
        console = new Console;
        serial = new QSerialPort(this);
    
        connect(serial, SIGNAL(error(QSerialPort::SerialPortError)), this,
                SLOT(handleError(QSerialPort::SerialPortError)));
        connect(serial, SIGNAL(readyRead()), this, SLOT(readData()));
    
        connect(console, SIGNAL(getData(QByteArray)), this, SLOT(writeData(QByteArray)));
    }
    
    Seriel::~Seriel(){}
    
    void Seriel::writeData(const QByteArray &data)
    {
        serial->write(data);
        qDebug() << "written" << serial->bytesToWrite();
    }
    
    void Seriel::openSerialPort()
    {
    
        setting = new Settings;
        Settings::SettingsCom p = setting->localsettings();
    
        setting->updateSettings();
        p = setting->localsettings();
    
        //setting->
        p.name = "COM2";
        p = setting->localsettings();
        qDebug() << "p.name" << p.name;
    
        serial->setPortName(p.name);
        serial->setBaudRate(p.baudRate);
        serial->setDataBits(p.dataBits);
        serial->setParity(p.parity);
        serial->setStopBits(p.stopBits);
        serial->setFlowControl(p.flowControl);
    
        if (serial->open(QIODevice::ReadWrite)) {
            qDebug() << "serial connected";
        } else {
            qDebug() << "Fehler" << serial->errorString();
        }
    }
    
    void Seriel::closeSerialPort()
    {
        serial->close();
    }
    
    void Seriel::readData()
    {
        QByteArray data = serial->readLine();
        console->putData(data);
    }
    
    void Seriel::handleError(QSerialPort::SerialPortError error)
    {
        if (error == QSerialPort::ResourceError) {
            qDebug() << "handle Error:" << serial->errorString();
            closeSerialPort();
        }
    }
    
    int Seriel::AskHardware(void) {
    
        int i=0;
    
        openSerialPort();
        console->GMD();
    
        if ( serial->isOpen()) {
            i++;
        }
    
        return i;
    }
    

    settings.h

    #ifndef SETTINGS_H
    #define SETTINGS_H
    
    #include <QObject>
    #include <QtSerialPort/QSerialPortInfo>
    #include <QtSerialPort>
    #include <QSerialPort>
    
    class Settings
    {
    public:
        Settings();
        ~Settings();
    
    public:
        struct SettingsCom {
            QString name;
            qint32 baudRate;
            QString stringBaudRate;
            QSerialPort::DataBits dataBits;
            QString stringDataBits;
            QSerialPort::Parity parity;
            QString stringParity;
            QSerialPort::StopBits stopBits;
            QString stringStopBits;
            QSerialPort::FlowControl flowControl;
            QString stringFlowControl;
            bool localEchoEnabled;
        };
    
        SettingsCom localsettings() const;
    
    //private:
          void updateSettings(void);
    
    private:
        SettingsCom currentSettings;
    
    };
    
    #endif // SETTINGS_H
    

    settings.cpp

    #include "settings.h"
    
    Settings::Settings()
    {
        currentSettings.name = "COM2";
        currentSettings.baudRate = QSerialPort::Baud115200;
        currentSettings.dataBits = QSerialPort::Data8;
        currentSettings.parity   = QSerialPort::NoParity;
        currentSettings.stopBits = QSerialPort::OneStop;
        currentSettings.flowControl = QSerialPort::NoFlowControl;
    }
    
    Settings::~Settings()
    {
    
    }
    
    void Settings::updateSettings(void) {
        currentSettings.name = "COM4";
    }
    
    Settings::SettingsCom Settings::localsettings() const
    {
        return currentSettings;
    }
    

    main.cpp

    #ifndef MAIN_H
    #define MAIN_H
    #define MY_API extern "C" __declspec(dllexport)
    
    #include "protocol.h"
    
    MY_API int main(int argc, char *argv[]);
    
    #endif // MAIN_H
    


  • Deine Klasse Protocol macht nicht das was Du dir denkst.

    Das alpha in void Protocol::GMD(QString data) ist von ausserhalb nicht mehr zugreifbar. Du forderst da Speicher an den auf den Du gar nicht mehr zugreifen kannst.

    Deine Klasse Protocol braucht einen "Container" für die Messwerte in die Du die Alphas reinschieben kannst und den Du dann auch wieder sauber abräumen kannst.

    z.B. std::vector<Messwerte> wäre geeignet, dann muss Du das alpha auch nicht mit new erzeugen.

    Auf den vector kannst Du dann auch im main zugreifen und da durch iterieren oder sonstwas mit machen.

    @Moderatoren: Eigentlich gehört das ins C++ Forum. Mit Qt oder GUI hat das nichts zu tun.



  • Hallo Michael,

    danke für Deine Antwort. Ich lese mich gerade mal in das Thema Container ein, aber wenn ich Dich recht verstehe meinst du sowas in der Art:

    Lediglich mit der Zuzweisung: this->hardware_messwerte.assign(p); muss ich noch ein wenig experimentieren....

    Protocol.cpp

    [...]
    
    Protocol::Protocol()
    {
        [...]
    
        std::vector<Messwerte>(10);
    }
    
    void Protocol::GMD(QString data){
    
       [...]
    
        Protocol *alpha;
        alpha = new Protocol;
        Messwerte p = alpha->localmw();
        alpha->updateMesswerte(data.mid(03,8), data.mid(32,8), data.mid(18,3).toInt(), data.mid(47,3).toInt());
        p = alpha->localmw();
    
        this->hardware_messwerte.assign(p);
    }
       [...]
    

    protocol.h

    class Protocol
    {
    public:
    
       [...]
    
        struct Messwerte {
            int status_x;
            int status_y;
            QString d_x;
            QString d_y;
        };
    
        [...]
        std::vector<Messwerte> hardware_messwerte;
    
    [...]
    


  • Das ändert nichts.
    Du erzeugst mit

    alpha = new Protocol;
    

    neue Protocol-Objekte die nicht mehr zugreifbar sind.

    Wieso erzeugst du immer neue Protocol Objekte?
    Ich gehe mal davon aus dass Du das gar nicht möchtest.

    void Protocol::GMD(QString data){
    
       [...]
    
        updateMesswerte(data.mid(03,8), data.mid(32,8), data.mid(18,3).toInt(), data.mid(47,3).toInt());
        hardware_messwerte.push_back(currentMW);
    }
       [...]
    

    Wobei ich das currentMW und localmw() weglassen würde.

    void Protocol::GMD(QString data){
    
       [...]
    
        Messwerte mw;
        updateMesswerte(mw, data.mid(03,8), data.mid(32,8), data.mid(18,3).toInt(), data.mid(47,3).toInt());
        hardware_messwerte.push_back(mw);
    }
       [...]
    
    class Protocol
    {
    public:
     ....
        struct Messwerte {
            int status_x;
            int status_y;
            QString d_x;
            QString d_y;
        };
    
    private:
    
        void updateMesswerte(Messwerte& mw, QString dx, QString dy, int status_x,    int status_y);
    
    };
    
    void Protocol::updateMesswerte(Messwerte& mw, QString dx, QString dy, int status_x, int status_y)
    {
        mw.d_x = dx;
        mw.d_y = dy;
        mw.status_x = status_x;
        mw.status_y = status_y;
    }
    


  • Hallo Martin,

    soweit erstmal danke. Ich denke so langsam wird es für mich klarer wie das mit den Klassen in C++ funktioniert.

    Ich habe noch folgendes geändert:

    static void updateMesswerte(Messwerte& mw, QString dx, QString dy, int status_x,int status_y);
    

    Wo ich jedoch noch nicht sicher bin, wird der Vektor

    std::vector<Messwerte> hardware_messwerte;
    

    auch in der Klasse "Protocol" als public definiert?
    Wenn ich mit meiner Main diesen Vektor auslesen will, dann muss ich mir doch dort einen Klassenzugriff erzeugen und wird damit dann nicht ein leerer Vektor erzeugt?

    Gruß



  • Für den anfang kannst Du den vector public machen.

    Sauberer wäre es eine Methode anzubieten, die einen Iterator auf den ersten Messwert zurückliefert und den vector private zu machen.

    Da wärst Du aber selber drauf gekommen wenn du dich etwas eingehender mit dem Konzept der STL-Container beschäftigst.



  • Bohnsopp schrieb:

    Wenn ich mit meiner Main diesen Vektor auslesen will, dann muss ich mir doch dort einen Klassenzugriff erzeugen und wird damit dann nicht ein leerer Vektor erzeugt?

    Gruß

    Irgendwo musst Du eine Instanz Protocol erzeugen. Diese Instanz muss Deine Instanz von seriell zugewiesen bekommen.
    Da fehlt noch etliches in Deinem gezeigten Code und was class console zeigts du gar nicht.

    Wieso verwendest Du überall Zeiger?

    ...
    ...
    private:
        Console *console;
        QSerialPort *serial;
        Settings *setting;
        Protocol *protocol;
    };
    
    #endif // SERIEL_H
    


  • Sorry, die Klasse console hatte ich vergessen.

    In serial.cpp werden einige Signal/Slots definiert. Hierfür benötige ich die Pointer. Aber wie schon gesagt, OO-Programmieung ist für mich recht neu und möglicherweise gibt es besser geeignete Lösungen.

    console.h

    #ifndef CONSOLE_H
    #define CONSOLE_H
    
    #include <QString>
    #include <QObject>
    #include <boost/circular_buffer.hpp>
    
    class Console: public QObject
    {
        Q_OBJECT
    
    public:
        explicit Console(QObject *parent = 0);
        ~Console();
    
    signals:
        void getData(const QByteArray &data);
    
    public:
        void putData(const QByteArray &data);
        void setLocalEchoEnabled(bool set);
        int bcc_calc(QString data);
    
    public slots:
        void GMD();
    
    private:
        bool localEchoEnabled;
        int cnt_console = 0;
    
        boost::circular_buffer<char> buffer;
    
        QString outputString;
        QString BCC;
    
        int stx_active = 0;
        int etx_active = 1;
        int read_bcc = 0;
    
    };
    
    #endif // CONSOLE_H
    

    console.cpp

    #include <QDebug>
    #include <boost/circular_buffer.hpp>
    #include <QCoreApplication>
    #include "console.h"
    #include "protocol.h"
    
    typedef boost::circular_buffer<char> CircularBuffer;
    
    Console::Console(QObject *parent) : QObject(parent)
    {
        buffer.set_capacity(100);
    }
    
    Console::~Console()
    {
        buffer.clear();
    }
    
    void Console::putData(const QByteArray &data)
    {
        //qDebug() << "Antwort: " << QString(data);
        //qDebug() << "Größe von Data: " << data.size();
    
        // Daten in den Buffer schreiben
        for (QByteArray::const_iterator it=data.begin(); it != data.end(); ++it)
        {
            char aa = *it;
            buffer.push_back(aa);
        }
    
        QString Input;
        Input.append(buffer[0]);
        QString Test = QString::fromLatin1(Input.toLatin1().toHex());
    
        // STX = Anfang finden
        if (stx_active == 0){
            while (Test != "02") {
                buffer.pop_front();
                Input = (buffer[0]);
                Test = (QString::fromLatin1(Input.toLatin1().toHex()));
            }
        }
        if (Test == "02") {
            stx_active = 1;
        }
    
        // cnt sorg dafür, dass der buffer nicht leerläuft
        int cnt = buffer.size();
        while (Test != "03" && cnt > 1) {
            --cnt;
            // 2. inkl ETX
            buffer.pop_front();
            outputString.append(buffer[0]);
            Input = (buffer[0]);
            Test = (QString::fromLatin1(Input.toLatin1().toHex()));
        }
    
        // ETX finden
        if (Test == "03") {
            stx_active = 0;
            buffer.pop_front();
            Input = (buffer[0]);
            BCC = (QString::fromLatin1(Input.toLatin1().toHex()));
            buffer.pop_front();
            bool ok;
    
            // BCC berechnen
            if (BCC.toInt(&ok, 16) == bcc_calc(outputString)) {
                Protocol::GMD(outputString);
                // Threads beenden
                QCoreApplication::quit();
            }
    
        } else {
            BCC.clear();
        }
    
        if (stx_active == 0) {
            outputString.clear();
        }
    }
    
    void Console::GMD() {
        QByteArray msg;
    
        // GMD 02 47 4D 44 03 4D
        msg.append(0x02);
        msg.append(0x47);
        msg.append(0x4D);
        msg.append(0x44);
        msg.append(0x03);
        quint8 bcc = bcc_calc(msg.mid(1,4));
        msg.append(bcc);
    
        // Feuere anfrage an RS232
        emit getData(msg);
    }
    
    int Console::bcc_calc(QString data) {
    
        int bcc=0;
        bool ok;
        for (QString::iterator it= data.begin(); it != data.end(); ++it)
        {
            QString tmp1, tmp2;
            tmp1.append(*it);
            tmp2 = QString::fromLatin1(tmp1.toLatin1().toHex());
            bcc ^= tmp2.toInt(&ok, 16);
        }
        if (bcc < 0x20) {
            bcc += 0x20;
        }
        return bcc;
    }
    


  • Achso,
    void Console::putData(const QByteArray &data)
    wird ausgeführt wenn die RS232 ein Signal bei zurückgelieferten Daten liefert.

    Somit existiert keine direkte Verbindung zwischen main().



  • Irgendwo muss Du doch Deine Objekte instanziieren.
    Wo kommt die console her, wo das Protocol-Objekt in Console ...

    Das meinte ich mit "es fehlt noch einiges".
    die Deklaration eines Zeigers Protocol* protocol erzeugt kein Objekt, sondern nur einen Zeiger der auf ein Protocol-Objekt zeigen könnte. Ohne Zuwweisung zeigt der zunächst mal irgendwohin im Speicher.
    Protocol protocol in würde direkt ein benutzbares Objekt auf dem Stack erzeugen, das solange lebt bis der Block in dem es deklariert ist verlassen wird.

    Dir fehlen anscheinend sämtliche Grundlagen von C++. C++ ist kein Java.



  • Hallo Michael,

    danke für deine Anregungen.
    Ich habe mir die Klassenerzeugung nochmal angesehen und noch ein paar Fehler gefunden.
    Jetzt funktioniert es soweit - da sind sicherlich noch ein paar Dinge drin die ein Profi so nicht machen würde, aber immer mit der Ruhe.

    main.h

    #ifndef MAIN_H
    #define MAIN_H
    #define MY_API extern "C" __declspec(dllexport)
    
    #include <QCoreApplication>
    #include <QDebug>
    #include "serial.h"
    #include "protocol.h"
    
    MY_API int main(int argc, char *argv[]);
    
    #endif // MAIN_H
    

    main.c

    #include "main.h"
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        int i;
        Seriel messgeraet;
    
        i = messgeraet.AskHardware();
    
        a.exec();
    
        qDebug() << "/////////////////////////";
        qDebug() << "zurück zu Main";
    
        Protocol::Messwerte mw;
        mw = messgeraet.GetMeasValue();
    
        qDebug() << "DX:" << mw.d_x;
        qDebug() << "DY:" << mw.d_y;
        qDebug() << "STATUS_X:" << mw.status_x;
        qDebug() << "STATUS_Y:" << mw.status_y;
    
        qDebug() << "/////////////////////////";
    
        return i;
    }
    

    console.h

    #ifndef CONSOLE_H
    #define CONSOLE_H
    
    #include <QString>
    #include <QObject>
    #include <QDebug>
    #include <QCoreApplication>
    #include <boost/circular_buffer.hpp>
    #include "protocol.h"
    
    class Console: public QObject
    {
        Q_OBJECT
    
    public:
        explicit Console(QObject *parent = 0);
        ~Console();
    
    signals:
        void getData(const QByteArray &data);
    
    public:
        void putData(const QByteArray &data, Protocol* protocol);
        void setLocalEchoEnabled(bool set);
        int bcc_calc(QString data);
    
    public slots:
        void GMD();
    
    private:
        bool localEchoEnabled;
        int cnt_console = 0;
    
        boost::circular_buffer<char> buffer;
    
        QString outputString;
        QString BCC;
    
        int stx_active = 0;
        int etx_active = 1;
        int read_bcc = 0;
    
    };
    
    #endif // CONSOLE_H
    

    console.cpp

    #include "console.h"
    
    typedef boost::circular_buffer<char> CircularBuffer;
    
    Console::Console(QObject *parent) : QObject(parent)
    {
        buffer.set_capacity(100);
    }
    
    Console::~Console()
    {
        buffer.clear();
    }
    
    void Console::putData(const QByteArray &data, Protocol* protocol)
    {
        //qDebug() << "Antwort: " << QString(data);
        //qDebug() << "Größe von Data: " << data.size();
    
        // Daten in den Buffer schreiben
        for (QByteArray::const_iterator it=data.begin(); it != data.end(); ++it)
        {
            char aa = *it;
            buffer.push_back(aa);
        }
    
        QString Input;
        Input.append(buffer[0]);
        QString Test = QString::fromLatin1(Input.toLatin1().toHex());
    
        // STX = Anfang finden
        if (stx_active == 0){
            while (Test != "02") {
                buffer.pop_front();
                Input = (buffer[0]);
                Test = (QString::fromLatin1(Input.toLatin1().toHex()));
            }
        }
        if (Test == "02") {
            stx_active = 1;
        }
    
        // cnt sorg dafür, dass der buffer nicht leerläuft
        int cnt = buffer.size();
        while (Test != "03" && cnt > 1) {
            --cnt;
            // 2. inkl ETX
            buffer.pop_front();
            outputString.append(buffer[0]);
            Input = (buffer[0]);
            Test = (QString::fromLatin1(Input.toLatin1().toHex()));
        }
    
        // ETX finden
        if (Test == "03") {
            stx_active = 0;
            buffer.pop_front();
            Input = (buffer[0]);
            BCC = (QString::fromLatin1(Input.toLatin1().toHex()));
            buffer.pop_front();
            bool ok;
    
            // BCC berechnen
            if (BCC.toInt(&ok, 16) == bcc_calc(outputString)) {
    
                // Datenstream per Protokoll auslesen
                protocol->GMD(outputString);
                // QT Application beenden
                QCoreApplication::quit();
            }
    
        } else {
            BCC.clear();
        }
    
        if (stx_active == 0) {
            outputString.clear();
        }
    }
    
    void Console::GMD() {
        QByteArray msg;
    
        // GMD 02 47 4D 44 03 4D
        msg.append(0x02);
        msg.append(0x47);
        msg.append(0x4D);
        msg.append(0x44);
        msg.append(0x03);
        quint8 bcc = bcc_calc(msg.mid(1,4));
        msg.append(bcc);
    
        // Feuere anfrage an RS232
        emit getData(msg);
    }
    
    int Console::bcc_calc(QString data) {
    
        int bcc=0;
        bool ok;
        for (QString::iterator it= data.begin(); it != data.end(); ++it)
        {
            QString tmp1, tmp2;
            tmp1.append(*it);
            tmp2 = QString::fromLatin1(tmp1.toLatin1().toHex());
            bcc ^= tmp2.toInt(&ok, 16);
        }
        if (bcc < 0x20) {
            bcc += 0x20;
        }
        return bcc;
    }
    

    protocol.h

    #ifndef PROTOCOL_H
    #define PROTOCOL_H
    
    #include <QPlainTextEdit>
    #include <QString>
    #include <QDebug>
    #include <vector>
    
    class Protocol
    {
    public:
        Protocol();
        ~Protocol();
    
        struct Messwerte {
            int status_x;
            int status_y;
            QString d_x;
            QString d_y;
        };
    
        void GMD(QString data);
        Messwerte Protocol::getMesswert();
    
    private:
        Messwerte currentMW;
        std::vector<Messwerte> hardware_messwerte;
    
        static void updateMesswerte(Messwerte& mw, QString dx, QString dy, int status_x,int status_y);
    
        QString status_xx ;
    
    };
    
    #endif // PROTOCOL_H
    

    protocol.cpp

    #include "protocol.h"
    
    Protocol::Protocol() { }
    Protocol::~Protocol() { }
    
    void Protocol::GMD(QString data){
        qDebug() << "Befehl" << data.mid(0,3);
    
        qDebug() << "Pos X" << data.mid(3,8);
        qDebug() << "Dim X" << data.mid(11,7);
        qDebug() << "Status X" << data.mid(18,3);
        qDebug() << "Pos Y" << data.mid(32,8);
        qDebug() << "Dim Y" << data.mid(40,7);
        qDebug() << "Status Y" << data.mid(47,3);
    
        Messwerte mw;
        updateMesswerte(mw, data.mid(03,8), data.mid(32,8), data.mid(18,3).toInt(), data.mid(47,3).toInt());
        hardware_messwerte.push_back(mw);
        return;
    }
    
    void Protocol::updateMesswerte(Messwerte& mw, QString dx, QString dy, int status_x, int status_y)
    {
        mw.d_x = dx;
        mw.d_y = dy;
        mw.status_x = status_x;
        mw.status_y = status_y;
    }
    
    Protocol::Messwerte Protocol::getMesswert() {
        Messwerte mw;
        mw = hardware_messwerte.front();
        return mw;
    }
    

    serial.h

    #ifndef SERIEL_H
    #define SERIEL_H
    
    #include <QtCore/QtGlobal>
    #include <QtSerialPort/QSerialPort>
    #include "protocol.h"
    
    class Console;
    class Settings;
    class Protocol;
    
    class Seriel: public QObject
    {
        Q_OBJECT
    
    signals:
        void getData(const QByteArray &data);
    
    public:
        explicit Seriel(QObject *parent = 0);
        ~Seriel();
        Protocol::Messwerte GetMeasValue(void);
    
    private slots:
        void writeData(const QByteArray &data);
    
    public slots:
        void openSerialPort();
        void closeSerialPort();
        void readData();
    
        void handleError(QSerialPort::SerialPortError error);
        int AskHardware(void);
    
    private:
        Console *console;
        QSerialPort *serial;
        Settings *setting;
        Protocol *protocol;
    };
    
    #endif // SERIEL_H
    

    serial.cpp

    #include <QtSerialPort/QSerialPort>
    #include <QDebug>
    
    #include "console.h"
    #include "settings.h"
    #include "protocol.h"
    #include "serial.h"
    #include "protocol.h"
    
    Seriel::Seriel(QObject *parent) : QObject(parent)
    {
        console = new Console;
        serial = new QSerialPort(this);
        protocol = new Protocol;
    
        connect(serial, SIGNAL(error(QSerialPort::SerialPortError)), this,
                SLOT(handleError(QSerialPort::SerialPortError)));
        connect(serial, SIGNAL(readyRead()), this, SLOT(readData()));
        connect(console, SIGNAL(getData(QByteArray)), this, SLOT(writeData(QByteArray)));
    }
    
    Seriel::~Seriel(){
        delete console;
        delete serial;
        delete protocol;
    }
    
    void Seriel::writeData(const QByteArray &data)
    {
        serial->write(data);
        qDebug() << "written" << serial->bytesToWrite();
    }
    
    void Seriel::openSerialPort()
    {
    
        setting = new Settings;
        Settings::SettingsCom p = setting->localsettings();
    
        setting->updateSettings();
        p = setting->localsettings();
        p.name = "COM2";
        p = setting->localsettings();
        qDebug() << "p.name" << p.name;
    
        serial->setPortName(p.name);
        serial->setBaudRate(p.baudRate);
        serial->setDataBits(p.dataBits);
        serial->setParity(p.parity);
        serial->setStopBits(p.stopBits);
        serial->setFlowControl(p.flowControl);
    
        if (serial->open(QIODevice::ReadWrite)) {
            qDebug() << "serial connected";
        } else {
            qDebug() << "Fehler" << serial->errorString();
        }
    }
    
    void Seriel::closeSerialPort()
    {
        serial->close();
    }
    
    void Seriel::readData()
    {
        QByteArray data = serial->readLine();
        console->putData(data, protocol);
    }
    
    void Seriel::handleError(QSerialPort::SerialPortError error)
    {
        if (error == QSerialPort::ResourceError) {
            qDebug() << "handle Error:" << serial->errorString();
            closeSerialPort();
        }
    }
    
    Protocol::Messwerte Seriel::GetMeasValue(void) {
        Protocol::Messwerte mw;
        mw = protocol->getMesswert();
        return mw;
    }
    
    int Seriel::AskHardware(void) {
    
        int i=0;
    
        openSerialPort();
        console->GMD();
    
        if ( serial->isOpen()) {
            i++;
        }
    
        return i;
    }
    

    settings.h

    #ifndef SETTINGS_H
    #define SETTINGS_H
    #include <QObject>
    #include <QtSerialPort/QSerialPortInfo>
    #include <QtSerialPort>
    #include <QSerialPort>
    
    class Settings
    {
    public:
        Settings();
        ~Settings();
    
    public:
        struct SettingsCom {
            QString name;
            qint32 baudRate;
            QString stringBaudRate;
            QSerialPort::DataBits dataBits;
            QString stringDataBits;
            QSerialPort::Parity parity;
            QString stringParity;
            QSerialPort::StopBits stopBits;
            QString stringStopBits;
            QSerialPort::FlowControl flowControl;
            QString stringFlowControl;
            bool localEchoEnabled;
        };
    
        SettingsCom localsettings() const;
    
        void updateSettings(void);
    
    private:
        SettingsCom currentSettings;
    
    };
    
    #endif // SETTINGS_H
    

    settings.cpp

    #include "settings.h"
    
    Settings::Settings()
    {
        currentSettings.name = "COM2";
        currentSettings.baudRate = QSerialPort::Baud115200;
        currentSettings.dataBits = QSerialPort::Data8;
        currentSettings.parity   = QSerialPort::NoParity;
        currentSettings.stopBits = QSerialPort::OneStop;
        currentSettings.flowControl = QSerialPort::NoFlowControl;
    }
    
    Settings::~Settings()
    {
    
    }
    
    void Settings::updateSettings(void) {
        currentSettings.name = "COM4";
    }
    
    Settings::SettingsCom Settings::localsettings() const
    {
        return currentSettings;
    }
    

Anmelden zum Antworten