diff --git a/src/atcore.h b/src/atcore.h
--- a/src/atcore.h
+++ b/src/atcore.h
@@ -59,6 +59,8 @@
Q_PROPERTY(QStringList portSpeeds READ portSpeeds)
Q_PROPERTY(QString connectedPort READ connectedPort)
Q_PROPERTY(AtCore::STATES state READ state WRITE setState NOTIFY stateChanged)
+ Q_PROPERTY(bool sdMount READ isSdMounted NOTIFY sdMountChanged)
+ Q_PROPERTY(QStringList sdFileList READ sdFileList NOTIFY sdCardFileListChanged)
public:
/**
* @brief STATES enum Possible states the printer can be in
@@ -200,6 +202,18 @@
*/
quint16 serialTimerInterval() const;
+ /**
+ * @brief Attempt to Mount an sd card
+ * @param slot: Sd card Slot on machine (0 is default)
+ */
+ void mountSd(int slot = 0);
+
+ /**
+ * @brief Attempt to Unmount an sd card
+ * @param slot: Sd card Slot on machine (0 is default)
+ */
+ void umountSd(int slot = 0);
+
signals:
/**
@@ -227,6 +241,16 @@
*/
void portsChanged(QStringList);
+ /**
+ * @brief Sd Card Mount Changed
+ */
+ void sdMountChanged(bool);
+
+ /**
+ * @brief get a list of the files on the sd card
+ */
+ void sdCardFileListChanged(QStringList);
+
public slots:
/**
@@ -246,8 +270,9 @@
/**
* @brief Public Interface for printing a file
* @param fileName: the gcode file to print.
+ * @param sdPrint: set true to print fileName from Sd card
*/
- void print(const QString &fileName);
+ void print(const QString &fileName, bool sdPrint);
/**
* @brief Stop the Printer by empting the queue and aborting the print job (if running)
@@ -266,6 +291,7 @@
*
* Sends M114 on pause to store the location where the head stoped.
* This is known to cause problems on fake printers
+ * Post Pause moves are not sent for sd card jobs firmware has it own post pause moves
* @param pauseActions: Gcode to run after pausing commands are ',' separated
* @sa resume(),stop(),emergencyStop()
*/
@@ -378,6 +404,23 @@
*/
void setSerialTimerInterval(const quint16 &newTime);
+ /**
+ * @brief sdFileList
+ * @return List of files on the sd card.
+ */
+ QStringList sdFileList();
+
+ /**
+ * @brief Check if an sd card is mounted on the printer
+ * @return True if card mounted
+ */
+ bool isSdMounted();
+
+ /**
+ * @brief delete file from sd card
+ */
+ void sdDelete(const QString &fileName);
+
private slots:
/**
* @brief processQueue send commands from the queue.
@@ -407,6 +450,11 @@
*/
void locateSerialPort();
+ /**
+ * @brief Send request to the printer for the sd card file list.
+ */
+ void getSDFileList();
+
private:
/**
* @brief True if a firmware plugin is loaded
diff --git a/src/atcore.cpp b/src/atcore.cpp
--- a/src/atcore.cpp
+++ b/src/atcore.cpp
@@ -61,6 +61,11 @@
AtCore::STATES printerState; //!< @param printerState: State of the Printer
QStringList serialPorts; //!< @param seralPorts: Detected serial Ports
QTimer *serialTimer = nullptr; //!< @param serialTimer: Timer connected to locateSerialPorts
+ bool sdCardMounted = false; //!< @param sdCardMounted: True if Sd Card is mounted.
+ bool sdCardReadingFileList = false; //!< @param sdCardReadingFileList: True while getting file names from sd card
+ QString sdCardFileName; //!< @param sdCardFileName: name of file being used from sd card.
+ bool sdCardPrinting = false; //!< @param sdCardPrinting: True if currently printing from sd card.
+ QStringList sdCardFileList; //!< @param sdCardFileList: List of files on sd card.
};
AtCore::AtCore(QObject *parent) :
@@ -297,15 +302,40 @@
void AtCore::newMessage(const QByteArray &message)
{
d->lastMessage = message;
- if (message.startsWith(QString::fromLatin1("X:").toLocal8Bit())) {
- d->posString = message;
- d->posString.resize(d->posString.indexOf('E'));
- d->posString.replace(':', "");
- }
- //Check if have temperature info and decode it
- if (d->lastMessage.contains("T:") || d->lastMessage.contains("B:")) {
- temperature().decodeTemp(message);
+ if (message.contains("End file list")) {
+ d->sdCardReadingFileList = false;
+ emit(sdCardFileListChanged(d->sdCardFileList));
+ } else if (d->sdCardReadingFileList) {
+ // Below is to not add directories
+ if (!message.endsWith('/')) {
+ QString fileName = QString::fromLocal8Bit(message);
+ fileName.chop(fileName.length() - fileName.lastIndexOf(QChar::fromLatin1(' ')));
+ d->sdCardFileList.append(fileName);
+ qCDebug(ATCORE_CORE) << "Adding " << fileName << " to file list";
+ }
+ } else {
+ if (message.startsWith(QString::fromLatin1("X:").toLocal8Bit())) {
+ d->posString = message;
+ d->posString.resize(d->posString.indexOf('E'));
+ d->posString.replace(':', "");
+ } else if (message.contains("SD card")) {
+ if (message.contains("inserted")) {
+ d->sdCardMounted = true;
+ } else if (message.contains("removed")) {
+ d->sdCardMounted = false;
+ }
+ emit sdMountChanged(d->sdCardMounted);
+ } else if (message.contains("Begin file list")) {
+ if (d->sdCardMounted != true) {
+ d->sdCardMounted = true;
+ emit sdMountChanged(true);
+ }
+ d->sdCardReadingFileList = true;
+ d->sdCardFileList.clear();
+ } else if (d->lastMessage.contains("T:") || d->lastMessage.contains("B:")) {
+ temperature().decodeTemp(message);
+ }
}
emit(receivedMessage(d->lastMessage));
}
@@ -322,27 +352,43 @@
float AtCore::percentagePrinted() const
{
+ /*
+ if(d->sdCardPrinting) {
+ pushCommand(GCode::toCommand(GCode::M27));
+ } else {
+ return d->percentage;
+ }
+ */
return d->percentage;
}
-void AtCore::print(const QString &fileName)
+void AtCore::print(const QString &fileName, bool sdPrint)
{
- if (state() == AtCore::CONNECTING) {
- qCDebug(ATCORE_CORE) << "Load a firmware plugin to print.";
- return;
- }
- //START A THREAD AND CONNECT TO IT
- setState(AtCore::STARTPRINT);
- QThread *thread = new QThread();
- PrintThread *printThread = new PrintThread(this, fileName);
- printThread->moveToThread(thread);
-
- connect(printThread, &PrintThread::printProgressChanged, this, &AtCore::printProgressChanged, Qt::QueuedConnection);
- connect(thread, &QThread::started, printThread, &PrintThread::start);
- connect(printThread, &PrintThread::finished, thread, &QThread::quit);
- connect(thread, &QThread::finished, printThread, &PrintThread::deleteLater);
- if (!thread->isRunning()) {
- thread->start();
+ if (sdPrint) {
+ pushCommand(GCode::toCommand(GCode::M23, fileName));
+ d->sdCardFileName = fileName;
+ pushCommand(GCode::toCommand(GCode::M24));
+ setState(AtCore::STARTPRINT);
+ setState(AtCore::BUSY);
+ d->sdCardPrinting = true;
+ } else {
+ if (state() == AtCore::CONNECTING) {
+ qCDebug(ATCORE_CORE) << "Load a firmware plugin to print.";
+ return;
+ }
+ //START A THREAD AND CONNECT TO IT
+ setState(AtCore::STARTPRINT);
+ QThread *thread = new QThread();
+ PrintThread *printThread = new PrintThread(this, fileName);
+ printThread->moveToThread(thread);
+
+ connect(printThread, &PrintThread::printProgressChanged, this, &AtCore::printProgressChanged, Qt::QueuedConnection);
+ connect(thread, &QThread::started, printThread, &PrintThread::start);
+ connect(printThread, &PrintThread::finished, thread, &QThread::quit);
+ connect(thread, &QThread::finished, printThread, &PrintThread::deleteLater);
+ if (!thread->isRunning()) {
+ thread->start();
+ }
}
}
@@ -391,8 +437,14 @@
void AtCore::stop()
{
setState(AtCore::STOP);
- d->commandQueue.clear();
+ if (d->sdCardPrinting) {
+ pushCommand(GCode::toCommand(GCode::M25));
+ d->sdCardFileName = QStringLiteral("");
+ pushCommand(GCode::toCommand(GCode::M23, d->sdCardFileName));
+ d->sdCardPrinting = false;
+ }
setExtruderTemp(0, 0);
+ d->commandQueue.clear();
setBedTemp(0);
home(AtCore::X);
}
@@ -403,6 +455,9 @@
setState(AtCore::STOP);
}
d->commandQueue.clear();
+ if (d->sdCardPrinting) {
+ stop();
+ }
serial()->pushCommand(GCode::toCommand(GCode::M112).toLocal8Bit());
}
@@ -468,19 +523,27 @@
void AtCore::pause(const QString &pauseActions)
{
- pushCommand(GCode::toCommand(GCode::M114));
- setState(AtCore::PAUSE);
- if (!pauseActions.isEmpty()) {
- QStringList temp = pauseActions.split(QChar::fromLatin1(','));
- for (int i = 0; i < temp.length(); i++) {
- pushCommand(temp.at(i));
+ if (d->sdCardPrinting) {
+ pushCommand(GCode::toCommand(GCode::M25));
+ } else {
+ pushCommand(GCode::toCommand(GCode::M114));
+ if (!pauseActions.isEmpty()) {
+ QStringList temp = pauseActions.split(QChar::fromLatin1(','));
+ for (int i = 0; i < temp.length(); i++) {
+ pushCommand(temp.at(i));
+ }
}
}
+ setState(AtCore::PAUSE);
}
void AtCore::resume()
{
- pushCommand(GCode::toCommand(GCode::G0, QString::fromLatin1(d->posString)));
+ if (d->sdCardPrinting) {
+ pushCommand(GCode::toCommand(GCode::M24));
+ } else {
+ pushCommand(GCode::toCommand(GCode::G0, QString::fromLatin1(d->posString)));
+ }
setState(AtCore::BUSY);
}
@@ -624,3 +687,37 @@
pushCommand(GCode::toCommand(GCode::M84));
}
}
+
+bool AtCore::isSdMounted()
+{
+ return d->sdCardMounted;
+}
+
+void AtCore::getSDFileList()
+{
+ pushCommand(GCode::toCommand(GCode::M20));
+}
+
+QStringList AtCore::sdFileList()
+{
+ if (d->sdCardFileList.isEmpty()) {
+ getSDFileList();
+ }
+ return d->sdCardFileList;
+}
+
+void AtCore::sdDelete(const QString &fileName)
+{
+ pushCommand(GCode::toCommand(GCode::M30, fileName));
+ getSDFileList();
+}
+
+void AtCore::mountSd(int slot)
+{
+ pushCommand(GCode::toCommand(GCode::M21, QString::number(slot)));
+}
+
+void AtCore::umountSd(int slot)
+{
+ pushCommand(GCode::toCommand(GCode::M22, QString::number(slot)));
+}
diff --git a/src/gcodecommands.cpp b/src/gcodecommands.cpp
--- a/src/gcodecommands.cpp
+++ b/src/gcodecommands.cpp
@@ -139,7 +139,7 @@
return QObject::tr("M21: Initialize SDCard");
case M22://Teacup - Sprinter - Marlin - Repetier - RepRap Firmware
return QObject::tr("M22: Release SDCard");
- case M23:////Teacup - Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware
+ case M23://Teacup - Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware
return QObject::tr("M23: Select SD file");
case M24://Teacup - Sprinter - Marlin - Repetier - Smoothie - RepRap Firmware
return QObject::tr("M24: Start/resume SD print");
@@ -299,7 +299,7 @@
return QObject::tr("M231: Set OPS parameter");
case M232://Repetier
return QObject::tr("M232: Read and reset max. advance values");
- case M240: //Marlin
+ case M240://Marlin
return QObject::tr("M240: Trigger camera");
case M250://Marlin
return QObject::tr("M250: Set LCD contrast");
@@ -504,6 +504,67 @@
QString GCode::toCommand(MCommands gcode, const QString &value1, const QString &value2)
{
switch (gcode) {
+ case M20: {
+ return QStringLiteral("M20");
+ }
+ case M21: {
+ if (!value1.isEmpty()) {
+ return QStringLiteral("M21 P%1").arg(value1);
+ }
+ return QStringLiteral("M21");
+ }
+ case M22: {
+ if (!value1.isEmpty()) {
+ return QStringLiteral("M22 P%1").arg(value1);
+ }
+ return QStringLiteral("M22");
+ }
+ case M23: {
+ if (!value1.isEmpty()) {
+ return QStringLiteral("M23 %1").arg(value1);
+ }
+ return QObject::tr("ERROR! M23: It's obligatory to have an argument");
+ }
+ case M24: {
+ return QStringLiteral("M24");
+ }
+ case M25: {
+ return QStringLiteral("M25");
+ }
+ /// For M26 values that end with %. AtCore will send the percentage verison of the command (optional in firmwares)
+ /// For all values not ending in % it will start on that byte. This is the standard Sd resume supported by all reprap based firmware.
+ case M26: {
+ if (!value1.isEmpty()) {
+ if (value1.endsWith(QStringLiteral("%"))) {
+ QString temp = value1;
+ temp.replace(QStringLiteral("%"), QStringLiteral(""));
+ return QStringLiteral("M26 P%1").arg(temp.toDouble() / 100);
+ }
+ return QStringLiteral("M26 S%1").arg(value1);
+ }
+ return QObject::tr("ERROR! M26: It's obligatory to have an argument");
+ }
+ case M27: {
+ return QStringLiteral("M27");
+ }
+ case M28: {
+ if (!value1.isEmpty()) {
+ return QStringLiteral("M28 %1").arg(value1);
+ }
+ return QObject::tr("ERROR! M28: It's obligatory to have an argument");
+ }
+ case M29: {
+ if (!value1.isEmpty()) {
+ return QStringLiteral("M29 %1").arg(value1);
+ }
+ return QObject::tr("ERROR! M29: It's obligatory to have an argument");
+ }
+ case M30: {
+ if (!value1.isEmpty()) {
+ return QStringLiteral("M30 %1").arg(value1);
+ }
+ return QObject::tr("ERROR! M30: It's obligatory to have an argument");
+ }
case M84: {
if (!value1.isEmpty()) {
return QStringLiteral("M84 S%1").arg(value1);
diff --git a/testclient/mainwindow.h b/testclient/mainwindow.h
--- a/testclient/mainwindow.h
+++ b/testclient/mainwindow.h
@@ -131,6 +131,10 @@
*/
void printPBClicked();
+ /**
+ * @brief Print Button for Sd Prints clicked.
+ */
+ void pb_printSDClicked();
/**
* @brief Save the log file.
*/
@@ -176,12 +180,24 @@
* @brief Show the about dialog
*/
void about();
+
+ /**
+ * @brief List Files on the sd card.
+ */
+ void getSdList();
+
+ /**
+ * @brief Sd Card Delete file clicked
+ */
+ void pb_sdDelClicked();
+
signals:
/**
* @brief printFile emit ready to print a file to atcore
* @param fileName : the file to print
+ * @param sdPrint : True if file is on printers Sd Card
*/
- void printFile(const QString &fileName);
+ void printFile(const QString &fileName, bool sdPrint = false);
private:
Ui::MainWindow *ui;
@@ -269,4 +285,9 @@
* @brief Populate comboboxes
*/
void populateCBs();
+
+ /**
+ * @brief Gui Changes for when sd card mount status has changed.
+ */
+ void sdChanged(bool mounted);
};
diff --git a/testclient/mainwindow.cpp b/testclient/mainwindow.cpp
--- a/testclient/mainwindow.cpp
+++ b/testclient/mainwindow.cpp
@@ -90,18 +90,27 @@
connect(ui->mvAxisPB, &QPushButton::clicked, this, &MainWindow::mvAxisPBClicked);
connect(ui->fanSpeedPB, &QPushButton::clicked, this, &MainWindow::fanSpeedPBClicked);
connect(ui->printPB, &QPushButton::clicked, this, &MainWindow::printPBClicked);
+ connect(ui->pb_printSD, &QPushButton::clicked, this, &MainWindow::pb_printSDClicked);
+ connect(ui->pb_sdDel, &QPushButton::clicked, this, &MainWindow::pb_sdDelClicked);
connect(ui->printerSpeedPB, &QPushButton::clicked, this, &MainWindow::printerSpeedPBClicked);
connect(ui->flowRatePB, &QPushButton::clicked, this, &MainWindow::flowRatePBClicked);
connect(ui->showMessagePB, &QPushButton::clicked, this, &MainWindow::showMessage);
connect(ui->pluginCB, &QComboBox::currentTextChanged, this, &MainWindow::pluginCBChanged);
connect(ui->disableMotorsPB, &QPushButton::clicked, this, &MainWindow::disableMotorsPBClicked);
+ connect(ui->pb_sdList, &QPushButton::clicked, this, &MainWindow::getSdList);
connect(core, &AtCore::stateChanged, this, &MainWindow::printerStateChanged);
connect(this, &MainWindow::printFile, core, &AtCore::print);
connect(ui->stopPB, &QPushButton::clicked, core, &AtCore::stop);
connect(ui->emergencyStopPB, &QPushButton::clicked, core, &AtCore::emergencyStop);
connect(axisControl, &AxisControl::clicked, this, &MainWindow::axisControlClicked);
connect(core, &AtCore::portsChanged, this, &MainWindow::locateSerialPort);
connect(core, &AtCore::printProgressChanged, this, &MainWindow::printProgressChanged);
+ connect(core, &AtCore::sdMountChanged, this, &MainWindow::sdChanged);
+
+ connect(core, &AtCore::sdCardFileListChanged, [this](QStringList fileList) {
+ ui->list_sdFileView->clear();
+ ui->list_sdFileView->addItems(fileList);
+ });
connect(&core->temperature(), &Temperature::bedTemperatureChanged, [ = ](float temp) {
checkTemperature(0x00, 0, temp);
@@ -135,11 +144,13 @@
ui->menuView->insertAction(nullptr, ui->moveDock->toggleViewAction());
ui->menuView->insertAction(nullptr, ui->tempTimelineDock->toggleViewAction());
ui->menuView->insertAction(nullptr, ui->logDock->toggleViewAction());
+ ui->menuView->insertAction(nullptr, ui->sdDock->toggleViewAction());
//more dock stuff.
setTabPosition(Qt::LeftDockWidgetArea, QTabWidget::North);
setTabPosition(Qt::RightDockWidgetArea, QTabWidget::North);
tabifyDockWidget(ui->moveDock, ui->tempControlsDock);
+ tabifyDockWidget(ui->moveDock, ui->sdDock);
ui->moveDock->raise();
tabifyDockWidget(ui->connectDock, ui->printDock);
@@ -487,14 +498,16 @@
ui->moveDock->setDisabled(true);
ui->tempControlsDock->setDisabled(true);
ui->printDock->setDisabled(true);
+ ui->sdDock->setDisabled(true);
break;
case AtCore::CONNECTING:
stateString = QStringLiteral("Connecting");
ui->commandDock->setDisabled(false);
ui->moveDock->setDisabled(false);
ui->tempControlsDock->setDisabled(false);
ui->printDock->setDisabled(false);
+ ui->sdDock->setDisabled(false);
break;
case AtCore::STOP:
@@ -552,14 +565,16 @@
delete ui->moveDock->titleBarWidget();
delete ui->tempControlsDock->titleBarWidget();
delete ui->printDock->titleBarWidget();
+ delete ui->sdDock->titleBarWidget();
} else {
ui->connectDock->setTitleBarWidget(new QWidget());
ui->logDock->setTitleBarWidget(new QWidget());
ui->tempTimelineDock->setTitleBarWidget(new QWidget());
ui->commandDock->setTitleBarWidget(new QWidget());
ui->moveDock->setTitleBarWidget(new QWidget());
ui->tempControlsDock->setTitleBarWidget(new QWidget());
ui->printDock->setTitleBarWidget(new QWidget());
+ ui->sdDock->setTitleBarWidget(new QWidget());
}
}
@@ -580,3 +595,36 @@
{
core->setIdleHold(0);
}
+
+void MainWindow::sdChanged(bool mounted)
+{
+ if (mounted) {
+ ui->lbl_sd->setText(QStringLiteral("SD"));
+ } else {
+ ui->lbl_sd->setText(QStringLiteral(""));
+ }
+}
+
+void MainWindow::getSdList()
+{
+ core->sdFileList();
+}
+
+void MainWindow::pb_printSDClicked()
+{
+ if (ui->list_sdFileView->currentRow() == -1) {
+ QMessageBox::information(this, QStringLiteral("Print Error"), QStringLiteral("You must Select a file from the list"));
+ } else {
+ core->print(ui->list_sdFileView->currentItem()->text(), true);
+ }
+}
+
+void MainWindow::pb_sdDelClicked()
+{
+ if (ui->list_sdFileView->currentRow() == -1) {
+ QMessageBox::information(this, QStringLiteral("Print Error"), QStringLiteral("You must Select a file from the list"));
+ } else {
+ core->sdDelete(ui->list_sdFileView->currentItem()->text());
+ ui->list_sdFileView->setCurrentRow(-1);
+ }
+}
diff --git a/testclient/mainwindow.ui b/testclient/mainwindow.ui
--- a/testclient/mainwindow.ui
+++ b/testclient/mainwindow.ui
@@ -56,6 +56,41 @@
+ -
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Fixed
+
+
+
+ 10
+ 20
+
+
+
+
+ -
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
-
+
+
+
+
+
+
+
+
+
-
@@ -380,6 +415,71 @@
+
+
+ false
+
+
+
+ 0
+ 42
+ 515
+ 317
+
+
+
+ S&d Card
+
+
+
+
-
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
-
+
+
+ Get List
+
+
+
+ -
+
+
+ Print Selected
+
+
+
+ -
+
+
+ Delete Selected
+
+
+
+
+
+
+ -
+
+
+ Files On Sd Card.
+
+
+
-
+
+
+
+
+
+
+
+
diff --git a/unittests/gcodetests.h b/unittests/gcodetests.h
--- a/unittests/gcodetests.h
+++ b/unittests/gcodetests.h
@@ -59,6 +59,17 @@
void string_G161();
void string_G162();
+ void command_M20();
+ void command_M21();
+ void command_M22();
+ void command_M23();
+ void command_M24();
+ void command_M25();
+ void command_M26();
+ void command_M27();
+ void command_M28();
+ void command_M29();
+ void command_M30();
void command_M84();
void command_M104();
void command_M105();
diff --git a/unittests/gcodetests.cpp b/unittests/gcodetests.cpp
--- a/unittests/gcodetests.cpp
+++ b/unittests/gcodetests.cpp
@@ -183,6 +183,70 @@
QVERIFY(GCode::toString(GCode::G162) == QObject::tr("G162: Home axis to maximum"));
}
+void GCodeTests::command_M20()
+{
+ QVERIFY(GCode::toCommand(GCode::M20) == QStringLiteral("M20"));
+}
+
+void GCodeTests::command_M21()
+{
+ QVERIFY(GCode::toCommand(GCode::M21) == QStringLiteral("M21"));
+ QVERIFY(GCode::toCommand(GCode::M21, QStringLiteral("2")) == QStringLiteral("M21 P2"));
+}
+
+void GCodeTests::command_M22()
+{
+ QVERIFY(GCode::toCommand(GCode::M22) == QStringLiteral("M22"));
+ QVERIFY(GCode::toCommand(GCode::M22, QStringLiteral("5")) == QStringLiteral("M22 P5"));
+}
+
+void GCodeTests::command_M23()
+{
+ QVERIFY(GCode::toCommand(GCode::M23) == QStringLiteral("ERROR! M23: It's obligatory to have an argument"));
+ QVERIFY(GCode::toCommand(GCode::M23, QStringLiteral("FileName")) == QStringLiteral("M23 FileName"));
+}
+
+void GCodeTests::command_M24()
+{
+ QVERIFY(GCode::toCommand(GCode::M24) == QStringLiteral("M24"));
+}
+
+void GCodeTests::command_M25()
+{
+ QVERIFY(GCode::toCommand(GCode::M25) == QStringLiteral("M25"));
+}
+
+void GCodeTests::command_M26()
+{
+ QVERIFY(GCode::toCommand(GCode::M26) == QStringLiteral("ERROR! M26: It's obligatory to have an argument"));
+ QVERIFY(GCode::toCommand(GCode::M26, QStringLiteral("15%")) == QStringLiteral("M26 P0.15"));
+ QVERIFY(GCode::toCommand(GCode::M26, QStringLiteral("15")) == QStringLiteral("M26 S15"));
+
+}
+
+void GCodeTests::command_M27()
+{
+ QVERIFY(GCode::toCommand(GCode::M27) == QStringLiteral("M27"));
+}
+
+void GCodeTests::command_M28()
+{
+ QVERIFY(GCode::toCommand(GCode::M28) == QStringLiteral("ERROR! M28: It's obligatory to have an argument"));
+ QVERIFY(GCode::toCommand(GCode::M28, QStringLiteral("FileName")) == QStringLiteral("M28 FileName"));
+}
+
+void GCodeTests::command_M29()
+{
+ QVERIFY(GCode::toCommand(GCode::M29) == QStringLiteral("ERROR! M29: It's obligatory to have an argument"));
+ QVERIFY(GCode::toCommand(GCode::M29, QStringLiteral("FileName")) == QStringLiteral("M29 FileName"));
+}
+
+void GCodeTests::command_M30()
+{
+ QVERIFY(GCode::toCommand(GCode::M30) == QStringLiteral("ERROR! M30: It's obligatory to have an argument"));
+ QVERIFY(GCode::toCommand(GCode::M30, QStringLiteral("FileName")) == QStringLiteral("M30 FileName"));
+}
+
void GCodeTests::command_M84()
{
QVERIFY(GCode::toCommand(GCode::M84) == QStringLiteral("M84"));