migrating and archiving

stable
Penguin 2 years ago
commit 0d9a6ed5b9

Binary file not shown.

@ -0,0 +1 @@
# skywave

@ -0,0 +1,38 @@
~~PREFACE
If you're going to run the demo, simply download the .rar, unzip and run the exe. Read the instructions on how to use the demo below.
If you're going to want to edit the code to add more graphs and rename things, you'll need to install Qt. After you install Qt, download the project files from here:
https://github.com/adragott/skywave (Ignore the README on github)
NOTE: I highly recommend just using the demo if you don't have Qt already installed and aren't proficient with C++. Qt takes a super long time to install and can randomly cut out during the install, making you hate life.
Once you've extracted and saved the folder to where ever you want, open the .pro file and pick your compiler kit. Hit configure project and you're done. You'll have to figure things out for the Qt instructions because theres too much to explain here without a full tutorial. All you really need to know is (inside of your main.cpp) :
groundStation.CreateNewPlot("PlotNameHere"); //this creates a new plot
//this creates a plot with x and y axis titles
groundStation.CreateNewPlot("PlotNameHere", "XValueTitleHere", "YValueTitleHere");
Make sure these are called after the declaration and initialization of groundStation and before groundStation.show();
~~DEMO INSTRUCTIONS:
The demo works by taking in whatever serial data you're sending from your MCU and automatically graphing it, regardless of how many values you send it. The demo only has 4 graphs, so I'd recommend sending 4 values. You can send more or less and nothing will break, though.
From Atmel, program your MCU to send a printf statement in the following format:
printf("%d,%d,%d,%d\n", val1, val2, val3, val4);
Simply separate each value with a comma and end the string with a '\n' character.
Note that the order of values sent will be the same as the order of values graphed. So val1 will be first graphed, val2 second, and so on.
If the groundstation doesn't connect and throws you an error saying something like "Device not found" go into the settings and change your comport to the one your MCU is using. If it's not there, your MCU isn't plugged in correctly.
If the groundstation does connect but it doesn't log or graph any values, it's likely due to the baudrate being wrong. Change it in the settings.
NOTE: log.csv files will be produced in the folder containing the .exe.

@ -0,0 +1,48 @@
#-------------------------------------------------
#
# Project created by QtCreator 2017-11-13T22:21:11
#
#-------------------------------------------------
QT += core gui serialport printsupport
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = SkywaveGroundStation
TEMPLATE = app
# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
groundstation.cpp \
qcustomplot.cpp \
gscustomplot.cpp \
gsplot.cpp \
gsterminal.cpp \
gssettingsdialog.cpp \
gsplotlayout.cpp
HEADERS += \
groundstation.h \
qcustomplot.h \
gscustomplot.h \
gsplot.h \
gsterminal.h \
gssettingsdialog.h \
gs_headers.h \
gsplotlayout.h
FORMS += \
groundstation.ui \
gssettingsdialog.ui

@ -0,0 +1,250 @@
#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;

@ -0,0 +1,70 @@
#ifndef GROUNDSTATION_H
#define GROUNDSTATION_H
#pragma once
#include <QMainWindow>
#include "gs_headers.h"
class GSCustomPlot;
class GSTerminal;
class GSSettingsDialog;
class GSPlotLayout;
namespace Ui {
class GroundStation;
}
enum Status
{
Disconnected,
Connected,
};
class GroundStation : public QMainWindow
{
Q_OBJECT
public:
explicit GroundStation(QWidget *parent = 0);
void CreateNewPlot(QString Name, QString xAxisLabel, QString yAxisLabel);
void CreateNewPlot(QString Name);
~GroundStation();
int GetNumberOfPlots() const;
private slots:
void ConnectDevice();
void DisconnectDevice();
void UpdateAllPlots(const QList<int> &data);
void readData();
void OpenSettings();
private:
Ui::GroundStation *ui;
QWidget* gsMain;
QWidget* gsPlotHub;
QPointer<QVBoxLayout> gsMainLayout;
static QPointer<GSPlotLayout> gsPlotHubLayout;
GSTerminal* gsTerminal;
//Plots
QSplitter* vertSplit;
//currently unused, but will be used
Status gsStatus = Disconnected;
QSerialPort* serial;
GSSettingsDialog* settingsWindow;
QPointer<QLabel> statusLabel;
void InitActions();
int seconds;
QByteArray serialData;
QVector<GSCustomPlot*> gsPlotBank;
};
#endif // GROUNDSTATION_H

@ -0,0 +1,70 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>GroundStation</class>
<widget class="QMainWindow" name="GroundStation">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>GroundStation</string>
</property>
<widget class="QWidget" name="centralWidget"/>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>21</height>
</rect>
</property>
<widget class="QMenu" name="menuDevice">
<property name="title">
<string>Device</string>
</property>
<addaction name="actionConnect"/>
<addaction name="actionDisconnect"/>
</widget>
<widget class="QMenu" name="menuOptions">
<property name="title">
<string>Options</string>
</property>
<addaction name="actionConfigure"/>
</widget>
<addaction name="menuDevice"/>
<addaction name="menuOptions"/>
</widget>
<widget class="QToolBar" name="mainToolBar">
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<widget class="QStatusBar" name="statusBar"/>
<action name="actionConnect">
<property name="text">
<string>Connect</string>
</property>
</action>
<action name="actionDisconnect">
<property name="text">
<string>Disconnect</string>
</property>
</action>
<action name="actionConfigure">
<property name="text">
<string>Configure</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>

@ -0,0 +1,23 @@
#ifndef GS_HEADERS_H
#define GS_HEADERS_H
#include <QDebug>
#include <QVBoxLayout>
#include <QGridLayout>
#include <QVector>
#include <QSplitter>
#include <QSerialPort>
#include <QSerialPortInfo>
#include <QHBoxLayout>
#include <math.h>
#include <QFile>
#include <QTimer>
#include <QScrollBar>
#include <QByteArray>
#include <QLabel>
#include <QPointer>
#endif // GS_HEADERS_H

@ -0,0 +1,37 @@
#include "gscustomplot.h"
#include "gsplot.h"
GSCustomPlot::GSCustomPlot(QWidget* parent) : QGroupBox(parent)
{
name = "Default Name";
Init();
}
GSCustomPlot::GSCustomPlot(QString iName, QWidget *parent) : QGroupBox(parent)
{
name = iName;
Init();
}
GSCustomPlot::~GSCustomPlot()
{
delete layout;
--numPlots;
}
int GSCustomPlot::numPlots = 0;
void GSCustomPlot::Init()
{
layout = new QHBoxLayout;
customPlot = new GSPlot(this);
layout->addWidget(customPlot);
setLayout(layout);
numPlots++;
setTitle(name);
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
}

@ -0,0 +1,32 @@
#ifndef GSCUSTOMPLOT_H
#define GSCUSTOMPLOT_H
#pragma once
#include <QGroupBox>
#include "gs_headers.h"
class GSPlot;
class GSCustomPlot : public QGroupBox
{
Q_OBJECT
public:
GSCustomPlot(QWidget* parent = nullptr);
GSCustomPlot(QString iName, QWidget* parent = nullptr);
~GSCustomPlot();
static int GetNumberOfPlots() { return numPlots; }
QString GetName() const { return name; }
void SetName(QString iName) { name = iName; }
GSPlot& GetPlot() { return *customPlot; }
private:
GSPlot* customPlot;
QHBoxLayout* layout;
QString name;
static int numPlots;
void Init();
};
#endif // GSCUSTOMPLOT_H

@ -0,0 +1,47 @@
#include "gsplot.h"
GSPlot::GSPlot(QWidget* parent) : QCustomPlot(parent)
{
xAxisRange = 8;
yAxisRange = 8;
yAxis->setRange(0, yAxisRange);
xAxis->setRange(0, xAxisRange);
makePlot();
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
}
GSPlot::~GSPlot()
{
}
void GSPlot::makePlot()
{
addGraph();
QPen myPen;
myPen.setWidth(1.f);
myPen.setColor(QColor(255, 100, 0));
graph(0)->setPen(myPen);
}
//eventually replace this with a 2d vector with x and y values for each graph needed to update
void GSPlot::UpdatePlot(qint16 xVal, qint32 yVal)
{
if(xVal >= xAxisRange)
{
xAxisRange = xVal * 2;
xAxis->setRange(0, xAxisRange);
}
if(yVal >= yAxisRange)
{
yAxisRange = yVal * 2;
yAxis->setRange(0, yAxisRange);
}
graph(0)->addData(xVal, yVal);
replot();
}

@ -0,0 +1,34 @@
#ifndef GSPLOT_H
#define GSPLOT_H
#pragma once
#include "qcustomplot.h"
#include "gs_headers.h"
class GSPlot : public QCustomPlot
{
Q_OBJECT
public:
void UpdatePlot(qint16 xVal, qint32 yVal);
GSPlot(QWidget* parent = nullptr);
~GSPlot();
private:
qint32 xAxisRange;
qint32 yAxisRange;
private slots:
void makePlot();
public slots:
//Plots Container
};
#endif // GSPLOT_H

