diff --git a/src/core/atcore.h b/src/core/atcore.h --- a/src/core/atcore.h +++ b/src/core/atcore.h @@ -42,7 +42,7 @@ * aims to provides a high level interface for serial based gcode devices
* * #### General Workflow - * - Connect to a serial port with initSerial() + * - Connect to a serial port with newConnection() * - Firmware will be auto detected. Use loadFirmwarePLugin() to force load a firmware. * - Send commands to the device (pushCommand(),print(),...) * - AtCore::close() when you are all done. @@ -132,7 +132,7 @@ /** * @brief Returns a List of detected serial ports * @return List of detected ports - * @sa initSerial(),serial(),closeConnection() + * @sa newConnection(),serial(),closeConnection() */ QStringList serialPorts() const; @@ -146,20 +146,21 @@ * @brief Initialize a connection to \p port at a speed of \p baud
* @param port: the port to initialize * @param baud: the baud of the port + * @param fwPlugin: Firmware plugin to use ("Auto-Detect" or plugin name) * @param disableROC: atcore will attempt to disable reset on connect for this device. * @return True is connection was successful * @sa serialPorts(),serial(),closeConnection() */ - Q_INVOKABLE bool initSerial(const QString &port, int baud, bool disableROC = false); + Q_INVOKABLE bool newConnection(const QString &port, int baud, QString fwName = QStringLiteral("Auto-Detect"), bool disableROC = false); /** * @brief Returns a list of valid baud speeds */ QStringList portSpeeds() const; /** * @brief Close the current serial connection - * @sa initSerial(),serial(),serialPorts(),AtCore::close() + * @sa newConnection(),serial(),serialPorts(),AtCore::close() */ Q_INVOKABLE void closeConnection(); @@ -577,6 +578,12 @@ */ void stopSdPrint(); + /** + * @brief waits for the printer to startup. + * @return machine has sent a message + */ + bool waitForStart(const QByteArray &message); + /** * @brief Hold private data of AtCore. */ diff --git a/src/core/atcore.cpp b/src/core/atcore.cpp --- a/src/core/atcore.cpp +++ b/src/core/atcore.cpp @@ -147,32 +147,26 @@ return d->temperature; } -void AtCore::findFirmware(const QByteArray &message) +bool AtCore::waitForStart(const QByteArray &message) { - if (state() == AtCore::STATES::DISCONNECTED) { - qCWarning(ATCORE_CORE) << tr("Cant find firwmware, serial not connected!"); - return; + if (message.isEmpty()) { + return false; } - if (state() == AtCore::STATES::CONNECTING) { - //Most Firmwares will return "start" on connect, some return their firmware name. - if (message.contains("start")) { - qCDebug(ATCORE_CORE) << "Waiting requestFirmware."; - QTimer::singleShot(500, this, &AtCore::requestFirmware); - return; - } + if (message != QByteArray("\x00")) { if (message.contains("Grbl")) { loadFirmwarePlugin(QString::fromLatin1("grbl")); - return; - } - if (message.contains("Smoothie")) { + } else if (message.contains("Smoothie")) { loadFirmwarePlugin(QString::fromLatin1("smoothie")); - return; } - - qCDebug(ATCORE_CORE) << "Waiting for firmware detect."; - emit atcoreMessage(tr("Waiting for firmware detect.")); + return false; } + return true; +} + +void AtCore::findFirmware(const QByteArray &message) +{ + emit atcoreMessage(tr("Waiting for firmware detect.")); qCDebug(ATCORE_CORE) << "Find Firmware: " << message; if (!message.contains("FIRMWARE_NAME:")) { qCDebug(ATCORE_CORE) << "No firmware yet."; @@ -233,25 +227,40 @@ } } -bool AtCore::initSerial(const QString &port, int baud, bool disableROC) +bool AtCore::newConnection(const QString &port, int baud, QString fwName, bool disableROC) { if (disableROC) { disableResetOnConnect(port); } d->serial = new SerialLayer(port, baud, this); connect(d->serial, &SerialLayer::serialError, this, &AtCore::handleSerialError); if (serialInitialized() && d->serial->isWritable()) { - setState(AtCore::CONNECTING); + setState(AtCore::STATES::CONNECTING); connect(d->serial, &SerialLayer::pushedCommand, this, &AtCore::newCommand); - connect(d->serial, &SerialLayer::receivedCommand, this, &AtCore::findFirmware); + + if (!disableROC) { + emit atcoreMessage(tr("Waiting for machine restart")); + connect(d->serial, &SerialLayer::receivedCommand, this, [this, fwName](const QByteArray & message) { + if (!waitForStart(message)) { + disconnect(d->serial, &SerialLayer::receivedCommand, this, {}); + if (fwName == QStringLiteral("Auto-Detect") || fwName.isEmpty()) { + connect(d->serial, &SerialLayer::receivedCommand, this, &AtCore::findFirmware); + QTimer::singleShot(500, this, &AtCore::requestFirmware); + } else { + loadFirmwarePlugin(fwName); + } + } + }); + } else { + loadFirmwarePlugin(fwName); + } d->serialTimer.stop(); return true; } qCDebug(ATCORE_CORE) << "Failed to open device for Read / Write."; emit atcoreMessage(tr("Failed to open device in read/write mode.")); return false; - } bool AtCore::serialInitialized() const diff --git a/testclient/mainwindow.cpp b/testclient/mainwindow.cpp --- a/testclient/mainwindow.cpp +++ b/testclient/mainwindow.cpp @@ -265,7 +265,7 @@ newLabel = new QLabel(tr("Use Plugin:")); comboPlugin = new QComboBox; - comboPlugin->addItem(tr("Autodetect")); + comboPlugin->addItem(tr("Auto-Detect")); comboPlugin->addItems(core->availableFirmwarePlugins()); connect(comboPlugin, &QComboBox::currentTextChanged, this, &MainWindow::pluginCBChanged); @@ -279,7 +279,7 @@ mainLayout->addWidget(cbReset); connect(comboPlugin, &QComboBox::currentTextChanged, this, [this](const QString & currentText) { - cbReset->setHidden(currentText == tr("Autodetect")); + cbReset->setHidden(currentText == tr("Auto-Detect")); }); buttonConnect = new QPushButton(tr("Connect")); @@ -447,12 +447,11 @@ void MainWindow::connectPBClicked() { if (core->state() == AtCore::DISCONNECTED) { - if (core->initSerial(comboPort->currentText(), comboBAUD->currentText().toInt(), cbReset->isChecked())) { + if (core->newConnection(comboPort->currentText(), comboBAUD->currentText().toInt(), comboPlugin->currentText(), cbReset->isChecked())) { connect(core, &AtCore::receivedMessage, logWidget, &LogWidget::appendRLog); connect(core, &AtCore::pushedCommand, logWidget, &LogWidget::appendSLog); logWidget->appendLog(tr("Serial connected")); - if (!comboPlugin->currentText().contains(tr("Autodetect"))) { - core->loadFirmwarePlugin(comboPlugin->currentText()); + if (!comboPlugin->currentText().contains(tr("Auto-Detect"))) { if (cbReset->isChecked()) { //Wait a few seconds after connect to avoid the normal errors QTimer::singleShot(5000, core, &AtCore::sdCardPrintStatus); @@ -508,7 +507,7 @@ void MainWindow::pluginCBChanged(const QString ¤tText) { if (core->state() != AtCore::DISCONNECTED) { - if (!currentText.contains(tr("Autodetect"))) { + if (!currentText.contains(tr("Auto-Detect"))) { core->loadFirmwarePlugin(currentText); sdDock->setVisible(core->firmwarePlugin()->isSdSupported()); } diff --git a/unittests/atcoretests.cpp b/unittests/atcoretests.cpp --- a/unittests/atcoretests.cpp +++ b/unittests/atcoretests.cpp @@ -58,7 +58,7 @@ void AtCoreTests::testConnectInvalidDevice() { QEXPECT_FAIL("", "Invalid Device Attempt", Continue); - QVERIFY(core->initSerial(QStringLiteral("/dev/ptyp5"), 9600)); + QVERIFY(core->newConnection(QStringLiteral("/dev/ptyp5"), 9600)); } void AtCoreTests::testStateChange()