You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
251 lines
7.6 KiB
C++
251 lines
7.6 KiB
C++
#include "groundstation.h"
|
|
#include "ui_groundstation.h"
|
|
#include "gscustomplot.h"
|
|
#include "gsterminal.h"
|
|
#include "gsplot.h"
|
|
#include "gssettingsdialog.h"
|
|
#include <QTextStream>
|
|
#include <QStringList>
|
|
#include <QByteArray>
|
|
#include <QThread>
|
|
#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<QSerialPortInfo> 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<int> 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<int> &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<int> 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<int> 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<int> sizes;
|
|
sizes << gsPlotHub->size().height() << 50;
|
|
vertSplit->setSizes(sizes);
|
|
|
|
|
|
|
|
}
|
|
|
|
QPointer<GSPlotLayout> GroundStation::gsPlotHubLayout;
|