Reputation: 83
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.
Upvotes: 1
Views: 89
Reputation: 10077
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 ...)
Upvotes: 2