[closed] Issue in print using QSerialPort



  • Hi,

    I am trying to create an application which prints data using a printer connected in serial port of my pc.

    The issue is:
    The printer prints only when it receives 42 characters or its multiples. This is the number of characters the printer prints in one line.

    If I give 50 characters to print, it will print 42 characters and rest 8 will be print when next data comes and reaches 42 characters..

    My code is:

    //mainwindow.h

    @#ifndef MAINWINDOW_H
    #define MAINWINDOW_H

    #include <QMainWindow>
    #include "serialportwriter.h"

    class QPushButton;
    class QLabel;
    class QTextEdit;

    namespace Ui {
    class MainWindow;
    }

    class MainWindow : public QMainWindow
    {
    Q_OBJECT

    public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

    private:
    Ui::MainWindow *ui;

    QPushButton     *m_pPrintButton;
    QLabel          *m_pResultLabel;
    QTextEdit       *m_pInputDataTextEdit;
    
    QSerialPort     m_Serialport;
    SerialPortWriter *m_pSerialPortWriter;
    

    private slots:
    void printData();

    };

    #endif // MAINWINDOW_H
    @

    //mainwindow.cpp
    @#include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include <QTextEdit>
    #include <QLabel>
    #include <QPushButton>

    MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
    {
    ui->setupUi(this);

    m_pInputDataTextEdit   = ui->inputTextEdit;
    m_pResultLabel         = ui->resultLabel;
    m_pPrintButton         = ui->printButton;
    
    m_pSerialPortWriter     = new SerialPortWriter();
    m_pInputDataTextEdit->setMaximumWidth(265);
    
    QObject::connect(m_pPrintButton, SIGNAL(clicked()), this, SLOT(printData()));
    

    }

    MainWindow::~MainWindow()
    {
    delete ui;
    }

    void MainWindow::printData()
    {
    QByteArray data = m_pInputDataTextEdit->toPlainText().toUtf8();
    m_Serialport.open(QIODevice::WriteOnly);
    m_pSerialPortWriter->write(data);
    }
    @

    //serialportwriter.h
    @#ifndef SERIALPORTWRITER_H
    #define SERIALPORTWRITER_H

    #include <QObject>
    #include <QtSerialPort/QtSerialPort>

    class QTimer;
    class QByteArray;
    class QTextStream;

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

    void write(QByteArray data);
    

    signals:

    public slots:

    private:
    QSerialPort *m_pSerialPort;
    QTimer *m_pTimer;
    QTextStream *m_pTextStream;
    QByteArray *m_pByteArray;
    qint64 m_DataLength;

    private slots:
    void handleWriteComplete(qint64);
    void handleErrorOccurance(QSerialPort::SerialPortError);
    void handleTimeout();
    };

    #endif // SERIALPORTWRITER_H
    @

    //serialportwriter.cpp
    @#include "serialportwriter.h"
    #include <QByteArray>
    #include <QTimer>
    #include <QTextStream>
    #include <QString>

    SerialPortWriter::SerialPortWriter(QObject *parent) :
    QObject(parent)
    {
    m_pTimer = new QTimer();
    m_pTextStream = new QTextStream();
    m_pByteArray = new QByteArray();
    m_pSerialPort = new QSerialPort(this);

    m_pTimer->setSingleShot(true);
    
    QObject::connect(m_pSerialPort, SIGNAL(bytesWritten(qint64)), this, SLOT(handleWriteComplete(qint64)));
    QObject::connect(m_pSerialPort, SIGNAL(error(QSerialPort::SerialPortError)), this, SLOT(handleErrorOccurance(QSerialPort::SerialPortError)));
    QObject::connect(m_pTimer, SIGNAL(timeout()), this, SLOT(handleTimeout()));
    

    }

    SerialPortWriter::~SerialPortWriter()
    {
    delete m_pTimer;
    delete m_pTextStream;
    delete m_pByteArray;
    delete m_pSerialPort;

    m_pTimer = NULL;
    m_pTextStream = NULL;
    m_pByteArray = NULL;
    m_pSerialPort = NULL;
    

    }

    void SerialPortWriter::handleWriteComplete(qint64 dataLength)
    {
    qDebug("handleWriteComplete() Invoked");
    m_DataLength += dataLength;
    if (m_DataLength >= m_pByteArray->length())
    {
    if(m_pSerialPort->clear())
    {
    qDebug("cleared all data in handleWriteComplete()");
    }
    m_pSerialPort->close();
    }
    }

    void SerialPortWriter::handleErrorOccurance(QSerialPort::SerialPortError error)
    {
    qDebug("handleErrorOccurance() Invoked");
    qDebug(qPrintable(m_pSerialPort->errorString()));
    if (error == QSerialPort::WriteError)
    {
    qDebug(qPrintable(m_pSerialPort->errorString()));
    }
    }

    void SerialPortWriter::handleTimeout()
    {
    qDebug("handleTimeout() Invoked");
    }

    void SerialPortWriter::write(const QByteArray data)
    {
    m_DataLength = 0;
    m_pByteArray->clear();
    *m_pByteArray = data;
    m_pSerialPort->setPortName("COM2");

    if (m_pSerialPort->open(QIODevice::WriteOnly))
    {
        if (m_pSerialPort->setBaudRate(9200)
                && m_pSerialPort->setFlowControl(QSerialPort::HardwareControl)
                && m_pSerialPort->setDataBits(QSerialPort::Data8)
                && m_pSerialPort->setParity(QSerialPort::NoParity)
                && m_pSerialPort->setStopBits(QSerialPort::OneStop))
        {
            m_pSerialPort->clear();
            qint64 bytesWritten = m_pSerialPort->write(data);
            qDebug("length written:");
            qDebug(qPrintable(QString::number(bytesWritten)));
            m_pTimer->start(5000);
        }
        m_pSerialPort->flush();
    
    }
    else
    {
        qDebug("port not open in write()");
    }
    

    }
    @

    I doubt if this is the printer property or my coding problem.. Hope someone could help me out..



  • I think the problem is here. You are printing only when the data length exceeds the array length. Of course the 8 bytes stay in buffer.

    @
    if (m_DataLength >= m_pByteArray->length())
    {
    if(m_pSerialPort->clear())
    {
    qDebug("cleared all data in handleWriteComplete()");
    }
    m_pSerialPort->close();
    }@



  • bool QSerialPort::clear(Directions directions = AllDirections)

    Discards all characters from the output or input buffer, depending on given directions directions. Including clear an internal class buffers and the UART (driver) buffers. Also terminate pending read or write operations. If successful, returns true; otherwise returns false.

    So print should have already complete at the step
    @qint64 bytesWritten = m_pSerialPort->write(data);@
    correct?



  • I think you need one more write with leftover data before closing.



  • @ if (m_DataLength >= m_pByteArray->length())
    {
    if(m_pSerialPort->clear())
    {
    qDebug("cleared all data in handleWriteComplete()");
    }
    m_pSerialPort->close();
    }@

    means I close only once whole data is written correct?



  • It means that a piece of m_DataLength is left in buffer when

    m_DataLength < m_pByteArray->length())

    Write one more time m_DataLength before clear and close



  • Thanks all,

    I am told that it is printer property that it prints only when 42 characters reach its buffer...



  • When then. The only thing you have to do is fill the remaining chunck with spaces before sending.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.