简体   繁体   中英

How to exchange between each other value of variables in two(or more) classes in qt 5.6?

I work on for update STM mcu from qt program. I use qt for GUI but if I have a file that has specific format, I should begin update procedure. I send start char to STM and I must send update data according to the answer. I parsed my code to classes for usefull. So UART class send data to STM and read data incoming from STM mcu. PROTOCOL class should send update data to UART accordingly to incoming data.

My problem is here. I transfered data between classes but just one direction(from PROTOCOL to UART ). I sent data from PROTOCOL class to UART class. I need incoming data from STM mcu in PROTOCOL class. UART class read data but it can not send to PROTOCOL class(or PROTOCOL class can not read incoming data). How can I accomplish this?

uart.h

#ifndef UART_H
#define UART_H

#include <QObject>
#include <QtSerialPort>
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>


class UART : public QObject
{
    Q_OBJECT
public:
    explicit UART(QObject *parent = 0);


    void Start();
    bool Updating = true;

    QByteArray received_new_data;

signals:

public slots:
    void ReadFromSerialPort();
    void WriteToSerialPort(const QByteArray &update_data, const qint64 &message_size);

private:
    const static QString DEBUG_IDENTIFIER;

    QSerialPort serial;
    QByteArray data;
    qint64 messageSize;


    void Initialize(const QString &portName);
    void Stop();

    static QString PORT_NAME;
};

#endif // UART_H

uart.cpp

  #include "uart.h"
    #include <QDebug>

    QString const UART::DEBUG_IDENTIFIER = "[UART]"; QString
    UART::PORT_NAME = "/dev/ttyS1";

    UART::UART( QObject *parent) : QObject(parent) {

    }

    void UART::Initialize(const QString &portName) {
        serial.setPortName(portName);
        serial.setBaudRate(QSerialPort::Baud115200);
        serial.setDataBits(QSerialPort::Data8);
        serial.setParity(QSerialPort::NoParity);
        serial.setStopBits(QSerialPort::OneStop);
        serial.setFlowControl(QSerialPort::NoFlowControl);
        serial.open(QIODevice::ReadWrite);       
    }

    void UART::ReadFromSerialPort() {
        quint64 available_byte_amount = serial.bytesAvailable();

        if(available_byte_amount)
        {
            received_new_data = serial.readAll();
            qDebug() << DEBUG_IDENTIFIER << "received_data: " << received_new_data;  
        } 
}



    void UART::WriteToSerialPort(const QByteArray &update_data, const
    qint64 &message_size) {

        data = update_data;                              //! max bytes lenght
        messageSize = message_size;

        //! When incoming hex "10" program continue send "U" char

            serial.write(data,messageSize);
            serial.flush();
            qDebug() <<"send";
            qDebug() << "data: " << received_new_data;
    }

    void UART::Start() {
        Initialize(PORT_NAME);

        if(serial.isOpen())
        {
            serial.clear();
            serial.clearError();
            connect(&serial,SIGNAL(readyRead()), this, SLOT(ReadFromSerialPort()));

        }
        else
        {
            qDebug() << DEBUG_IDENTIFIER << "(Start)"
                     << "Serial device is not open";
        }

        if(serial.error() == QSerialPort::NoError)
        {
            qDebug() << DEBUG_IDENTIFIER << "No Error";
        }
        else
        {
            qDebug() << DEBUG_IDENTIFIER << "An error occured:" << serial.errorString();
        } }

    void UART::Stop() {
        disconnect(&serial,SIGNAL(readyRead()), this, SLOT(ReadFromSerialPort())); }

protocol.h

#ifndef PROTOCOL_H
#define PROTOCOL_H

#include <QObject>
#include <QTimer>
#include "uart.h"

class UART;

class PROTOCOL : public QObject
{
    Q_OBJECT
public:
    explicit PROTOCOL(UART *target_STM, QObject *parent = 0);

    static UART *ptr_uart;

    void gentnuma();
signals:

public slots:
    void readSTM(const QByteArray &readData);
    void writeSTM(const QByteArray &stm_data, const qint64 &stm_message_size);
    void read_data();

private:
    const static QString DEBUG_IDENTIFIER;

    QTimer *m_timer;

};

#endif // PROTOCOL_H

protocol.cpp

#include <QByteArray>
#include <QDebug>

#include "protocol.h"
#include "uart.h"


QString const PROTOCOL::DEBUG_IDENTIFIER = "[PROTOCOL]";
UART *PROTOCOL::ptr_uart = NULL;


PROTOCOL::PROTOCOL(UART *target_uart, QObject *parent) : QObject(parent)
{
    ptr_uart = target_uart;

    QTimer *timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(read_data()));
    timer->start(1);

}

void PROTOCOL::gentnuma()
{
    UART begin;
    QByteArray a = begin.received_new_data; 


    qDebug() << DEBUG_IDENTIFIER << "TEST:";
    qDebug() << DEBUG_IDENTIFIER << "COMING DATA:"<< a;  // I expected read data here
}


void PROTOCOL::readSTM(const QByteArray &readData)
{
    qDebug() << DEBUG_IDENTIFIER << "read_STM_request:" << readData;



}


void PROTOCOL::writeSTM(const QByteArray &stm_data, const qint64 &stm_message_size)
{

    qDebug() << DEBUG_IDENTIFIER << "send STM_data: " << stm_data;
    qDebug() << DEBUG_IDENTIFIER << "send STM_data size: " << stm_message_size;



        ptr_uart->WriteToSerialPort(stm_data,stm_message_size);     //send data to uart
}

void PROTOCOL::read_data()
{
    gentnuma();


}

Sorry bad English and long code lines. Thanks.

Solution is just a few steps away: have a signal in your UART class:

signals:
    void newData();

emit it when new data are read:

void UART::ReadFromSerialPort() 
{
    quint64 available_byte_amount = serial.bytesAvailable();

    if(available_byte_amount)
    {
        received_new_data = serial.readAll();
        qDebug() << DEBUG_IDENTIFIER << "received_data: " << received_new_data;

        emit newData();  
    } 
}

You then connect the UART signal to the PROTOCOL slot you happen to already have, so, in PROTOCOL constructor, instead of

QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(read_data()));
timer->start(1);

do:

connect(ptr_uart, SIGNAL(newData()), this, SLOT(read_data()));

This way, instead of polling for new data every second, your PROTOCOL class will be able to read new data from 'UART' whenever there's any.

But, watch out, you're doing it wrong here:

void PROTOCOL::gentnuma()
{
    UART begin;
    QByteArray a = begin.received_new_data; 


    qDebug() << DEBUG_IDENTIFIER << "TEST:";
    qDebug() << DEBUG_IDENTIFIER << "COMING DATA:"<< a;  // I expected read data here
}

since you're instantiating a new UART object out of the blue, and it has not (and never will have) new data to show. You already have a pointer to UART as a private class member, so you must use that one:

void PROTOCOL::gentnuma()
{
    QByteArray a = ptr_uart->received_new_data; 

    qDebug() << DEBUG_IDENTIFIER << "TEST:";
    qDebug() << DEBUG_IDENTIFIER << "COMING DATA:"<< a;  // I expected read data here
}

(just as a footnote: as far as I can see, that ptr_uart doesn't really need to be static ...)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM