Subversion Repositories Code-Repo

Compare Revisions

Ignore whitespace Rev 350 → Rev 351

/Misc Projects/PcMarlinInterface/SerialController.cpp
1,140 → 1,227
#include "SerialController.h"
 
SerialController::SerialController(QObject *parent) : QObject(parent)
SerialController::SerialController(QWidget *parent) : QWidget(parent)
{
connected = false;
speeds << "9600" << "19200" << "38400" << "57600" << "115200" << "230400" << "250000";
dataBits << "8 Bits" << "7 Bits" << "6 Bits" << "5 Bits";
stopBits << "1 Bit" << "1.5 Bits" << "2 Bits";
parity << "None" << "Even" << "Odd" << "Space" << "Mark";
flowControl << "None" << "Hardware" << "Software";
bufferInIndex = 0;
bufferInOverflow = false;
// Serial connection UI
btnSerialConnect = new QPushButton("&Connect");
btnSerialRefresh = new QPushButton("&Refresh");
labelSerialPort = new QLabel("Serial Port:");
labelSerialSpeed = new QLabel("Baud Rate:");
labelSerialDataBits = new QLabel("Data:");
labelSerialStopBits = new QLabel("Stop:");
labelSerialParity = new QLabel("Parity Bit:");
labelSerialFlowControl = new QLabel("Flow Control:");
cboxSerialPort = new QComboBox();
cboxSerialPort->setMinimumWidth(80);
cboxSerialSpeed = new QComboBox();
cboxSerialSpeed->setEditable(true);
cboxSerialSpeed->setValidator(new QIntValidator(0, 100000000, this));
cboxSerialDataBits = new QComboBox();
cboxSerialDataBits->setMaximumWidth(60);
cboxSerialStopBits = new QComboBox();
cboxSerialStopBits->setMaximumWidth(60);
cboxSerialParity = new QComboBox();
cboxSerialFlowControl = new QComboBox();
cboxSerialFlowControl->setMinimumWidth(70);
 
QGridLayout *serialSettingsLayout = new QGridLayout();
serialSettingsLayout->addWidget(btnSerialConnect, 0, 0);
serialSettingsLayout->addWidget(labelSerialPort, 0, 1);
serialSettingsLayout->addWidget(cboxSerialPort, 0, 2);
serialSettingsLayout->addWidget(labelSerialDataBits, 0, 3);
serialSettingsLayout->addWidget(cboxSerialDataBits, 0, 4);
serialSettingsLayout->addWidget(labelSerialParity, 0, 5);
serialSettingsLayout->addWidget(cboxSerialParity, 0, 6);
 
serialSettingsLayout->addWidget(btnSerialRefresh, 1, 0);
serialSettingsLayout->addWidget(labelSerialSpeed, 1, 1);
serialSettingsLayout->addWidget(cboxSerialSpeed, 1, 2);
serialSettingsLayout->addWidget(labelSerialStopBits, 1, 3);
serialSettingsLayout->addWidget(cboxSerialStopBits, 1, 4);
serialSettingsLayout->addWidget(labelSerialFlowControl, 1, 5);
serialSettingsLayout->addWidget(cboxSerialFlowControl, 1, 6);
 
setLayout(serialSettingsLayout);
 
serialHelper = new SerialHelper();
serialThread = new QThread();
serialHelper->moveToThread(serialThread);
 
connect(serialHelper, SIGNAL(UpdateStatus(QString)), this, SIGNAL(UpdateStatus(QString)));
 
// Parameters
connect(this, SIGNAL(Serial_QueryParameters()), serialHelper, SLOT(Serial_QueryParameters()));
connect(serialHelper, SIGNAL(Serial_UpdateParameters(QStringList,QStringList,QStringList,QStringList,QStringList,QStringList)),
this, SLOT(Serial_UpdateParameters(QStringList,QStringList,QStringList,QStringList,QStringList,QStringList)));
 
// Connect
connect(this, SIGNAL(Serial_Connect(QString,QString,QString,QString,QString,QString)),
serialHelper, SLOT(Serial_Connect(QString,QString,QString,QString,QString,QString)));
connect(serialHelper, SIGNAL(Serial_Connected()), this, SIGNAL(Serial_Connected()));
connect(serialHelper, SIGNAL(Serial_Connected()), this, SLOT(Serial_LocalConnected()));
 
// Disconnect
connect(this, SIGNAL(Serial_Disconnect()), serialHelper, SLOT(Serial_Disconnect()));
connect(serialHelper, SIGNAL(Serial_Disconnected()), this, SIGNAL(Serial_Disconnected()));
connect(serialHelper, SIGNAL(Serial_Disconnected()), this, SLOT(Serial_LocalDisconnected()));
 
// Transmit
connect(this, SIGNAL(Serial_TransmitString(QString)), serialHelper, SLOT(Serial_TransmitString(QString)));
connect(this, SIGNAL(Serial_TransmitByteArray(QByteArray)), serialHelper, SLOT(Serial_TransmitByteArray(QByteArray)));
 
// Receive
connect(serialHelper, SIGNAL(Serial_ReceivedByte(char)), this, SIGNAL(Serial_ReceivedByte(char)));
 
// Threading
connect(serialThread, SIGNAL(finished()), serialHelper, SLOT(deleteLater()));
serialThread->start();
 
// Local GUI
connect(btnSerialConnect, SIGNAL(clicked()), this, SLOT(Serial_ConnectToggleBtn()));
connect(btnSerialRefresh, SIGNAL(clicked()), this, SIGNAL(Serial_QueryParameters()));
 
emit Serial_QueryParameters();
Serial_LocalDisconnected();
}
 
