Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. USB <=> Serial Test Bug
Forum Updated to NodeBB v4.3 + New Features

USB <=> Serial Test Bug

Scheduled Pinned Locked Moved General and Desktop
6 Posts 2 Posters 1.4k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • Flaming MoeF Offline
    Flaming MoeF Offline
    Flaming Moe
    wrote on last edited by
    #1

    Hello once again,

    based on the Terminal example i tried a stripped down version, where are existing two
    buttons and a lable on a ui-File. The buttons are triggering a send process on a QSerialPort instance. One button sends a string "String 1", the other "String 2", both terminated with "\0".
    I use one of these "cable-build-in" FTDI adapter cables and shortcutted RX and TX.

    When i press the button a few times, it happens, that bytes get lost. What i´m doing wrong?

    best regards,
    Moe

    Project is based on QWidget template project, i didn´t do anything to main.cpp.

    widget.h:
    #ifndef WIDGET_H
    #define WIDGET_H

    #include <QWidget>
    #include <QtSerialPort/QSerialPort>

    namespace Ui {
    class Widget;
    }

    class Widget : public QWidget
    {
    Q_OBJECT

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

    private:
    Ui::Widget *ui;
    QSerialPort serial;
    QString s1;
    QString s2;

    private slots:
    void NewSerialData();
    void s1Slot();
    void s2Slot();
    };

    #endif // WIDGET_H

    //******************************************

    widget.cpp:
    #include "widget.h"
    #include "ui_widget.h"

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

    serial.setPortName("COM11");
    serial.setBaudRate(QSerialPort::Baud9600);
    serial.setDataBits(QSerialPort::Data8);
    serial.setParity(QSerialPort::NoParity);
    serial.setStopBits(QSerialPort::OneStop);
    serial.setFlowControl(QSerialPort::NoFlowControl);
    serial.open(QIODevice::ReadWrite);
    connect(ui->s1, SIGNAL(clicked()), this, SLOT(s1Slot()));
    connect(ui->s2, SIGNAL(clicked()), this, SLOT(s2Slot()));
    connect(&serial, SIGNAL(readyRead()), this, SLOT(NewSerialData()));
    s1 = "String 1";
    s2 = "String 2";
    

    }

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

    void Widget::s1Slot()
    {
    serial.write(s1.toLocal8Bit()+"\0");
    }

    void Widget::s2Slot()
    {
    serial.write(s2.toLocal8Bit()+"\0");
    }

    void Widget::NewSerialData()
    {
    ui->label->setText(serial.readAll());
    }

    //**************************************
    widget.ui

    <?xml version="1.0" encoding="UTF-8"?>
    <ui version="4.0">
    <class>Widget</class>
    <widget class="QWidget" name="Widget">
    <property name="geometry">
    <rect>
    <x>0</x>
    <y>0</y>
    <width>477</width>
    <height>114</height>
    </rect>
    </property>
    <property name="windowTitle">
    <string>Widget</string>
    </property>
    <widget class="QPushButton" name="s2">
    <property name="geometry">
    <rect>
    <x>360</x>
    <y>40</y>
    <width>75</width>
    <height>23</height>
    </rect>
    </property>
    <property name="text">
    <string>String 2</string>
    </property>
    </widget>
    <widget class="QLabel" name="label">
    <property name="geometry">
    <rect>
    <x>40</x>
    <y>30</y>
    <width>141</width>
    <height>31</height>
    </rect>
    </property>
    <property name="font">
    <font>
    <pointsize>12</pointsize>
    </font>
    </property>
    <property name="text">
    <string/>
    </property>
    </widget>
    <widget class="QPushButton" name="s1">
    <property name="geometry">
    <rect>
    <x>250</x>
    <y>40</y>
    <width>75</width>
    <height>23</height>
    </rect>
    </property>
    <property name="text">
    <string>String 1</string>
    </property>
    </widget>
    </widget>
    <layoutdefault spacing="6" margin="11"/>
    <resources/>
    <connections/>
    </ui>

    //************************************************

    .pro:

    QT += core gui
    QT += widgets serialport

    greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

    TARGET = USB_SERIAL_Test
    TEMPLATE = app

    SOURCES += main.cpp
    widget.cpp

    HEADERS += widget.h

    FORMS += widget.ui

    A lovely day for a ̶g̶̶u̶̶i̶̶n̶̶n̶̶e̶̶s̶ DUFF^^

    1 Reply Last reply
    0
    • K Offline
      K Offline
      kuzulis
      Qt Champions 2020
      wrote on last edited by
      #2

      What i´m doing wrong?

      Why are you think that this:

      void Widget::NewSerialData()
      {
          ui->label->setText(serial.readAll());
      }
      

      will display whole your string? This is not true.

      You should do something:

      void Widget::NewSerialData()
      {
          if (serial.bytesAvailable() == expected)
              ui->label->setText(serial.readAll());
      }
      

      where 'expected' - is an expected size of your string, in bytes

      1 Reply Last reply
      0
      • Flaming MoeF Offline
        Flaming MoeF Offline
        Flaming Moe
        wrote on last edited by
        #3

        Yes, this way it works.
        Thanks for answer!

        The point is, i don´t know what happens behind the scenes. I "think" the Qt will trigger "readyRead()" Signal the moment the first byte arives? But until the moment the OS goes to get them, there allready arived an unkown ammount of new bytes. I think this can vary by time elapsing from Signal to Service wich is unpredictable for a non RT-OS.
        Plus what happens when reading the Serial driver? Is it a linear or circular buffer? Are the amount of incoming and read out bytes are counted?
        When i have serial slaves which are sending a random amount of bytes per burst, i don´t know the amount in advance, so how would i handle that?

        A lovely day for a ̶g̶̶u̶̶i̶̶n̶̶n̶̶e̶̶s̶ DUFF^^

        1 Reply Last reply
        0
        • K Offline
          K Offline
          kuzulis
          Qt Champions 2020
          wrote on last edited by kuzulis
          #4

          Signal the moment the first byte arives?

          No. For one or several bytes (in reality in FIFO can be several bytes in current moment)!

          But until the moment the OS goes to get them, there allready arived an unkown ammount of new bytes. I think this can vary by time elapsing from Signal to Service wich is unpredictable for a non RT-OS.

          Yes, it is.

          Plus what happens when reading the Serial driver?

          Reads all available data from the FIFO into own internal buffer.

          Is it a linear or circular buffer?

          Linear, unlimited by default.

          Are the amount of incoming and read out bytes are counted?

          For the user it is has sense only bytesAvailable() which defines a count of bytes that are stored in internal buffer of the class and available to reading for the user.

          When i have serial slaves which are sending a random amount of bytes per burst, i don´t know the amount in advance, so how would i handle that?

          I don't know, it depends on you.

          For this purpose it is necessary to develop the appropriate communication protocol between a master and slave. Where the slave sends a frame, which containd a field in which described the size of whole frame.

          Or, you can use the QTimer to handle a timeout of frame. The timer should be re-started on each readyRead(), but the data reading should be happens only by the timeout() signal from the timer.

          1 Reply Last reply
          0
          • Flaming MoeF Offline
            Flaming MoeF Offline
            Flaming Moe
            wrote on last edited by
            #5

            Ah, more clear now.

            Something itches me.

            Are the amount of incoming and read out bytes are counted?
            

            For the user it is has sense only bytesAvailable() which defines a count of bytes that are stored in internal buffer of the class and available to reading for the user.

            From the moment "bytesAvailable()" return the amount to the moment the if clause performs the descision; following Murphy, this is the exact moment a new byte arives and the returned amount is wrong.
            Is this scenario handled by the OS or framework?

            And much more important:
            How do i get the information you gave me on my own next time in order to help myself?

            A lovely day for a ̶g̶̶u̶̶i̶̶n̶̶n̶̶e̶̶s̶ DUFF^^

            1 Reply Last reply
            0
            • K Offline
              K Offline
              kuzulis
              Qt Champions 2020
              wrote on last edited by
              #6

              Is this scenario handled by the OS or framework?

              • The readyRead() is emitted when the new data has been appended into the internal buffer of class.
              • The bytesAvailable() returns the size of the internal buffer of class
              • The read()/readAll() reads data from the internal buffer of class.

              So, I do not understand what is difficulties for you.

              How do i get the information you gave me on my own next time in order to help myself?

              I do not understand what you mean.

              1 Reply Last reply
              0

              • Login

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved