Implement sending command and receiving response from sensor
This commit is contained in:
parent
c86ec41b75
commit
dad6f0835f
@ -11,6 +11,7 @@
|
|||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
qInstallMessageHandler(logToFile);
|
qInstallMessageHandler(logToFile);
|
||||||
|
QApplication application(argc, argv);
|
||||||
|
|
||||||
qDebug("Starting application");
|
qDebug("Starting application");
|
||||||
|
|
||||||
@ -29,7 +30,6 @@ int main(int argc, char* argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QApplication application(argc, argv);
|
|
||||||
MainWindow mainWindow;
|
MainWindow mainWindow;
|
||||||
mainWindow.show();
|
mainWindow.show();
|
||||||
return application.exec();
|
return application.exec();
|
||||||
|
@ -1,17 +1,20 @@
|
|||||||
#include "sensor_driver.hpp"
|
#include "sensor_driver.hpp"
|
||||||
|
|
||||||
|
#include <QSerialPort>
|
||||||
#include <QSerialPortInfo>
|
#include <QSerialPortInfo>
|
||||||
#include <QtDebug>
|
#include <QtDebug>
|
||||||
#include <QtGlobal>
|
#include <QtGlobal>
|
||||||
|
|
||||||
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()
|
SensorDriver::Sensor::~Sensor()
|
||||||
{
|
{
|
||||||
qDebug("Destroying sensor");
|
qDebug(ltr("Destroying sensor on serial port %1").arg(m_serialPortName));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<int, int> SensorDriver::Sensor::readRange() const
|
std::pair<int, int> SensorDriver::Sensor::readRange() const
|
||||||
@ -47,8 +50,7 @@ SensorDriver::SensorDriver()
|
|||||||
qInfo() << "Manufacturer: " << (!manufacturer.isEmpty() ? manufacturer : blankString);
|
qInfo() << "Manufacturer: " << (!manufacturer.isEmpty() ? manufacturer : blankString);
|
||||||
qInfo() << "Serial number: " << (!serialNumber.isEmpty() ? serialNumber : blankString);
|
qInfo() << "Serial number: " << (!serialNumber.isEmpty() ? serialNumber : blankString);
|
||||||
qInfo() << "Vendor Identifier: " << (serialPortInfo.hasVendorIdentifier() ? QByteArray::number(serialPortInfo.vendorIdentifier(), 16) : blankString);
|
qInfo() << "Vendor Identifier: " << (serialPortInfo.hasVendorIdentifier() ? QByteArray::number(serialPortInfo.vendorIdentifier(), 16) : blankString);
|
||||||
qInfo() << "Product Identifier: ";
|
qInfo() << "Product Identifier: " << (serialPortInfo.hasProductIdentifier() ? QByteArray::number(serialPortInfo.productIdentifier(), 16) : blankString);
|
||||||
qInfo() << (serialPortInfo.hasProductIdentifier() ? QByteArray::number(serialPortInfo.productIdentifier(), 16) : blankString);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,5 +61,93 @@ SensorDriver::~SensorDriver()
|
|||||||
|
|
||||||
std::vector<SensorDriver::Sensor> SensorDriver::enumerateSensors() const
|
std::vector<SensorDriver::Sensor> SensorDriver::enumerateSensors() const
|
||||||
{
|
{
|
||||||
return {Sensor()};
|
qDebug(ltr("Enumerating sensors"));
|
||||||
|
|
||||||
|
std::vector<Sensor> 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<int>(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;
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,23 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <string_view>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include <QByteArray>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
class SensorDriver {
|
class SensorDriver {
|
||||||
class Sensor {
|
class Sensor {
|
||||||
public:
|
public:
|
||||||
Sensor();
|
Sensor(const QString& serialPortName);
|
||||||
~Sensor();
|
~Sensor();
|
||||||
|
|
||||||
std::pair<int, int> readRange() const;
|
std::pair<int, int> readRange() const;
|
||||||
std::vector<int> readValues() const;
|
std::vector<int> readValues() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
QString m_serialPortName;
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -22,4 +27,6 @@ class SensorDriver {
|
|||||||
std::vector<Sensor> enumerateSensors() const;
|
std::vector<Sensor> enumerateSensors() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool getSensorCommandResponse(const QString& serialPortName, QByteArray command, QByteArray& response) const;
|
||||||
|
bool isValidSensor(const QString& serialPortName) const;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user