diff --git a/RepRaptor.pro b/RepRaptor.pro index a900241..e3c5963 100644 --- a/RepRaptor.pro +++ b/RepRaptor.pro @@ -44,7 +44,8 @@ SOURCES += main.cpp\ erroricon.cpp \ sdwindow.cpp \ eepromwindow.cpp \ - parser.cpp + parser.cpp \ + sender.cpp HEADERS += mainwindow.h \ settingswindow.h \ @@ -54,7 +55,8 @@ HEADERS += mainwindow.h \ sdwindow.h \ repraptor.h \ eepromwindow.h \ - parser.h + parser.h \ + sender.h FORMS += mainwindow.ui \ settingswindow.ui \ diff --git a/mainwindow.cpp b/mainwindow.cpp index a2088be..95a5d08 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -50,7 +50,6 @@ MainWindow::MainWindow(QWidget *parent) : chekingSDStatus = settings.value("core/checksdstatus", 1).toBool(); firmware = settings.value("printer/firmware", OtherFirmware).toInt(); statusTimer.setInterval(settings.value("core/statusinterval", 3000).toInt()); - sendTimer.setInterval(settings.value("core/senderinterval", 2).toInt()); int size = settings.beginReadArray("user/recentfiles"); for(int i = 0; i < size; ++i) { @@ -64,9 +63,10 @@ MainWindow::MainWindow(QWidget *parent) : paused = false; readingFiles = false; sdprinting = false; + opened = false; sdBytes = 0; currentLine = 0; - readyRecieve = 1; + readyRecieve = false; lastRecieved = 0; userHistoryPos = 0; totalLineNum = 0; @@ -77,37 +77,59 @@ MainWindow::MainWindow(QWidget *parent) : serialupdate(); //Internal signal-slots - connect(&printer, SIGNAL(error(QSerialPort::SerialPortError)), this, SLOT(serialError(QSerialPort::SerialPortError))); - connect(&printer, SIGNAL(readyRead()), this, SLOT(readSerial())); connect(&statusTimer, SIGNAL(timeout()), this, SLOT(checkStatus())); - connect(&sendTimer, SIGNAL(timeout()), this, SLOT(sendNext())); connect(&progressSDTimer, SIGNAL(timeout()), this, SLOT(checkSDStatus())); connect(this, SIGNAL(eepromReady()), this, SLOT(openEEPROMeditor())); //Parser thread signal-slots and init qRegisterMetaType("TemperatureReadings"); qRegisterMetaType("SDProgress"); - parser = new Parser(); - parserThread = new QThread(); - parser->moveToThread(parserThread); - connect(parserThread, &QThread::finished, parser, &QObject::deleteLater); - connect(this, &MainWindow::recievedData, parser, &Parser::parse); - connect(this, &MainWindow::startedReadingEEPROM, parser, &Parser::setEEPROMReadingMode); - connect(parser, &Parser::recievedTemperature, this, &MainWindow::updateTemperature); - connect(parser, &Parser::recievedOkNum, this, &MainWindow::recievedOkNum); - connect(parser, &Parser::recievedOkWait, this, &MainWindow::recievedWait); - connect(parser, &Parser::recievedSDFilesList, this, &MainWindow::initSDprinting); - connect(parser, &Parser::recievedEEPROMLine, this, &MainWindow::EEPROMSettingRecieved); - connect(parser, &Parser::recievingEEPROMDone, this, &MainWindow::openEEPROMeditor); - connect(parser, &Parser::recievedError, this, &MainWindow::recievedError); - connect(parser, &Parser::recievedSDDone, this, &MainWindow::recievedSDDone); - connect(parser, &Parser::recievedResend, this, &MainWindow::recievedResend); - connect(parser, &Parser::recievedSDUpdate, this, &MainWindow::updateSDStatus); + parserWorker = new Parser(); + parserThread = new QThread(this); + parserWorker->moveToThread(parserThread); + connect(parserThread, &QThread::finished, parserWorker, &QObject::deleteLater); + connect(this, &MainWindow::recievedData, parserWorker, &Parser::parse); + connect(this, &MainWindow::startedReadingEEPROM, parserWorker, &Parser::setEEPROMReadingMode); + connect(parserWorker, &Parser::recievedTemperature, this, &MainWindow::updateTemperature); + connect(parserWorker, &Parser::recievedSDFilesList, this, &MainWindow::initSDprinting); + connect(parserWorker, &Parser::recievedEEPROMLine, this, &MainWindow::EEPROMSettingRecieved); + connect(parserWorker, &Parser::recievingEEPROMDone, this, &MainWindow::openEEPROMeditor); + connect(parserWorker, &Parser::recievedError, this, &MainWindow::recievedError); + connect(parserWorker, &Parser::recievedSDDone, this, &MainWindow::recievedSDDone); + connect(parserWorker, &Parser::recievedSDUpdate, this, &MainWindow::updateSDStatus); parserThread->start(); + //Sender thread signal-slots and init + qRegisterMetaType("QSerialPortInfo"); + qRegisterMetaType< QVector >("QVector"); + qRegisterMetaType("FileProgress"); + qRegisterMetaType("QSerialPort::SerialPortError"); + senderWorker = new Sender(); + senderThread = new QThread(this); + senderWorker->moveToThread(senderThread); + connect(senderThread, &QThread::finished, senderWorker, &QObject::deleteLater); + connect(parserWorker, &Parser::recievedOkNum, senderWorker, &Sender::recievedOkNum); + connect(parserWorker, &Parser::recievedOkWait, senderWorker, &Sender::recievedOkWait); + connect(parserWorker, &Parser::recievedResend, senderWorker, &Sender::recievedResend); + connect(parserWorker, &Parser::recievedStart, senderWorker, &Sender::recievedStart); + connect(senderWorker, &Sender::errorRecieved, this, &MainWindow::serialError); + connect(senderWorker, &Sender::dataRecieved, parserWorker, &Parser::parse, Qt::QueuedConnection); + connect(senderWorker, &Sender::dataRecieved, this, &MainWindow::readSerial, Qt::QueuedConnection); + connect(senderWorker, &Sender::reportProgress, this, &MainWindow::updateFileProgress); + connect(this, &MainWindow::setFile, senderWorker, &Sender::setFile); + connect(this, &MainWindow::startPrinting, senderWorker, &Sender::startPrinting); + connect(this, &MainWindow::stopPrinting, senderWorker, &Sender::stopPrinting); + connect(this, &MainWindow::pause, senderWorker, &Sender::pause); + connect(this, &MainWindow::setBaudrate, senderWorker, &Sender::setBaudrate); + connect(this, &MainWindow::openPort, senderWorker, &Sender::openPort); + connect(this, &MainWindow::closePort, senderWorker, &Sender::closePort); + connect(this, &MainWindow::injectCommand, senderWorker, &Sender::injectCommand); + connect(this, &MainWindow::flushInjectionBuffer, senderWorker, &Sender::flushInjectionBuffer); + senderThread->start(); + //Timers init statusTimer.start(); - sendTimer.start(); + //sendTimer.start(); progressSDTimer.setInterval(2500); if(chekingSDStatus) progressSDTimer.start(); sinceLastTemp.start(); @@ -135,9 +157,10 @@ MainWindow::~MainWindow() //Cleanup what is left if(gfile.isOpen()) gfile.close(); - if(printer.isOpen()) printer.close(); parserThread->quit(); parserThread->wait(); + senderThread->quit(); + senderThread->wait(); delete ui; } @@ -169,13 +192,13 @@ void MainWindow::parseFile(QString filename) if (gfile.open(QIODevice::ReadOnly)) { QTextStream in(&gfile); - int n = 0; while (!in.atEnd()) { QString line = in.readLine(); if(!line.startsWith(";")) gcode.append(line); } gfile.close(); + emit setFile(gcode); ui->fileBox->setEnabled(true); ui->progressBar->setEnabled(true); ui->sendBtn->setText("Send"); @@ -184,34 +207,6 @@ void MainWindow::parseFile(QString filename) } } -bool MainWindow::sendLine(QString line) -{ - if(printer.isOpen()) - { - if(sendingChecksum) - { - if(line.contains("M110")) totalLineNum = 0; - - //Checksum algorithm from RepRap wiki - line = "N"+QString::number(totalLineNum)+line+"*"; - int cs = 0; - for(int i = 0; line.at(i) != '*'; i++) cs = cs ^ line.at(i).toLatin1(); - cs &= 0xff; - line += QString::number(cs); - totalLineNum++; - } - if(printer.write(line.toUtf8()+'\n')) - { - if(echo) printMsg(line + '\n'); - return true; - } - else return false; - } - - else return false; - -} - void MainWindow::serialupdate() { ui->serialBox->clear(); @@ -222,9 +217,9 @@ void MainWindow::serialupdate() void MainWindow::serialconnect() { - userCommands.clear(); + emit flushInjectionBuffer(); - if(!printer.isOpen()) + if(!opened) { foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) { @@ -235,49 +230,24 @@ void MainWindow::serialconnect() } } - printer.setPort(printerinfo); - - if(printer.open(QIODevice::ReadWrite)) - { - - //Moved here to be compatible with Qt 5.2.1 - switch(ui->baudbox->currentText().toInt()) - { - case 4800: - printer.setBaudRate(QSerialPort::Baud4800); - break; - - case 9600: - printer.setBaudRate(QSerialPort::Baud9600); - break; - - case 115200: - printer.setBaudRate(QSerialPort::Baud115200); - break; - - default: - printer.setBaudRate(ui->baudbox->currentText().toInt()); - break; - } - - printer.setFlowControl(QSerialPort::HardwareControl); - - ui->connectBtn->setText("Disconnect"); - ui->sendBtn->setDisabled(false); - //ui->pauseBtn->setDisabled(false); - ui->progressBar->setValue(0); - ui->controlBox->setDisabled(false); - ui->consoleGroup->setDisabled(false); - ui->statusGroup->setDisabled(false); - ui->actionPrint_from_SD->setEnabled(true); - ui->actionSet_SD_printing_mode->setEnabled(true); - if(firmware == Repetier) ui->actionEEPROM_editor->setDisabled(false); - } + emit setBaudrate(ui->baudbox->currentText().toInt()); + emit openPort(printerinfo); + opened=true; + ui->connectBtn->setText("Disconnect"); + ui->sendBtn->setDisabled(false); + //ui->pauseBtn->setDisabled(false); + ui->progressBar->setValue(0); + ui->controlBox->setDisabled(false); + ui->consoleGroup->setDisabled(false); + ui->statusGroup->setDisabled(false); + ui->actionPrint_from_SD->setEnabled(true); + ui->actionSet_SD_printing_mode->setEnabled(true); + if(firmware == Repetier) ui->actionEEPROM_editor->setDisabled(false); } - else if(printer.isOpen()) + else if(opened) { - printer.close(); + emit closePort(); ui->connectBtn->setText("Connect"); ui->sendBtn->setDisabled(true); @@ -289,7 +259,9 @@ void MainWindow::serialconnect() ui->actionSet_SD_printing_mode->setDisabled(true); ui->statusGroup->setDisabled(true); ui->actionEEPROM_editor->setDisabled(false); + opened = false; } + } ///////////////// @@ -298,123 +270,123 @@ void MainWindow::serialconnect() void MainWindow::xplus() { QString command = "G91\nG1 X" + ui->stepspin->text() + "\nG90"; - injectCommand(command); + emit injectCommand(command); } void MainWindow::xminus() { QString command = "G91\nG1 X-" + ui->stepspin->text() + "\nG90"; - injectCommand(command); + emit injectCommand(command); } void MainWindow::xhome() { - injectCommand("G28 X0"); + emit injectCommand("G28 X0"); } void MainWindow::yplus() { QString command = "G91\nG1 Y" + ui->stepspin->text() + "\nG90"; - injectCommand(command); + emit injectCommand(command); } void MainWindow::yminus() { QString command = "G91\nG1 Y-" + ui->stepspin->text() + "\nG90"; - injectCommand(command); + emit injectCommand(command); } void MainWindow::yhome() { - injectCommand("G28 Y0"); + emit injectCommand("G28 Y0"); } void MainWindow::zplus() { QString command = "G91\nG1 Z" + ui->stepspin->text() + "\nG90"; - injectCommand(command); + emit injectCommand(command); } void MainWindow::zminus() { QString command = "G91\nG1 Z-" + ui->stepspin->text() + "\nG90"; - injectCommand(command); + emit injectCommand(command); } void MainWindow::zhome() { - injectCommand("G28 Z0"); + emit injectCommand("G28 Z0"); } void MainWindow::eplus() { QString command = "G91\nG1 E" + ui->estepspin->text() + "\nG90"; - injectCommand(command); + emit injectCommand(command); } void MainWindow::eminus() { QString command = "G91\nG1 E-" + ui->estepspin->text() + "\nG90"; - injectCommand(command); + emit injectCommand(command); } void MainWindow::ezero() { - injectCommand("G92 E0"); + emit injectCommand("G92 E0"); } void MainWindow::homeall() { - injectCommand("G28"); + emit injectCommand("G28"); } void MainWindow::on_sendbtn_clicked() { - injectCommand(ui->sendtext->text()); + emit injectCommand(ui->sendtext->text()); userHistory.append(ui->sendtext->text()); userHistoryPos = 0; } void MainWindow::on_fanonbtn_clicked() { - injectCommand("M106"); + emit injectCommand("M106"); } void MainWindow::on_fanoffbtn_clicked() { - injectCommand("M107"); + emit injectCommand("M107"); } void MainWindow::on_atxonbtn_clicked() { - injectCommand("M80"); + emit injectCommand("M80"); } void MainWindow::on_atxoffbtn_clicked() { - injectCommand("M81"); + emit injectCommand("M81"); } void MainWindow::on_etmpset_clicked() { QString command = "M80\nM104 S" + ui->etmpspin->text(); - injectCommand(command); + emit injectCommand(command); } void MainWindow::on_etmpoff_clicked() { - injectCommand("M104 S0"); + emit injectCommand("M104 S0"); } void MainWindow::on_btmpset_clicked() { QString command = "M80\nM140 S" + ui->btmpspin->text(); - injectCommand(command); + emit injectCommand(command); } void MainWindow::on_btmpoff_clicked() { - injectCommand("M140 S0"); + emit injectCommand("M140 S0"); } void MainWindow::bedcenter() @@ -425,7 +397,7 @@ void MainWindow::bedcenter() y = settings.value("printer/bedy", 200).toInt(); QString command = "G1 X" + QString::number(x/2) + "Y" + QString::number(y/2); - injectCommand(command); + emit injectCommand(command); } void MainWindow::on_speedslider_valueChanged(int value) @@ -442,7 +414,7 @@ void MainWindow::on_speededit_textChanged(const QString &arg1) void MainWindow::on_speedsetbtn_clicked() { QString command = "M220 S" + QString::number(ui->speedslider->value()); - injectCommand(command); + emit injectCommand(command); } void MainWindow::on_flowedit_textChanged(const QString &arg1) @@ -459,24 +431,24 @@ void MainWindow::on_flowslider_valueChanged(int value) void MainWindow::on_flowbutton_clicked() { QString command = "M221 S" + QString::number(ui->flowslider->value()); - injectCommand(command); + emit injectCommand(command); } void MainWindow::on_haltbtn_clicked() { if(sending && !paused)ui->pauseBtn->click(); - userCommands.clear(); - injectCommand("M112"); + emit flushInjectionBuffer(); + emit injectCommand("M112"); } void MainWindow::on_actionPrint_from_SD_triggered() { - injectCommand("M20"); + emit injectCommand("M20"); } void MainWindow::on_sendBtn_clicked() { - userCommands.clear(); + emit flushInjectionBuffer(); if(sending && !sdprinting) { sending = false; @@ -485,6 +457,8 @@ void MainWindow::on_sendBtn_clicked() ui->pauseBtn->setDisabled(true); if(autolock) ui->controlBox->setChecked(true); paused = false; + emit pause(paused); + emit stopPrinting(); } else if(!sending && !sdprinting) { @@ -494,17 +468,20 @@ void MainWindow::on_sendBtn_clicked() ui->pauseBtn->setEnabled(true); if(autolock) ui->controlBox->setChecked(false); paused = false; + emit pause(paused); + emit startPrinting(); } else if(sdprinting) { sending = false; - injectCommand("M24"); - injectCommand("M27"); + emit injectCommand("M24"); + emit injectCommand("M27"); ui->sendBtn->setText("Start"); ui->pauseBtn->setText("Pause"); ui->pauseBtn->setEnabled(true); if(autolock) ui->controlBox->setChecked(true); paused = false; + emit pause(paused); } ui->progressBar->setValue(0); @@ -516,42 +493,34 @@ void MainWindow::on_pauseBtn_clicked() if(paused && !sdprinting) { paused = false; + emit pause(paused); if(autolock) ui->controlBox->setChecked(false); ui->pauseBtn->setText("Pause"); } else if(!paused && !sdprinting) { paused = true; + emit pause(paused); if(autolock) ui->controlBox->setChecked(true); ui->pauseBtn->setText("Resume"); } else if(sdprinting) { - injectCommand("M25"); + emit injectCommand("M25"); } } void MainWindow::on_releasebtn_clicked() { - injectCommand("M84"); + emit injectCommand("M84"); } ///////////////// //Buttons end // ///////////////// -void MainWindow::readSerial() +void MainWindow::readSerial(QByteArray data) { - if(printer.canReadLine()) //Check if full line in buffer - { - QByteArray data = printer.readLine(); //Read the line - - emit recievedData(data); //Send data to parser thread - - if(data.startsWith("ok")) readyRecieve++; - else if(data.startsWith("wa")) readyRecieve=1; - - printMsg(QString(data)); //echo - } + printMsg(QString(data)); //echo } void MainWindow::printMsg(const char* text) @@ -575,58 +544,10 @@ void MainWindow::printMsg(QString text) ui->terminal->setTextCursor(cursor); } - - -void MainWindow::sendNext() -{ - if(printer.isWritable()) - { - if(resendLineNum != -1) - { - if(gcode.isEmpty()) sendLine("M110 N0"); - else sendLine(gcode.at(resendLineNum)); - resendLineNum = -1; - - return; - } - if(!userCommands.isEmpty() && readyRecieve > 0) //Inject user command - { - sendLine(userCommands.dequeue()); - readyRecieve--; - return; - } - else if(sending && !paused && readyRecieve > 0 && !sdprinting) //Send line of gcode - { - if(currentLine >= gcode.size()) //check if we are at the end of array - { - sending = false; - currentLine = 0; - ui->sendBtn->setText("Send"); - ui->pauseBtn->setDisabled(true); - ui->filelines->setText(QString::number(gcode.size()) - + QString("/") - + QString::number(currentLine) - + QString(" Lines")); - if(sendingChecksum) injectCommand("M110 N0"); - return; - } - sendLine(gcode.at(currentLine)); - currentLine++; - readyRecieve--; - - ui->filelines->setText(QString::number(gcode.size()) - + QString("/") - + QString::number(currentLine) - + QString(" Lines")); - ui->progressBar->setValue(((float)currentLine/gcode.size()) * 100); - } - } -} - void MainWindow::checkStatus() { if(checkingTemperature - &&(sinceLastTemp.elapsed() > statusTimer.interval())) injectCommand("M105"); + &&(sinceLastTemp.elapsed() > statusTimer.interval())) emit injectCommand("M105"); } void MainWindow::on_checktemp_stateChanged(int arg1) @@ -649,11 +570,6 @@ void MainWindow::on_actionAbout_triggered() aboutwindow.exec(); } -void MainWindow::injectCommand(QString command) -{ - if(!userCommands.contains(command)) userCommands.enqueue(command); -} - void MainWindow::updateRecent() { if(!recentFiles.isEmpty()) //If array is empty we should not be bothered @@ -678,11 +594,12 @@ void MainWindow::serialError(QSerialPort::SerialPortError error) if(error == QSerialPort::NoError) return; if(error == QSerialPort::NotOpenError) return; //this error is internal - if(printer.isOpen()) printer.close(); + emit closePort(); if(sending) paused = true; + emit pause(paused); - userCommands.clear(); + emit flushInjectionBuffer(); ui->connectBtn->setText("Connect"); ui->sendBtn->setDisabled(true); @@ -692,6 +609,7 @@ void MainWindow::serialError(QSerialPort::SerialPortError error) ui->actionPrint_from_SD->setDisabled(true); ui->actionSet_SD_printing_mode->setDisabled(true); ui->actionEEPROM_editor->setDisabled(true); + opened = false; qDebug() << error; @@ -772,8 +690,8 @@ void MainWindow::selectSDfile(QString file) ui->sendBtn->setText("Start"); sdBytes = bytes.toDouble(); - userCommands.clear(); - injectCommand("M23 " + filename); + emit flushInjectionBuffer(); + emit injectCommand("M23 " + filename); sdprinting = true; ui->fileBox->setDisabled(false); } @@ -793,7 +711,7 @@ void MainWindow::updateSDStatus(SDProgress p) void MainWindow::checkSDStatus() { if(sdprinting && chekingSDStatus && sinceLastSDStatus.elapsed() > progressSDTimer.interval()) - injectCommand("M27"); + emit injectCommand("M27"); } void MainWindow::on_stepspin_valueChanged(const QString &arg1) @@ -818,16 +736,16 @@ void MainWindow::on_actionSet_SD_printing_mode_triggered() void MainWindow::requestEEPROMSettings() { - userCommands.clear(); + emit flushInjectionBuffer(); EEPROMSettings.clear(); switch(firmware) { case Marlin: - injectCommand("M503"); + emit injectCommand("M503"); break; case Repetier: - injectCommand("M205"); + emit injectCommand("M205"); break; case OtherFirmware: return; @@ -853,22 +771,22 @@ void MainWindow::openEEPROMeditor() void MainWindow::sendEEPROMsettings(QStringList changes) { - userCommands.clear(); + emit flushInjectionBuffer(); foreach (QString str, changes) { - injectCommand(str); + emit injectCommand(str); } } void MainWindow::recievedOkNum(int num) { - readyRecieve++; + readyRecieve=true; lastRecieved = num; } void MainWindow::recievedWait() { - readyRecieve = 1; + readyRecieve = true; } void MainWindow::EEPROMSettingRecieved(QString esetting) @@ -892,10 +810,38 @@ void MainWindow::recievedSDDone() void MainWindow::recievedResend(int num) { - if(!sendingChecksum) currentLine--; + if(!sendingChecksum) emit injectCommand("M110 N0"); else resendLineNum = num; } +void MainWindow::recievedStart() +{ + readyRecieve = true; +} + +void MainWindow::updateFileProgress(FileProgress p) +{ + if(p.P >= p.T) + { + ui->sendBtn->setText("Send"); + ui->pauseBtn->setDisabled(true); + sending = false; + paused = false; + emit pause(paused); + } + else + { + ui->sendBtn->setText("Stop"); + ui->pauseBtn->setEnabled(true); + sending = true; + } + ui->filelines->setText(QString::number(p.P) + + QString("/") + + QString::number(p.T) + + QString(" Lines")); + ui->progressBar->setValue(((float)p.P/p.T) * 100); +} + bool MainWindow::eventFilter(QObject *obj, QEvent *event) { if(obj == ui->sendtext && !userHistory.isEmpty()) diff --git a/mainwindow.h b/mainwindow.h index ea21ac5..83c8f64 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -21,6 +21,7 @@ #include "repraptor.h" #include "eepromwindow.h" #include "parser.h" +#include "sender.h" using namespace RepRaptor; @@ -36,14 +37,15 @@ public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); - Parser *parser; + Parser *parserWorker; + Sender *senderWorker; QThread *parserThread; + QThread *senderThread; protected: QFile gfile; QVector gcode; QQueue userCommands; - QTimer sendTimer; QTimer progressSDTimer; QTimer statusTimer; QElapsedTimer sinceLastTemp; @@ -59,10 +61,11 @@ protected: private: Ui::MainWindow *ui; - QSerialPort printer; QSerialPortInfo printerinfo; + bool opened; bool firstrun; bool autolock; + bool printing; bool sending; bool paused; bool checkingTemperature; @@ -74,7 +77,7 @@ private: int firmware; long int currentLine; unsigned long int lastRecieved; - int readyRecieve; + bool readyRecieve; unsigned long int totalLineNum; long int resendLineNum; int userHistoryPos; @@ -84,14 +87,11 @@ private slots: void open(); void serialconnect(); void serialupdate(); - bool sendLine(QString line); - void readSerial(); + void readSerial(QByteArray data); void printMsg(QString text); void printMsg(const char* text); - void sendNext(); void checkStatus(); void updateRecent(); - void injectCommand(QString command); void initSDprinting(QStringList sdFiles); void selectSDfile(QString file); void checkSDStatus(); @@ -106,8 +106,10 @@ private slots: void recievedError(); void recievedSDDone(); void recievedResend(int num); + void recievedStart(); void parseFile(QString filename); void recentClicked(); + void updateFileProgress(FileProgress); void xplus(); void yplus(); @@ -158,6 +160,16 @@ signals: void eepromReady(); void recievedData(QByteArray); void startedReadingEEPROM(); + + void openPort(QSerialPortInfo i); + void closePort(); + void startPrinting(); + void stopPrinting(); + void pause(bool p); + void setBaudrate(int b); + void setFile(QVector f); + void injectCommand(QString command); + void flushInjectionBuffer(); }; #endif // MAINWINDOW_H diff --git a/mainwindow.ui b/mainwindow.ui index dff62a8..20ede34 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -304,7 +304,7 @@ - 13 + 9 @@ -1117,7 +1117,7 @@ STOP 0 0 791 - 22 + 20 diff --git a/parser.cpp b/parser.cpp index ff763bc..84718c4 100644 --- a/parser.cpp +++ b/parser.cpp @@ -65,7 +65,7 @@ void Parser::parse(QByteArray data) else emit recievedOkNum(0); } */ - else if(data.startsWith("T:") || data.startsWith("ok T:")) + else if(data.contains("T:")) { TemperatureReadings r; @@ -81,8 +81,8 @@ void Parser::parse(QByteArray data) emit recievedTemperature(r); } //else if(data.startsWith("wait")) emit recievedOkWait(); - else if(data.startsWith("rs") || data.startsWith("Resend")) - emit recievedResend(data.split(' ').at(0).toInt()); + else if(data.startsWith("rs") || data.toLower().startsWith("resend")) + emit recievedResend(data.split(':').at(1).toInt()); else if(data.startsWith("!!")) emit recievedError(); else if(data.startsWith("Done")) emit recievedSDDone(); else if(data.startsWith("start")) emit recievedStart(); diff --git a/repraptor.h b/repraptor.h index 020ee28..807f401 100644 --- a/repraptor.h +++ b/repraptor.h @@ -28,6 +28,11 @@ namespace RepRaptor { unsigned long int progress, total; } SDProgress; + + typedef struct + { + unsigned int T, P; + } FileProgress; } #endif // REPRAPTOR_H diff --git a/sender.cpp b/sender.cpp new file mode 100644 index 0000000..0b9ff4e --- /dev/null +++ b/sender.cpp @@ -0,0 +1,205 @@ +#include "sender.h" + +Sender::Sender(QObject *parent) : QObject(parent) +{ + //Initial values + currentLine=0; + totalLineNum=0; + baudrate=115200; + sendingChecksum=false; + paused=false; + sending=false; + readyRecieve = false; + printer = new QSerialPort(this); + + //Fetch settings + QSettings settings; + sendTimer.setInterval(settings.value("core/senderinterval", 2).toInt()); + sendingChecksum = settings.value("core/checksums", 0).toBool(); + + sendTimer.start(); + + connect(printer, SIGNAL(error(QSerialPort::SerialPortError)), this, SLOT(recievedError(QSerialPort::SerialPortError))); + connect(printer, &QSerialPort::readyRead, this, &Sender::recievedData); + connect(&sendTimer, &QTimer::timeout, this, &Sender::sendNext); +} + +Sender::~Sender() +{ + closePort(); + sendTimer.stop(); +} + +//Mainloop of sending +void Sender::sendNext() +{ + if(printer->isWritable()) + { + if(!userCommands.isEmpty() && readyRecieve) //Inject user command + { + sendLine(userCommands.dequeue()); + readyRecieve = false; + return; + } + else if(sending && !paused && readyRecieve) //Send line of gcode + { + FileProgress p; + if(currentLine >= gcode.size()) //check if we are at the end of array + { + sending = false; + currentLine = 0; + if(sendingChecksum) sendLine("M110 N0"); + + p.P = gcode.size(); + p.T = gcode.size(); + emit reportProgress(p); + + return; + } + sendLine(gcode.at(currentLine)); + currentLine++; + readyRecieve=false; + + p.P = currentLine; + p.T = gcode.size(); + emit reportProgress(p); + } + } +} + +bool Sender::sendLine(QString line) +{ + if(printer->isOpen()) + { + if(sendingChecksum) + { + if(line.contains("M110")) totalLineNum = 0; + + //Checksum algorithm from RepRap wiki + line = "N"+QString::number(totalLineNum)+line+"*"; + int cs = 0; + for(int i = 0; line.at(i) != '*'; i++) cs = cs ^ line.at(i).toLatin1(); + cs &= 0xff; + line += QString::number(cs); + totalLineNum++; + } + if(printer->write(line.toUtf8()+'\n')) return true; + else return false; + } + else return false; +} + +void Sender::openPort(QSerialPortInfo i) +{ + printer->setPort(i); + + if(!printer->isOpen() && printer->open(QIODevice::ReadWrite)) + { + + //Moved here to be compatible with Qt 5.2.1 + switch(baudrate) + { + case 4800: + printer->setBaudRate(QSerialPort::Baud4800); + break; + + case 9600: + printer->setBaudRate(QSerialPort::Baud9600); + break; + + case 115200: + printer->setBaudRate(QSerialPort::Baud115200); + break; + + default: + printer->setBaudRate(baudrate); + break; + } + + printer->setFlowControl(QSerialPort::HardwareControl); + } +} + +void Sender::closePort() +{ + if(printer->isOpen()) printer->close(); +} + +void Sender::startPrinting() +{ + currentLine = 0; + paused = false; + sending = true; +} + +void Sender::stopPrinting() +{ + currentLine = 0; + paused = false; + sending = false; +} + +void Sender::pause(bool p) +{ + paused = p; +} + +void Sender::setBaudrate(int b) +{ + baudrate = b; +} + +void Sender::setFile(QVector f) +{ + gcode = f; +} + +void Sender::injectCommand(QString command) +{ + userCommands.enqueue(command); +} + +void Sender::recievedOkWait() +{ + readyRecieve = true; +} + +void Sender::recievedOkNum(int) +{ + readyRecieve = true; +} + +void Sender::recievedStart() +{ + readyRecieve = true; +} + +void Sender::flushInjectionBuffer() +{ + userCommands.clear(); +} + +void Sender::recievedResend(int) +{ + +} + +void Sender::recievedData() +{ + if(printer->canReadLine()) + { + QByteArray data = printer->readLine(); + if(data == "") return; + emit dataRecieved(data); + if(data.startsWith("ok") || data.startsWith("wa")) readyRecieve=true; + } +} + +void Sender::recievedError(QSerialPort::SerialPortError error) +{ + if(error > 0) + { + closePort(); + emit errorRecieved(error); + } +} diff --git a/sender.h b/sender.h new file mode 100644 index 0000000..9a1b5b6 --- /dev/null +++ b/sender.h @@ -0,0 +1,67 @@ +#ifndef SENDER_H +#define SENDER_H + +#include +#include +#include +#include +#include +#include +#include + +#include "repraptor.h" + +using namespace RepRaptor; + +class Sender : public QObject +{ + Q_OBJECT +public: + explicit Sender(QObject *parent = 0); + ~Sender(); + + QSerialPort *printer; + +protected: + int currentLine; + int totalLineNum; + int baudrate; + bool paused; + bool sending; + bool readyRecieve; + bool sendingChecksum; + QTimer sendTimer; + QQueue userCommands; + QStringList sentCommands; + QVector gcode; + + bool sendLine(QString s); + +signals: + void errorRecieved(QSerialPort::SerialPortError error); + void dataRecieved(QByteArray data); + void reportProgress(FileProgress p); + +public slots: + void openPort(QSerialPortInfo i); + void closePort(); + void startPrinting(); + void stopPrinting(); + void pause(bool p); + void setBaudrate(int b); + void setFile(QVector f); + void injectCommand(QString); + void flushInjectionBuffer(); + + void recievedOkWait(); + void recievedOkNum(int); + void recievedStart(); + void recievedResend(int); + + void sendNext(); + + void recievedData(); + void recievedError(QSerialPort::SerialPortError error); +}; + +#endif // SENDER_H