SerialController::~SerialController()
{
serialPort->close();
delete serialPort;
serialThread->quit();
}
 
void SerialController::Serial_QueryParameters()
void SerialController::Serial_UpdateParameters(QStringList ports, QStringList speeds, QStringList dataBits,
QStringList stopBits, QStringList parity, QStringList flowControl)
{
QList<QSerialPortInfo> portsList = QSerialPortInfo::availablePorts();
QStringList ports;
for (int i = 0; i < portsList.size(); i++) {
ports.append(portsList[i].portName());
}
emit Serial_UpdateParameters(ports, speeds, dataBits, stopBits, parity, flowControl);
}
QString currPort = cboxSerialPort->currentText();
cboxSerialPort->clear();
cboxSerialPort->addItems(ports);
if (currPort != "" && ports.contains(currPort))
cboxSerialPort->setCurrentText(currPort);
 
void SerialController::Serial_Connect(QString port, QString speed, QString dataBits,
QString stopBits, QString parity, QString flowControl)
{
if (!connected) {
serialPort = new QSerialPort();
connect(serialPort, SIGNAL(readyRead()), this, SLOT(Serial_ProcessIncomingData()));
serialPort->setPortName(port);
if (!serialPort->open(QIODevice::ReadWrite)) {
Serial_Disconnect();
} else {
connected = true;
bool ok = false;
QString currSpeed = cboxSerialSpeed->currentText();
cboxSerialSpeed->clear();
cboxSerialSpeed->addItems(speeds);
if (currSpeed != "") cboxSerialSpeed->setCurrentText(currSpeed);
 
int baud = speed.toInt(&ok);
if (ok) serialPort->setBaudRate(baud);
int currData = cboxSerialDataBits->currentIndex();
cboxSerialDataBits->clear();
cboxSerialDataBits->addItems(dataBits);
if (currData >= 0) cboxSerialDataBits->setCurrentIndex(currData);
 
if (dataBits == "5 Bits")
serialPort->setDataBits(QSerialPort::Data5);
else if (dataBits == "6 Bits")
serialPort->setDataBits(QSerialPort::Data6);
else if (dataBits == "7 Bits")
serialPort->setDataBits(QSerialPort::Data7);
else
serialPort->setDataBits(QSerialPort::Data8);
int currStop = cboxSerialStopBits->currentIndex();
cboxSerialStopBits->clear();
cboxSerialStopBits->addItems(stopBits);
if (currStop >= 0) cboxSerialStopBits->setCurrentIndex(currStop);
 
if (stopBits == "1.5 Bits")
serialPort->setStopBits(QSerialPort::OneAndHalfStop);
else if (stopBits == "2 Bits")
serialPort->setStopBits(QSerialPort::TwoStop);
else
serialPort->setStopBits(QSerialPort::OneStop);
int currParity = cboxSerialParity->currentIndex();
cboxSerialParity->clear();
cboxSerialParity->addItems(parity);
if (currParity >= 0) cboxSerialParity->setCurrentIndex(currParity);
 
if (parity == "Even")
serialPort->setParity(QSerialPort::EvenParity);
else if (parity == "Odd")
serialPort->setParity(QSerialPort::OddParity);
else if (parity == "Space")
serialPort->setParity(QSerialPort::SpaceParity);
else if (parity == "Mark")
serialPort->setParity(QSerialPort::MarkParity);
else
serialPort->setParity(QSerialPort::NoParity);
 
if (flowControl == "Hardware")
serialPort->setFlowControl(QSerialPort::HardwareControl);
else if (flowControl == "Software")
serialPort->setFlowControl(QSerialPort::SoftwareControl);
else
serialPort->setFlowControl(QSerialPort::NoFlowControl);
 
// See http://umforum.ultimaker.com/index.php?/topic/5886-um2-controller-resetreboot-when-opening-usb-port-on-linux/
serialPort->setDataTerminalReady(1);
 
if (ok) emit Serial_Connected();
else Serial_Disconnect();
}
}
int currFlow = cboxSerialFlowControl->currentIndex();
cboxSerialFlowControl->clear();
cboxSerialFlowControl->addItems(flowControl);
if (currFlow >= 0) cboxSerialFlowControl->setCurrentIndex(currFlow);
}
 
