From dad6f0835fd424a1b1d69d088c06c0b7ceedd48a Mon Sep 17 00:00:00 2001 From: BlackMark Date: Sat, 4 Jul 2020 22:37:59 +0200 Subject: [PATCH] Implement sending command and receiving response from sensor --- AdaptiveBrightness/main.cpp | 2 +- AdaptiveBrightness/sensor_driver.cpp | 102 +++++++++++++++++++++++++-- AdaptiveBrightness/sensor_driver.hpp | 9 ++- 3 files changed, 105 insertions(+), 8 deletions(-) diff --git a/AdaptiveBrightness/main.cpp b/AdaptiveBrightness/main.cpp index 9c791d7..37bd397 100644 --- a/AdaptiveBrightness/main.cpp +++ b/AdaptiveBrightness/main.cpp @@ -11,6 +11,7 @@ int main(int argc, char* argv[]) { qInstallMessageHandler(logToFile); + QApplication application(argc, argv); qDebug("Starting application"); @@ -29,7 +30,6 @@ int main(int argc, char* argv[]) } } - QApplication application(argc, argv); MainWindow mainWindow; mainWindow.show(); return application.exec(); diff --git a/AdaptiveBrightness/sensor_driver.cpp b/AdaptiveBrightness/sensor_driver.cpp index aa27bc8..73b263a 100644 --- a/AdaptiveBrightness/sensor_driver.cpp +++ b/AdaptiveBrightness/sensor_driver.cpp @@ -1,17 +1,20 @@ #include "sensor_driver.hpp" +#include #include #include #include -SensorDriver::Sensor::Sensor() +#include "log_tr.hpp" + +SensorDriver::Sensor::Sensor(const QString& serialPortName) : m_serialPortName(serialPortName) { - qDebug("Creating sensor"); + qDebug(ltr("Creating sensor on serial port %1").arg(m_serialPortName)); } SensorDriver::Sensor::~Sensor() { - qDebug("Destroying sensor"); + qDebug(ltr("Destroying sensor on serial port %1").arg(m_serialPortName)); } std::pair SensorDriver::Sensor::readRange() const @@ -47,8 +50,7 @@ SensorDriver::SensorDriver() qInfo() << "Manufacturer: " << (!manufacturer.isEmpty() ? manufacturer : blankString); qInfo() << "Serial number: " << (!serialNumber.isEmpty() ? serialNumber : blankString); qInfo() << "Vendor Identifier: " << (serialPortInfo.hasVendorIdentifier() ? QByteArray::number(serialPortInfo.vendorIdentifier(), 16) : blankString); - qInfo() << "Product Identifier: "; - qInfo() << (serialPortInfo.hasProductIdentifier() ? QByteArray::number(serialPortInfo.productIdentifier(), 16) : blankString); + qInfo() << "Product Identifier: " << (serialPortInfo.hasProductIdentifier() ? QByteArray::number(serialPortInfo.productIdentifier(), 16) : blankString); } } @@ -59,5 +61,93 @@ SensorDriver::~SensorDriver() std::vector SensorDriver::enumerateSensors() const { - return {Sensor()}; + qDebug(ltr("Enumerating sensors")); + + std::vector sensors; + + const auto portsInfo = QSerialPortInfo::availablePorts(); + + qInfo(ltr("Found %1 serial ports").arg(portsInfo.count())); + + for(const auto& portInfo: portsInfo) { + qDebug(ltr("Checking port %1").arg(portInfo.portName())); + if(isValidSensor(portInfo.portName())) { + sensors.emplace_back(portInfo.portName()); + } + } + + return std::move(sensors); +} + +bool SensorDriver::getSensorCommandResponse(const QString& serialPortName, QByteArray command, QByteArray& response) const +{ + QSerialPort serialPort; + serialPort.setPortName(serialPortName); + serialPort.setBaudRate(115200); + + if(!serialPort.open(QIODevice::ReadWrite)) { + qCritical(ltr("Unable to open serial port %1, error code: %2").arg(serialPortName).arg(serialPort.errorString())); + return false; + } + + qDebug(ltr("Sending \"%1\" command to serial port %2").arg(QString(command)).arg(serialPortName)); + + command.prepend("\r\n"); + command.append("\r\n"); + + const auto bytesWritten = serialPort.write(command); + + if(bytesWritten == -1) { + qCritical(ltr("Failed to write data to serial port %1, error code: %2").arg(serialPortName).arg(serialPort.errorString())); + return false; + } + else if(bytesWritten != command.size()) { + qCritical(ltr("Only %1/%2 bytes written to serial port %3, error: %4") + .arg(bytesWritten) + .arg(command.size()) + .arg(serialPortName) + .arg(serialPort.errorString())); + return false; + } + else if(!serialPort.waitForBytesWritten(1000)) { + qCritical(ltr("Writing operation timed out for serial port %1, error: %2").arg(serialPortName).arg(serialPort.errorString())); + return false; + } + + response = serialPort.readAll(); + qDebug(ltr("Read %1 bytes from serial port %2").arg(response.size()).arg(serialPortName)); + + while(serialPort.waitForReadyRead(1000)) { + const auto newData = serialPort.readAll(); + qDebug(ltr("Read additional %1 bytes from serial port %2").arg(newData.size()).arg(serialPortName)); + response.append(newData); + } + + if(serialPort.error() == QSerialPort::ReadError) { + qCritical(ltr("Failed to read from serial port %1, error: %2").arg(serialPortName).arg(serialPort.errorString())); + return false; + } + else if(serialPort.error() == QSerialPort::TimeoutError && response.isEmpty()) { + qCritical(ltr("No data was read from serial port %1, error: %2").arg(serialPortName).arg(serialPort.errorString())); + return false; + } + + return true; +} + +bool SensorDriver::isValidSensor(const QString& serialPortName) const +{ + constexpr auto VERSION_CMD = std::string_view{"version"}; + const auto versionCmd = QByteArray(VERSION_CMD.data(), static_cast(VERSION_CMD.size())); + + QByteArray response; + + if(!getSensorCommandResponse(serialPortName, versionCmd, response)) { + if(!response.isEmpty()) { + qCritical(ltr("Only read \"%1\" from serial port %2").arg(QString(response)).arg(serialPortName)); + } + return false; + } + + return false; } diff --git a/AdaptiveBrightness/sensor_driver.hpp b/AdaptiveBrightness/sensor_driver.hpp index aa0188d..b164601 100644 --- a/AdaptiveBrightness/sensor_driver.hpp +++ b/AdaptiveBrightness/sensor_driver.hpp @@ -1,18 +1,23 @@ #pragma once +#include #include #include +#include +#include + class SensorDriver { class Sensor { public: - Sensor(); + Sensor(const QString& serialPortName); ~Sensor(); std::pair readRange() const; std::vector readValues() const; private: + QString m_serialPortName; }; public: @@ -22,4 +27,6 @@ class SensorDriver { std::vector enumerateSensors() const; private: + bool getSensorCommandResponse(const QString& serialPortName, QByteArray command, QByteArray& response) const; + bool isValidSensor(const QString& serialPortName) const; };