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.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

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;