diff --git a/src/core/atcore.h b/src/core/atcore.h --- a/src/core/atcore.h +++ b/src/core/atcore.h @@ -504,6 +504,11 @@ */ void getSDFileList(); + /** + * @brief Handle serial Errors. + */ + void handleSerialError(const QString &errorString); + private: /** * @brief True if a firmware plugin is loaded diff --git a/src/core/atcore.cpp b/src/core/atcore.cpp --- a/src/core/atcore.cpp +++ b/src/core/atcore.cpp @@ -218,6 +218,7 @@ bool AtCore::initSerial(const QString &port, int baud) { d->serial = new SerialLayer(port, baud); + connect(serial(), &SerialLayer::serialError, this, &AtCore::handleSerialError); if (serialInitialized() && d->serial->isWritable()) { setState(AtCore::CONNECTING); connect(serial(), &SerialLayer::receivedCommand, this, &AtCore::findFirmware); @@ -395,6 +396,7 @@ QString msg = d->pluginLoader.unload() ? QStringLiteral("closed.") : QStringLiteral("Failed to close."); qCDebug(ATCORE_CORE) << QStringLiteral("Firmware plugin %1 %2").arg(name, msg); } + disconnect(serial(), &SerialLayer::serialError, this, &AtCore::handleSerialError); serial()->close(); //Clear our copy of the sdcard filelist clearSdCardFileList(); @@ -770,3 +772,15 @@ } pushCommand(GCode::toCommand(GCode::M27)); } + +void AtCore::handleSerialError(const QString &errorString) +{ + static const QString checkString(tr("The device is unavailable")); + + if (errorString == checkString) { + closeConnection(); + qDebug() << "Connection closed"; + } + + emit atcoreMessage(QStringLiteral("SerialError: %1").arg(errorString)); +} diff --git a/src/core/seriallayer.h b/src/core/seriallayer.h --- a/src/core/seriallayer.h +++ b/src/core/seriallayer.h @@ -1,5 +1,5 @@ /* AtCore - Copyright (C) <2016> + Copyright (C) <2016 - 2018> Authors: Patrick José Pereira @@ -61,6 +61,12 @@ * @param comm : Command */ void receivedCommand(const QByteArray &comm); + + /** + * @brief Emit a signal if an error has happened. + * @param errorString + */ + void serialError(const QString &errorString); public: /** @@ -87,6 +93,12 @@ */ void add(const QByteArray &comm); + /** + * @brief handleError Handle Errors from the serial port + * @param error: The reported error + */ + void handleError(QSerialPort::SerialPortError error); + /** * @brief Push command directly * diff --git a/src/core/seriallayer.cpp b/src/core/seriallayer.cpp --- a/src/core/seriallayer.cpp +++ b/src/core/seriallayer.cpp @@ -57,6 +57,7 @@ { public: bool _serialOpened; //!< @param _serialOpened: is serial port opened + QSerialPort::SerialPortError _lastError; //!< @param _lastError: the last reported error QByteArray _rawData; //!< @param _rawData: the raw serial data QVector _rByteCommands; //!< @param _rByteCommand: received Messages QVector _sByteCommands; //!< @param _sByteCommand: sent Messages @@ -70,6 +71,7 @@ if (open(QIODevice::ReadWrite)) { d->_serialOpened = true; connect(this, &QSerialPort::readyRead, this, &SerialLayer::readAllData); + connect(this, &QSerialPort::errorOccurred, this, &SerialLayer::handleError); } }; @@ -145,3 +147,52 @@ { return _validBaudRates; } + +void SerialLayer::handleError(QSerialPort::SerialPortError error) +{ + if (d->_lastError == error) { + return; + } + + d->_lastError = error; + + switch (error) { + case (QSerialPort::DeviceNotFoundError): + emit serialError(tr("Device not found")); + break; + case (QSerialPort::PermissionError): + emit serialError(tr("Device is in use or user lacks permission to use it.")); + break; + case (QSerialPort::OpenError): + emit serialError(tr("Device is already connected")); + break; + case (QSerialPort::NotOpenError): + emit serialError(tr("Device needs to be connected first")); + break; + case (QSerialPort::WriteError): + emit serialError(tr("Unable to write to device")); + break; + case (QSerialPort::ReadError): + emit serialError(tr("Unable to read from device")); + break; + case (QSerialPort::ResourceError): + emit serialError(tr("The device is unavailable")); + break; + case (QSerialPort::UnsupportedOperationError): + emit serialError(tr("Device does not support opperation")); + break; + case (QSerialPort::TimeoutError): + emit serialError(tr("Device timeout")); + break; + case (QSerialPort::UnknownError): + emit serialError(tr("Unknown Error")); + break; + default: + //Not Directly processed errors + //QSerialPort::NoError, No error has happened + //QSerialPort::ParityError, Its Obsolete. Qt Docs "We strongly advise against using it in new code." + //QSerialPort::FramingError, Its Obsolete. Qt Docs "We strongly advise against using it in new code." + //QSerialPort::BreakConditionError, Its Obsolete. Qt Docs "We strongly advise against using it in new code." + break; + };//End of Switch +} diff --git a/testclient/mainwindow.cpp b/testclient/mainwindow.cpp --- a/testclient/mainwindow.cpp +++ b/testclient/mainwindow.cpp @@ -416,7 +416,6 @@ if (core->initSerial(comboPort->currentText(), comboBAUD->currentText().toInt())) { connect(core, &AtCore::receivedMessage, logWidget, &LogWidget::appendRLog); connect(core->serial(), &SerialLayer::pushedCommand, logWidget, &LogWidget::appendSLog); - buttonConnect->setText(tr("Disconnect")); logWidget->appendLog(tr("Serial connected")); if (!comboPlugin->currentText().contains(tr("Autodetect"))) { core->loadFirmwarePlugin(comboPlugin->currentText()); @@ -428,7 +427,7 @@ core->closeConnection(); core->setState(AtCore::DISCONNECTED); logWidget->appendLog(tr("Disconnected")); - buttonConnect->setText(tr("Connect")); + } } @@ -484,6 +483,7 @@ QString stateString; switch (state) { case AtCore::IDLE: + buttonConnect->setText(tr("Disconnect")); printWidget->setPrintText(tr("Print File")); stateString = tr("Connected to ") + core->connectedPort(); sdDock->setVisible(core->firmwarePlugin()->isSdSupported()); @@ -513,6 +513,7 @@ case AtCore::DISCONNECTED: stateString = QStringLiteral("Not Connected"); + buttonConnect->setText(tr("Connect")); setDangeriousDocksDisabled(true); break; @@ -566,5 +567,8 @@ if (!disabled) { temperatureWidget->updateExtruderCount(core->extruderCount()); printWidget->updateFanCount(fanCount); + } else { + printWidget->setPrintText(tr("Print File")); + statusWidget->showPrintArea(false); } }