From 46d894c35aa29596ac10fd2d9b15ecd8ad1280a1 Mon Sep 17 00:00:00 2001 From: Mingcan Li Date: Wed, 24 Apr 2024 23:28:30 -0500 Subject: [PATCH 1/3] Add serial to telemetrylib --- telemetrylib/Serial.cpp | 57 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 telemetrylib/Serial.cpp diff --git a/telemetrylib/Serial.cpp b/telemetrylib/Serial.cpp new file mode 100644 index 0000000..1117135 --- /dev/null +++ b/telemetrylib/Serial.cpp @@ -0,0 +1,57 @@ +#include "DTI.h" +#include +#include + +class Serial : public DTI { +public: + Serial(QString SerialDevice) { + // Initialize serial port with the provided device name + serial.setPortName(SerialDevice); + + // Open the serial port in ReadWrite mode + if (!serial.open(QIODevice::ReadWrite)) { + qDebug() << "Failed to open serial port" << SerialDevice; + return; + } + + // Set Baud rate, Data bits, Parity, Stop bits, and Flow control + serial.setBaudRate(QSerialPort::Baud115200); + serial.setDataBits(QSerialPort::Data8); + serial.setParity(QSerialPort::NoParity); + serial.setStopBits(QSerialPort::OneStop); + serial.setFlowControl(QSerialPort::NoFlowControl); + + // Connect readyRead signal to a slot for reading incoming data + connect(&serial, &QSerialPort::readyRead, this, &Serial::readData); + } + + ~Serial() { + // Close the serial port upon destruction + serial.close(); + } + + void sendData(QByteArray bytes, long long timestamp) override { + qDebug()<<"sending via Serial"; + bytes.push_front(""); + bytes.push_back(""); + // Write data to the serial port + serial.write(bytes); + // You might want to use timestamp for something + } + +private slots: + void readData() { + // Read data from the serial port when data is available + QByteArray data = serial.readAll(); + // Process the received data as needed + processReceivedData(data); + } + +private: + QSerialPort serial; + + void processReceivedData(const QByteArray &data) { + // Implement your data processing logic here + qDebug() << "Received data:" << data; + } +}; From aa3bc962c0910dea4eeac88adbe0468b4727344b Mon Sep 17 00:00:00 2001 From: Mingcan Li Date: Thu, 9 May 2024 16:38:00 -0500 Subject: [PATCH 2/3] hand serial device disconnect --- telemetrylib/Serial.cpp | 52 ++++++++++++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 8 deletions(-) diff --git a/telemetrylib/Serial.cpp b/telemetrylib/Serial.cpp index 1117135..c03d8c8 100644 --- a/telemetrylib/Serial.cpp +++ b/telemetrylib/Serial.cpp @@ -1,19 +1,16 @@ #include "DTI.h" #include #include +#include +#include class Serial : public DTI { public: Serial(QString SerialDevice) { // Initialize serial port with the provided device name + device = SerialDevice; serial.setPortName(SerialDevice); - // Open the serial port in ReadWrite mode - if (!serial.open(QIODevice::ReadWrite)) { - qDebug() << "Failed to open serial port" << SerialDevice; - return; - } - // Set Baud rate, Data bits, Parity, Stop bits, and Flow control serial.setBaudRate(QSerialPort::Baud115200); serial.setDataBits(QSerialPort::Data8); @@ -23,6 +20,14 @@ class Serial : public DTI { // Connect readyRead signal to a slot for reading incoming data connect(&serial, &QSerialPort::readyRead, this, &Serial::readData); + + // Connect errorOccurred signal to handle errors, such as device unplugged + connect(&serial, QOverload::of(&QSerialPort::errorOccurred), + this, &Serial::handleError); + + // Setup timer for checking serial port status and reconnecting if necessary + connect(&reconnectTimer, &QTimer::timeout, this, &Serial::checkConnection); + reconnectTimer.start(5000); // Check every 5 seconds } ~Serial() { @@ -35,8 +40,12 @@ class Serial : public DTI { bytes.push_front(""); bytes.push_back(""); // Write data to the serial port - serial.write(bytes); - // You might want to use timestamp for something + int returnCode = serial.write(bytes); + if (returnCode == -1) { + qDebug()<<"Error occurred send data"; + serial.close(); + } + serial.flush(); } private slots: @@ -47,8 +56,35 @@ private slots: processReceivedData(data); } + void checkConnection() { + if (!serial.isOpen()) { + qDebug() << "Serial port disconnected. Reconnecting..."; + serial.close(); + serial.open(QIODevice::ReadWrite); + if (!serial.isOpen()) { + qDebug() << "Failed to reconnect to serial port"; + } + } else { + qDebug() << "Still open"; + } + } + + void handleError(QSerialPort::SerialPortError error) { + if (error == QSerialPort::ResourceError) { + qDebug() << "Serial port error occurred. Reconnecting..."; + // Attempt to reconnect + serial.close(); + serial.open(QIODevice::ReadWrite); + if (!serial.isOpen()) { + qDebug() << "Failed to reconnect to serial port"; + } + } + } + private: QSerialPort serial; + QString device; + QTimer reconnectTimer; void processReceivedData(const QByteArray &data) { // Implement your data processing logic here From 62211bbaa3c02590e1b0a2038bff04e7888076a0 Mon Sep 17 00:00:00 2001 From: Mingcan Li Date: Mon, 13 May 2024 16:57:46 -0500 Subject: [PATCH 3/3] Implement serial interface into system --- CMakeLists.txt | 5 +++-- backendprocesses.cpp | 6 ++++-- backendprocesses.h | 1 + 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2646289..a21067d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,7 @@ project(solar-car-dashboard) # Find the required Qt packages find_package(QT NAMES Qt5 Qt6 COMPONENTS Core Quick) -find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Quick REQUIRED) +find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Quick SerialPort REQUIRED) message(----------QT-VERSION:${QT_VERSION_MAJOR}-----------) # Set C++ standard to C++20 @@ -23,6 +23,7 @@ set(SOURCES telemetrylib/TCP.cpp telemetrylib/Telemetry.cpp telemetrylib/SQL.cpp + telemetrylib/Serial.cpp gps/gps.cpp 3rdparty/serial/serialib.cpp ) @@ -50,5 +51,5 @@ qt_add_resources(RESOURCES add_executable(${PROJECT_NAME} ${SOURCES} ${HEADERS} ${RESOURCES}) # Link against the required Qt modules -target_link_libraries(${PROJECT_NAME} PRIVATE Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Quick) +target_link_libraries(${PROJECT_NAME} PRIVATE Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Quick Qt${QT_VERSION_MAJOR}::SerialPort) target_include_directories(${PROJECT_NAME} PRIVATE ./) diff --git a/backendprocesses.cpp b/backendprocesses.cpp index 77d0f1c..f4a21a0 100644 --- a/backendprocesses.cpp +++ b/backendprocesses.cpp @@ -45,11 +45,13 @@ void BackendProcesses::comm_status(bool s) { } void BackendProcesses::startThread() { - std::vector obj(2); //create a bunch of DTI instances and add them into this array in order of priority to be sent to telemetrylib + std::vector obj(3); //create a bunch of DTI instances and add them into this array in order of priority to be sent to telemetrylib long long first_msec = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); obj[0]=new SQL(QString::fromStdString(std::to_string(first_msec))); //This sends data to the cloud server obj[1]=new UDP(QHostAddress("192.168.1.18"), 4003); //This sends data to the chase car + obj[2] = new Serial("/dev/ttyS0"); + this->tel = new Telemetry(obj); connect(this->tel, &Telemetry::eng_dash_connection, this, &BackendProcesses::comm_status); //for notifing the system connection status } @@ -104,7 +106,7 @@ void BackendProcesses::threadProcedure() all_bytes_in_minute.push_back(""); // only output the file when our buffer has reached - if (all_bytes_in_minute.size() >= 10000 || min_time != last_minute) { + if (all_bytes_in_minute.size() >= 100000 || min_time != last_minute) { std::ofstream(basePath.toStdString() + std::to_string(curr_msec) + "_all_bytes.bin", std::ios::binary) .write(all_bytes_in_minute.data(), all_bytes_in_minute.size()); last_minute = min_time; diff --git a/backendprocesses.h b/backendprocesses.h index 3107463..a25415f 100644 --- a/backendprocesses.h +++ b/backendprocesses.h @@ -15,6 +15,7 @@ #include "telemetrylib/TCP.cpp" #include "telemetrylib/SQL.cpp" #include "telemetrylib/UDP.cpp" +#include "telemetrylib/Serial.cpp" struct timestampOffsets { int hr;