@ -0,0 +1,37 @@
#include "gsplotlayout.h"
#include "gscustomplot.h"
GSPlotLayout::GSPlotLayout(QWidget *parent) : QVBoxLayout(parent)
{
AddRow(new QHBoxLayout);
}
void GSPlotLayout::addWidget(QWidget *widget)
{
if(LayoutBank.last()->count() >= MAX_ROW_COUNT)
{
AddRow(new QHBoxLayout);
LayoutBank.last()->addWidget(widget);
}
else
{
LayoutBank.last()->addWidget(widget);
}
}
GSPlotLayout::~GSPlotLayout()
{
}
void GSPlotLayout::AddRow(QHBoxLayout *layout)
{
LayoutBank.append(layout);
addLayout(layout);
}

@ -0,0 +1,21 @@
#ifndef GSPLOTLAYOUT_H
#define GSPLOTLAYOUT_H
#include "gs_headers.h"
#define MAX_ROW_COUNT 2
class GSPlotLayout : public QVBoxLayout
{
Q_OBJECT
public:
explicit GSPlotLayout(QWidget* parent = nullptr);
virtual void addWidget(QWidget* widget);
~GSPlotLayout();
private:
QVector<QPointer<QHBoxLayout>> LayoutBank;
void AddRow(QHBoxLayout* layout);
};
#endif // GSPLOTLAYOUT_H

