[solved] incomplete data read by qserialdevice



  • hi all
    im using QSerialDevice to read some data on my serial port in linux in unbuffered mode because when i use buffered mode the readall() function returns 2 or 3 times of the answer sometimes,and i cant handle this repeating.but in the unbuffered mode when i use readall() function (as i dont know how much data im gonna get) the data is sometimes incomplete and most of the times changed and damaged and i cant retrieve the correct data.I have searched through threads and havent found any answer.do u think using qextserial port will help me better in linux or does anybody have any idea about what i can do to get the correct data when it is on my serial port?
    another issue to add is, when i run my program in debugging mode and just wait before reading the port right when the readyread signal is emitted, i can get the correct data.also if I put a 3 second delay befor reading the data when signal is emitted, most of the times the correct data is read correctly. what can u get from this point? what do u think will help me?



  • So, AFAIK trhere is no general way to know, whetrher all data is available in a serial port. If you call readAll, you will get all data, that is available now. but some bits might not be retreived now, so no guarantee for fully available data. A sleep just blocks you from reading, so data send might be finished. It totally depends on the device you put on a serial port to get to a solution on how to know, data is complet.



  • yes i have put some interface devices and i know the data on the port is complete and as I said most of the times the data is damaged and has even the correct size.it means that when i get notified that data is available on the port by ready read and call readAll immediately,it reads the data incorrectly while i see what there is on my port the function has changed it.what should i do?



  • If your data is damaged, are you sure you are using the right connection flags & speed?



  • check with another application to test your device. maybe your device is sending incorrect data or as Andre said baudrates are not same as each other.


  • Moderators

    [quote author="arianoo" date="1321504770"]it means that when i get notified that data is available on the port by ready read and call readAll immediately,it reads the data incorrectly while i see what there is on my port the function has changed it.what should i do?[/quote]

    The readyRead signal is issued when some data ist available. This does not mean the sequence is already completed. As a matter of fact with low baud rates it might take considerable time to receive even short sequences.

    As I understand your data is partially corrupted, but not completely. This does not sound like a wrong baud rate, but may be other settings as suggestesd above.

    The question is what you are trying to achieve. If you want to communicate as in a dialog with a device, the approach with readAll may be feasible. Providing that the sequences send by the other device are reasonably short. You may wait some time after you have received readyRead and then start reading (e.g. readAll).

    However, in my opinion this approach will be very fast at its limits. If you have varying length of information which cannot be determined beforehand. Especially, if you are doing some real-time communication with some sensor sending information at specific rate but different information length, you will run into trouble.

    I would read the device in smaller chunks and store the data in a buffer myself. You may do this bytewise or in chunks based on the return of bytesAvailable.



  • thank u all so much for considering my question and answering it. The settings of the port are all correct as i am able to communicate with devices by the commands i send to them and i also monitor the port by an interface device with the same settings and it works correctly and the problem is absolutely the way i read data from the port.
    dear koahnig u have mentioned many points that can help me understand how serial ports work ,the bytesAvailable function always returns exactly the number of bytes that readAll would read and i have tried to read that size of data each time with read() function and it hasnt helped either.my problem with waiting is that for a good result and a high percentage of getting correct data i have to wait 3 seconds every time something is available on my port and it makes my program run too slow.i was using this approach up to last week but its really impossible to have this much delay. the way that has answered for me by now and is not yet reliable at all, is that i am opening the port in buffered mode and calling readall. most of the times it returns the exact data which is available on the port but this also has its own problems.
    Im truely confused with this issue i have to work with two different devices through serial port and getting correct data from them is so important for me:(
    ill be thankfull if u tell me the ideas that come to ur mind so that my problem gets fixed.
    thanks alot for your attention


  • Moderators

    dear arianoo
    at first I like to mention two major differences. The experiences I collected on windows and wince. Futhermore, I had retrieved an old version of QExtSerialDevice. The project has been part of SourceForge at a time. Later I have found out that the project has been moved to google.
    I just saw that you are refering to QSerialDevice. I do not know if the roots are the same. However, it seem to be newer than QExtSerialDevice.
    I have a program reading data from a device in real-time. The information is of the form prefix-data-suffix. Initially the program used only TCP/IP for reading the data. It basically scans the input for the starting bytes of the prefix where also the also the complete record length can be found. This led to reading the input bytewise until the starting character found. The remainder will be read bytewise as well until bytesAvailable are read or the complete record has been received. The collected record will be processed immediately. Initially QExtSerialDevice could substitute the QTcpSocket since both are derived from QIODevice. The only difference was the opposite definition of atEnd() in QExtSerialDevice. Later I ported to WinCE where the API functions are completely different. Nevertheless, I maintained the bytewise copying process. A port to linux never happened and probably will never.
    Since the information records are rather short, it was never an issue with TCP/IP. Depending on the baudrate it becomes an issue with serial comms. I personally would prefer the bytewise reading especialyl for my application. I need to buffer anyway, because half a record is a lost record.
    I have no experience with QSerialDevice. Probably the readAll implementation is save, but I would be careful until I know. Only the developers working on it can tell what is happening during readAll and additional information is received. Or you have to dig into that yourself.



  • hi Koahnig
    I'm really thankful for your post i read it 10 days ago but didn't have time to answer.as your advice I started using buffered mode but I still have to add some delay before reading long data because if i read it immediately it gets damaged I also increased the time of setcharintervaltimeout which i don't know what exactly it does and i didn't realize if it changed anything.I want to thank u again cuz your ideas and information u wrote were truely helpful for me.
    I also want to ask people who have worked with serial port about the best way to read data from it and about the meaning of setcharintervaltimeout and such settings.
    thanks again
    wish to get more answers from you;)


  • Moderators

    Hi arianoo
    out of curiosity what is the baud rate of your serial device?



  • I'm connecting to two devices at the same time via 2 ports. one with baud rate 115200 which is most of the times w/o problems and the other one with baud rate 9600 that's killing me;) that device was a little different before and I had to communicate with it with 2400 baud and it was much more suffering but now with 9600 problems are less than before but still in getting long messages I'm having problem and haven't found any solutions so far.


  • Moderators

    Higher baud rates seem to be easier to handle.
    At first I used only fast baud rates. there was not an issue with reading a complete record at a time.
    Suddenly another device provided "only" 9600 baud. That was the point when buffering was getting important.



  • yeah you're right and I'm still looking for a reliable way for reading correct data from serial ports i really need it


  • Moderators

    Are you doing the reading of the device in a separate thread?



  • I'm reading it by events and also i stay in the current event to get my answer by waitforreadyread() do u think it might be a problem?


  • Moderators

    I would have to know the implementation in detail to give a proper answer. And I do not. Also I am using a different implementation (QExtSerialDevice).
    However, my application is reading from the serial port in a different thread.



  • i think the event driven application im using is working the same as if it was on another thread and i think im aware of where my program is living while executing the problem is that sometimes the signal of the readyread event is raised before it truly ready i guess


  • Moderators

    You might be right. I saw an implementation with different threads for reading and writing on the device. Since I have used it as a guideline, I have implemented in a separate thread as well. It could well be over-engineering, but it does not have the problems on lower baud rates. At least I do not know of such problems ;-)



  • Hi arianoo even i am using qserialdevice for serial data communication.
    I am connecting two devices on two diff ports one is running at 19200 baud and another at 4800 baud.
    but i am facing a serious problem ie when one port is open and at the same time if i am opening the other port it is unable to open it.
    I have taken two different instances of abstractserial class but i am unable to open both the ports at the same time..
    if i close the second port and then i am opening the other port then i am able to read the data successfully..
    i just caunt get where i am stuck. if you could guide me then i would be able to sort this problem out..



  • i am doing the same way also im openning two ports by two instances of qabstractserial and i have never had such problem maybe in some settings of your system there's a limitation for the number of open serial ports or maybe ur using the same name for both instances u create(???) or maybe something else is the problem because i never faced this issue u can also put a piece of ur program so that people on the forum see it maybe the answer will be found



  • Hey Arianoo i had already mailed a copy of my code to you you can check that out.



  • @
    #include "dialog.h"
    #include "ui_dialog.h"
    #include <QDebug>
    #include "qserialdevice_global.h"
    #include "abstractserial.h"
    QByteArray ba;
    QByteArray ba1;
    AbstractSerial *port;
    AbstractSerial *port1;
    Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
    {

    timer = new QTimer(this);
    

    // timer1 = new QTimer(this);
    udpsocket = new QUdpSocket(this);
    messageNo = 1;
    ui->setupUi(this);
    connect(ui->sstartButton, SIGNAL(clicked()), this, SLOT(startserialrecv()));
    connect(ui->startButton, SIGNAL(clicked()), this, SLOT(startBroadcasting()));
    connect(ui->sstartButton_2, SIGNAL(clicked()),this, SLOT(ttlopen()));
    connect(ui->quitButton, SIGNAL(clicked()), this, SLOT(close()));
    connect(ui->closebutton,SIGNAL(clicked()),this,SLOT(closeport()));
    connect(ui->closebutton_2,SIGNAL(clicked()), this, SLOT(ttlclose()));
    connect(timer, SIGNAL(timeout()), this, SLOT(broadcastDatagram()));
    //connect(timer1, SIGNAL(timeout()), this, SLOT(startserialrecv()));

    }
    void Dialog::startBroadcasting()
    {
    ui->startButton->setEnabled(false);
    timer->start(100);
    }

    void Dialog::startserialrecv()
    {
    port = new AbstractSerial(this);
    connect( port, SIGNAL(readyRead()), this, SLOT(slotread()));
    int rrto = 10;
    int len = 100;
    char *dn="/dev/ttyS0";
    port->setDeviceName("/dev/ttyS0");
    bool ret = port->open(AbstractSerial::ReadOnly);
    if(ret)
    {
    qDebug("Port Opened Successfully");
    if (!port->setBaudRate(AbstractSerial::BaudRate19200))
    {
    qDebug() << "Set baud rate " << AbstractSerial::BaudRate19200 << " error.";

       };
    
       if (!port->setDataBits(AbstractSerial::DataBits8))
       {
           qDebug() << "Set data bits " <<  AbstractSerial::DataBits8 << " error.";
    
       }
    
       if (!port->setParity(AbstractSerial::ParityEven))
       {
           qDebug() << "Set parity " <<  AbstractSerial::ParityEven << " error.";
    
       }
    
       if (!port->setStopBits(AbstractSerial::StopBits1))
       {
           qDebug() << "Set stop bits " <<  AbstractSerial::StopBits1 << " error.";
    
       }
    
       if (!port->setFlowControl(AbstractSerial::FlowControlOff))
       {
           qDebug() << "Set flow " <<  AbstractSerial::FlowControlOff << " error.";
    
       }
        if (port->waitForReadyRead(rrto))
            {
               /* ba = port->readAll();
                qDebug(ba);
                ui->textEdit1->setText(ba);
                ui->textEdit1->setText("Data Transmitted is: \"%1\"");
                qDebug(port->readAll());
             */}
             else
             {
                    qDebug() << "Timeout read data in time : " << QTime::currentTime();
             }
         }
    else
    {
        qDebug("Serial Port Opening Failed");
    }
    

    }
    void Dialog::slotread()
    {
    ba = port->readAll();
    qDebug()<<"Data Rcvd :"<<ba;
    ui->textEdit1->setText(ba);
    qDebug() << "Readed is : " << ba.size() << " bytes";

    }
    void Dialog::closeport()
    {
    port->close();
    qDebug() << "Serial device " << port->deviceName() << " is closed";
    delete port;
    port = 0;
    }
    void Dialog::ttlopen()
    {
    port1 = new AbstractSerial(this);
    connect( port1, SIGNAL(readyRead()), this, SLOT(slotttlread()));

    int rrto = 10;
    int len = 100;
    char *dn="/dev/ttyS1";
    port1->setDeviceName("/dev/ttyS1");
    

    // connect( port, SIGNAL(readyRead()), this, SLOT(readDataSlot()) );

    //port->openMode(QIODevice::OpenMode);
    bool ret = port1->open(AbstractSerial::ReadOnly);
       if(ret)
        {
       qDebug("Port Opened Successfully");
    
       //Here, the default current parameters (for example)
       if (!port1->setBaudRate(AbstractSerial::BaudRate115200))
           {
           qDebug() << "Set baud rate " <<  AbstractSerial::BaudRate115200 << " error.";
    
       };
    
       if (!port1->setDataBits(AbstractSerial::DataBits8))
       {
           qDebug() << "Set data bits " <<  AbstractSerial::DataBits8 << " error.";
    
       }
    
       if (!port1->setParity(AbstractSerial::ParityNone))
       {
           qDebug() << "Set parity " <<  AbstractSerial::ParityNone << " error.";
    
       }
    
       if (!port1->setStopBits(AbstractSerial::StopBits1))
       {
           qDebug() << "Set stop bits " <<  AbstractSerial::StopBits1 << " error.";
    
       }
    
       if (!port1->setFlowControl(AbstractSerial::FlowControlOff))
       {
           qDebug() << "Set flow " <<  AbstractSerial::FlowControlOff << " error.";
    
       }
    
       /* if (port1->waitForReadyRead(rrto))
            {
                ba = port->readAll();
                qDebug(ba);
                ui->textEdit1->setText(ba);
                ui->textEdit1->setText("Data Transmitted is: \"%1\"");
                qDebug(port->readAll());
             }
             else
             {
                    qDebug() << "Timeout read data in time : " << QTime::currentTime();
             }*/
         }
    
    else
    {
        qDebug("Serial Port Opening Failed");
    }
    

    }
    void Dialog::slotttlread()
    {
    ba1 = port1->readAll();
    qDebug()<<"Data Rcvd :"<<ba1;
    ui->textEdit1_2->setText(ba1);
    qDebug() << "Readed is : " << ba1.size() << " bytes";
    }

       void Dialog::ttlclose()
       {
           port1->close();
           qDebug() << "Serial device " << port1->deviceName() << " is closed";
           delete port1;
           port1 = 0;
    
       }
    

    void Dialog::broadcastDatagram()
    {

     QByteArray datagram = ba+ QByteArray::number(messageNo);
    // QByteArray datagram = ba+ "123456";
     udpsocket->writeDatagram(datagram.data(), datagram.size(),
                              QHostAddress::Broadcast, 5000);
     ++messageNo;
     ui->textEdit->setText(tr("Sending data: \"%1\"").arg(datagram.data()));
     qDebug("Data is being transmitted");
    

    }
    @

    [EDIT: code formatting, please wrap in @-tags, Volker]


  • Moderators

    [quote author="abhijsj" date="1323510423"]Hey Arianoo i had already mailed a copy of my code to you you can check that out.
    [/quote]

    You need to use '@' as tag for starting and ending a section with source code. Otherwise it is not readable (see "here":http://developer.qt.nokia.com/wiki/ForumHelp#e3f82045ad0f480d3fb9e0ac2d58fb01 ) .

    In addition it would have been better to start a new thread for your issue. This would attract more likely others to help you. Unfortunately, I cannot split threads.



  • @#include "dialog.h"
    #include "ui_dialog.h"
    #include <QDebug>
    #include "qserialdevice_global.h"
    #include "abstractserial.h"
    QByteArray ba;
    QByteArray ba1;
    AbstractSerial *port;
    AbstractSerial *port1;
    Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
    {

    timer = new QTimer(this);
    

    // timer1 = new QTimer(this);
    udpsocket = new QUdpSocket(this);
    messageNo = 1;
    ui->setupUi(this);
    connect(ui->sstartButton, SIGNAL(clicked()), this, SLOT(startserialrecv()));
    connect(ui->startButton, SIGNAL(clicked()), this, SLOT(startBroadcasting()));
    connect(ui->sstartButton_2, SIGNAL(clicked()),this, SLOT(ttlopen()));
    connect(ui->quitButton, SIGNAL(clicked()), this, SLOT(close()));
    connect(ui->closebutton,SIGNAL(clicked()),this,SLOT(closeport()));
    connect(ui->closebutton_2,SIGNAL(clicked()), this, SLOT(ttlclose()));
    connect(timer, SIGNAL(timeout()), this, SLOT(broadcastDatagram()));
    //connect(timer1, SIGNAL(timeout()), this, SLOT(startserialrecv()));

    }
    void Dialog::startBroadcasting()
    {
    ui->startButton->setEnabled(false);
    timer->start(100);
    }

    void Dialog::startserialrecv()
    {
    port = new AbstractSerial(this);
    connect( port, SIGNAL(readyRead()), this, SLOT(slotread()));
    int rrto = 10;
    int len = 100;
    char *dn="/dev/ttyS0";
    port->setDeviceName("/dev/ttyS0");
    bool ret = port->open(AbstractSerial::ReadOnly);
    if(ret)
    {
    qDebug("Port Opened Successfully");
    if (!port->setBaudRate(AbstractSerial::BaudRate19200))
    {
    qDebug() << "Set baud rate " << AbstractSerial::BaudRate19200 << " error.";

       };
    
       if (!port->setDataBits(AbstractSerial::DataBits8))
       {
           qDebug() << "Set data bits " <<  AbstractSerial::DataBits8 << " error.";
    
       }
    
       if (!port->setParity(AbstractSerial::ParityEven))
       {
           qDebug() << "Set parity " <<  AbstractSerial::ParityEven << " error.";
    
       }
    
       if (!port->setStopBits(AbstractSerial::StopBits1))
       {
           qDebug() << "Set stop bits " <<  AbstractSerial::StopBits1 << " error.";
    
       }
    
       if (!port->setFlowControl(AbstractSerial::FlowControlOff))
       {
           qDebug() << "Set flow " <<  AbstractSerial::FlowControlOff << " error.";
    
       }
        if (port->waitForReadyRead(rrto))
            {
               /* ba = port->readAll();
                qDebug(ba);
                ui->textEdit1->setText(ba);
                ui->textEdit1->setText("Data Transmitted is: \"%1\"");
                qDebug(port->readAll());
             */}
             else
             {
                    qDebug() << "Timeout read data in time : " << QTime::currentTime();
             }
         }
    else
    {
        qDebug("Serial Port Opening Failed");
    }
    

    }
    void Dialog::slotread()
    {
    ba = port->readAll();
    qDebug()<<"Data Rcvd :"<<ba;
    ui->textEdit1->setText(ba);
    qDebug() << "Readed is : " << ba.size() << " bytes";

    }
    void Dialog::closeport()
    {
    port->close();
    qDebug() << "Serial device " << port->deviceName() << " is closed";
    delete port;
    port = 0;
    }
    void Dialog::ttlopen()
    {
    port1 = new AbstractSerial(this);
    connect( port1, SIGNAL(readyRead()), this, SLOT(slotttlread()));

    int rrto = 10;
    int len = 100;
    char *dn="/dev/ttyS1";
    port1->setDeviceName("/dev/ttyS1");
    

    // connect( port, SIGNAL(readyRead()), this, SLOT(readDataSlot()) );

    //port->openMode(QIODevice::OpenMode);
    bool ret1 = port1->open(AbstractSerial::ReadOnly);
       if(ret1)
        {
       qDebug("Port Opened Successfully");
    
       //Here, the default current parameters (for example)
       if (!port1->setBaudRate(AbstractSerial::BaudRate115200))
           {
           qDebug() << "Set baud rate " <<  AbstractSerial::BaudRate115200 << " error.";
    
       };
    
       if (!port1->setDataBits(AbstractSerial::DataBits8))
       {
           qDebug() << "Set data bits " <<  AbstractSerial::DataBits8 << " error.";
    
       }
    
       if (!port1->setParity(AbstractSerial::ParityNone))
       {
           qDebug() << "Set parity " <<  AbstractSerial::ParityNone << " error.";
    
       }
    
       if (!port1->setStopBits(AbstractSerial::StopBits1))
       {
           qDebug() << "Set stop bits " <<  AbstractSerial::StopBits1 << " error.";
    
       }
    
       if (!port1->setFlowControl(AbstractSerial::FlowControlOff))
       {
           qDebug() << "Set flow " <<  AbstractSerial::FlowControlOff << " error.";
    
       }
    
       /* if (port1->waitForReadyRead(rrto))
            {
                ba = port->readAll();
                qDebug(ba);
                ui->textEdit1->setText(ba);
                ui->textEdit1->setText("Data Transmitted is: \"%1\"");
                qDebug(port->readAll());
             }
             else
             {
                    qDebug() << "Timeout read data in time : " << QTime::currentTime();
             }*/
         }
    
    else
    {
        qDebug("Serial Port Opening Failed");
    }
    

    }
    void Dialog::slotttlread()
    {
    ba1 = port1->readAll();
    qDebug()<<"Data Rcvd :"<<ba1;
    ui->textEdit1_2->setText(ba1);
    qDebug() << "Readed is : " << ba1.size() << " bytes";
    }

       void Dialog::ttlclose()
       {
           port1->close();
           qDebug() << "Serial device " << port1->deviceName() << " is closed";
           delete port1;
           port1 = 0;
    
       }
    

    void Dialog::broadcastDatagram()
    {

     QByteArray datagram = ba+ QByteArray::number(messageNo);
    // QByteArray datagram = ba+ "123456";
     udpsocket->writeDatagram(datagram.data(), datagram.size(),
                              QHostAddress::Broadcast, 5000);
     ++messageNo;
     ui->textEdit->setText(tr("Sending data: \"%1\"").arg(datagram.data()));
     qDebug("Data is being transmitted");
    

    }@


  • Moderators

    There has been a response in another "thread concerning QSerialDevice":http://developer.qt.nokia.com/forums/viewthread/11634/#67246



  • hi abhijsj
    ive looked at your code and im not sure what wxactly makes your problem but there are somethings i can mention:

    @ if (port->waitForReadyRead(rrto))
    {
    /* ba = port->readAll();
    qDebug(ba);
    ui->textEdit1->setText(ba);
    ui->textEdit1->setText("Data Transmitted is: "%1"");
    qDebug(port->readAll());
    */} @

    first of all i think this part on line 78 should be ommited.
    also i think theres no need to lines 11-15 in your main.cpp code.
    another point is, its better to put line 114 after opening your port in line 119 of the code.
    try this and tell the result and ill explore with more attention in your code maybe i can find the problem.



  • now there's a question i have:
    how did u use the close() in a method different from the one that created port?
    I mean i can only access port1->close() if im in the slot that i created port = new abstractserial(); i dont know how u got access to that from another method im so keen to know it plz answer me because i get segmentation fault when calling close() from another method in the same class ???



  • Thnx for replyin ...
    I declared AbstractSerial *port globally in line 8. because of which i am able to close it in different slot.
    I used another slot to close the port because i need the port to be always in open state because data is pumped on port every 100msecs so it couldnt be closed.
    I want to ask that can two ports be in open state at same time and whether they would be able to receive data at the same time at diff baud rates.
    Solution to my problem lies in this question.
    I am a newbie and had very little idea about serial ports.



  • dear abhijsj
    thank u so much u really helped me. my problem was that I created the ports in the constructor of my classes and so i couldn't get access to the close slot anywhere else in the same class but now that i create the port and open it outside of the constructor, everything works fine with closing the port:)
    about your question, it's absolutely possible to communicate with two different ports at the same time so easily. the program I'm working on now is also doing this and i have never faced any problem with having two ports opened and i think your program can also do it correctly if you pay attention to some points.
    as my experience says,if u press sstartButton or sstartButton2 two times your port wont get opened again i handled this problem by opening it the third time if it isnt opened yet as this:
    @

    port = new AbstractSerial();
    
    port->setDeviceName("/dev/ttyS1");
    
    port->open(AbstractSerial::ReadWrite);
    
        if (!port->openMode())
            port->open(AbstractSerial::ReadWrite )
        }
    

    @
    this way you will get sure each time you call the slot to open the port your port will be opened.
    next i think its a bit important that you first creat the port, then assign a name to it, then assign its properties and at last connect its signal to a slot. i think u should be careful about the order(im not sure).
    I cant find any other problem that prevents u from getting data from both ports at the same time because i'm doing the same thing and my two ports work simultanously and i havent seen any problem in it. u can also debug your program and say where it doesnt respond correctly.



  • Use QExtSerialPort, download it and just build the library and link it to your application

    Heres how I read the serial port instead of events (which can get hairy when parsing a lot of data)

    Start a while loop
    Set and start a timer for X milliseconds so when it fires, it changes the state of the while loop variable so you can exit the while loop
    Check for data on the port by using bytesavailable()
    Sit in while loop for a little while and keep reading the port until no more data is available or until a delimiter is reached
    use QCoreApplication::processEvents() while in the while loop so the gui doesn't freeze up

    Boom, timer fires, you delayed X mS to get all the data from where ever

    Carry on with what you want to do.



  • What u say about events making problem is quite correct ive even seen some cases in my own application but the method you are talking about makes lots of time loss which is very important in my case and i cant ignore it. i should write the program in a way that it works as fast as possible and i guess that i can achieve it via signals and events but maybe i'm wrong and using a while loop when needed to read data till its complete is better? Im getting curious about which way will make the program work faster???????



  • I guess it depends, do you know the size of the data that your expecting? Is there a delimiter on your string that you are expecting through the serial? You could do some simple timing tests to optimize your program.

    Either that, or when you get an event that data is on your port, then sit in a while and read, and repeat my previous suggestion.



  • We strongly recommend using QSerialDevice 2.0.

    People, you have ever read that thread "link":http://developer.qt.nokia.com/forums/viewthread/11634/#67246, which showed by Mr. koahnig?

    I recommend to read.



  • yea I'm using QSerialDevice and i hope to get better in working with this class because 90% of my application is about working with serial ports and its so important for me. dvez yes i can find the size of coming data by its third byte coming (if i get the first third bytes exactly as theyre sent) and i can stay in the while loop till i get as much data as i need and i can also call it when i send something and im waiting to get answer.do u think it'll work faster and ill be able to read data without getting it damaged?


  • Moderators

    [quote author="arianoo" date="1323964918"]yea I'm using QSerialDevice and i hope to get better in working with this class because 90% of my application is about working with serial ports and its so important for me. dvez yes i can find the size of coming data by its third byte coming (if i get the first third bytes exactly as theyre sent) and i can stay in the while loop till i get as much data as i need and i can also call it when i send something and im waiting to get answer.do u think it'll work faster and ill be able to read data without getting it damaged? [/quote]

    Did you update to QSerialdevice 2.0 ?



  • wow thanks alot for mentioning it i thought that im using the latest version but i wasnt! i did it recently and havent faced anything different up to now just a question why do u think the "setcharintervaltimeout" slot which was i think effective on reading data omitted in this version do u believe that it wont get me into any trouble?



  • I had updated to qserialdevice 2.0 and i am able to open multiple ports through this library.
    While reading data i faced a problem that if i am sending 10 bytes of data it is read as 8 bytes,2 bytes. Data is always received in fragments of 8 bytes only. I have checked all the examples of qserialdevice 2.0 all of them have the same problem. I dont know how to overcome this problem .

    Someone please guide me.

    Thanks in Advance



  • Abhishek,
    Do not torture the brain, I have already explained to you by e-mail the cause, and that in this situation needs to be done, what approaches to use.

    Final decision of your problems, no one will give you.

    [quote]
    While reading data i faced a problem that if i am sending 10 bytes of data it is read as 8 bytes,2 bytes.
    [/quote]
    This is not a problem. This is normal behavior for non-blocking data is received.

    Is it hard to think of, like this to such a:
    [code]
    class Reader : public QObject
    {
    Q_OBJECT
    signals:
    void onePacketReceivedComplete(const QByteArary &packet);

    public:

    enum { 
        ExpectedResponseSize = 78 // Your expected size of the incoming packet
    }; 
    
    Reader() {
        m_port = new SerialPort(this);
        connect(m_port, SIGNAL(readyRead(), this, SLOT(checkAvailable()));
        ...
        // Open and configure port
        ...
        
        m_timer = new QTimer(this);
        connect(m_timer, SIGNAL(timeout()), this, SLOT(processRead()));
        m_timer->setInterval(10); // Maximum interval a wait end of packet, 10 msec (for example)
        ...
    }
    

    private slots:

    void checkAvailable() {
        if (m_port->bytesAvailable() < ExpectedResponseSize) {
           if (!m_timer->isActive())
                m_timer->start();
        } else {
            processRead();       
        }
    
    void processRead() {
        m_timer->stop();
        
        // Here search a marker/header field in beginning of the packet 
        // (use peek(), example) or etc,
        // ie, is synchronized with the input packets 
        // (looking for begin a valid package from stream).
        ...
        ...
        
        QByteArray incomingData = m_port->read(ExpectedResponseSize);
    
        // Here check CRC and etc
        ...
        ...
    
        // If all checks are successful - it returns the packet.
        if (isOk) { 
            emit onePacketReceivedComplete(incomingData);
        } else {
            // do
        }
    }
    

    private:
    SerialPort *m_port;
    QTimer *m_timer;
    };
    [/code]

    ???



  • thank kuzulis, i am getting stuck with this problem (incomplete data read) and i found the solution only in this site. thanks again


Log in to reply
 

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