void SerialController::Serial_Disconnect()
void SerialController::Serial_LocalConnected()
{
serialPort->close();
delete serialPort;
connected = false;
emit Serial_Disconnected();
btnSerialConnect->setText("&Disconnect");
// cboxSerialPort->setEnabled(false);
// cboxSerialSpeed->setEnabled(false);
// cboxSerialDataBits->setEnabled(false);
// cboxSerialStopBits->setEnabled(false);
// cboxSerialParity->setEnabled(false);
// cboxSerialFlowControl->setEnabled(false);
// btnSerialRefresh->setEnabled(false);
btnSerialRefresh->hide();
labelSerialPort->hide();
labelSerialSpeed->hide();
labelSerialDataBits->hide();
labelSerialStopBits->hide();
labelSerialParity->hide();
labelSerialFlowControl->hide();
cboxSerialPort->hide();
cboxSerialSpeed->hide();
cboxSerialDataBits->hide();
cboxSerialStopBits->hide();
cboxSerialParity->hide();
cboxSerialFlowControl->hide();
emit UpdateStatus("Serial: Connected");
}
 
void SerialController::Serial_TransmitString(QString string)
void SerialController::Serial_LocalDisconnected()
{
serialPort->write(string.toStdString().c_str());
serialPort->write(SERIAL_NEWLINE_CHAR);
btnSerialConnect->setText("&Connect");
// cboxSerialPort->setEnabled(true);
// cboxSerialSpeed->setEnabled(true);
// cboxSerialDataBits->setEnabled(true);
// cboxSerialStopBits->setEnabled(true);
// cboxSerialParity->setEnabled(true);
// cboxSerialFlowControl->setEnabled(true);
// btnSerialRefresh->setEnabled(true);
btnSerialRefresh->show();
labelSerialPort->show();
labelSerialSpeed->show();
labelSerialDataBits->show();
labelSerialStopBits->show();
labelSerialParity->show();
labelSerialFlowControl->show();
cboxSerialPort->show();
cboxSerialSpeed->show();
cboxSerialDataBits->show();
cboxSerialStopBits->show();
cboxSerialParity->show();
cboxSerialFlowControl->show();
emit UpdateStatus("Serial: Disconnected");
}
 
