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..bb032f0 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -66,7 +66,7 @@ MainWindow::MainWindow(QWidget *parent) : sdprinting = false; sdBytes = 0; currentLine = 0; - readyRecieve = 1; + readyRecieve = false; lastRecieved = 0; userHistoryPos = 0; totalLineNum = 0; @@ -77,8 +77,8 @@ 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(&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())); @@ -87,24 +87,38 @@ MainWindow::MainWindow(QWidget *parent) : //Parser thread signal-slots and init qRegisterMetaType("TemperatureReadings"); qRegisterMetaType("SDProgress"); - parser = new Parser(); + parserWorker = 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->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::recievedOkNum, this, &MainWindow::recievedOkNum); + //connect(parserWorker, &Parser::recievedOkWait, this, &MainWindow::recievedWait); + 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(parser, &Parser::recievedResend, this, &MainWindow::recievedResend); + connect(parserWorker, &Parser::recievedSDUpdate, this, &MainWindow::updateSDStatus); + //connect(parser, &Parser::recievedStart, this, &MainWindow::recievedStart); parserThread->start(); + //Sender thread signal-slots and init + senderWorker = new Sender(); + senderThread = new QThread(); + 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); + senderThread->start(); + //Timers init statusTimer.start(); sendTimer.start(); @@ -138,6 +152,8 @@ MainWindow::~MainWindow() if(printer.isOpen()) printer.close(); parserThread->quit(); parserThread->wait(); + senderThread->quit(); + senderThread->wait(); delete ui; } @@ -176,6 +192,7 @@ void MainWindow::parseFile(QString filename) if(!line.startsWith(";")) gcode.append(line); } gfile.close(); + emit setFile(gcode); ui->fileBox->setEnabled(true); ui->progressBar->setEnabled(true); ui->sendBtn->setText("Send"); @@ -207,7 +224,6 @@ bool MainWindow::sendLine(QString line) } else return false; } - else return false; } @@ -235,8 +251,12 @@ void MainWindow::serialconnect() } } - printer.setPort(printerinfo); + emit setBaudrate(ui->baudbox->currentText().toInt()); + emit openPort(printerinfo); + } + //printer.setPort(printerinfo); + /* if(printer.open(QIODevice::ReadWrite)) { @@ -290,6 +310,7 @@ void MainWindow::serialconnect() ui->statusGroup->setDisabled(true); ui->actionEEPROM_editor->setDisabled(false); } + */ } ///////////////// @@ -476,6 +497,7 @@ void MainWindow::on_actionPrint_from_SD_triggered() void MainWindow::on_sendBtn_clicked() { + /* userCommands.clear(); if(sending && !sdprinting) { @@ -509,6 +531,8 @@ void MainWindow::on_sendBtn_clicked() ui->progressBar->setValue(0); currentLine = 0; + */ + emit startPrinting(); } void MainWindow::on_pauseBtn_clicked() @@ -547,8 +571,7 @@ void MainWindow::readSerial() emit recievedData(data); //Send data to parser thread - if(data.startsWith("ok")) readyRecieve++; - else if(data.startsWith("wa")) readyRecieve=1; + if(data.startsWith("ok") || data.startsWith("wa")) readyRecieve = true; printMsg(QString(data)); //echo } @@ -575,8 +598,6 @@ void MainWindow::printMsg(QString text) ui->terminal->setTextCursor(cursor); } - - void MainWindow::sendNext() { if(printer.isWritable()) @@ -589,13 +610,13 @@ void MainWindow::sendNext() return; } - if(!userCommands.isEmpty() && readyRecieve > 0) //Inject user command + if(!userCommands.isEmpty() && readyRecieve) //Inject user command { sendLine(userCommands.dequeue()); - readyRecieve--; + readyRecieve = false; return; } - else if(sending && !paused && readyRecieve > 0 && !sdprinting) //Send line of gcode + else if(sending && !paused && readyRecieve && !sdprinting) //Send line of gcode { if(currentLine >= gcode.size()) //check if we are at the end of array { @@ -612,7 +633,7 @@ void MainWindow::sendNext() } sendLine(gcode.at(currentLine)); currentLine++; - readyRecieve--; + readyRecieve=false; ui->filelines->setText(QString::number(gcode.size()) + QString("/") @@ -862,13 +883,13 @@ void MainWindow::sendEEPROMsettings(QStringList changes) void MainWindow::recievedOkNum(int num) { - readyRecieve++; + readyRecieve=true; lastRecieved = num; } void MainWindow::recievedWait() { - readyRecieve = 1; + readyRecieve = true; } void MainWindow::EEPROMSettingRecieved(QString esetting) @@ -892,10 +913,15 @@ void MainWindow::recievedSDDone() void MainWindow::recievedResend(int num) { - if(!sendingChecksum) currentLine--; + if(!sendingChecksum) injectCommand("M110 N0"); else resendLineNum = num; } +void MainWindow::recievedStart() +{ + readyRecieve = true; +} + bool MainWindow::eventFilter(QObject *obj, QEvent *event) { if(obj == ui->sendtext && !userHistory.isEmpty()) diff --git a/mainwindow.h b/mainwindow.h index ea21ac5..7622a8e 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,8 +37,10 @@ public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); - Parser *parser; + Parser *parserWorker; + Sender *senderWorker; QThread *parserThread; + QThread *senderThread; protected: QFile gfile; @@ -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; @@ -106,6 +109,7 @@ private slots: void recievedError(); void recievedSDDone(); void recievedResend(int num); + void recievedStart(); void parseFile(QString filename); void recentClicked(); @@ -158,6 +162,14 @@ 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); }; #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..e2e9478 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/sender.cpp b/sender.cpp new file mode 100644 index 0000000..a4ccc03 --- /dev/null +++ b/sender.cpp @@ -0,0 +1,191 @@ +#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(); + + 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 + { + if(currentLine >= gcode.size()) //check if we are at the end of array + { + sending = false; + currentLine = 0; + if(sendingChecksum) sendLine("M110 N0"); + + return; + } + sendLine(gcode.at(currentLine)); + currentLine++; + readyRecieve=false; + } + } +} + +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->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); + + sendTimer.start(); + } +} + +void Sender::closePort() +{ + if(printer->isOpen()) printer->close(); + sendTimer.stop(); +} + +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::recievedResend(int) +{ + +} + +void Sender::recievedData() +{ + if(printer->canReadLine()) + { + QByteArray data = printer->readLine(); + 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..8c12fd1 --- /dev/null +++ b/sender.h @@ -0,0 +1,66 @@ +#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 reportPeogress(SDProgress 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 recievedOkWait(); + void recievedOkNum(int); + void recievedStart(); + void recievedResend(int); + + void sendNext(); + + void recievedData(); + void recievedError(QSerialPort::SerialPortError error); +}; + +#endif // SENDER_H