RepRaptor/sender.cpp

237 lines
5.2 KiB
C++

#include "sender.h"
Sender::Sender(QObject *parent) : QObject(parent)
{
//Initial values
currentLine=0;
totalLineNum=0;
baudrate=115200;
resendNum = 0;
resending = false;
sendingChecksum=false;
paused=false;
sending=false;
readyRecieve = false;
printer = new QSerialPort(this);
sendTimer = new QTimer(this);
//Fetch settings
QSettings settings;
sendTimer->setInterval(settings.value("core/senderinterval", 2).toFloat());
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() && readyRecieve)
{
if(sendingChecksum && resending)
{
if(resendNum < sentCommands.size())
{
sendLine(sentCommands.at(resendNum));
resendNum++;
}
else if(resendNum == sentCommands.size())
{
resending = false;
resendNum = 0;
}
else if(resendNum > sentCommands.size())
{
sendLine("M110 N0");
totalLineNum = 0;
resendNum = 0;
sentCommands.clear();
}
return;
}
if(!userCommands.isEmpty()) //Inject user command
{
sendLine(userCommands.dequeue());
readyRecieve = false;
return;
}
else if(sending && !paused) //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)
{
sentCommands.clear();
if(printer->isOpen())
{
if(sendingChecksum)
{
if(line.contains("M110")) totalLineNum = 0;
sentCommands.append(line);
//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 <QString> f)
{
gcode = f;
}
void Sender::injectCommand(QString command)
{
if(!userCommands.contains(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 r)
{
if(sendingChecksum)
{
resending = true;
resendNum = r;
}
else currentLine--;
}
void Sender::recievedData()
{
if(printer->canReadLine())
{
QByteArray data = printer->readLine();
if(data == "") return;
emit dataRecieved(data);
//Yeah, yeah, I know. This class is called "Sender", but checking this here is faster.
if(data.startsWith("ok") || data.startsWith("wa")) readyRecieve=true;
}
}
void Sender::recievedError(QSerialPort::SerialPortError error)
{
if(error > 0)
{
closePort();
emit errorRecieved(error);
}
}