QSerialPort Buffer Problems



  • Hello
    I have some problems with QSerialport. I made it similar to the example here. It all works fine when not much data are coming. But when there are a lot, and the computer is calculating for example a graph and has to do a little of stuff to do, he begins to confuse my buffer. To show it, I wrote all recieved data in a text file, and it looks like that:

    Good:
    +2.307,+0.000,1981991,+1981993.250
    +2.041,+0.000,1984314,+1984316.000
    +2.025,+0.000,1986635,+1986637.000
    +1.599,+0.000,1988956,+1988957.625
    +1.387,+0.000,1991281,+1991282.375

    But suddenly it change to:
    +2.135,+0.000,20028989.8752
    +1.725
    +0.000,,+0.362,+174031,.750
    +2.350
    0.000,,+0.000,+1742687.3007
    +2.056,+0.000,,+0.000,20095011.200
    +6.625,+0.000,,+0.330,+0127332.2012
    +1.650
    +0.000,,+49655,2074965,.625
    512.104

    My Problem is, that I have no Idea where to search the Problem. Had anyone seen a similar thing? As Serialport I use USB-Serial converter from ATEM.
    Is ther mabye a bufferoverlow somewhere in the hardware?

    Thank you for your help!

    Metty

    Qt Creator 3.3.1 (opensource)
    Based on Qt 5.4.1 (MSVC 2010, 32 bit)
    Windows 8



  • It could be a buffer problem I suppose but I haven't ran into this using QSerialPort and I have blasted the input with large blocks of data (25k) without issue.

    It is more likely something related to how you process your data. When you have a lot of data arriving at the input you will likely end up with partial 'lines'. How you handle this could be the reason for the problem. You should not expect that all data will arrive aligned to the end of line character.

    What I have done to handle this is to create a queue. When data arrives it goes to the end of the queue (using readAll() ) and then is processed until either empty or only contains a partial line. It prevents processing partial lines of data.



  • This post is deleted!


  • Strange.. Now I made it like this. The "Ready-Read" Signal trigger a Methode with the Read all. There I put all into a QString as Buffer, and into this file. After this I don't have to call a "clear-method", or not?
    Now the Slot from the Readyread (serialRecieve()) looks like this:

    QByteArray testba = serialport_pres->readAll();
    rxBuf>append(testba);   //rxBuf is a QString
    QFile file("logfile.txt");
    file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Append);
    QTextStream out(&file);
    out << testba;
    out << "*";
    file.close();
    

    And the Result:
    Good:
    +4.3* 59,+0.00 0*,* ,+48091* 9,+1* 348092* 3.000*
    +3.* 063,+0* .000* ,* ,+0.3261,* +104* 832* 65.0* 00

    Bad:
    0.000* ,10* 0.000,109266823* +10921
    +3.7* 00
    0.000* ,* ,+0.000,,+106* 46577.0* 923
    +4.6* 00,+0.0* 00* ,* ,+67291* ,10906729* ,+.000

    So some data has to be lost already before I call the ReadAll, or am I wrong?



  • Yeah, it looks like some data is lost.

    Are you sure the source of the data is okay? Maybe it is sent this way for some reason. If you have a second computer you can tap into the Tx signal and monitor with Hyperterminal or equivalent. Maybe the data is being sent from the source you are trying to read from in this corrupted form?

    Corruption usually causes the data to be scrambled and not simply sections removed. I have had problems with USB-Serial adapters so I wouldn't exclude the hardware unless you have been able to verify this is not the source.

    I don't think the problem is with QSerialPort. I have (and do) use this class for data transfer without issue (Qt 5.4.0 presently). My use consists of small interactive data and large transfers of binary or ascii data. I frequently with USB-Serial adapters as most new computers no longer have serial or lpt ports. I have never had an issue as you describe it (have had lots of other issues though). I can't guarantee that this is not the problem but I would be surprised if it was.

    I assume the serial port stays open (you do not open, read, then close it right away). I also assume the data is not potentially read from two different locations in the program (maybe one part reads looking for commands while the other reads the data your having issue with).



  • The data-source sould be ok. I think the source is ok, beacause it seems to have a connection between this error, and the Programm. If I run only this part, it work better. When I use downloded h-term the data is perfekt. But when I am plotting a graph, parallel in my program (from the data), and the other serial-ports are active (ther are two more in the same program), then the problem is always present. Witch USB-Serial Adapters do you use? I can imagine, that they could be the problem. They often crash also when I start the soldering iron, or something like that. Not at all happy with them.



  • I usually use the cheap USB-Serial adapters. They are no-name and I have a small pile of them now. The ones I have purchased for a premium gave me the most problems (Belkin in particular). The odds are low it is an adapter problem but easily checked if you can replace what you are using with something else.

    You have three ports open? That means you have three pointers or scope/global serial port instances. Make sure that you are not accidentally using the one for your data in some other part of the program. Example, if 'port3' is your data port you might have some other part of the program reading data from 'port3' instead of the intended 'port1' or 'port2' (therefore a small part of the data is lost each time it reads from the wrong port).

    The default read buffer size is unlimited for QSerialPort. The device or low level buffer is probably at least 4k. This shouldn't be an issue unless you start to have issues after 4k of data has been received.

    The working to non-working samples show roughly the same amount of data between the '*' characters. The time to render the graph doesn't appear to be slowing it down (I would expect larger blocks of read data if it was).

    I have not opened three ports simultaneously. I don't know if this is part of the problem. That would be new ground for me.

    You don't have to get out the soldering iron (lol). If you have an old serial cable cut it, strip the wires for tx, rx, and ground connecting them half hazzardly together. To monitor you only need the tx line from the data source and the ground wire. You should be certain the input data is correct as the problem occurs (or you are 'chasing a wild goose').





  • The error-methode returns always "0", in both cases.

    So I comanded three other different USB-Serial converters. I hope that I will see a difference. Somtimes my windows is also crashing. With this driver is anything wrong I think. I currently use this one: link

    For the three connections I created three different QSerialPort-Objects, and manage them all separate. But I have the problem also, when I use only one Serialconnection.

    The only time, that I read the Port ist in the "serialRecieved" Slot who is connected to the "readyRead".
    Hmm.. now I have an idea:
    I have also in the serialRecieved, all the parsing algorithms in there. And if it is a big package it can take mabye longer. What happens, when the slot ("serialRecieved") is not jet finisched, and a new signal from "readyRead" is coming. Does he start again, or does he wait, until the oldone is done? Mabye I have conflicts there.



  • The qt architecture is Asynchronous, but it secretly isn't.
    The main returns a.exec(), and that is where you're event loop is handled, and where your application sleeps when there is nothing interesting happening. The actual serial port implementation might not be in your thread though.
    It is impossible to have your serialRecieved() run twice without you implementing threading.

    The adapter linked most likely works on a Prolific USB-UART, those never worked reliably for me.
    I'd recommend you either get Silabs or FTDI converter chips. Such as FTDI Chipi-X.

    Meanwhile, HHD has a "free" serial port monitor. That might help determine the location of the problem.



  • Hello again! So I learnt something more about QT :)... I tried the new converters:
    With this one from Exsys my Problem is still there but a lot better. As I saw it has also a FTDI chip in there.
    This one from Moxa workt also better and with the Maxxtro, the driver does not work properly on my computer. I saw that FTDI Chipi-X is also very cheap. I will try this one too next monday.

    So thank you for your help until now, Jeroen3 and Rondog! It was helpful! Hope that I will find the solution soon...



  • Most likelly, a problem is in your code. QSerialPort doesn't lose data, especially on lowest 9600 baud (as I can see from your video).

    UPD: Maybe you do wrong QByteArray <-> QString conversion.



  • Qt cannot keep up if you want to plot full speed 9600 baud to a multiline QTextEdit.
    Neither can C# or VC++. There is severe lag in Windows' GUI implementation somewhere.

    QSerialPort does lose data if the above is occurring and the buffer is not unlimited.



  • QSerialPort does lose data if the above is occurring and the buffer is not unlimited.

    No. This may happens only in case when event-loop is freezes (depends on wrong application design and by others reasons, e.g. QTBUG-34946). In this case QSerialPort does not read data which collected in FIFO of driver timely, and the FIFO can be overflowed.

    Common recommendations:

    • for Qt < 5.5 it is enough to move QSerialPort to the separate thread, to exclude an event-loop freezing (strongly recommended with a high streaming).
    • for Qt >= 5.5 this do not need to do (but, also can be moved to the separate thread too).


  • Obviously if you thread the QSerialPort doing gui stuff does not lock up the QSerialPort containing thread. However, you're still producing faster than the gui can consume.



  • Actually I use the baudrate 115200 and I have around 50 strings like above in a second. Now after recieving the data, I put it firstly in the database, then I plot them with qcustomplot. I used QT 5.4. Now I updated to 5.5 and the problem is still there. I saw, that when I start the program, all seems to work. But after a while the errors become more and more. Also when I drag and drop the mainwindow, there is always coming an error. I will try to make a thead for this. This make sens to me.



  • It means what are you doing something wrong. Somewhere you something blocks Qt event-loop.

    Also when I drag and drop the mainwindow, there is always coming an error.

    This should not be in Qt 5.5, check your code again and again.

    PS: We here do not play in telepathists and predictors. If you want to get help, you should provide the minimal and simple example which reproduces an issue. E.g. try it with the com0com driver at first..



  • Replace the SerialPort with a TCPSocket. They both use QIOdevice api.
    Then you can determine if the problem exists in the qt buffering, your display class ,or the hardware.
    Here is an example to tunnel COM to TCP for windows https://github.com/Jeroen6/MultiTerminal/tree/master/driver.

    You can easily spy on a TCP localhost socket with wireshark.



  • I am sorry about my last post. I made a stupid error. I updatet to QT5.5, but I haven't reconfigurated the project, so I was still using QT5.4.
    Now I tried also the Chipi-X10 USB-RS converters. I have to say, they work a lot better. I have now for all three ports, this converter. With the others, a lot of times I had to unplug and replug the connectors to get dem work. So there is something strange. The Chipi worked really good until now, thank you jeroen3, this will save a lot of time.
    After building the programm with QT5.5, the programm also work a lot better. I saw that the qcustemplot keeps plotting while I drag and drop the window. I have sometimes errors but now only sporadic. For example when I resize the window very fast, I can provoke it. But in general the errorrate is about one or two percent, and with that I can live.

    PS: We here do not play in telepathists and predictors. If you want to get help, you should provide the minimal and simple example....

    My problem was, that with the minimal simple example all seems to working. This communication problem I had only, wenn all the data was coming and when I was plotting someting in the same time. And I checked my code a lot of times. The problem is, my knowhow about QT and generell about programming with PCs is not very big. So I think there is something I do not know. So when I check my code a hundet times more, I will not find an error.

    I made also an easy experiment to isolate the error:
    My I slowed up the replot, so that I plot only every tenth time, but ten points at the same time. Like this I can see, that this error, comes only when the window is plotting. The error comes more, the more points he has to plot on the screen. So if I make fullscreen, and I set up the scale so that I have the maximum of points in the axis, the error comes every time again.
    So QT has an influence to this problem. I think there is an overflow in some buffer, beause the program is to slow to read it or that he overwrites any part for some other reasons. But anyway.. For me I will pay attention now to not overcharge my comuter :)
    Thank you for all help!



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