@ -0,0 +1,172 @@
#include "gssettingsdialog.h"
#include "ui_gssettingsdialog.h"
static const char blankString[] = QT_TRANSLATE_NOOP("SettingsDialog", "N/A");
GSSettingsDialog::GSSettingsDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::GSSettingsDialog)
{
ui->setupUi(this);
FillParameters();
FillPortsInfo();
UpdateSettings();
ShowPortInfo(ui->serialPortBox->currentIndex());
connect(ui->buttonBox, SIGNAL(accepted()), this, SLOT(ApplyUpdates()));
connect(ui->serialPortBox, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &GSSettingsDialog::ShowPortInfo);
}
GSSettingsDialog::~GSSettingsDialog()
{
delete ui;
}
Settings &GSSettingsDialog::GetSettings()
{
return gsSettings;
}
void GSSettingsDialog::UpdatePortName(QString iString)
{
gsSettings.name = iString;
}
void GSSettingsDialog::ApplySettings(const Settings &iSettings)
{
gsSettings = iSettings;
}
void GSSettingsDialog::FillParameters()
{
ui->baudRateBox->addItem(QStringLiteral("9600"), QSerialPort::Baud9600);
ui->baudRateBox->addItem(QStringLiteral("19200"), QSerialPort::Baud19200);
ui->baudRateBox->addItem(QStringLiteral("38400"), QSerialPort::Baud38400);
ui->baudRateBox->addItem(QStringLiteral("115200"), QSerialPort::Baud115200);
for(int x = ui->baudRateBox->count() - 1; x >= 0; x--)
{
if(static_cast<QSerialPort::BaudRate>(ui->baudRateBox->itemData(x).toInt()) == gsSettings.baudRate)
{
ui->baudRateBox->setCurrentIndex(x);
break;
}
}
ui->dataBitsBox->addItem(QStringLiteral("5"), QSerialPort::Data5);
ui->dataBitsBox->addItem(QStringLiteral("6"), QSerialPort::Data6);
ui->dataBitsBox->addItem(QStringLiteral("7"), QSerialPort::Data7);
ui->dataBitsBox->addItem(QStringLiteral("8"), QSerialPort::Data8);
for(int x = ui->dataBitsBox->count() - 1; x >= 0; x--)
{
if(static_cast<QSerialPort::DataBits>(ui->dataBitsBox->itemData(x).toInt()) == gsSettings.dataBits)
{
ui->dataBitsBox->setCurrentIndex(x);
break;
}
}
ui->stopBitsBox->addItem(QStringLiteral("1"), QSerialPort::OneStop);
ui->stopBitsBox->addItem(QStringLiteral("2"), QSerialPort::TwoStop);
for(int x = ui->stopBitsBox->count() - 1; x >= 0; x--)
{
if(static_cast<QSerialPort::StopBits>(ui->stopBitsBox->itemData(x).toInt()) == gsSettings.stopBits)
{
ui->stopBitsBox->setCurrentIndex(x);
break;
}
}
//this may seem pointless because there is only 1 option for flow control, but if I ever need to add more options down the line I can
ui->flowControlBox->addItem(QStringLiteral("None"), QSerialPort::NoFlowControl);
for(int x = ui->flowControlBox->count() - 1; x >= 0; x--)
{
if(static_cast<QSerialPort::FlowControl>(ui->flowControlBox->itemData(x).toInt()) == gsSettings.flowControl)
{
ui->flowControlBox->setCurrentIndex(x);
break;
}
}
ui->parityBox->addItem(tr("None"), QSerialPort::NoParity);
ui->parityBox->addItem(tr("Even"), QSerialPort::EvenParity);
ui->parityBox->addItem(tr("Odd"), QSerialPort::OddParity);
ui->parityBox->addItem(tr("Mark"), QSerialPort::MarkParity);
ui->parityBox->addItem(tr("Space"), QSerialPort::SpaceParity);
for(int x = ui->parityBox->count() - 1; x >= 0; x--)
{
if(static_cast<QSerialPort::Parity>(ui->parityBox->itemData(x).toInt()) == gsSettings.parity)
{
ui->parityBox->setCurrentIndex(x);
break;
}
}
}
void GSSettingsDialog::FillPortsInfo()
{
ui->serialPortBox->clear();
QString description;
QString manufacturer;
QString serialNumber;
const auto infos = QSerialPortInfo::availablePorts();
for(const QSerialPortInfo &info : infos)
{
QStringList list;
description = info.description();
manufacturer = info.manufacturer();
serialNumber = info.serialNumber();
list << info.portName()
<< (!description.isEmpty() ? description : blankString)
<< (!manufacturer.isEmpty() ? manufacturer : blankString)
<< (!serialNumber.isEmpty() ? serialNumber : blankString)
<< (info.vendorIdentifier() ? QString::number(info.vendorIdentifier(), 16) : blankString)
<< (info.productIdentifier() ? QString::number(info.productIdentifier(), 16) : blankString);
ui->serialPortBox->addItem(list.first(), list);
}
}
void GSSettingsDialog::UpdateSettings()
{
Settings activeSettings;
activeSettings.name = ui->serialPortBox->currentText();
qDebug() << activeSettings.name;
activeSettings.baudRate = static_cast<QSerialPort::BaudRate>(ui->baudRateBox->itemData(ui->baudRateBox->currentIndex()).toInt());
activeSettings.dataBits = static_cast<QSerialPort::DataBits>(ui->dataBitsBox->itemData(ui->dataBitsBox->currentIndex()).toInt());
activeSettings.flowControl = static_cast<QSerialPort::FlowControl>(ui->flowControlBox->itemData(ui->flowControlBox->currentIndex()).toInt());
activeSettings.parity = static_cast<QSerialPort::Parity>(ui->parityBox->itemData(ui->parityBox->currentIndex()).toInt());
activeSettings.stopBits = static_cast<QSerialPort::StopBits>(ui->stopBitsBox->itemData(ui->stopBitsBox->currentIndex()).toInt());
gsSettings = activeSettings;
}
void GSSettingsDialog::ApplyUpdates()
{
UpdateSettings();
}
void GSSettingsDialog::ShowPortInfo(int ID)
{
if(ID == -1)
{
return;
}
QStringList list = ui->serialPortBox->itemData(ID).toStringList();
ui->description_info->setText(list.count() > 1 ? list.at(1) : tr(blankString));
ui->manufacturer_info->setText(list.count() > 2 ? list.at(2) : tr(blankString));
ui->serial_number_info->setText(list.count() > 3 ? list.at(3) : tr(blankString));
ui->vendor_id_info->setText(list.count() > 4 ? list.at(4) : tr(blankString));
ui->product_id_info->setText(list.count() > 5 ? list.at(5) : tr(blankString));
}
Settings GSSettingsDialog::gsSettings;

@ -0,0 +1,55 @@
#ifndef GSSETTINGSDIALOG_H
#define GSSETTINGSDIALOG_H
#pragma once
#include <QDialog>
#include "gs_headers.h"
struct Settings
{
QString name;
qint32 baudRate;
QSerialPort::DataBits dataBits;
QSerialPort::Parity parity;
QSerialPort::FlowControl flowControl;
QSerialPort::StopBits stopBits;
Settings()
{
name = "COM1";
baudRate = 9600;
dataBits = QSerialPort::Data8;
parity = QSerialPort::NoParity;
stopBits = QSerialPort::OneStop;
flowControl = QSerialPort::NoFlowControl;
}
};
namespace Ui {
class GSSettingsDialog;
}
class GSSettingsDialog : public QDialog
{
Q_OBJECT
public:
explicit GSSettingsDialog(QWidget *parent = 0);
~GSSettingsDialog();
static Settings& GetSettings();
static void UpdatePortName(QString iString);
private:
Ui::GSSettingsDialog *ui;
static Settings gsSettings;
void ApplySettings(const Settings &iSettings);
void FillParameters();
void FillPortsInfo();
void UpdateSettings();
private slots:
void ApplyUpdates();
void ShowPortInfo(int ID);
};
#endif // GSSETTINGSDIALOG_H

