Refactoring: splitting mode logic into different classes
This commit is contained in:
parent
e266d37b96
commit
b7033a029e
Binary file not shown.
@ -13,11 +13,8 @@ HEADERS += \
|
|||||||
Device/devicelog.h \
|
Device/devicelog.h \
|
||||||
Device/firmwareupdatedialog.h \
|
Device/firmwareupdatedialog.h \
|
||||||
Device/manualcontroldialog.h \
|
Device/manualcontroldialog.h \
|
||||||
Menu/menu.h \
|
Generator/generator.h \
|
||||||
Menu/menuaction.h \
|
Generator/signalgenwidget.h \
|
||||||
Menu/menubool.h \
|
|
||||||
Menu/menuitem.h \
|
|
||||||
Menu/menuvalue.h \
|
|
||||||
Tools/eseries.h \
|
Tools/eseries.h \
|
||||||
Tools/impedancematchdialog.h \
|
Tools/impedancematchdialog.h \
|
||||||
Traces/bodeplotaxisdialog.h \
|
Traces/bodeplotaxisdialog.h \
|
||||||
@ -33,14 +30,14 @@ HEADERS += \
|
|||||||
Traces/traceplot.h \
|
Traces/traceplot.h \
|
||||||
Traces/tracesmithchart.h \
|
Traces/tracesmithchart.h \
|
||||||
Traces/tracewidget.h \
|
Traces/tracewidget.h \
|
||||||
|
VNA/vna.h \
|
||||||
|
appwindow.h \
|
||||||
averaging.h \
|
averaging.h \
|
||||||
|
mode.h \
|
||||||
preferences.h \
|
preferences.h \
|
||||||
qwtplotpiecewisecurve.h \
|
qwtplotpiecewisecurve.h \
|
||||||
signalgenerator.h \
|
|
||||||
touchstone.h \
|
touchstone.h \
|
||||||
unit.h \
|
unit.h
|
||||||
valueinput.h \
|
|
||||||
vna.h
|
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
../VNA_embedded/Application/Communication/Protocol.cpp \
|
../VNA_embedded/Application/Communication/Protocol.cpp \
|
||||||
@ -49,6 +46,7 @@ SOURCES += \
|
|||||||
Calibration/calkit.cpp \
|
Calibration/calkit.cpp \
|
||||||
Calibration/calkitdialog.cpp \
|
Calibration/calkitdialog.cpp \
|
||||||
Calibration/measurementmodel.cpp \
|
Calibration/measurementmodel.cpp \
|
||||||
|
CustomWidgets/qwtplotpiecewisecurve.cpp \
|
||||||
CustomWidgets/siunitedit.cpp \
|
CustomWidgets/siunitedit.cpp \
|
||||||
CustomWidgets/tilewidget.cpp \
|
CustomWidgets/tilewidget.cpp \
|
||||||
CustomWidgets/toggleswitch.cpp \
|
CustomWidgets/toggleswitch.cpp \
|
||||||
@ -57,11 +55,8 @@ SOURCES += \
|
|||||||
Device/devicelog.cpp \
|
Device/devicelog.cpp \
|
||||||
Device/firmwareupdatedialog.cpp \
|
Device/firmwareupdatedialog.cpp \
|
||||||
Device/manualcontroldialog.cpp \
|
Device/manualcontroldialog.cpp \
|
||||||
Menu/menu.cpp \
|
Generator/generator.cpp \
|
||||||
Menu/menuaction.cpp \
|
Generator/signalgenwidget.cpp \
|
||||||
Menu/menubool.cpp \
|
|
||||||
Menu/menuitem.cpp \
|
|
||||||
Menu/menuvalue.cpp \
|
|
||||||
Tools/eseries.cpp \
|
Tools/eseries.cpp \
|
||||||
Tools/impedancematchdialog.cpp \
|
Tools/impedancematchdialog.cpp \
|
||||||
Traces/bodeplotaxisdialog.cpp \
|
Traces/bodeplotaxisdialog.cpp \
|
||||||
@ -77,15 +72,14 @@ SOURCES += \
|
|||||||
Traces/traceplot.cpp \
|
Traces/traceplot.cpp \
|
||||||
Traces/tracesmithchart.cpp \
|
Traces/tracesmithchart.cpp \
|
||||||
Traces/tracewidget.cpp \
|
Traces/tracewidget.cpp \
|
||||||
|
VNA/vna.cpp \
|
||||||
|
appwindow.cpp \
|
||||||
averaging.cpp \
|
averaging.cpp \
|
||||||
main.cpp \
|
main.cpp \
|
||||||
|
mode.cpp \
|
||||||
preferences.cpp \
|
preferences.cpp \
|
||||||
qwtplotpiecewisecurve.cpp \
|
|
||||||
signalgenerator.cpp \
|
|
||||||
touchstone.cpp \
|
touchstone.cpp \
|
||||||
unit.cpp \
|
unit.cpp
|
||||||
valueinput.cpp \
|
|
||||||
vna.cpp
|
|
||||||
|
|
||||||
LIBS += -lusb-1.0
|
LIBS += -lusb-1.0
|
||||||
unix:INCLUDEPATH += /usr/include/qwt
|
unix:INCLUDEPATH += /usr/include/qwt
|
||||||
@ -103,6 +97,7 @@ FORMS += \
|
|||||||
Device/devicelog.ui \
|
Device/devicelog.ui \
|
||||||
Device/firmwareupdatedialog.ui \
|
Device/firmwareupdatedialog.ui \
|
||||||
Device/manualcontroldialog.ui \
|
Device/manualcontroldialog.ui \
|
||||||
|
Generator/signalgenwidget.ui \
|
||||||
Tools/impedancematchdialog.ui \
|
Tools/impedancematchdialog.ui \
|
||||||
Traces/bodeplotaxisdialog.ui \
|
Traces/bodeplotaxisdialog.ui \
|
||||||
Traces/markerwidget.ui \
|
Traces/markerwidget.ui \
|
||||||
@ -111,8 +106,7 @@ FORMS += \
|
|||||||
Traces/traceimportdialog.ui \
|
Traces/traceimportdialog.ui \
|
||||||
Traces/tracewidget.ui \
|
Traces/tracewidget.ui \
|
||||||
main.ui \
|
main.ui \
|
||||||
preferencesdialog.ui \
|
preferencesdialog.ui
|
||||||
signalgenerator.ui
|
|
||||||
|
|
||||||
DISTFILES +=
|
DISTFILES +=
|
||||||
|
|
||||||
|
@ -8,6 +8,96 @@
|
|||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
USBInBuffer::USBInBuffer(libusb_device_handle *handle, unsigned char endpoint, int buffer_size) :
|
||||||
|
buffer_size(buffer_size),
|
||||||
|
received_size(0),
|
||||||
|
inCallback(false)
|
||||||
|
{
|
||||||
|
buffer = new unsigned char[buffer_size];
|
||||||
|
transfer = libusb_alloc_transfer(0);
|
||||||
|
libusb_fill_bulk_transfer(transfer, handle, endpoint, buffer, 64, CallbackTrampoline, this, 100);
|
||||||
|
libusb_submit_transfer(transfer);
|
||||||
|
}
|
||||||
|
|
||||||
|
USBInBuffer::~USBInBuffer()
|
||||||
|
{
|
||||||
|
if(transfer) {
|
||||||
|
qDebug() << "Start cancellation";
|
||||||
|
libusb_cancel_transfer(transfer);
|
||||||
|
// wait for cancellation to complete
|
||||||
|
mutex mtx;
|
||||||
|
unique_lock<mutex> lck(mtx);
|
||||||
|
cv.wait(lck);
|
||||||
|
qDebug() << "Cancellation complete";
|
||||||
|
}
|
||||||
|
delete buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void USBInBuffer::removeBytes(int handled_bytes)
|
||||||
|
{
|
||||||
|
if(!inCallback) {
|
||||||
|
throw runtime_error("Removing of bytes is only allowed from within receive callback");
|
||||||
|
}
|
||||||
|
if(handled_bytes >= received_size) {
|
||||||
|
received_size = 0;
|
||||||
|
} else {
|
||||||
|
// not removing all bytes, have to move remaining data to the beginning of the buffer
|
||||||
|
memmove(buffer, &buffer[handled_bytes], received_size - handled_bytes);
|
||||||
|
received_size -= handled_bytes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int USBInBuffer::getReceived() const
|
||||||
|
{
|
||||||
|
return received_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void USBInBuffer::Callback(libusb_transfer *transfer)
|
||||||
|
{
|
||||||
|
switch(transfer->status) {
|
||||||
|
case LIBUSB_TRANSFER_COMPLETED:
|
||||||
|
received_size += transfer->actual_length;
|
||||||
|
inCallback = true;
|
||||||
|
emit DataReceived();
|
||||||
|
inCallback = false;
|
||||||
|
break;
|
||||||
|
case LIBUSB_TRANSFER_ERROR:
|
||||||
|
case LIBUSB_TRANSFER_NO_DEVICE:
|
||||||
|
case LIBUSB_TRANSFER_OVERFLOW:
|
||||||
|
case LIBUSB_TRANSFER_STALL:
|
||||||
|
qCritical() << "LIBUSB_TRANSFER_ERROR";
|
||||||
|
libusb_free_transfer(transfer);
|
||||||
|
this->transfer = nullptr;
|
||||||
|
emit TransferError();
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
case LIBUSB_TRANSFER_TIMED_OUT:
|
||||||
|
// nothing to do
|
||||||
|
break;
|
||||||
|
case LIBUSB_TRANSFER_CANCELLED:
|
||||||
|
// destructor called, do not resubmit
|
||||||
|
libusb_free_transfer(transfer);
|
||||||
|
this->transfer = nullptr;
|
||||||
|
cv.notify_all();
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Resubmit the transfer
|
||||||
|
transfer->buffer = &buffer[received_size];
|
||||||
|
libusb_submit_transfer(transfer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void USBInBuffer::CallbackTrampoline(libusb_transfer *transfer)
|
||||||
|
{
|
||||||
|
auto usb = (USBInBuffer*) transfer->user_data;
|
||||||
|
usb->Callback(transfer);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *USBInBuffer::getBuffer() const
|
||||||
|
{
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
Device::Device(QString serial)
|
Device::Device(QString serial)
|
||||||
{
|
{
|
||||||
qDebug() << "Starting device connection...";
|
qDebug() << "Starting device connection...";
|
||||||
@ -62,6 +152,9 @@ Device::Device(QString serial)
|
|||||||
connect(dataBuffer, &USBInBuffer::DataReceived, this, &Device::ReceivedData, Qt::DirectConnection);
|
connect(dataBuffer, &USBInBuffer::DataReceived, this, &Device::ReceivedData, Qt::DirectConnection);
|
||||||
connect(dataBuffer, &USBInBuffer::TransferError, this, &Device::ConnectionLost);
|
connect(dataBuffer, &USBInBuffer::TransferError, this, &Device::ConnectionLost);
|
||||||
connect(logBuffer, &USBInBuffer::DataReceived, this, &Device::ReceivedLog, Qt::DirectConnection);
|
connect(logBuffer, &USBInBuffer::DataReceived, this, &Device::ReceivedLog, Qt::DirectConnection);
|
||||||
|
connect(&transmissionTimer, &QTimer::timeout, this, &Device::transmissionTimeout);
|
||||||
|
transmissionTimer.setSingleShot(true);
|
||||||
|
transmissionActive = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Device::~Device()
|
Device::~Device()
|
||||||
@ -82,26 +175,17 @@ Device::~Device()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Device::SendPacket(Protocol::PacketInfo packet)
|
bool Device::SendPacket(Protocol::PacketInfo packet, std::function<void(TransmissionResult)> cb, unsigned int timeout)
|
||||||
{
|
{
|
||||||
if(m_connected) {
|
Transmission t;
|
||||||
unsigned char buffer[1024];
|
t.packet = packet;
|
||||||
unsigned int length = Protocol::EncodePacket(packet, buffer, sizeof(buffer));
|
t.timeout = timeout;
|
||||||
if(!length) {
|
t.callback = cb;
|
||||||
qCritical() << "Failed to encode packet";
|
transmissionQueue.enqueue(t);
|
||||||
return false;
|
if(!transmissionActive) {
|
||||||
}
|
startNextTransmission();
|
||||||
int actual_length;
|
|
||||||
auto ret = libusb_bulk_transfer(m_handle, EP_Data_Out_Addr, buffer, length, &actual_length, 0);
|
|
||||||
if(ret < 0) {
|
|
||||||
qCritical() << "Error sending data: "
|
|
||||||
<< libusb_strerror((libusb_error) ret);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Device::Configure(Protocol::SweepSettings settings)
|
bool Device::Configure(Protocol::SweepSettings settings)
|
||||||
@ -303,93 +387,38 @@ QString Device::serial() const
|
|||||||
return m_serial;
|
return m_serial;
|
||||||
}
|
}
|
||||||
|
|
||||||
USBInBuffer::USBInBuffer(libusb_device_handle *handle, unsigned char endpoint, int buffer_size) :
|
void Device::startNextTransmission()
|
||||||
buffer_size(buffer_size),
|
|
||||||
received_size(0),
|
|
||||||
inCallback(false)
|
|
||||||
{
|
{
|
||||||
buffer = new unsigned char[buffer_size];
|
if(transmissionQueue.empty() || !m_connected) {
|
||||||
transfer = libusb_alloc_transfer(0);
|
// nothing more to transmit
|
||||||
libusb_fill_bulk_transfer(transfer, handle, endpoint, buffer, 64, CallbackTrampoline, this, 100);
|
transmissionActive = false;
|
||||||
libusb_submit_transfer(transfer);
|
|
||||||
}
|
|
||||||
|
|
||||||
USBInBuffer::~USBInBuffer()
|
|
||||||
{
|
|
||||||
if(transfer) {
|
|
||||||
qDebug() << "Start cancellation";
|
|
||||||
libusb_cancel_transfer(transfer);
|
|
||||||
// wait for cancellation to complete
|
|
||||||
mutex mtx;
|
|
||||||
unique_lock<mutex> lck(mtx);
|
|
||||||
cv.wait(lck);
|
|
||||||
qDebug() << "Cancellation complete";
|
|
||||||
}
|
|
||||||
delete buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
void USBInBuffer::removeBytes(int handled_bytes)
|
|
||||||
{
|
|
||||||
if(!inCallback) {
|
|
||||||
throw runtime_error("Removing of bytes is only allowed from within receive callback");
|
|
||||||
}
|
|
||||||
if(handled_bytes >= received_size) {
|
|
||||||
received_size = 0;
|
|
||||||
} else {
|
|
||||||
// not removing all bytes, have to move remaining data to the beginning of the buffer
|
|
||||||
memmove(buffer, &buffer[handled_bytes], received_size - handled_bytes);
|
|
||||||
received_size -= handled_bytes;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int USBInBuffer::getReceived() const
|
|
||||||
{
|
|
||||||
return received_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
void USBInBuffer::Callback(libusb_transfer *transfer)
|
|
||||||
{
|
|
||||||
switch(transfer->status) {
|
|
||||||
case LIBUSB_TRANSFER_COMPLETED:
|
|
||||||
received_size += transfer->actual_length;
|
|
||||||
inCallback = true;
|
|
||||||
emit DataReceived();
|
|
||||||
inCallback = false;
|
|
||||||
break;
|
|
||||||
case LIBUSB_TRANSFER_ERROR:
|
|
||||||
case LIBUSB_TRANSFER_NO_DEVICE:
|
|
||||||
case LIBUSB_TRANSFER_OVERFLOW:
|
|
||||||
case LIBUSB_TRANSFER_STALL:
|
|
||||||
qCritical() << "LIBUSB_TRANSFER_ERROR";
|
|
||||||
libusb_free_transfer(transfer);
|
|
||||||
this->transfer = nullptr;
|
|
||||||
emit TransferError();
|
|
||||||
return;
|
return;
|
||||||
break;
|
|
||||||
case LIBUSB_TRANSFER_TIMED_OUT:
|
|
||||||
// nothing to do
|
|
||||||
break;
|
|
||||||
case LIBUSB_TRANSFER_CANCELLED:
|
|
||||||
// destructor called, do not resubmit
|
|
||||||
libusb_free_transfer(transfer);
|
|
||||||
this->transfer = nullptr;
|
|
||||||
cv.notify_all();
|
|
||||||
return;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
// Resubmit the transfer
|
transmissionActive = true;
|
||||||
transfer->buffer = &buffer[received_size];
|
auto t = transmissionQueue.head();
|
||||||
libusb_submit_transfer(transfer);
|
unsigned char buffer[1024];
|
||||||
|
unsigned int length = Protocol::EncodePacket(t.packet, buffer, sizeof(buffer));
|
||||||
|
if(!length) {
|
||||||
|
qCritical() << "Failed to encode packet";
|
||||||
|
transmissionFinished(TransmissionResult::InternalError);
|
||||||
|
}
|
||||||
|
int actual_length;
|
||||||
|
auto ret = libusb_bulk_transfer(m_handle, EP_Data_Out_Addr, buffer, length, &actual_length, 0);
|
||||||
|
if(ret < 0) {
|
||||||
|
qCritical() << "Error sending data: "
|
||||||
|
<< libusb_strerror((libusb_error) ret);
|
||||||
|
transmissionFinished(TransmissionResult::InternalError);
|
||||||
|
}
|
||||||
|
transmissionTimer.start(t.timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
void USBInBuffer::CallbackTrampoline(libusb_transfer *transfer)
|
void Device::transmissionFinished(TransmissionResult result)
|
||||||
{
|
{
|
||||||
auto usb = (USBInBuffer*) transfer->user_data;
|
transmissionTimer.stop();
|
||||||
usb->Callback(transfer);
|
// remove transmitted packet
|
||||||
|
auto t = transmissionQueue.dequeue();
|
||||||
|
if(t.callback) {
|
||||||
|
t.callback(result);
|
||||||
|
}
|
||||||
|
startNextTransmission();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *USBInBuffer::getBuffer() const
|
|
||||||
{
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#ifndef DEVICE_H
|
#ifndef DEVICE_H
|
||||||
#define DEVICE_H
|
#define DEVICE_H
|
||||||
|
|
||||||
#include "../VNA_embedded/Application/Communication/Protocol.hpp"
|
#include "../VNA_embedded/Application/Communication/Protocol.hpp"
|
||||||
@ -8,6 +8,8 @@
|
|||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <QQueue>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(Protocol::Datapoint);
|
Q_DECLARE_METATYPE(Protocol::Datapoint);
|
||||||
Q_DECLARE_METATYPE(Protocol::ManualStatus);
|
Q_DECLARE_METATYPE(Protocol::ManualStatus);
|
||||||
@ -43,10 +45,17 @@ class Device : public QObject
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
enum class TransmissionResult {
|
||||||
|
Ack,
|
||||||
|
Nack,
|
||||||
|
Timeout,
|
||||||
|
InternalError,
|
||||||
|
};
|
||||||
|
|
||||||
// connect to a VNA device. If serial is specified only connecting to this device, otherwise to the first one found
|
// connect to a VNA device. If serial is specified only connecting to this device, otherwise to the first one found
|
||||||
Device(QString serial = QString());
|
Device(QString serial = QString());
|
||||||
~Device();
|
~Device();
|
||||||
bool SendPacket(Protocol::PacketInfo packet);
|
bool SendPacket(Protocol::PacketInfo packet, std::function<void(TransmissionResult)> cb = nullptr, unsigned int timeout = 10);
|
||||||
bool Configure(Protocol::SweepSettings settings);
|
bool Configure(Protocol::SweepSettings settings);
|
||||||
bool SetManual(Protocol::ManualControl manual);
|
bool SetManual(Protocol::ManualControl manual);
|
||||||
bool SendFirmwareChunk(Protocol::FirmwarePacket &fw);
|
bool SendFirmwareChunk(Protocol::FirmwarePacket &fw);
|
||||||
@ -68,6 +77,9 @@ signals:
|
|||||||
private slots:
|
private slots:
|
||||||
void ReceivedData();
|
void ReceivedData();
|
||||||
void ReceivedLog();
|
void ReceivedLog();
|
||||||
|
void transmissionTimeout() {
|
||||||
|
transmissionFinished(TransmissionResult::Timeout);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr int VID = 0x0483;
|
static constexpr int VID = 0x0483;
|
||||||
@ -86,6 +98,17 @@ private:
|
|||||||
USBInBuffer *dataBuffer;
|
USBInBuffer *dataBuffer;
|
||||||
USBInBuffer *logBuffer;
|
USBInBuffer *logBuffer;
|
||||||
|
|
||||||
|
using Transmission = struct {
|
||||||
|
Protocol::PacketInfo packet;
|
||||||
|
unsigned int timeout;
|
||||||
|
std::function<void(TransmissionResult)> callback;
|
||||||
|
};
|
||||||
|
|
||||||
|
QQueue<Transmission> transmissionQueue;
|
||||||
|
void startNextTransmission();
|
||||||
|
void transmissionFinished(TransmissionResult result);
|
||||||
|
QTimer transmissionTimer;
|
||||||
|
bool transmissionActive;
|
||||||
|
|
||||||
QString m_serial;
|
QString m_serial;
|
||||||
bool m_connected;
|
bool m_connected;
|
||||||
|
@ -29,7 +29,8 @@
|
|||||||
<string>To File</string>
|
<string>To File</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset theme="document-save"/>
|
<iconset theme="document-save">
|
||||||
|
<normaloff>.</normaloff>.</iconset>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@ -39,7 +40,8 @@
|
|||||||
<string>Clear</string>
|
<string>Clear</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset theme="edit-clear"/>
|
<iconset theme="edit-clear">
|
||||||
|
<normaloff>.</normaloff>.</iconset>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@ -48,6 +50,9 @@
|
|||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Autoscroll</string>
|
<string>Autoscroll</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
|
25
Software/PC_Application/Generator/generator.cpp
Normal file
25
Software/PC_Application/Generator/generator.cpp
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#include "generator.h"
|
||||||
|
|
||||||
|
Generator::Generator(AppWindow *window)
|
||||||
|
: Mode(window, "Signal Generator")
|
||||||
|
{
|
||||||
|
central = new SignalgeneratorWidget();
|
||||||
|
finalize(central);
|
||||||
|
connect(central, &SignalgeneratorWidget::SettingsChanged, this, &Generator::updateDevice);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Generator::initializeDevice()
|
||||||
|
{
|
||||||
|
updateDevice();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Generator::updateDevice()
|
||||||
|
{
|
||||||
|
if(!window->getDevice()) {
|
||||||
|
// can't updat if not connected
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto status = central->getDeviceStatus();
|
||||||
|
// TODO comment in once status is filled with valid values
|
||||||
|
// window->getDevice()->SetManual(status);
|
||||||
|
}
|
18
Software/PC_Application/Generator/generator.h
Normal file
18
Software/PC_Application/Generator/generator.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#ifndef GENERATOR_H
|
||||||
|
#define GENERATOR_H
|
||||||
|
|
||||||
|
#include "mode.h"
|
||||||
|
#include "signalgenwidget.h"
|
||||||
|
|
||||||
|
class Generator : public Mode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Generator(AppWindow *window);
|
||||||
|
void initializeDevice() override;
|
||||||
|
private slots:
|
||||||
|
void updateDevice();
|
||||||
|
private:
|
||||||
|
SignalgeneratorWidget *central;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // GENERATOR_H
|
@ -1,9 +1,9 @@
|
|||||||
#include "signalgenerator.h"
|
#include "signalgenwidget.h"
|
||||||
#include "ui_signalgenerator.h"
|
#include "ui_signalgenerator.h"
|
||||||
|
|
||||||
Signalgenerator::Signalgenerator(QWidget *parent) :
|
SignalgeneratorWidget::SignalgeneratorWidget(QWidget *parent) :
|
||||||
QWidget(parent),
|
QWidget(parent),
|
||||||
ui(new Ui::Signalgenerator)
|
ui(new Ui::SignalgeneratorWidget)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
ui->frequency->setUnit("Hz");
|
ui->frequency->setUnit("Hz");
|
||||||
@ -17,9 +17,9 @@ Signalgenerator::Signalgenerator(QWidget *parent) :
|
|||||||
newval = 6000000000;
|
newval = 6000000000;
|
||||||
}
|
}
|
||||||
ui->frequency->setValueQuiet(newval);
|
ui->frequency->setValueQuiet(newval);
|
||||||
SettingsChanged();
|
emit SettingsChanged();
|
||||||
});
|
});
|
||||||
connect(ui->levelSpin, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &Signalgenerator::setLevel);
|
connect(ui->levelSpin, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &SignalgeneratorWidget::setLevel);
|
||||||
connect(ui->levelSlider, &QSlider::valueChanged, [=](int value) {
|
connect(ui->levelSlider, &QSlider::valueChanged, [=](int value) {
|
||||||
setLevel((double) value / 100.0);
|
setLevel((double) value / 100.0);
|
||||||
});
|
});
|
||||||
@ -27,22 +27,29 @@ Signalgenerator::Signalgenerator(QWidget *parent) :
|
|||||||
if(ui->EnablePort1->isChecked() && ui->EnablePort2->isChecked()) {
|
if(ui->EnablePort1->isChecked() && ui->EnablePort2->isChecked()) {
|
||||||
ui->EnablePort2->setCheckState(Qt::CheckState::Unchecked);
|
ui->EnablePort2->setCheckState(Qt::CheckState::Unchecked);
|
||||||
}
|
}
|
||||||
SettingsChanged();
|
emit SettingsChanged();
|
||||||
});
|
});
|
||||||
connect(ui->EnablePort2, &QCheckBox::clicked, [=](){
|
connect(ui->EnablePort2, &QCheckBox::clicked, [=](){
|
||||||
if(ui->EnablePort1->isChecked() && ui->EnablePort2->isChecked()) {
|
if(ui->EnablePort1->isChecked() && ui->EnablePort2->isChecked()) {
|
||||||
ui->EnablePort1->setCheckState(Qt::CheckState::Unchecked);
|
ui->EnablePort1->setCheckState(Qt::CheckState::Unchecked);
|
||||||
}
|
}
|
||||||
SettingsChanged();
|
emit SettingsChanged();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Signalgenerator::~Signalgenerator()
|
SignalgeneratorWidget::~SignalgeneratorWidget()
|
||||||
{
|
{
|
||||||
delete ui;
|
delete ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Signalgenerator::setLevel(double level)
|
Protocol::ManualControl SignalgeneratorWidget::getDeviceStatus()
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
Protocol::ManualControl s = {};
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SignalgeneratorWidget::setLevel(double level)
|
||||||
{
|
{
|
||||||
// TODO constrain to frequency dependent levels
|
// TODO constrain to frequency dependent levels
|
||||||
ui->levelSpin->blockSignals(true);
|
ui->levelSpin->blockSignals(true);
|
||||||
@ -54,7 +61,3 @@ void Signalgenerator::setLevel(double level)
|
|||||||
SettingsChanged();
|
SettingsChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Signalgenerator::SettingsChanged()
|
|
||||||
{
|
|
||||||
// TODO compile manual settings packet and send
|
|
||||||
}
|
|
@ -5,25 +5,26 @@
|
|||||||
#include "Device/device.h"
|
#include "Device/device.h"
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class Signalgenerator;
|
class SignalgeneratorWidget;
|
||||||
}
|
}
|
||||||
|
|
||||||
class Signalgenerator : public QWidget
|
class SignalgeneratorWidget : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Signalgenerator(QWidget *parent = nullptr);
|
explicit SignalgeneratorWidget(QWidget *parent = nullptr);
|
||||||
~Signalgenerator();
|
~SignalgeneratorWidget();
|
||||||
|
|
||||||
|
Protocol::ManualControl getDeviceStatus();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void NewManualState(Protocol::ManualStatus s);
|
void SettingsChanged();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void setLevel(double level);
|
void setLevel(double level);
|
||||||
private:
|
private:
|
||||||
void SettingsChanged();
|
Ui::SignalgeneratorWidget *ui;
|
||||||
Ui::Signalgenerator *ui;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SIGNALGENERATOR_H
|
#endif // SIGNALGENERATOR_H
|
@ -1,84 +0,0 @@
|
|||||||
#include "menu.h"
|
|
||||||
#include <QKeyEvent>
|
|
||||||
#include "menuaction.h"
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
Menu::Menu(QStackedLayout &layout, QString name)
|
|
||||||
: name(name),
|
|
||||||
m_containingLayout(layout)
|
|
||||||
{
|
|
||||||
m_layout = new QVBoxLayout;
|
|
||||||
setLayout(m_layout);
|
|
||||||
m_widgetCount = 0;
|
|
||||||
setFixedSize(180, 800);
|
|
||||||
parent = nullptr;
|
|
||||||
layout.addWidget(this);
|
|
||||||
if(name.length() > 0) {
|
|
||||||
auto back = new MenuAction(name, MenuAction::ArrowType::Left);
|
|
||||||
back->setStyleSheet("background-color:lightblue;");
|
|
||||||
connect(back, &MenuAction::triggered, this, &Menu::leave);
|
|
||||||
addItem(back);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Menu::addItem(MenuItem *i)
|
|
||||||
{
|
|
||||||
if(m_widgetCount >= maxWidgets) {
|
|
||||||
throw runtime_error("Menu already at maximum capacity");
|
|
||||||
}
|
|
||||||
m_layout->addWidget(i, 1);
|
|
||||||
items.push_back(i);
|
|
||||||
m_widgetCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Menu::addMenu(Menu *m)
|
|
||||||
{
|
|
||||||
auto menuLabel = new MenuAction(m->name, MenuAction::ArrowType::Right);
|
|
||||||
submenus.push_back(SubmenuEntry(menuLabel, m, m_widgetCount));
|
|
||||||
connect(menuLabel, &MenuAction::triggered, [=]() {
|
|
||||||
m->m_containingLayout.setCurrentWidget(m);
|
|
||||||
});
|
|
||||||
addItem(menuLabel);
|
|
||||||
m->parent = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Menu::finalize()
|
|
||||||
{
|
|
||||||
m_layout->addStretch(maxWidgets - m_widgetCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Menu::keyPressEvent(QKeyEvent *event)
|
|
||||||
{
|
|
||||||
// check if softkey pressed
|
|
||||||
int index = -1;
|
|
||||||
switch(event->key()) {
|
|
||||||
case Qt::Key_F1: index = 0; break;
|
|
||||||
case Qt::Key_F2: index = 1; break;
|
|
||||||
case Qt::Key_F3: index = 2; break;
|
|
||||||
case Qt::Key_F4: index = 3; break;
|
|
||||||
case Qt::Key_F5: index = 4; break;
|
|
||||||
case Qt::Key_F6: index = 5; break;
|
|
||||||
case Qt::Key_F7: index = 6; break;
|
|
||||||
case Qt::Key_F8: index = 7; break;
|
|
||||||
}
|
|
||||||
if(index >= 0) {
|
|
||||||
auto w = m_layout->itemAt(index);
|
|
||||||
w->widget()->setFocus();
|
|
||||||
items[index]->userSelected();
|
|
||||||
event->accept();
|
|
||||||
} else if(event->key() == Qt::Key_Escape) {
|
|
||||||
leave();
|
|
||||||
event->accept();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Menu::leave()
|
|
||||||
{
|
|
||||||
if(parent) {
|
|
||||||
// got a parent menu
|
|
||||||
parent->m_containingLayout.setCurrentWidget(parent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,41 +0,0 @@
|
|||||||
#ifndef MENU_H
|
|
||||||
#define MENU_H
|
|
||||||
|
|
||||||
#include <QWidget>
|
|
||||||
#include <QStackedLayout>
|
|
||||||
#include "menuitem.h"
|
|
||||||
#include "menuaction.h"
|
|
||||||
|
|
||||||
class Menu : public QWidget
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
Menu(QStackedLayout &layout, QString name = QString());
|
|
||||||
void addItem(MenuItem *i);
|
|
||||||
void addMenu(Menu *m);
|
|
||||||
void finalize();
|
|
||||||
signals:
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void keyPressEvent(QKeyEvent *event) override;
|
|
||||||
private:
|
|
||||||
void leave();
|
|
||||||
class SubmenuEntry {
|
|
||||||
public:
|
|
||||||
SubmenuEntry(MenuAction *label, Menu *menu, int index) :
|
|
||||||
label(label), menu(menu), index(index){};
|
|
||||||
MenuAction *label;
|
|
||||||
Menu *menu;
|
|
||||||
int index;
|
|
||||||
};
|
|
||||||
static constexpr int maxWidgets = 12;
|
|
||||||
QVBoxLayout *m_layout;
|
|
||||||
Menu *parent;
|
|
||||||
const QString name;
|
|
||||||
QStackedLayout &m_containingLayout;
|
|
||||||
std::vector<SubmenuEntry> submenus;
|
|
||||||
std::vector<MenuItem*> items;
|
|
||||||
int m_widgetCount;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // MENU_H
|
|
@ -1,65 +0,0 @@
|
|||||||
#include "menuaction.h"
|
|
||||||
|
|
||||||
#include <QLabel>
|
|
||||||
#include <QStyle>
|
|
||||||
#include <QSizePolicy>
|
|
||||||
|
|
||||||
MenuAction::MenuAction(const QString &l, MenuAction::ArrowType arrow)
|
|
||||||
{
|
|
||||||
subline = nullptr;
|
|
||||||
auto label = new QLabel(l, this);
|
|
||||||
label->setAlignment(Qt::AlignCenter);
|
|
||||||
auto labelLayout = new QHBoxLayout();
|
|
||||||
if(arrow == ArrowType::Left) {
|
|
||||||
auto lIcon = new QLabel(this);
|
|
||||||
lIcon->setPixmap(style()->standardIcon(QStyle::SP_ArrowLeft).pixmap(16));
|
|
||||||
lIcon->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
|
||||||
labelLayout->addWidget(lIcon);
|
|
||||||
}
|
|
||||||
labelLayout->addWidget(label);
|
|
||||||
if(arrow == ArrowType::Right) {
|
|
||||||
auto lIcon = new QLabel(this);
|
|
||||||
lIcon->setPixmap(style()->standardIcon(QStyle::SP_ArrowRight).pixmap(16));
|
|
||||||
lIcon->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
|
||||||
labelLayout->addWidget(lIcon);
|
|
||||||
}
|
|
||||||
layout.addLayout(labelLayout);
|
|
||||||
setLayout(&layout);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MenuAction::AddSubline(const QString &l)
|
|
||||||
{
|
|
||||||
if(!subline) {
|
|
||||||
subline = new QLabel(this);
|
|
||||||
subline->setAlignment(Qt::AlignCenter);
|
|
||||||
layout.addWidget(subline);
|
|
||||||
}
|
|
||||||
QFont f( "Arial", 8);
|
|
||||||
subline->setFont( f);
|
|
||||||
subline->setText(l);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MenuAction::RemoveSubline()
|
|
||||||
{
|
|
||||||
if(subline) {
|
|
||||||
layout.removeWidget(subline);
|
|
||||||
delete subline;
|
|
||||||
subline = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MenuAction::userSelected()
|
|
||||||
{
|
|
||||||
emit triggered();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MenuAction::mouseReleaseEvent(QMouseEvent *me)
|
|
||||||
{
|
|
||||||
setFrameStyle(QFrame::Raised | QFrame::Panel);
|
|
||||||
MenuItem::mouseReleaseEvent(me);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MenuAction::mousePressEvent(QMouseEvent *)
|
|
||||||
{
|
|
||||||
setFrameStyle(QFrame::Sunken | QFrame::Panel);
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
#ifndef MENULABEL_H
|
|
||||||
#define MENULABEL_H
|
|
||||||
|
|
||||||
#include "menuitem.h"
|
|
||||||
#include <QVBoxLayout>
|
|
||||||
#include <QLabel>
|
|
||||||
|
|
||||||
class MenuAction : public MenuItem
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
enum class ArrowType {
|
|
||||||
None,
|
|
||||||
Left,
|
|
||||||
Right,
|
|
||||||
};
|
|
||||||
|
|
||||||
MenuAction(const QString &l, ArrowType arrow = ArrowType::None);
|
|
||||||
void AddSubline(const QString &l);
|
|
||||||
void RemoveSubline();
|
|
||||||
signals:
|
|
||||||
void triggered();
|
|
||||||
public slots:
|
|
||||||
void userSelected() override;
|
|
||||||
private:
|
|
||||||
QVBoxLayout layout;
|
|
||||||
QLabel *subline;
|
|
||||||
protected:
|
|
||||||
void mouseReleaseEvent(QMouseEvent *me) override;
|
|
||||||
void mousePressEvent(QMouseEvent *me) override;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // MENULABEL_H
|
|
@ -1,36 +0,0 @@
|
|||||||
#include "menubool.h"
|
|
||||||
|
|
||||||
#include <QLabel>
|
|
||||||
|
|
||||||
MenuBool::MenuBool(QString name, bool defaultValue)
|
|
||||||
{
|
|
||||||
auto label = new QLabel(name, this);
|
|
||||||
label->setAlignment(Qt::AlignCenter);
|
|
||||||
layout.addWidget(label);
|
|
||||||
sw = new ToggleSwitch(this, defaultValue);
|
|
||||||
layout.addWidget(sw);
|
|
||||||
setLayout(&layout);
|
|
||||||
connect(sw, &ToggleSwitch::toggled, this, &MenuBool::valueChanged);
|
|
||||||
sw->setFocusPolicy(Qt::NoFocus);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MenuBool::setValue(bool value)
|
|
||||||
{
|
|
||||||
sw->setState(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MenuBool::userSelected()
|
|
||||||
{
|
|
||||||
sw->toggle();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MenuBool::mouseReleaseEvent(QMouseEvent *me)
|
|
||||||
{
|
|
||||||
setFrameStyle(QFrame::Raised | QFrame::Panel);
|
|
||||||
MenuItem::mouseReleaseEvent(me);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MenuBool::mousePressEvent(QMouseEvent *)
|
|
||||||
{
|
|
||||||
setFrameStyle(QFrame::Sunken | QFrame::Panel);
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
#ifndef MENUBOOL_H
|
|
||||||
#define MENUBOOL_H
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include "menuitem.h"
|
|
||||||
#include <QVBoxLayout>
|
|
||||||
#include "CustomWidgets/toggleswitch.h"
|
|
||||||
|
|
||||||
class MenuBool : public MenuItem
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
MenuBool(QString name, bool defaultValue = false);
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void valueChanged(bool value);
|
|
||||||
public slots:
|
|
||||||
void setValue(bool value);
|
|
||||||
void userSelected() override;
|
|
||||||
protected:
|
|
||||||
void mouseReleaseEvent(QMouseEvent *me) override;
|
|
||||||
void mousePressEvent(QMouseEvent *me) override;
|
|
||||||
private:
|
|
||||||
QVBoxLayout layout;
|
|
||||||
ToggleSwitch *sw;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // MENUBOOL_H
|
|
@ -1,17 +0,0 @@
|
|||||||
#include "menuitem.h"
|
|
||||||
|
|
||||||
#include <QMouseEvent>
|
|
||||||
|
|
||||||
MenuItem::MenuItem() : QFrame()
|
|
||||||
{
|
|
||||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
|
||||||
//setStyleSheet("*:focus {background: lightblue}");
|
|
||||||
setFocusPolicy(Qt::StrongFocus);
|
|
||||||
setFrameStyle(QFrame::Raised | QFrame::Panel);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MenuItem::mouseReleaseEvent(QMouseEvent *me)
|
|
||||||
{
|
|
||||||
userSelected();
|
|
||||||
me->accept();
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
#ifndef MENUITEM_H
|
|
||||||
#define MENUITEM_H
|
|
||||||
|
|
||||||
#include <QFrame>
|
|
||||||
|
|
||||||
class MenuItem : public QFrame
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
MenuItem();
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
virtual void userSelected(){};
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void mouseReleaseEvent(QMouseEvent *me) override;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // MENUITEM_H
|
|
@ -1,46 +0,0 @@
|
|||||||
#include "menuvalue.h"
|
|
||||||
|
|
||||||
#include <QVBoxLayout>
|
|
||||||
#include <math.h>
|
|
||||||
#include <sstream>
|
|
||||||
#include <iomanip>
|
|
||||||
#include "valueinput.h"
|
|
||||||
#include <QMouseEvent>
|
|
||||||
#include "unit.h"
|
|
||||||
#include <QDoubleValidator>
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
MenuValue::MenuValue(QString name, double defaultValue, QString unit, QString prefixes, int precision)
|
|
||||||
: name(name)
|
|
||||||
{
|
|
||||||
if(prefixes.indexOf(' ') < 0) {
|
|
||||||
throw runtime_error("Prefix string must contain space");
|
|
||||||
}
|
|
||||||
auto layout = new QVBoxLayout;
|
|
||||||
auto label = new QLabel(name, this);
|
|
||||||
label->setAlignment(Qt::AlignCenter);
|
|
||||||
layout->addWidget(label);
|
|
||||||
lvalue = new SIUnitEdit(unit, prefixes, precision);
|
|
||||||
// pass on signal
|
|
||||||
connect(lvalue, &SIUnitEdit::valueChanged, this, &MenuValue::valueChanged);
|
|
||||||
layout->addWidget(lvalue);
|
|
||||||
setValue(defaultValue);
|
|
||||||
setLayout(layout);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MenuValue::setValue(double value)
|
|
||||||
{
|
|
||||||
lvalue->setValue(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MenuValue::setValueQuiet(double value)
|
|
||||||
{
|
|
||||||
lvalue->setValueQuiet(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MenuValue::userSelected()
|
|
||||||
{
|
|
||||||
lvalue->setFocus();
|
|
||||||
//startInputDialog();
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
#ifndef MENUVALUE_H
|
|
||||||
#define MENUVALUE_H
|
|
||||||
|
|
||||||
#include "menuitem.h"
|
|
||||||
#include <QLabel>
|
|
||||||
#include <CustomWidgets/siunitedit.h>
|
|
||||||
|
|
||||||
class MenuValue : public MenuItem
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
MenuValue(QString name, double defaultValue = 0.0, QString unit = QString(), QString prefixes = " ", int precision = 0);
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void valueChanged(double value);
|
|
||||||
public slots:
|
|
||||||
void setValue(double value);
|
|
||||||
// same as setValue, except that no valueChanged signal is emitted
|
|
||||||
void setValueQuiet(double value);
|
|
||||||
void userSelected() override;
|
|
||||||
private:
|
|
||||||
SIUnitEdit *lvalue;
|
|
||||||
const QString name;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // MENUVALUE_H
|
|
File diff suppressed because it is too large
Load Diff
89
Software/PC_Application/VNA/vna.h
Normal file
89
Software/PC_Application/VNA/vna.h
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
#ifndef VNA_H
|
||||||
|
#define VNA_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QWidget>
|
||||||
|
#include "appwindow.h"
|
||||||
|
#include "mode.h"
|
||||||
|
#include "CustomWidgets/tilewidget.h"
|
||||||
|
|
||||||
|
class VNA : public Mode
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
VNA(AppWindow *window);
|
||||||
|
|
||||||
|
void deactivate() override;
|
||||||
|
void initializeDevice() override;
|
||||||
|
private slots:
|
||||||
|
void NewDatapoint(Protocol::Datapoint d);
|
||||||
|
void StartImpedanceMatching();
|
||||||
|
// Sweep control
|
||||||
|
void SetStartFreq(double freq);
|
||||||
|
void SetStopFreq(double freq);
|
||||||
|
void SetCenterFreq(double freq);
|
||||||
|
void SetSpan(double span);
|
||||||
|
void SetFullSpan();
|
||||||
|
void SpanZoomIn();
|
||||||
|
void SpanZoomOut();
|
||||||
|
// Acquisition control
|
||||||
|
void SetSourceLevel(double level);
|
||||||
|
void SetPoints(unsigned int points);
|
||||||
|
void SetIFBandwidth(double bandwidth);
|
||||||
|
void SetAveraging(unsigned int averages);
|
||||||
|
// Calibration
|
||||||
|
void DisableCalibration(bool force = false);
|
||||||
|
void ApplyCalibration(Calibration::Type type);
|
||||||
|
void StartCalibrationMeasurement(Calibration::Measurement m);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void CalibrationMeasurementComplete(Calibration::Measurement m);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void UpdateStatusPanel();
|
||||||
|
void SettingsChanged();
|
||||||
|
void ConstrainAndUpdateFrequencies();
|
||||||
|
void LoadSweepSettings();
|
||||||
|
void StoreSweepSettings();
|
||||||
|
|
||||||
|
Preferences pref;
|
||||||
|
|
||||||
|
QActionGroup *deviceActionGroup;
|
||||||
|
Protocol::SweepSettings settings;
|
||||||
|
unsigned int averages;
|
||||||
|
TraceModel traceModel;
|
||||||
|
TraceMarkerModel *markerModel;
|
||||||
|
Averaging average;
|
||||||
|
|
||||||
|
// Calibration
|
||||||
|
Calibration cal;
|
||||||
|
bool calValid;
|
||||||
|
Calibration::Measurement calMeasurement;
|
||||||
|
bool calMeasuring;
|
||||||
|
bool calWaitFirst;
|
||||||
|
QProgressDialog calDialog;
|
||||||
|
|
||||||
|
// Status Labels
|
||||||
|
QLabel *lStart, *lCenter, *lStop, *lSpan, *lPoints, *lBandwidth;
|
||||||
|
QLabel *lCalibration;
|
||||||
|
QLabel *lAverages;
|
||||||
|
|
||||||
|
TileWidget *central;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void dataChanged();
|
||||||
|
void startFreqChanged(double freq);
|
||||||
|
void stopFreqChanged(double freq);
|
||||||
|
void centerFreqChanged(double freq);
|
||||||
|
void spanChanged(double span);
|
||||||
|
|
||||||
|
void sourceLevelChanged(double level);
|
||||||
|
void pointsChanged(unsigned int points);
|
||||||
|
void IFBandwidthChanged(double bandwidth);
|
||||||
|
void averagingChanged(unsigned int averages);
|
||||||
|
|
||||||
|
void CalibrationDisabled();
|
||||||
|
void CalibrationApplied(Calibration::Type type);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // VNA_H
|
316
Software/PC_Application/appwindow.cpp
Normal file
316
Software/PC_Application/appwindow.cpp
Normal file
@ -0,0 +1,316 @@
|
|||||||
|
#include "appwindow.h"
|
||||||
|
#include <QGridLayout>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <math.h>
|
||||||
|
#include <QToolBar>
|
||||||
|
#include <QMenu>
|
||||||
|
#include <QToolButton>
|
||||||
|
#include <QActionGroup>
|
||||||
|
#include <QSpinBox>
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QSettings>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QFileDialog>
|
||||||
|
#include <QFile>
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <QDateTime>
|
||||||
|
#include "unit.h"
|
||||||
|
#include "CustomWidgets/toggleswitch.h"
|
||||||
|
#include "Device/manualcontroldialog.h"
|
||||||
|
#include "Traces/tracemodel.h"
|
||||||
|
#include "Traces/tracewidget.h"
|
||||||
|
#include "Traces/tracesmithchart.h"
|
||||||
|
#include "Traces/tracebodeplot.h"
|
||||||
|
#include "Traces/traceimportdialog.h"
|
||||||
|
#include "CustomWidgets/tilewidget.h"
|
||||||
|
#include "CustomWidgets/siunitedit.h"
|
||||||
|
#include <QDockWidget>
|
||||||
|
#include "Traces/markerwidget.h"
|
||||||
|
#include "Tools/impedancematchdialog.h"
|
||||||
|
#include "Calibration/calibrationtracedialog.h"
|
||||||
|
#include "ui_main.h"
|
||||||
|
#include "Device/firmwareupdatedialog.h"
|
||||||
|
#include "preferences.h"
|
||||||
|
#include "Generator/signalgenwidget.h"
|
||||||
|
#include <QDesktopWidget>
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QActionGroup>
|
||||||
|
#include <mode.h>
|
||||||
|
#include "VNA/vna.h"
|
||||||
|
#include "Generator/generator.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
AppWindow::AppWindow(QWidget *parent)
|
||||||
|
: QMainWindow(parent)
|
||||||
|
, deviceActionGroup(new QActionGroup(this))
|
||||||
|
, ui(new Ui::MainWindow)
|
||||||
|
{
|
||||||
|
QCoreApplication::setOrganizationName("VNA");
|
||||||
|
QCoreApplication::setApplicationName("Application");
|
||||||
|
|
||||||
|
pref.load();
|
||||||
|
device = nullptr;
|
||||||
|
|
||||||
|
ui->setupUi(this);
|
||||||
|
// ui->statusbar->insertPermanentWidget(0, &lDeviceStatus);
|
||||||
|
// ui->statusbar->insertPermanentWidget(1, new QPushButton("Test"));
|
||||||
|
ui->statusbar->addWidget(&lConnectionStatus);
|
||||||
|
auto div1 = new QFrame;
|
||||||
|
div1->setFrameShape(QFrame::VLine);
|
||||||
|
ui->statusbar->addWidget(div1);
|
||||||
|
ui->statusbar->addWidget(&lDeviceInfo);
|
||||||
|
ui->statusbar->addWidget(new QLabel, 1);
|
||||||
|
//ui->statusbar->setStyleSheet("QStatusBar::item { border: 1px solid black; };");
|
||||||
|
|
||||||
|
CreateToolbars();
|
||||||
|
auto logDock = new QDockWidget("Device Log");
|
||||||
|
logDock->setWidget(&deviceLog);
|
||||||
|
addDockWidget(Qt::BottomDockWidgetArea, logDock);
|
||||||
|
|
||||||
|
// fill toolbar/dock menu
|
||||||
|
ui->menuDocks->clear();
|
||||||
|
for(auto d : findChildren<QDockWidget*>()) {
|
||||||
|
ui->menuDocks->addAction(d->toggleViewAction());
|
||||||
|
}
|
||||||
|
ui->menuToolbars->clear();
|
||||||
|
for(auto t : findChildren<QToolBar*>()) {
|
||||||
|
ui->menuToolbars->addAction(t->toggleViewAction());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create GUI modes
|
||||||
|
central = new QStackedWidget;
|
||||||
|
setCentralWidget(central);
|
||||||
|
auto vna = new VNA(this);
|
||||||
|
new Generator(this);
|
||||||
|
// auto signalGenWidget = new Signalgenerator;
|
||||||
|
// modeSGen = new GUIMode(this, "Signal Generator", signalGenWidget);
|
||||||
|
|
||||||
|
// UI connections
|
||||||
|
connect(ui->actionUpdate_Device_List, &QAction::triggered, this, &AppWindow::UpdateDeviceList);
|
||||||
|
connect(ui->actionDisconnect, &QAction::triggered, this, &AppWindow::DisconnectDevice);
|
||||||
|
connect(ui->actionQuit, &QAction::triggered, this, &AppWindow::close);
|
||||||
|
connect(ui->actionManual_Control, &QAction::triggered, this, &AppWindow::StartManualControl);
|
||||||
|
connect(ui->actionFirmware_Update, &QAction::triggered, [=](){
|
||||||
|
if(device) {
|
||||||
|
auto fw_update = new FirmwareUpdateDialog(device);
|
||||||
|
fw_update->exec();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
connect(ui->actionPreferences, &QAction::triggered, [=](){
|
||||||
|
pref.edit();
|
||||||
|
});
|
||||||
|
|
||||||
|
setWindowTitle("VNA");
|
||||||
|
|
||||||
|
setCorner(Qt::TopLeftCorner, Qt::LeftDockWidgetArea);
|
||||||
|
setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea);
|
||||||
|
setCorner(Qt::TopRightCorner, Qt::RightDockWidgetArea);
|
||||||
|
setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea);
|
||||||
|
|
||||||
|
{
|
||||||
|
QSettings settings;
|
||||||
|
restoreGeometry(settings.value("geometry").toByteArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set ObjectName for toolbars and docks
|
||||||
|
for(auto d : findChildren<QDockWidget*>()) {
|
||||||
|
d->setObjectName(d->windowTitle());
|
||||||
|
}
|
||||||
|
for(auto t : findChildren<QToolBar*>()) {
|
||||||
|
t->setObjectName(t->windowTitle());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set default mode
|
||||||
|
vna->activate();
|
||||||
|
|
||||||
|
qRegisterMetaType<Protocol::Datapoint>("Datapoint");
|
||||||
|
|
||||||
|
// List available devices
|
||||||
|
if(UpdateDeviceList() && pref.Startup.ConnectToFirstDevice) {
|
||||||
|
// at least one device available
|
||||||
|
ConnectToDevice();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppWindow::closeEvent(QCloseEvent *event)
|
||||||
|
{
|
||||||
|
QSettings settings;
|
||||||
|
settings.setValue("geometry", saveGeometry());
|
||||||
|
// deactivate currently used mode (stores mode state in settings)
|
||||||
|
if(Mode::getActiveMode()) {
|
||||||
|
Mode::getActiveMode()->deactivate();
|
||||||
|
}
|
||||||
|
pref.store();
|
||||||
|
QMainWindow::closeEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppWindow::ConnectToDevice(QString serial)
|
||||||
|
{
|
||||||
|
if(device) {
|
||||||
|
DisconnectDevice();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
qDebug() << "Attempting to connect to device...";
|
||||||
|
device = new Device(serial);
|
||||||
|
lConnectionStatus.setText("Connected to " + device->serial());
|
||||||
|
qInfo() << "Connected to " << device->serial();
|
||||||
|
lDeviceInfo.setText(device->getLastDeviceInfoString());
|
||||||
|
connect(device, &Device::LogLineReceived, &deviceLog, &DeviceLog::addLine);
|
||||||
|
connect(device, &Device::ConnectionLost, this, &AppWindow::DeviceConnectionLost);
|
||||||
|
connect(device, &Device::DeviceInfoUpdated, [this]() {
|
||||||
|
lDeviceInfo.setText(device->getLastDeviceInfoString());
|
||||||
|
});
|
||||||
|
ui->actionDisconnect->setEnabled(true);
|
||||||
|
ui->actionManual_Control->setEnabled(true);
|
||||||
|
ui->menuDefault_Calibration->setEnabled(true);
|
||||||
|
ui->actionFirmware_Update->setEnabled(true);
|
||||||
|
|
||||||
|
Mode::getActiveMode()->initializeDevice();
|
||||||
|
UpdateReference();
|
||||||
|
} catch (const runtime_error e) {
|
||||||
|
DisconnectDevice();
|
||||||
|
UpdateDeviceList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppWindow::DisconnectDevice()
|
||||||
|
{
|
||||||
|
if(device) {
|
||||||
|
delete device;
|
||||||
|
device = nullptr;
|
||||||
|
}
|
||||||
|
ui->actionDisconnect->setEnabled(false);
|
||||||
|
ui->actionManual_Control->setEnabled(false);
|
||||||
|
ui->menuDefault_Calibration->setEnabled(false);
|
||||||
|
ui->actionFirmware_Update->setEnabled(false);
|
||||||
|
if(deviceActionGroup->checkedAction()) {
|
||||||
|
deviceActionGroup->checkedAction()->setChecked(false);
|
||||||
|
}
|
||||||
|
lConnectionStatus.setText("No device connected");
|
||||||
|
lDeviceInfo.setText("No device information available yet");
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppWindow::DeviceConnectionLost()
|
||||||
|
{
|
||||||
|
DisconnectDevice();
|
||||||
|
QMessageBox::warning(this, "Disconnected", "The USB connection to the device has been lost");
|
||||||
|
UpdateDeviceList();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppWindow::CreateToolbars()
|
||||||
|
{
|
||||||
|
// Reference toolbar
|
||||||
|
auto tb_reference = new QToolBar("Reference", this);
|
||||||
|
tb_reference->addWidget(new QLabel("Ref:"));
|
||||||
|
toolbars.reference.type = new QComboBox();
|
||||||
|
toolbars.reference.type->addItem("Int");
|
||||||
|
toolbars.reference.type->addItem("Ext");
|
||||||
|
toolbars.reference.automatic = new QCheckBox("Auto");
|
||||||
|
connect(toolbars.reference.automatic, &QCheckBox::clicked, [this](bool checked) {
|
||||||
|
toolbars.reference.type->setEnabled(!checked);
|
||||||
|
UpdateReference();
|
||||||
|
});
|
||||||
|
// toolbars.reference.automatic->setChecked(true);
|
||||||
|
tb_reference->addWidget(toolbars.reference.type);
|
||||||
|
tb_reference->addWidget(toolbars.reference.automatic);
|
||||||
|
tb_reference->addSeparator();
|
||||||
|
tb_reference->addWidget(new QLabel("Ref out:"));
|
||||||
|
toolbars.reference.outputEnabled = new QCheckBox();
|
||||||
|
toolbars.reference.outFreq = new QComboBox();
|
||||||
|
toolbars.reference.outFreq->addItem("10 MHz");
|
||||||
|
toolbars.reference.outFreq->addItem("100 MHz");
|
||||||
|
tb_reference->addWidget(toolbars.reference.outputEnabled);
|
||||||
|
tb_reference->addWidget(toolbars.reference.outFreq);
|
||||||
|
connect(toolbars.reference.type, qOverload<int>(&QComboBox::currentIndexChanged), this, &AppWindow::UpdateReference);
|
||||||
|
connect(toolbars.reference.outFreq, qOverload<int>(&QComboBox::currentIndexChanged), this, &AppWindow::UpdateReference);
|
||||||
|
connect(toolbars.reference.outputEnabled, &QCheckBox::clicked, this, &AppWindow::UpdateReference);
|
||||||
|
|
||||||
|
addToolBar(tb_reference);
|
||||||
|
}
|
||||||
|
|
||||||
|
int AppWindow::UpdateDeviceList()
|
||||||
|
{
|
||||||
|
ui->menuConnect_to->clear();
|
||||||
|
auto devices = Device::GetDevices();
|
||||||
|
if(devices.size()) {
|
||||||
|
for(auto d : devices) {
|
||||||
|
auto connectAction = ui->menuConnect_to->addAction(d);
|
||||||
|
deviceActionGroup->addAction(connectAction);
|
||||||
|
connectAction->setCheckable(true);
|
||||||
|
if(device && d == device->serial()) {
|
||||||
|
connectAction->setChecked(true);
|
||||||
|
}
|
||||||
|
connect(connectAction, &QAction::triggered, [this, connectAction, d]() {
|
||||||
|
ConnectToDevice(d);
|
||||||
|
if(device) {
|
||||||
|
// connectAction might have been unchecked if it was a reconnect to the already connected device
|
||||||
|
connectAction->setChecked(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
ui->menuConnect_to->setEnabled(true);
|
||||||
|
} else {
|
||||||
|
// no devices available, disable connection option
|
||||||
|
ui->menuConnect_to->setEnabled(false);
|
||||||
|
}
|
||||||
|
return devices.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppWindow::StartManualControl()
|
||||||
|
{
|
||||||
|
auto control = new ManualControlDialog(*device, this);
|
||||||
|
connect(control, &QDialog::finished, [=](){
|
||||||
|
Mode::getActiveMode()->initializeDevice();
|
||||||
|
});
|
||||||
|
control->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppWindow::UpdateReference()
|
||||||
|
{
|
||||||
|
if(!device) {
|
||||||
|
// can't update without a device connected
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Protocol::ReferenceSettings s = {};
|
||||||
|
if(toolbars.reference.automatic->isChecked()) {
|
||||||
|
s.AutomaticSwitch = 1;
|
||||||
|
}
|
||||||
|
if(toolbars.reference.type->currentText()=="Ext") {
|
||||||
|
s.UseExternalRef = 1;
|
||||||
|
}
|
||||||
|
if(toolbars.reference.outputEnabled->isChecked()) {
|
||||||
|
switch(toolbars.reference.outFreq->currentIndex()) {
|
||||||
|
case 0:
|
||||||
|
s.ExtRefOuputFreq = 10000000;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
s.ExtRefOuputFreq = 100000000;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Protocol::PacketInfo p;
|
||||||
|
p.type = Protocol::PacketType::Reference;
|
||||||
|
p.reference = s;
|
||||||
|
device->SendPacket(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
Device *AppWindow::getDevice() const
|
||||||
|
{
|
||||||
|
return device;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStackedWidget *AppWindow::getCentral() const
|
||||||
|
{
|
||||||
|
return central;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ui::MainWindow *AppWindow::getUi() const
|
||||||
|
{
|
||||||
|
return ui;
|
||||||
|
}
|
75
Software/PC_Application/appwindow.h
Normal file
75
Software/PC_Application/appwindow.h
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
#ifndef APPWINDOW_H
|
||||||
|
#define APPWINDOW_H
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QMainWindow>
|
||||||
|
#include <QGridLayout>
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QStackedWidget>
|
||||||
|
#include "Device/device.h"
|
||||||
|
#include "Traces/traceplot.h"
|
||||||
|
#include "Calibration/calibration.h"
|
||||||
|
#include <QProgressDialog>
|
||||||
|
#include "Traces/tracemodel.h"
|
||||||
|
#include "Traces/tracemarkermodel.h"
|
||||||
|
#include "averaging.h"
|
||||||
|
#include "Device/devicelog.h"
|
||||||
|
#include "preferences.h"
|
||||||
|
#include <QButtonGroup>
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QLabel>
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class MainWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
class AppWindow : public QMainWindow
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
AppWindow(QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
|
||||||
|
Ui::MainWindow *getUi() const;
|
||||||
|
QStackedWidget *getCentral() const;
|
||||||
|
Device *getDevice() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void closeEvent(QCloseEvent *event) override;
|
||||||
|
private slots:
|
||||||
|
void ConnectToDevice(QString serial = QString());
|
||||||
|
void DisconnectDevice();
|
||||||
|
int UpdateDeviceList();
|
||||||
|
void StartManualControl();
|
||||||
|
void UpdateReference();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void DeviceConnectionLost();
|
||||||
|
void CreateToolbars();
|
||||||
|
|
||||||
|
QStackedWidget *central;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
struct {
|
||||||
|
QComboBox *type;
|
||||||
|
QCheckBox *automatic;
|
||||||
|
QCheckBox *outputEnabled;
|
||||||
|
QComboBox *outFreq;
|
||||||
|
} reference;
|
||||||
|
} toolbars;
|
||||||
|
|
||||||
|
Preferences pref;
|
||||||
|
|
||||||
|
Device *device;
|
||||||
|
DeviceLog deviceLog;
|
||||||
|
QString deviceSerial;
|
||||||
|
QActionGroup *deviceActionGroup;
|
||||||
|
|
||||||
|
// Status bar widgets
|
||||||
|
QLabel lConnectionStatus;
|
||||||
|
QLabel lDeviceInfo;
|
||||||
|
|
||||||
|
Ui::MainWindow *ui;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // VNA_H
|
@ -2,12 +2,7 @@
|
|||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <QtWidgets/QApplication>
|
#include <QtWidgets/QApplication>
|
||||||
#include "vna.h"
|
#include "appwindow.h"
|
||||||
#include "valueinput.h"
|
|
||||||
|
|
||||||
#include "Menu/menu.h"
|
|
||||||
#include "Menu/menuaction.h"
|
|
||||||
#include "Menu/menuvalue.h"
|
|
||||||
|
|
||||||
#include "Calibration/calkit.h"
|
#include "Calibration/calkit.h"
|
||||||
#include "touchstone.h"
|
#include "touchstone.h"
|
||||||
@ -15,7 +10,7 @@
|
|||||||
#include <complex>
|
#include <complex>
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
QApplication a(argc, argv);
|
QApplication a(argc, argv);
|
||||||
VNA vna;
|
AppWindow vna;
|
||||||
vna.resize(1280, 800);
|
vna.resize(1280, 800);
|
||||||
vna.show();
|
vna.show();
|
||||||
a.exec();
|
a.exec();
|
||||||
|
@ -60,12 +60,6 @@
|
|||||||
<addaction name="menuDefault_Calibration"/>
|
<addaction name="menuDefault_Calibration"/>
|
||||||
<addaction name="actionFirmware_Update"/>
|
<addaction name="actionFirmware_Update"/>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QMenu" name="menuTools">
|
|
||||||
<property name="title">
|
|
||||||
<string>Tools</string>
|
|
||||||
</property>
|
|
||||||
<addaction name="actionImpedance_Matching"/>
|
|
||||||
</widget>
|
|
||||||
<widget class="QMenu" name="menuWindow">
|
<widget class="QMenu" name="menuWindow">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Window</string>
|
<string>Window</string>
|
||||||
@ -86,20 +80,8 @@
|
|||||||
<addaction name="menuToolbars"/>
|
<addaction name="menuToolbars"/>
|
||||||
<addaction name="actionPreferences"/>
|
<addaction name="actionPreferences"/>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QMenu" name="menuCalibration">
|
|
||||||
<property name="title">
|
|
||||||
<string>Calibration</string>
|
|
||||||
</property>
|
|
||||||
<addaction name="actionCalDisabled"/>
|
|
||||||
<addaction name="separator"/>
|
|
||||||
<addaction name="actionTracedata"/>
|
|
||||||
<addaction name="actionImport_error_terms_as_traces"/>
|
|
||||||
<addaction name="actionEdit_Calibration_Kit"/>
|
|
||||||
</widget>
|
|
||||||
<addaction name="menuFile"/>
|
<addaction name="menuFile"/>
|
||||||
<addaction name="menuDevice"/>
|
<addaction name="menuDevice"/>
|
||||||
<addaction name="menuCalibration"/>
|
|
||||||
<addaction name="menuTools"/>
|
|
||||||
<addaction name="menuWindow"/>
|
<addaction name="menuWindow"/>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QStatusBar" name="statusbar"/>
|
<widget class="QStatusBar" name="statusbar"/>
|
||||||
@ -137,11 +119,6 @@
|
|||||||
<string>Dummy</string>
|
<string>Dummy</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="actionImpedance_Matching">
|
|
||||||
<property name="text">
|
|
||||||
<string>Impedance Matching</string>
|
|
||||||
</property>
|
|
||||||
</action>
|
|
||||||
<action name="actionManual_Control">
|
<action name="actionManual_Control">
|
||||||
<property name="enabled">
|
<property name="enabled">
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
@ -160,32 +137,6 @@
|
|||||||
<string>Dummy</string>
|
<string>Dummy</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="actionCalDisabled">
|
|
||||||
<property name="checkable">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Disabled</string>
|
|
||||||
</property>
|
|
||||||
</action>
|
|
||||||
<action name="actionTracedata">
|
|
||||||
<property name="text">
|
|
||||||
<string>Calibration Data</string>
|
|
||||||
</property>
|
|
||||||
</action>
|
|
||||||
<action name="actionEdit_Calibration_Kit">
|
|
||||||
<property name="text">
|
|
||||||
<string>Edit Calibration Kit</string>
|
|
||||||
</property>
|
|
||||||
</action>
|
|
||||||
<action name="actionImport_error_terms_as_traces">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Import error terms as traces</string>
|
|
||||||
</property>
|
|
||||||
</action>
|
|
||||||
<action name="actionAssignDefaultCal">
|
<action name="actionAssignDefaultCal">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Assign...</string>
|
<string>Assign...</string>
|
||||||
@ -212,11 +163,6 @@
|
|||||||
<string>Preferences</string>
|
<string>Preferences</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="actionDummy_4">
|
|
||||||
<property name="text">
|
|
||||||
<string>Dummy</string>
|
|
||||||
</property>
|
|
||||||
</action>
|
|
||||||
</widget>
|
</widget>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections/>
|
<connections/>
|
||||||
|
151
Software/PC_Application/mode.cpp
Normal file
151
Software/PC_Application/mode.cpp
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
#include "mode.h"
|
||||||
|
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QSettings>
|
||||||
|
#include "ui_main.h"
|
||||||
|
|
||||||
|
Mode* Mode::activeMode = nullptr;
|
||||||
|
QWidget* Mode::cornerWidget = nullptr;
|
||||||
|
QButtonGroup* Mode::modeButtonGroup = nullptr;
|
||||||
|
|
||||||
|
Mode::Mode(AppWindow *window, QString name)
|
||||||
|
: window(window),
|
||||||
|
name(name),
|
||||||
|
central(nullptr)
|
||||||
|
{
|
||||||
|
// Create mode switch button
|
||||||
|
auto modeSwitch = new QPushButton(name);
|
||||||
|
modeSwitch->setCheckable(true);
|
||||||
|
modeSwitch->setMaximumHeight(window->getUi()->menubar->height());
|
||||||
|
if(!cornerWidget) {
|
||||||
|
// this is the first created mode, initialize corner widget and set this mode as active
|
||||||
|
modeSwitch->setChecked(true);
|
||||||
|
cornerWidget = new QWidget;
|
||||||
|
cornerWidget->setLayout(new QHBoxLayout);
|
||||||
|
cornerWidget->layout()->setSpacing(0);
|
||||||
|
cornerWidget->layout()->setMargin(0);
|
||||||
|
cornerWidget->layout()->setContentsMargins(0,0,0,0);
|
||||||
|
window->menuBar()->setCornerWidget(cornerWidget);
|
||||||
|
modeButtonGroup = new QButtonGroup;
|
||||||
|
window->getUi()->menubar->setMaximumHeight(window->getUi()->menubar->height());
|
||||||
|
}
|
||||||
|
cornerWidget->layout()->addWidget(modeSwitch);
|
||||||
|
modeButtonGroup->addButton(modeSwitch);
|
||||||
|
|
||||||
|
connect(modeSwitch, &QPushButton::clicked, [=](){
|
||||||
|
activate();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mode::activate()
|
||||||
|
{
|
||||||
|
if(activeMode == this) {
|
||||||
|
// already active;
|
||||||
|
return;
|
||||||
|
} else if(activeMode) {
|
||||||
|
activeMode->deactivate();
|
||||||
|
}
|
||||||
|
|
||||||
|
// show all mode specific GUI elements
|
||||||
|
for(auto t : toolbars) {
|
||||||
|
t->show();
|
||||||
|
window->getUi()->menuToolbars->addAction(t->toggleViewAction());
|
||||||
|
}
|
||||||
|
for(auto d : docks) {
|
||||||
|
d->show();
|
||||||
|
window->getUi()->menuDocks->addAction(d->toggleViewAction());
|
||||||
|
}
|
||||||
|
for(auto a : actions) {
|
||||||
|
a->setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
QSettings settings;
|
||||||
|
window->getCentral()->setCurrentWidget(central);
|
||||||
|
|
||||||
|
// restore dock and toolbar positions
|
||||||
|
// window->restoreGeometry(settings.value("geometry_"+name).toByteArray());
|
||||||
|
window->restoreState(settings.value("windowState_"+name).toByteArray());
|
||||||
|
|
||||||
|
// restore visibility of toolbars and docks
|
||||||
|
// window->getUi()->menuDocks->clear();
|
||||||
|
for(auto d : window->findChildren<QDockWidget*>()) {
|
||||||
|
// window->getUi()->menuDocks->addAction(d->toggleViewAction());
|
||||||
|
bool hidden = settings.value("dock_"+name+"_"+d->windowTitle(), d->isHidden()).toBool();
|
||||||
|
if(hidden) {
|
||||||
|
d->hide();
|
||||||
|
} else {
|
||||||
|
d->show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// window->getUi()->menuToolbars->clear();
|
||||||
|
for(auto t : window->findChildren<QToolBar*>()) {
|
||||||
|
// window->getUi()->menuToolbars->addAction(t->toggleViewAction());
|
||||||
|
bool hidden = settings.value("toolbar_"+name+"_"+t->windowTitle(), t->isHidden()).toBool();
|
||||||
|
if(hidden) {
|
||||||
|
t->hide();
|
||||||
|
} else {
|
||||||
|
t->show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
activeMode = this;
|
||||||
|
|
||||||
|
if(window->getDevice()) {
|
||||||
|
initializeDevice();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mode::deactivate()
|
||||||
|
{
|
||||||
|
QSettings settings;
|
||||||
|
// save dock/toolbar visibility
|
||||||
|
for(auto d : window->findChildren<QDockWidget*>()) {
|
||||||
|
settings.setValue("dock_"+name+"_"+d->windowTitle(), d->isHidden());
|
||||||
|
}
|
||||||
|
for(auto t : window->findChildren<QToolBar*>()) {
|
||||||
|
settings.setValue("toolbar_"+name+"_"+t->windowTitle(), t->isHidden());
|
||||||
|
}
|
||||||
|
// settings.setValue("geometry_"+name, window->saveGeometry());
|
||||||
|
settings.setValue("windowState_"+name, window->saveState());
|
||||||
|
|
||||||
|
// hide all mode specific GUI elements
|
||||||
|
for(auto t : toolbars) {
|
||||||
|
t->hide();
|
||||||
|
window->getUi()->menuToolbars->removeAction(t->toggleViewAction());
|
||||||
|
}
|
||||||
|
for(auto d : docks) {
|
||||||
|
d->hide();
|
||||||
|
window->getUi()->menuDocks->removeAction(d->toggleViewAction());
|
||||||
|
}
|
||||||
|
for(auto a : actions) {
|
||||||
|
a->setVisible(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
activeMode = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Mode *Mode::getActiveMode()
|
||||||
|
{
|
||||||
|
return activeMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mode::finalize(QWidget *centralWidget)
|
||||||
|
{
|
||||||
|
central = centralWidget;
|
||||||
|
window->getCentral()->addWidget(central);
|
||||||
|
// hide all mode specific GUI elements
|
||||||
|
for(auto t : toolbars) {
|
||||||
|
t->hide();
|
||||||
|
}
|
||||||
|
for(auto d : docks) {
|
||||||
|
d->hide();
|
||||||
|
}
|
||||||
|
for(auto a : actions) {
|
||||||
|
a->setVisible(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Mode::getName() const
|
||||||
|
{
|
||||||
|
return name;
|
||||||
|
}
|
39
Software/PC_Application/mode.h
Normal file
39
Software/PC_Application/mode.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
#ifndef MODE_H
|
||||||
|
#define MODE_H
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QButtonGroup>
|
||||||
|
#include <QToolBar>
|
||||||
|
#include <QDockWidget>
|
||||||
|
#include <set>
|
||||||
|
#include "appwindow.h"
|
||||||
|
|
||||||
|
class Mode : public QWidget
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Mode(AppWindow *window, QString name);
|
||||||
|
virtual void activate();
|
||||||
|
virtual void deactivate();
|
||||||
|
QString getName() const;
|
||||||
|
static Mode *getActiveMode();
|
||||||
|
|
||||||
|
virtual void initializeDevice() = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// call once the derived class is fully initialized
|
||||||
|
void finalize(QWidget *centralWidget);
|
||||||
|
AppWindow *window;
|
||||||
|
std::set<QAction*> actions;
|
||||||
|
std::set<QToolBar*> toolbars;
|
||||||
|
std::set<QDockWidget*> docks;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static Mode *activeMode;
|
||||||
|
static QWidget *cornerWidget;
|
||||||
|
static QButtonGroup *modeButtonGroup;
|
||||||
|
const QString name;
|
||||||
|
QWidget *central;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MODE_H
|
@ -1,148 +0,0 @@
|
|||||||
#include "valueinput.h"
|
|
||||||
#include <QGridLayout>
|
|
||||||
#include <QKeyEvent>
|
|
||||||
#include <QApplication>
|
|
||||||
#include <QDesktopWidget>
|
|
||||||
|
|
||||||
constexpr QSize ValueInput::minButtonSize;
|
|
||||||
|
|
||||||
ValueInput::ValueInput(std::vector<Unit> units, QString name, QString initialValue)
|
|
||||||
{
|
|
||||||
auto fontButton = QFont("Arial", 12);
|
|
||||||
auto fontLabel = QFont("Arial", 30);
|
|
||||||
|
|
||||||
input = initialValue;
|
|
||||||
// always use dots instead of comma
|
|
||||||
input.replace(',', '.');
|
|
||||||
this->units = units;
|
|
||||||
setWindowTitle(name);
|
|
||||||
|
|
||||||
// Create layout
|
|
||||||
auto layout = new QGridLayout();
|
|
||||||
|
|
||||||
// Add Label
|
|
||||||
label = new QLabel();
|
|
||||||
layout->addWidget(label, 0, 0, 2, 4);
|
|
||||||
label->setText(input);
|
|
||||||
label->setAlignment(Qt::AlignCenter);
|
|
||||||
label->setFont(fontLabel);
|
|
||||||
|
|
||||||
// Create buttons and add to layout
|
|
||||||
for(int i=0;i<3;i++) {
|
|
||||||
for(int j=0;j<3;j++) {
|
|
||||||
int number = i+1 + j*3;
|
|
||||||
auto name = QString::number(number);
|
|
||||||
auto button = new QPushButton(name);
|
|
||||||
button->setFont(fontButton);
|
|
||||||
button->setMinimumSize(minButtonSize);
|
|
||||||
connect(button, &QPushButton::clicked, [=]() {this->AddToInput(name);});
|
|
||||||
layout->addWidget(button, j+2, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bDot = new QPushButton(".");
|
|
||||||
bDot->setFont(fontButton);
|
|
||||||
bDot->setMinimumSize(minButtonSize);
|
|
||||||
if(input.contains('.')) {
|
|
||||||
bDot->setDisabled(true);
|
|
||||||
}
|
|
||||||
layout->addWidget(bDot, 5, 0);
|
|
||||||
connect(bDot, &QPushButton::clicked, [=]() {this->AddToInput(".");});
|
|
||||||
auto bZero = new QPushButton("0");
|
|
||||||
bZero->setFont(fontButton);
|
|
||||||
bZero->setMinimumSize(minButtonSize);
|
|
||||||
connect(bZero, &QPushButton::clicked, [=]() {this->AddToInput("0");});
|
|
||||||
layout->addWidget(bZero, 5, 1);
|
|
||||||
auto bSign = new QPushButton("+/-");
|
|
||||||
bSign->setFont(fontButton);
|
|
||||||
bSign->setMinimumSize(minButtonSize);
|
|
||||||
layout->addWidget(bSign, 5, 2);
|
|
||||||
connect(bSign, SIGNAL(clicked()), this, SLOT(ChangeSign()));
|
|
||||||
|
|
||||||
auto bDel = new QPushButton("Backspace");
|
|
||||||
bDel->setMinimumSize(minButtonSize);
|
|
||||||
layout->addWidget(bDel, 6, 0, 1, 3);
|
|
||||||
connect(bDel, SIGNAL(clicked()), this, SLOT(Backspace()));
|
|
||||||
|
|
||||||
auto bAbort = new QPushButton("Abort");
|
|
||||||
bAbort->setMinimumSize(minButtonSize);
|
|
||||||
layout->addWidget(bAbort, 6, 3);
|
|
||||||
connect(bAbort, SIGNAL(clicked()), this, SLOT(Abort()));
|
|
||||||
|
|
||||||
// Add unit inputs
|
|
||||||
if(units.size() > 4) {
|
|
||||||
units.resize(4);
|
|
||||||
}
|
|
||||||
for(unsigned int i=0;i<units.size();i++) {
|
|
||||||
auto bUnit = new QPushButton(units[i].name);
|
|
||||||
bUnit->setFont(fontButton);
|
|
||||||
bUnit->setMinimumSize(minButtonSize);
|
|
||||||
connect(bUnit, &QPushButton::clicked, [=](){this->UnitPressed(units[i].factor);});
|
|
||||||
layout->addWidget(bUnit, i+2, 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
setLayout(layout);
|
|
||||||
setWindowModality(Qt::ApplicationModal);
|
|
||||||
show();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ValueInput::keyPressEvent(QKeyEvent *event) {
|
|
||||||
auto key = event->key();
|
|
||||||
if(key >= '0' && key <= '9') {
|
|
||||||
AddToInput((QChar) key);
|
|
||||||
event->accept();
|
|
||||||
} else if((key == '.' || key == ',') && bDot->isEnabled()) {
|
|
||||||
AddToInput(".");
|
|
||||||
event->accept();
|
|
||||||
} else if(key == Qt::Key_Escape) {
|
|
||||||
Abort();
|
|
||||||
event->accept();
|
|
||||||
} else if(key == Qt::Key_Backspace) {
|
|
||||||
Backspace();
|
|
||||||
event->accept();
|
|
||||||
} else if(key == '-') {
|
|
||||||
ChangeSign();
|
|
||||||
event->accept();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ValueInput::AddToInput(QString a)
|
|
||||||
{
|
|
||||||
input.append(a);
|
|
||||||
label->setText(input);
|
|
||||||
if(a == '.') {
|
|
||||||
bDot->setDisabled(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ValueInput::ChangeSign()
|
|
||||||
{
|
|
||||||
if(input.at(0) == '-') {
|
|
||||||
input.remove(0, 1);
|
|
||||||
} else {
|
|
||||||
input.prepend('-');
|
|
||||||
}
|
|
||||||
label->setText(input);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ValueInput::Backspace()
|
|
||||||
{
|
|
||||||
if(input.size() > 0) {
|
|
||||||
if(input.at(input.size()-1) == '.') {
|
|
||||||
bDot->setEnabled(true);
|
|
||||||
}
|
|
||||||
input.chop(1);
|
|
||||||
label->setText(input);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ValueInput::Abort()
|
|
||||||
{
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ValueInput::UnitPressed(double factor)
|
|
||||||
{
|
|
||||||
double value = input.toDouble() * factor;
|
|
||||||
emit ValueChanged(value);
|
|
||||||
close();
|
|
||||||
}
|
|
@ -1,44 +0,0 @@
|
|||||||
#ifndef VALUEINPUT_H
|
|
||||||
#define VALUEINPUT_H
|
|
||||||
|
|
||||||
#include <QWidget>
|
|
||||||
#include <vector>
|
|
||||||
#include <QPushButton>
|
|
||||||
#include <QLabel>
|
|
||||||
#include <QSignalMapper>
|
|
||||||
|
|
||||||
class ValueInput : public QWidget
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
class Unit {
|
|
||||||
public:
|
|
||||||
Unit(){};
|
|
||||||
Unit(QString name, double factor):
|
|
||||||
name(name), factor(factor){};
|
|
||||||
QString name;
|
|
||||||
double factor;
|
|
||||||
};
|
|
||||||
ValueInput(std::vector<Unit> units, QString name = "Value input", QString initialValue = QString());
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void ValueChanged(double value);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void keyPressEvent(QKeyEvent *event) override;
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void AddToInput(QString a);
|
|
||||||
void ChangeSign();
|
|
||||||
void Backspace();
|
|
||||||
void Abort();
|
|
||||||
void UnitPressed(double factor);
|
|
||||||
private:
|
|
||||||
static constexpr QSize minButtonSize = QSize(50, 50);
|
|
||||||
QString input;
|
|
||||||
QLabel *label;
|
|
||||||
QPushButton *bDot;
|
|
||||||
std::vector<Unit> units;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // VALUEINPUT_H
|
|
@ -1,169 +0,0 @@
|
|||||||
#ifndef VNA_H
|
|
||||||
#define VNA_H
|
|
||||||
|
|
||||||
#include <QWidget>
|
|
||||||
#include <QMainWindow>
|
|
||||||
#include <QGridLayout>
|
|
||||||
#include <QComboBox>
|
|
||||||
#include <QStackedWidget>
|
|
||||||
#include "Device/device.h"
|
|
||||||
#include "Traces/traceplot.h"
|
|
||||||
#include "Calibration/calibration.h"
|
|
||||||
#include <QProgressDialog>
|
|
||||||
#include "Menu/menuaction.h"
|
|
||||||
#include "Traces/tracemodel.h"
|
|
||||||
#include "Traces/tracemarkermodel.h"
|
|
||||||
#include "averaging.h"
|
|
||||||
#include "Device/devicelog.h"
|
|
||||||
#include "preferences.h"
|
|
||||||
#include <QButtonGroup>
|
|
||||||
#include <QCheckBox>
|
|
||||||
|
|
||||||
namespace Ui {
|
|
||||||
class MainWindow;
|
|
||||||
}
|
|
||||||
|
|
||||||
class VNA : public QMainWindow
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
VNA(QWidget *parent = nullptr);
|
|
||||||
protected:
|
|
||||||
void closeEvent(QCloseEvent *event) override;
|
|
||||||
private:
|
|
||||||
static constexpr double minFreq = 0;
|
|
||||||
static constexpr double maxFreq = 6000000000;
|
|
||||||
static constexpr Protocol::SweepSettings defaultSweep = {
|
|
||||||
.f_start = 1000000,
|
|
||||||
.f_stop = (uint64_t) maxFreq,
|
|
||||||
.points = 501,
|
|
||||||
.if_bandwidth = 1000,
|
|
||||||
.cdbm_excitation = 0,
|
|
||||||
};
|
|
||||||
private slots:
|
|
||||||
void NewDatapoint(Protocol::Datapoint d);
|
|
||||||
void ConnectToDevice(QString serial = QString());
|
|
||||||
void DisconnectDevice();
|
|
||||||
int UpdateDeviceList();
|
|
||||||
void StartManualControl();
|
|
||||||
void StartImpedanceMatching();
|
|
||||||
// Sweep control
|
|
||||||
void SetStartFreq(double freq);
|
|
||||||
void SetStopFreq(double freq);
|
|
||||||
void SetCenterFreq(double freq);
|
|
||||||
void SetSpan(double span);
|
|
||||||
void SetFullSpan();
|
|
||||||
void SpanZoomIn();
|
|
||||||
void SpanZoomOut();
|
|
||||||
// Acquisition control
|
|
||||||
void SetSourceLevel(double level);
|
|
||||||
void SetPoints(unsigned int points);
|
|
||||||
void SetIFBandwidth(double bandwidth);
|
|
||||||
void SetAveraging(unsigned int averages);
|
|
||||||
// Calibration
|
|
||||||
void DisableCalibration(bool force = false);
|
|
||||||
void ApplyCalibration(Calibration::Type type);
|
|
||||||
void StartCalibrationMeasurement(Calibration::Measurement m);
|
|
||||||
void UpdateReference();
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void CalibrationMeasurementComplete(Calibration::Measurement m);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void UpdateStatusPanel();
|
|
||||||
void SettingsChanged();
|
|
||||||
void DeviceConnectionLost();
|
|
||||||
void CreateToolbars();
|
|
||||||
void ConstrainAndUpdateFrequencies();
|
|
||||||
void LoadSweepSettings();
|
|
||||||
void StoreSweepSettings();
|
|
||||||
|
|
||||||
class GUIMode {
|
|
||||||
friend class VNA;
|
|
||||||
public:
|
|
||||||
GUIMode(VNA *vna, QString name, QWidget *centralWidget);;
|
|
||||||
void addHiddenElement(QAction* a) {
|
|
||||||
hiddenActions.insert(a);
|
|
||||||
}
|
|
||||||
void addHiddenElement(QToolBar* a) {
|
|
||||||
hiddenToolbars.insert(a);
|
|
||||||
}
|
|
||||||
void addHiddenElement(QDockWidget* a) {
|
|
||||||
hiddenDocks.insert(a);
|
|
||||||
}
|
|
||||||
void activate();
|
|
||||||
void deactivate();
|
|
||||||
QString getName() const;
|
|
||||||
static GUIMode *getActiveMode();
|
|
||||||
|
|
||||||
private:
|
|
||||||
static GUIMode *activeMode;
|
|
||||||
static QWidget *cornerWidget;
|
|
||||||
static QButtonGroup *modeButtonGroup;
|
|
||||||
std::set<QAction*> hiddenActions;
|
|
||||||
std::set<QToolBar*> hiddenToolbars;
|
|
||||||
std::set<QDockWidget*> hiddenDocks;
|
|
||||||
VNA *vna;
|
|
||||||
const QString name;
|
|
||||||
QWidget *central;
|
|
||||||
};
|
|
||||||
GUIMode *modeVNA, *modeSGen;
|
|
||||||
|
|
||||||
QStackedWidget *central;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
struct {
|
|
||||||
QComboBox *type;
|
|
||||||
QCheckBox *automatic;
|
|
||||||
QCheckBox *outputEnabled;
|
|
||||||
QComboBox *outFreq;
|
|
||||||
} reference;
|
|
||||||
} toolbars;
|
|
||||||
|
|
||||||
Preferences pref;
|
|
||||||
|
|
||||||
Device *device;
|
|
||||||
DeviceLog deviceLog;
|
|
||||||
QString deviceSerial;
|
|
||||||
QActionGroup *deviceActionGroup;
|
|
||||||
Protocol::SweepSettings settings;
|
|
||||||
unsigned int averages;
|
|
||||||
TraceModel traceModel;
|
|
||||||
TraceMarkerModel *markerModel;
|
|
||||||
Averaging average;
|
|
||||||
|
|
||||||
// Calibration
|
|
||||||
Calibration cal;
|
|
||||||
bool calValid;
|
|
||||||
Calibration::Measurement calMeasurement;
|
|
||||||
bool calMeasuring;
|
|
||||||
bool calWaitFirst;
|
|
||||||
QProgressDialog calDialog;
|
|
||||||
|
|
||||||
// Status Labels
|
|
||||||
QLabel lStart, lCenter, lStop, lSpan, lPoints, lBandwidth;
|
|
||||||
QLabel lCalibration;
|
|
||||||
QLabel lAverages;
|
|
||||||
|
|
||||||
// Status bar widgets
|
|
||||||
QLabel lConnectionStatus;
|
|
||||||
QLabel lDeviceInfo;
|
|
||||||
|
|
||||||
Ui::MainWindow *ui;
|
|
||||||
signals:
|
|
||||||
void dataChanged();
|
|
||||||
void startFreqChanged(double freq);
|
|
||||||
void stopFreqChanged(double freq);
|
|
||||||
void centerFreqChanged(double freq);
|
|
||||||
void spanChanged(double span);
|
|
||||||
|
|
||||||
void sourceLevelChanged(double level);
|
|
||||||
void pointsChanged(unsigned int points);
|
|
||||||
void IFBandwidthChanged(double bandwidth);
|
|
||||||
void averagingChanged(unsigned int averages);
|
|
||||||
|
|
||||||
void CalibrationDisabled();
|
|
||||||
void CalibrationApplied(Calibration::Type type);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // VNA_H
|
|
Loading…
Reference in New Issue
Block a user