Reading data from serial port
-
wrote on 7 Jun 2023, 13:50 last edited by
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?
-
wrote 30 days ago last edited by
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.
-
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?
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.
-
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.
wrote on 13 Jun 2023, 05:46 last edited by@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; } }
-
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?
wrote on 13 Jun 2023, 07:44 last edited by...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. -
...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.wrote on 13 Jun 2023, 11:11 last edited by@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. -
wrote 30 days ago last edited by
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.
-