void SerialController::Serial_ProcessIncomingData()
void SerialController::Serial_ConnectToggleBtn()
{
char tmpBuffer[SERIAL_BUFFER_SIZE];
int len = serialPort->read(tmpBuffer, sizeof(tmpBuffer));
while (len > 0) {
for (int i = 0; i < len; i++) {
// Save received data into local buffer
bufferIn[bufferInIndex] = tmpBuffer[i];
 
// If newline char is received, end current string
if (tmpBuffer[i] == '\n') {
if (bufferInOverflow)
currString.append(QString::fromLocal8Bit(bufferIn, bufferInIndex));
else
currString = QString::fromLocal8Bit(bufferIn, bufferInIndex);
bufferInOverflow = false;
bufferInIndex = 0;
emit Serial_ReceivedString(currString);
} else {
bufferInIndex++;
}
 
// If received string is larger than our serial buffer, append to previous data
if (bufferInIndex == SERIAL_BUFFER_SIZE-1) {
bufferIn[SERIAL_BUFFER_SIZE-1] = 0x0;
if (bufferInOverflow)
currString.append(QString::fromLocal8Bit(bufferIn, bufferInIndex));
else
currString = QString::fromLocal8Bit(bufferIn, bufferInIndex);
bufferInOverflow = true;
bufferInIndex = 0;
}
if (serialHelper->connected) {
emit Serial_Disconnect();
} else {
if (cboxSerialPort->currentText() != "" && cboxSerialSpeed->currentText() != "") {
emit Serial_Connect(cboxSerialPort->currentText(), cboxSerialSpeed->currentText(), cboxSerialDataBits->currentText(),
cboxSerialStopBits->currentText(), cboxSerialParity->currentText(), cboxSerialFlowControl->currentText());
}
// Check if there is more data to be read from the serial port
len = serialPort->read(tmpBuffer, sizeof(tmpBuffer));
}
}
 
//void SerialController::Serial_ProcessIncomingData()
//{
// char tmpBuffer[SERIAL_BUFFER_SIZE];
// int len = serialPort->read(tmpBuffer, sizeof(tmpBuffer));
// while (len > 0) {
// for (int i = 0; i < len; i++) {
// // Save received data into local buffer
// bufferIn[bufferInIndex] = tmpBuffer[i];
 
// // If newline char is received, end current string
// if (tmpBuffer[i] == '\n') {
// if (bufferInOverflow)
// currString.append(QString::fromLocal8Bit(bufferIn, bufferInIndex));
// else
// currString = QString::fromLocal8Bit(bufferIn, bufferInIndex);
// bufferInOverflow = false;
// bufferInIndex = 0;
// emit Serial_ReceivedString(currString);
// } else {
// bufferInIndex++;
// }
 
// // If received string is larger than our serial buffer, append to previous data
// if (bufferInIndex == SERIAL_BUFFER_SIZE-1) {
// bufferIn[SERIAL_BUFFER_SIZE-1] = 0x0;
// if (bufferInOverflow)
// currString.append(QString::fromLocal8Bit(bufferIn, bufferInIndex));
// else
// currString = QString::fromLocal8Bit(bufferIn, bufferInIndex);
// bufferInOverflow = true;
// bufferInIndex = 0;
// }
// }
// // Check if there is more data to be read from the serial port
// len = serialPort->read(tmpBuffer, sizeof(tmpBuffer));
// }
//}