#include "groundstation.h" #include "ui_groundstation.h" #include "gscustomplot.h" #include "gsterminal.h" #include "gsplot.h" #include "gssettingsdialog.h" #include #include #include #include #include "gsplotlayout.h" //This needs to be broken down into seperate initializers. Constructor is WAY too big atm GroundStation::GroundStation(QWidget *parent) : QMainWindow(parent), ui(new Ui::GroundStation) { ui->setupUi(this); setMinimumSize(640, 480); statusLabel = new QLabel; setWindowTitle("Skywave Groundstation"); //widget containers gsMain = new QWidget(this); gsPlotHub = new QWidget(this); //change port name from default QList serialPorts = QSerialPortInfo::availablePorts(); QString newPortName = serialPorts.count() > 0 ? serialPorts.at(0).portName() : "COM1"; GSSettingsDialog::UpdatePortName(newPortName); //layouts for widgets gsMainLayout = new QVBoxLayout; gsPlotHubLayout = new GSPlotLayout; //terminal creation gsTerminal = new GSTerminal(this); //splitter so we can resize our terminal vertSplit = new QSplitter(Qt::Vertical); setCentralWidget(gsMain); gsMain->setLayout(gsMainLayout); gsMainLayout->addWidget(vertSplit); vertSplit->addWidget(gsPlotHub); vertSplit->addWidget(gsTerminal); //Make sure our graphs are not collapsible vertSplit->setCollapsible(0, false); vertSplit->setCollapsible(1, true); //add plots to layout gsPlotHub->setLayout(gsPlotHubLayout); QList sizes; sizes << gsPlotHub->size().height() << 50; vertSplit->setSizes(sizes); //qDebug() << GetNumberOfPlots(); gsPlotHubLayout->setMargin(0); gsTerminal->setEnabled(true); serial = new QSerialPort(this); connect(serial, SIGNAL(readyRead()), this, SLOT(readData())); ui->statusBar->addWidget(statusLabel); seconds = 0; InitActions(); } GroundStation::~GroundStation() { delete ui; if(serial->isOpen()) { serial->close(); } gsPlotBank.clear(); } int GroundStation::GetNumberOfPlots() const { return GSCustomPlot::GetNumberOfPlots(); } void GroundStation::ConnectDevice() { const Settings &iSettings = GSSettingsDialog::GetSettings(); serial->setBaudRate(iSettings.baudRate); serial->setParity(iSettings.parity); serial->setDataBits(iSettings.dataBits); serial->setFlowControl(iSettings.flowControl); serial->setStopBits(iSettings.stopBits); serial->setPortName(iSettings.name); if(serial->open(QIODevice::ReadOnly)) { //I've found that some MCUs need to have "setDataTerminalReady" to true. //From the SAMD21 user guide/documentation thing: // The virtual COM port in the EDBG requires the terminal software to set the data terminal // ready (DTR) signal to enable the UART pins connected to the ATSAMD21J18A. If the DTR // signal is not enabled the UART pins on the EDBG is kept in high-z (tristate) rendering the COM // port unusable. The DTR signal is set automatically by some terminal software, but it may have // to be manually enabled in your terminal. if(!serial->isDataTerminalReady()) { serial->setDataTerminalReady(true); } ui->actionConnect->setEnabled(false); ui->actionDisconnect->setEnabled(true); ui->actionConfigure->setEnabled(false); gsStatus = Connected; statusLabel->setText(tr("Status: Connected to %1. Baud: %2").arg(iSettings.name).arg(iSettings.baudRate)); } else { QMessageBox::critical(this, tr("Error opening device"), serial->errorString()); //showStatusMessage(tr("Error")); serial->close(); } } void GroundStation::DisconnectDevice() { if(serial->isOpen()) { serial->close(); } ui->actionConnect->setEnabled(true); ui->actionDisconnect->setEnabled(false); ui->actionConfigure->setEnabled(true); } void GroundStation::UpdateAllPlots(const QList &data) { for(int x = 0; x < data.count(); x++) { if(x < gsPlotBank.count()) { gsPlotBank[x]->GetPlot().UpdatePlot( seconds, data.at(x)); } } seconds++; } void GroundStation::readData() { //this is the old method of streaming data. I ditched it because it would occasionally drop pieces of numbers and thats NO GOOD // QTextStream stream(serial); // serialBuffer += stream.read(1); // if(serialBuffer.endsWith("\n")) // { // QStringList serialList = serialBuffer.split(",", QString::SkipEmptyParts); // qDebug() << serialList; // serialBuffer.clear(); // } //this is the new old method of streaming data. It's essentially the same thing as the current code but with more code. //keeping these notes here for future reference // serialData = serial->read(serial->bytesAvailable()); // serialBuffer += serialData; // if(serialBuffer.endsWith("\n")) // { // qDebug() << serial->bytesAvailable(); // QStringList serialList = serialBuffer.split(",", QString::SkipEmptyParts); // gsTerminal->putData(serialBuffer.toLocal8Bit()); // qDebug() << serialList; // serialBuffer.clear(); // } //current method of reading in data from our MCU if(serial->canReadLine()) { serialData = serial->readLine(); gsTerminal->putData(serialData); //convert serial data to a string. Use trimmed() to cut the \n character QString translatedData = QString(serialData).trimmed(); //Create a string list we can use to convert to graphable values QStringList translatedDataList = translatedData.split(",", QString::SkipEmptyParts); //int list to store values QList graphValues; for(int x = 0; x < translatedDataList.count(); x++) { if(QString(translatedDataList.at(x)).contains(".")) { graphValues << qRound(QString(translatedDataList.at(x)).toFloat()); } else { graphValues << QString(translatedDataList.at(x)).toInt(); } } //Update graphs UpdateAllPlots(graphValues); } } void GroundStation::OpenSettings() { settingsWindow = new GSSettingsDialog(this); settingsWindow->show(); } void GroundStation::InitActions() { connect(ui->actionConnect, SIGNAL(triggered()), this, SLOT(ConnectDevice())); connect(ui->actionDisconnect, SIGNAL(triggered()), this, SLOT(DisconnectDevice())); connect(ui->actionConfigure, SIGNAL(triggered()), this, SLOT(OpenSettings())); ui->actionDisconnect->setEnabled(false); } void GroundStation::CreateNewPlot(QString Name, QString xAxisLabel, QString yAxisLabel) { gsPlotBank.push_back(new GSCustomPlot(Name, this)); gsPlotBank.last()->GetPlot().xAxis->setLabel(xAxisLabel); gsPlotBank.last()->GetPlot().yAxis->setLabel(yAxisLabel); gsPlotHubLayout->addWidget(gsPlotBank.last()); QList sizes; sizes << gsPlotHub->size().height() << 50; vertSplit->setSizes(sizes); } void GroundStation::CreateNewPlot(QString Name) { gsPlotBank.push_back(new GSCustomPlot(Name, this)); gsPlotHubLayout->addWidget(gsPlotBank.last()); QList sizes; sizes << gsPlotHub->size().height() << 50; vertSplit->setSizes(sizes); } QPointer GroundStation::gsPlotHubLayout;