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. Reading data from serial port
Forum Update on Monday, May 27th 2025

Reading data from serial port

Scheduled Pinned Locked Moved Solved General and Desktop
6 Posts 3 Posters 308 Views
  • 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.
  • serkan_trS Offline
    serkan_trS Offline
    serkan_tr
    wrote on last edited by
    #1
    Serial::Serial(): _baudrate(BAUDRATE){
        _serial_port = new QSerialPort;
        if(portDetect()){
            while(_serial_port->open(QIODevice::ReadOnly)){
                qDebug() << "ReadOnly";
            }
                QObject::connect(this->_serial_port, &QSerialPort::readyRead, this, &Serial::readBytes);
            }
    }
    
    Serial::~Serial(){
        _serial_port->close();
        delete _serial_port;
    }
    
    bool Serial::portDetect(){
        for(const QSerialPortInfo port_list : QSerialPortInfo::availablePorts()){
            if(port_list.description() == "Arduino Mega 2560" ){
                _serial_port->setPortName(port_list.portName());
                _serial_port->setBaudRate(_baudrate);
                _serial_port->setDataBits(QSerialPort::Data8);
                #ifdef DEBUG
                qDebug() << "-----------------------------------------------------";
                qDebug() << "portName:          " << port_list.portName();
                qDebug() << "systemLocation:    " << port_list.systemLocation();
                qDebug() << "description:       " << port_list.description();
                qDebug() << "manufacturer:      " << port_list.manufacturer();
                qDebug() << "serialNumber:      " << port_list.serialNumber();
                qDebug() << "vendorIdentifier:  " << port_list.vendorIdentifier();
                qDebug() << "productIdentifier: " << port_list.productIdentifier();
                #endif
                return true;
            }
        }   
        return false;
    }
    
    void Serial::readBytes(){
        while(_serial_port->bytesAvailable()){
            uint8_t cur_byte;
            _serial_port->read((char*)&cur_byte, 1);
            qDebug() << cur_byte;
        }
    }
    
    

    I am reading data from serial port. I constantly detect where the card I will read is inserted and read that port. it does port scan and reads only the card I mentioned. but when I remove and insert the card, it does not read again because the port is not closed. My aim is to not delete the serial object when I remove the port, just close it with close and when it is reconnected, it will open and read from the wheel. Can this be done?

    SGaistS BosGemilerB 2 Replies Last reply
    0
    • serkan_trS Offline
      serkan_trS Offline
      serkan_tr
      wrote on last edited by
      #6

      I made the necessary modifications. In this part, I monitor the port at specific intervals and close the port if there is a change in the list of connected cards. This ensures that the port automatically connects and closes when the card is removed. My code is as follows, and you can access it on this GitHub page.

      1 Reply Last reply
      0
      • serkan_trS serkan_tr
        Serial::Serial(): _baudrate(BAUDRATE){
            _serial_port = new QSerialPort;
            if(portDetect()){
                while(_serial_port->open(QIODevice::ReadOnly)){
                    qDebug() << "ReadOnly";
                }
                    QObject::connect(this->_serial_port, &QSerialPort::readyRead, this, &Serial::readBytes);
                }
        }
        
        Serial::~Serial(){
            _serial_port->close();
            delete _serial_port;
        }
        
        bool Serial::portDetect(){
            for(const QSerialPortInfo port_list : QSerialPortInfo::availablePorts()){
                if(port_list.description() == "Arduino Mega 2560" ){
                    _serial_port->setPortName(port_list.portName());
                    _serial_port->setBaudRate(_baudrate);
                    _serial_port->setDataBits(QSerialPort::Data8);
                    #ifdef DEBUG
                    qDebug() << "-----------------------------------------------------";
                    qDebug() << "portName:          " << port_list.portName();
                    qDebug() << "systemLocation:    " << port_list.systemLocation();
                    qDebug() << "description:       " << port_list.description();
                    qDebug() << "manufacturer:      " << port_list.manufacturer();
                    qDebug() << "serialNumber:      " << port_list.serialNumber();
                    qDebug() << "vendorIdentifier:  " << port_list.vendorIdentifier();
                    qDebug() << "productIdentifier: " << port_list.productIdentifier();
                    #endif
                    return true;
                }
            }   
            return false;
        }
        
        void Serial::readBytes(){
            while(_serial_port->bytesAvailable()){
                uint8_t cur_byte;
                _serial_port->read((char*)&cur_byte, 1);
                qDebug() << cur_byte;
            }
        }
        
        

        I am reading data from serial port. I constantly detect where the card I will read is inserted and read that port. it does port scan and reads only the card I mentioned. but when I remove and insert the card, it does not read again because the port is not closed. My aim is to not delete the serial object when I remove the port, just close it with close and when it is reconnected, it will open and read from the wheel. Can this be done?

        SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #2

        Hi,

        You might want to use something like KDE's Solid framework for the hardware management part.

        Or maybe QtUsb to detect the hardware change and act on it.

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        serkan_trS 1 Reply Last reply
        2
        • SGaistS SGaist

          Hi,

          You might want to use something like KDE's Solid framework for the hardware management part.

          Or maybe QtUsb to detect the hardware change and act on it.

          serkan_trS Offline
          serkan_trS Offline
          serkan_tr
          wrote on last edited by
          #3

          @SGaist Is there any way to do it other than these two methods? I'm currently solving this problem with the following code, but it seems not very safe

          #include "SerialComm.hpp"
          #include <QSerialPortInfo>
          #define VOLTAGE_DEBUG
          // #define DEBUG
          
          Serial::Serial(): state(0), count(0), voltage(0), cam_value(0){
              port_ = new QSerialPort;
          
              connectionTimer = new QTimer(this);
              connectionTimer->setInterval(100);
              connectionTimer->start();
          
              raw_data.resize(V_SIZE);
              stable_data.resize(V_SIZE);
              joy_offset.resize(JOY_ALL);
              initializationData(RESET_ALL);
          
              checkDeviceConnection();
          
              connect(port_, &QSerialPort::readyRead, this, &Serial::readBytes);
              connect(port_, &QSerialPort::errorOccurred, this, [this]() { connectionTimer->start(); });
              connect(connectionTimer, &QTimer::timeout, this, &Serial::checkDeviceConnection);
          }
          
          Serial::~Serial(){
              port_->close();
              connectionTimer->stop();
              delete connectionTimer;
              delete port_;
          }
          
          void Serial::checkDeviceConnection(){
              if(port_->isOpen()) {  port_->close();  }
          
              for(const QSerialPortInfo port_list : QSerialPortInfo::availablePorts()){
                  if((port_list.manufacturer() == "FTDI") || (port_list.description() == "Arduino Mega 2560") ){
                      port_->setPortName(port_list.portName());
                      port_->setBaudRate(BAUDRATE);
                      port_->setDataBits(QSerialPort::Data8);
                      start_com = true;
                      while(port_->open(QIODevice::ReadOnly)){  qDebug() << "ReadOnly";   }
                      connectionTimer->stop();
                  }
          #ifdef DEBUG
                  qDebug() << "-----------------------------------------------------";
                  qDebug() << "portName:          " << port_list.portName();
                  qDebug() << "systemLocation:    " << port_list.systemLocation();
                  qDebug() << "description:       " << port_list.description();
                  qDebug() << "manufacturer:      " << port_list.manufacturer();
                  qDebug() << "serialNumber:      " << port_list.serialNumber();
                  qDebug() << "vendorIdentifier:  " << port_list.vendorIdentifier();
                  qDebug() << "productIdentifier: " << port_list.productIdentifier();
          #endif
              }
          }
          
          void Serial::readBytes(){
              while(port_->bytesAvailable()){
                  uint8_t cur_byte;
                  port_->read((char*)&cur_byte, 1);
                  if(state == 0){
                      if((cur_byte == HEADER) && (prev_byte == FOOTHER)){ rx_buffer[state++] = cur_byte; }
                      else { state = 0; }
                  }else if( state < HEADER_LEN + PAYLOAD_LEN){
                      rx_buffer[state++] = cur_byte;
                  }else if(state < HEADER_LEN + FOOTHER_LEN + PAYLOAD_LEN){
                      state = 0;
                      prev_byte = cur_byte;
                      if(cur_byte == FOOTHER){
                          raw_data[0] = (static_cast<int16_t>(rx_buffer[1] & 0x01));
                          raw_data[1] = (static_cast<int16_t>((rx_buffer[1]>>1) & 0x01));
                          raw_data[2] = (static_cast<int16_t>((rx_buffer[1]>>2) & 0x01));
                          raw_data[3] = (static_cast<int16_t>((rx_buffer[1]>>3) & 0x01));
                          raw_data[4] = (static_cast<int16_t>((rx_buffer[1] >> 4) | ((rx_buffer[2] << 4) & 0x03FF)));
                          raw_data[5] = (static_cast<int16_t>((rx_buffer[2] >> 6) | ((rx_buffer[3] << 2) & 0x03FF)));
                          raw_data[6] = (static_cast<int16_t>((rx_buffer[4])      | ((rx_buffer[5] << 8) & 0x03FF)));
                          raw_data[7] = (static_cast<int16_t>((rx_buffer[5] >> 2) | ((rx_buffer[6] << 6) & 0x03FF)));
                          raw_data[8] = (static_cast<int16_t>((rx_buffer[6] >> 4) | ((rx_buffer[7] << 4) & 0x03FF)));
                          raw_data[9] = (static_cast<int16_t>((rx_buffer[7] >> 6) | ((rx_buffer[8] << 2) & 0x03FF)));
                      }else{ state = 0;  }
                  }else    { state = 0;  }
                  prev_byte = cur_byte;
              }
          }
          
          void Serial::bufferCopy(QVector<int>& data){
              std::copy(raw_data.begin(), raw_data.end(), stable_data.begin());
          
              stable_data[QGC_VOL] = voltageFilter((float)raw_data[QGC_VOL]);
              stable_data[QGC_CAM] = camSliderFilter(raw_data[QGC_CAM]);
              stable_data[QGC_RX] = joyDataFilter(raw_data[4], JOY_RX);
              stable_data[QGC_RY] = joyDataFilter(raw_data[5], JOY_RY);
              stable_data[QGC_LX] = joyDataFilter(raw_data[8], JOY_LX);
              stable_data[QGC_LY] = joyDataFilter(raw_data[6], JOY_LY);
              std::copy(stable_data.begin(), stable_data.end(), data.begin());
          
          #ifdef DEBUG
              qDebug() << "Genel:" <<  raw_data[4] << raw_data[5] << raw_data[6] << raw_data[8];
              qDebug() << "Data: " << stable_data[QGC_RX] << stable_data[QGC_RY] << stable_data[QGC_LX] << stable_data[QGC_LY];
          #endif
          }
          
          int Serial::voltageFilter(float new_data){
          #ifdef VOLTAGE_DEBUG
              qDebug() << "voltage raw_data: " << new_data;
          #endif 
              new_data = filter[5].kalman(new_data);
              if(new_data < 610.0 || new_data > 860.0) { return -1; }
              new_data = map(new_data, 610.0, 860.0, 0.0, 100.0);
              if(filter[6].getKalmanDataOld() == 0){ filter[6].setKalmanDataOld(new_data);  }
              filter[6].setQR(0.005, 0.995);
              return (int)filter[6].kalman(new_data);  
          }
          
          int Serial::camSliderFilter(float new_data){
          #ifdef CAM_SLIDER_DEBUG
              qDebug() << "Cam slider raw_data: " << new_data;
          #endif 
              new_data = filter[4].kalman(new_data);
              if(new_data > (512 + OFFSET_CAM) ) { return cam_value += 5; }
              else if(new_data < (512 - OFFSET_CAM)) { return cam_value -= 5; }
              new_data  = constrain(new_data, 0.0, 1023.0);
              return (int)cam_value;
          }
          
          void Serial::calibrateJoy(){
              if(count == CALIBRATE_COUNT){
                  joy_offset[JOY_RX] /= CALIBRATE_COUNT;  
                  joy_offset[JOY_RY] /= CALIBRATE_COUNT;  
                  joy_offset[JOY_LX] /= CALIBRATE_COUNT;  
                  joy_offset[JOY_LY] /= CALIBRATE_COUNT;  
                  calibrated = false;
              }else if(calibrated){
                  joy_offset[JOY_RX] +=  filter[JOY_RX].kalman(constrain(raw_data[4], 0.0, 1023.0));
                  joy_offset[JOY_RY] +=  filter[JOY_RY].kalman(constrain(raw_data[5], 0.0, 1023.0));
                  joy_offset[JOY_LX] +=  filter[JOY_LX].kalman(constrain(raw_data[8], 0.0, 1023.0));
                  joy_offset[JOY_LY] +=  filter[JOY_LY].kalman(constrain(raw_data[6], 0.0, 1023.0));
              }
              count++;
          }
          
          int Serial::joyDataFilter(float new_data, JoyData_e joy_num){
              new_data = constrain(new_data, JOY_MIN_OFFSET, JOY_MAX_OFFSET);
              new_data = filter[joy_num].kalman(new_data);
              if((new_data > (joy_offset[joy_num] - JOY_OFFSET)) && (new_data < (joy_offset[joy_num] + JOY_OFFSET))){
                  new_data = 512;
              }else if(new_data <= (joy_offset[joy_num] - JOY_OFFSET)){
                  new_data = map(new_data, JOY_MIN_OFFSET, joy_offset[joy_num] - JOY_OFFSET, 0.0, 511.0);        
              }else{
                  new_data = map(new_data, joy_offset[joy_num] + JOY_OFFSET, JOY_MAX_OFFSET, 513.0, 1023.0);
              }
              new_data = map(new_data, 0, 1023, 0.0, 150.0);
              return (int)new_data;
          }
          
          void Serial::initializationData(DataReset_e n_data){
              switch (n_data){
                  case RAW_DATA_R:
                      std::fill(raw_data.begin(), raw_data.end(), 0);
                      break;
                  case STABLE_DATA_R:
                      std::fill(stable_data.begin(), stable_data.end(), 0); 
                      break;
                  case JOY_OFFSET_R:
                      std::fill(joy_offset.begin(), joy_offset.end(), 512);
                      break;
                  case JOY_OFFSET_Z:
                      std::fill(joy_offset.begin(), joy_offset.end(), 0);
                      calibrated = true; 
                      count = 0;
                      break;
                  case RESET_ALL:
                      std::fill(raw_data.begin(), raw_data.end(), 0);
                      std::fill(stable_data.begin(), stable_data.end(), 0); 
                      std::fill(joy_offset.begin(), joy_offset.end(), 512);
                      break;
                  default:
                      break;
              }
          }
          
          1 Reply Last reply
          0
          • serkan_trS serkan_tr
            Serial::Serial(): _baudrate(BAUDRATE){
                _serial_port = new QSerialPort;
                if(portDetect()){
                    while(_serial_port->open(QIODevice::ReadOnly)){
                        qDebug() << "ReadOnly";
                    }
                        QObject::connect(this->_serial_port, &QSerialPort::readyRead, this, &Serial::readBytes);
                    }
            }
            
            Serial::~Serial(){
                _serial_port->close();
                delete _serial_port;
            }
            
            bool Serial::portDetect(){
                for(const QSerialPortInfo port_list : QSerialPortInfo::availablePorts()){
                    if(port_list.description() == "Arduino Mega 2560" ){
                        _serial_port->setPortName(port_list.portName());
                        _serial_port->setBaudRate(_baudrate);
                        _serial_port->setDataBits(QSerialPort::Data8);
                        #ifdef DEBUG
                        qDebug() << "-----------------------------------------------------";
                        qDebug() << "portName:          " << port_list.portName();
                        qDebug() << "systemLocation:    " << port_list.systemLocation();
                        qDebug() << "description:       " << port_list.description();
                        qDebug() << "manufacturer:      " << port_list.manufacturer();
                        qDebug() << "serialNumber:      " << port_list.serialNumber();
                        qDebug() << "vendorIdentifier:  " << port_list.vendorIdentifier();
                        qDebug() << "productIdentifier: " << port_list.productIdentifier();
                        #endif
                        return true;
                    }
                }   
                return false;
            }
            
            void Serial::readBytes(){
                while(_serial_port->bytesAvailable()){
                    uint8_t cur_byte;
                    _serial_port->read((char*)&cur_byte, 1);
                    qDebug() << cur_byte;
                }
            }
            
            

            I am reading data from serial port. I constantly detect where the card I will read is inserted and read that port. it does port scan and reads only the card I mentioned. but when I remove and insert the card, it does not read again because the port is not closed. My aim is to not delete the serial object when I remove the port, just close it with close and when it is reconnected, it will open and read from the wheel. Can this be done?

            BosGemilerB Offline
            BosGemilerB Offline
            BosGemiler
            wrote on last edited by
            #4

            ...but when I remove and insert the card, it does not read again because the port is not closed....

            Hi @serkan_tr ,
            Do you need to be notified when serialport is inserted or removed ?
            I don't know which platform you use. But for linux platform, you can take a look at using DBus with libdbus-glib.

            https://packages.debian.org/sid/libdbus-1-3

            https://stackoverflow.com/questions/14144781/receiving-notification-event-signal-of-usb-device-insertion-in-c

            http://www.matthew.ath.cx/articles/dbus

            serkan_trS 1 Reply Last reply
            0
            • BosGemilerB BosGemiler

              ...but when I remove and insert the card, it does not read again because the port is not closed....

              Hi @serkan_tr ,
              Do you need to be notified when serialport is inserted or removed ?
              I don't know which platform you use. But for linux platform, you can take a look at using DBus with libdbus-glib.

              https://packages.debian.org/sid/libdbus-1-3

              https://stackoverflow.com/questions/14144781/receiving-notification-event-signal-of-usb-device-insertion-in-c

              http://www.matthew.ath.cx/articles/dbus

              serkan_trS Offline
              serkan_trS Offline
              serkan_tr
              wrote on last edited by
              #5

              @BosGemiler
              I am currently working on windows operating system. My goal is to prevent the screen from freezing when the connection is lost in unusual situations such as contactlessness, etc. I want the data stream to continue to flow the same as when the connection is restored.

              1 Reply Last reply
              0
              • serkan_trS Offline
                serkan_trS Offline
                serkan_tr
                wrote on last edited by
                #6

                I made the necessary modifications. In this part, I monitor the port at specific intervals and close the port if there is a change in the list of connected cards. This ensures that the port automatically connects and closes when the card is removed. My code is as follows, and you can access it on this GitHub page.

                1 Reply Last reply
                0
                • serkan_trS serkan_tr has marked this topic as solved on

                • Login

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