Qt SerialPort发送QByteArray并再次调用readAll()

时间:2018-12-23 06:07:22

标签: c++ qt serial-port qt5

我通过SerialPort将命令发送到固件。 我想检查我发送的命令,所以我添加了QTextEdit来显示我发送的命令。

我的代码是

//MainWindow.h
#include <QMainWindow>
#include <QSerialPort>

class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
private slots:
    void readData();
    void on_Send_Button_clicked();//This will return command
    void on_RTC_Get_Time_Button_clicked();
private:
    Ui::MainWindow *m_ui = nullptr;
    QSerialPort *m_serial = nullptr;
    QByteArray s;//String
    int16_t RTC_Year_H;
    int16_t RTC_Year_L;
    int16_t RTC_Month;
    int16_t RTC_Day;
    int16_t RTC_Hour;
    int16_t RTC_Minute;
    int16_t RTC_Second;
    QByteArray rgt;//RTC Get Time
    QByteArray rsht;//RTC Set Host Time
};

问题1:

//MainWindow.cpp
void MainWindow::on_Send_Button_clicked()
{
    QString T;
    QByteArray Temp;
    char *Data;
    int len;
    len = this->m_ui->Send_Text->toPlainText().size();
    T = m_ui->Send_Text->toPlainText();
    Temp = T.toLatin1();
    //Data = Temp.data();
    //qDebug() << len;
    //qDebug() << T;
    /*
    for(int i=0;i<len;i++)
    {
        writeData(Data);
    }//end for loop
    qDebug() << Data[0] << Data[1] << Data[2];
    */
    s.clear();
    s.append(0xAA);
    s.append(0x0D);
    s.append(len);
    s.append(Temp);
    s.append(0xC3);
    m_serial->write(s);
    m_ui->Command_Text->clear();
    m_ui->Command_Text->append(s.toHex().toUpper());
}

使用on_Send_Button_clicked()

如果我发送1则Command_Text将显示:

AA0D0131C3 .//它将字符串1转换为ASCII代码31。

如果我发送Command_Text将显示:

AA0D0161C3 .//它将字符串1转换为ASCII代码61。

我希望我的命令显示AA 0D 01 31 C3。

此表单如何实现?

问题2:

void MainWindow::readData()
{
    QByteArray buf;
    buf = m_serial->readAll();
    if(!buf.isEmpty())
    {
        //m_ui->Command_Text->append(buf);
        QString str = this->m_ui->OutReceive_Text->toPlainText();
        str += tr(buf);
        this->m_ui->OutReceive_Text->clear();
        this->m_ui->OutReceive_Text->append(str);
    }//end if
    buf.clear();
}

固件将发送一些反馈,例如“命令成功”。

但是有时它会发送命令,例如0x20 0x07 0x0d 0x09 0x18 0x0f 0x0f 0x0f。

它可以检查问题3。

如果反馈是字符串,我希望它显示在OutReceive_Text上,但是如果反馈是这样的命令:

0x20 0x07 0x0d 0x09 0x18 0x0f 0x0f 0x0f。

我没有在我的QTextEdit OutReceive_Text上显示它。

因为OutReceive_Text无法显示命令。

如何进行调整,以使我的OutReceive_Text可以显示字符串和QByteArray?

问题3:

void MainWindow::on_RTC_Set_Time_Button_clicked()
{
    rst.clear();
    rst.append(0xAA);
    rst.append(0x21);
    rst.append(0x07);
    rst.append(RTC_Year_H);
    rst.append(RTC_Year_L);
    rst.append(RTC_Month);
    rst.append(RTC_Day);
    rst.append(RTC_Hour);
    rst.append(RTC_Minute);
    rst.append(RTC_Second);
    rst.append(0xC3);
    m_serial->write(rst);
}

void MainWindow::on_RTC_Get_Time_Button_clicked()
{
    rgt.clear();
    rgt.append(0xAA);
    rgt.append(0x22);
    rgt.append(static_cast<char>(0x00));
    rgt.append(0xC3);
    m_serial->write(rgt);
    rsht.clear();
    rsht=m_serial->readAll();
}
void MainWindow::on_RTC_Set_Host_Time_Button_clicked()
{
    RTC_Year_H=rsht[1];
    RTC_Year_L=rsht[2];
    RTC_Month=rsht[3];
    RTC_Day=rsht[4];
    RTC_Hour=rsht[5];
    RTC_Minute=rsht[6];
    RTC_Second=rsht[7];
    m_ui->label_RTC_Time->setText(QTime(RTC_Hour, RTC_Minute, RTC_Second).toString("hh:mm:ss"));
    //m_ui->label_RTC_Time->setText(QTime(RTC_Hour, RTC_Minute, RTC_Second).toString("hh:mm:ss"));
}

问题3有点像问题2,on_RTC_Get_Time_Button_clicked()将要求固件通过串行端口发送命令。

然后我使用rsht = m_serial-> readAll();

但是我无法获得rsht的任何数据,因为问题2 readData()已调用m_serial-> readAll();

固件无法返回命令示例(如果设置了RTC 2013 Sep 24 15:15:15。

当我单击RTC_Get_Time_Button时,它将返回:

0x20 0x07 0x0d 0x09 0x18 0x0f 0x0f 0x0f

//0x20 is for other platform to use in this case just ignore it.

//0x70 is 2013/256.

//0x0d is 2013%256.

我使用Qdebug检查rsht [i] i = 0到i = 7 rsht [i]均为0。

表明我没有在rsht QByteArray内部读取值

但是与问题2相同,它将返回string和Hex。

所以我只需要像这样获得十六进制:

0x20 0x07 0x0d 0x09 0x18 0x0f 0x0f 0x0f

没有字符串回来。

然后将数据类型(例如0x20 0x07 0x0d 0x09 0x18 0x0f 0x0f 0x0f)放入:

rsht = m_serial-> readAll();

不仅只读十六进制。

如何解决这三个问题

谢谢

1 个答案:

答案 0 :(得分:0)

答案1: 在这种情况下,您将发送字符“ 1”,但是您希望从十六进制发送字节值1。您必须将在编辑框中输入的文本“ 1”转换为字节值。

答案2: 当处理非常依赖二进制值的协议时,您可以做的几件事取决于效果最佳的协议。当协议大部分是真实文本时,1会打印所有字节,因为十六进制在几乎没有实际文本时效果很好; 2则打印字符<32作为十六进制或更高,并且字符(低于32时不是可打印的控制字符)在协议主要是真实文本时效果很好; 3使用以下命令创建多列输出每个字节都使用十六进制和ascii,因此当您混合使用二进制和文本时,始终可以满足需要。

答案3:您将不得不习惯于二进制和ascii之间的转换。您有关于如何返回时间的文档?以为似乎很合理地期望前两个字节:

hex: 0x20 0x07 0x0d 0x09 0x18 0x0f 0x0f 0x0f
dec:   32    7   13    9   24   15   15   15
field:  ?    ?    y  mon    d    h  min    s