@ -0,0 +1,306 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>GSSettingsDialog</class>
<widget class="QDialog" name="GSSettingsDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>450</width>
<height>235</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>450</width>
<height>235</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>450</width>
<height>235</height>
</size>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2" stretch="3,2">
<item>
<layout class="QVBoxLayout" name="verticalLayout" stretch="1,3">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Select Serial Port</string>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0" colspan="2">
<widget class="QComboBox" name="serialPortBox"/>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Device Information</string>
</property>
<layout class="QFormLayout" name="formLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="description">
<property name="text">
<string>Description:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="description_info">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="manufacturer">
<property name="text">
<string>Manufacturer:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="manufacturer_info">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="serial_number">
<property name="text">
<string>Serial Number:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="serial_number_info">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="vendor_id">
<property name="text">
<string>Vendor ID: </string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="vendor_id_info">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="product_id">
<property name="text">
<string>Product ID: </string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLabel" name="product_id_info">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QGroupBox" name="groupBox_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="baseSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="title">
<string>Parameters</string>
</property>
<property name="flat">
<bool>true</bool>
</property>
<property name="checkable">
<bool>false</bool>
</property>
<layout class="QFormLayout" name="formLayout_3">
<property name="horizontalSpacing">
<number>20</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Baud Rate: </string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="baudRateBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Data Bits: </string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="dataBitsBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Parity: </string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="parityBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Stop Bits: </string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="stopBitsBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Flow Control: </string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QComboBox" name="flowControlBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>GSSettingsDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>227</x>
<y>232</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>249</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>GSSettingsDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>295</x>
<y>238</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>249</y>
</hint>
</hints>
</connection>
</connections>
</ui>

@ -0,0 +1,51 @@
#include "gsterminal.h"
#include <QTextStream>
#include <QDir>
GSTerminal::GSTerminal(QWidget *parent) : QPlainTextEdit(parent)
{
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum);
setMinimumHeight(50);
setMaximumHeight(200);
QPalette p = palette();
p.setColor(QPalette::Base, Qt::black);
p.setColor(QPalette::Text, Qt::white);
setPalette(p);
QFont newFont("Consolas", 10, QFont::Normal, true);
newFont.setItalic(false);
setFont(newFont);
setReadOnly(true);
int x = 0;
//QDir::rootPath for open logger <-----------PROBABLY. not tested
while(QFile::exists(QDir::currentPath() + QString(tr("/log_%1.csv").arg(x))))
{
x++;
}
logPath = new QFile(QString(QDir::currentPath() + QString(tr("/log_%1.csv").arg(x))), this);
}
GSTerminal::~GSTerminal()
{
}
void GSTerminal::putData(const QByteArray &data)
{
QTextCursor cursor = textCursor();
cursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor);
setTextCursor(cursor);
insertPlainText(QString(data));
QScrollBar* bar = verticalScrollBar();
//bar->setValue(bar->maximumHeight());
bar->setSliderDown(true);
if(logPath->open(QFile::WriteOnly | QFile::Truncate))
{
QTextStream stream(logPath);
stream << toPlainText();
logPath->close();
}
}

@ -0,0 +1,21 @@
#ifndef GSTERMINAL_H
#define GSTERMINAL_H
#pragma once
#include <QPlainTextEdit>
#include "gs_headers.h"
class GSTerminal : public QPlainTextEdit
{
Q_OBJECT
public:
explicit GSTerminal(QWidget* parent = nullptr);
~GSTerminal();
void putData(const QByteArray &data);
private:
QFile *logPath;
};
#endif // GSTERMINAL_H

@ -0,0 +1,18 @@
#include "groundstation.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
GroundStation groundStation;
groundStation.CreateNewPlot("Temp", "Time Elapsed", "Temperature in C");
groundStation.CreateNewPlot("Test2");
groundStation.CreateNewPlot("Test3");
groundStation.CreateNewPlot("Test4");
groundStation.show();
return a.exec();
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff