mirror of
https://github.com/jankae/LibreVNA.git
synced 2026-04-05 14:35:23 +00:00
Working source and receiver calibration
This commit is contained in:
parent
875f3b0170
commit
026fffd588
23 changed files with 722 additions and 68 deletions
|
|
@ -7,6 +7,7 @@ HEADERS += \
|
|||
Calibration/calkitdialog.h \
|
||||
Calibration/json.hpp \
|
||||
Calibration/measurementmodel.h \
|
||||
Calibration/receivercaldialog.h \
|
||||
Calibration/sourcecaldialog.h \
|
||||
CustomWidgets/colorpickerbutton.h \
|
||||
CustomWidgets/informationbox.h \
|
||||
|
|
@ -56,6 +57,7 @@ SOURCES += \
|
|||
Calibration/calkit.cpp \
|
||||
Calibration/calkitdialog.cpp \
|
||||
Calibration/measurementmodel.cpp \
|
||||
Calibration/receivercaldialog.cpp \
|
||||
Calibration/sourcecaldialog.cpp \
|
||||
CustomWidgets/colorpickerbutton.cpp \
|
||||
CustomWidgets/informationbox.cpp \
|
||||
|
|
@ -106,6 +108,7 @@ win32:LIBS += -LC:\Qwt-6.1.4\lib -lqwt
|
|||
QT += widgets
|
||||
|
||||
FORMS += \
|
||||
Calibration/addamplitudepointsdialog.ui \
|
||||
Calibration/amplitudecaldialog.ui \
|
||||
Calibration/calibrationtracedialog.ui \
|
||||
Calibration/calkitdialog.ui \
|
||||
|
|
|
|||
138
Software/PC_Application/Calibration/addamplitudepointsdialog.ui
Normal file
138
Software/PC_Application/Calibration/addamplitudepointsdialog.ui
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>AddAmplitudePointsDialog</class>
|
||||
<widget class="QDialog" name="AddAmplitudePointsDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>564</width>
|
||||
<height>139</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Add points</string>
|
||||
</property>
|
||||
<property name="modal">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2" stretch="0,0,1">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="singlePoint">
|
||||
<property name="text">
|
||||
<string>Single Point at</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">groupType</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="SIUnitEdit" name="frequency"/>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0,0,0,0,0,1">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="array">
|
||||
<property name="text">
|
||||
<string>Array of </string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">groupType</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="numPoints">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>64</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>10</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>points from</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="SIUnitEdit" name="startFreq"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>to</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="SIUnitEdit" name="stopFreq"/>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="deleteExisting">
|
||||
<property name="text">
|
||||
<string>Delete already existing points</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>SIUnitEdit</class>
|
||||
<extends>QLineEdit</extends>
|
||||
<header>CustomWidgets/siunitedit.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
<buttongroups>
|
||||
<buttongroup name="groupType"/>
|
||||
</buttongroups>
|
||||
</ui>
|
||||
|
|
@ -3,12 +3,17 @@
|
|||
#include "mode.h"
|
||||
#include "unit.h"
|
||||
#include <QDebug>
|
||||
#include "ui_addamplitudepointsdialog.h"
|
||||
#include <QMessageBox>
|
||||
|
||||
using namespace std;
|
||||
|
||||
AmplitudeCalDialog::AmplitudeCalDialog(Device *dev, QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::AmplitudeCalDialog),
|
||||
dev(dev),
|
||||
model(this)
|
||||
model(this),
|
||||
mode(CalibrationMode::BothPorts)
|
||||
{
|
||||
activeMode = Mode::getActiveMode();
|
||||
activeMode->deactivate();
|
||||
|
|
@ -20,9 +25,40 @@ AmplitudeCalDialog::AmplitudeCalDialog(Device *dev, QWidget *parent) :
|
|||
ui->view->setColumnWidth(AmplitudeModel::ColIndexPort1, 150);
|
||||
ui->view->setColumnWidth(AmplitudeModel::ColIndexPort2, 150);
|
||||
connect(dev, &Device::AmplitudeCorrectionPointReceived, this, &AmplitudeCalDialog::ReceivedPoint);
|
||||
connect(ui->load, &QPushButton::clicked, this, &AmplitudeCalDialog::LoadFromDevice);
|
||||
connect(ui->add, &QPushButton::clicked, this, &AmplitudeCalDialog::AddPoint);
|
||||
connect(ui->remove, &QPushButton::clicked, this, &AmplitudeCalDialog::RemovePoint);
|
||||
connect(ui->load, &QPushButton::clicked, [=](){
|
||||
if(ConfirmActionIfEdited()) {
|
||||
LoadFromDevice();
|
||||
}
|
||||
});
|
||||
connect(ui->save, &QPushButton::clicked, this, &AmplitudeCalDialog::SaveToDevice);
|
||||
connect(ui->add, &QPushButton::clicked, this, &AmplitudeCalDialog::AddPointDialog);
|
||||
connect(ui->remove, &QPushButton::clicked, [=](){
|
||||
unsigned int row = ui->view->currentIndex().row();
|
||||
if(row < points.size()) {
|
||||
RemovePoint(row);
|
||||
}
|
||||
});
|
||||
auto selectionModel = ui->view->selectionModel();
|
||||
connect(selectionModel, &QItemSelectionModel::currentChanged, [=](const QModelIndex ¤t, const QModelIndex&) {
|
||||
if(current.isValid() && (current.column() == model.ColIndexPort1 || current.column() == model.ColIndexPort2)) {
|
||||
SelectedPoint(points[current.row()].frequency, current.column() == model.ColIndexPort2);
|
||||
} else {
|
||||
// Invalid selection
|
||||
SelectedPoint(0, false);
|
||||
}
|
||||
});
|
||||
connect(ui->modeBoth, &QPushButton::pressed, [=](){
|
||||
mode = CalibrationMode::BothPorts;
|
||||
model.dataChanged(model.index(0, model.ColIndexPort1), model.index(points.size(), model.ColIndexPort2));
|
||||
});
|
||||
connect(ui->modePort1, &QPushButton::pressed, [=](){
|
||||
mode = CalibrationMode::OnlyPort1;
|
||||
model.dataChanged(model.index(0, model.ColIndexPort1), model.index(points.size(), model.ColIndexPort2));
|
||||
});
|
||||
connect(ui->modePort2, &QPushButton::pressed, [=](){
|
||||
mode = CalibrationMode::OnlyPort2;
|
||||
model.dataChanged(model.index(0, model.ColIndexPort1), model.index(points.size(), model.ColIndexPort2));
|
||||
});
|
||||
}
|
||||
|
||||
AmplitudeCalDialog::~AmplitudeCalDialog()
|
||||
|
|
@ -33,8 +69,9 @@ AmplitudeCalDialog::~AmplitudeCalDialog()
|
|||
|
||||
void AmplitudeCalDialog::reject()
|
||||
{
|
||||
// TODO check for unsaved data
|
||||
delete this;
|
||||
if(ConfirmActionIfEdited()) {
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<AmplitudeCalDialog::CorrectionPoint> AmplitudeCalDialog::getPoints() const
|
||||
|
|
@ -49,9 +86,24 @@ void AmplitudeCalDialog::setAmplitude(double amplitude, unsigned int point, bool
|
|||
}
|
||||
if(port2) {
|
||||
points[point].amplitudePort2 = amplitude;
|
||||
points[point].port2set = true;
|
||||
} else {
|
||||
points[point].amplitudePort1 = amplitude;
|
||||
points[point].port1set = true;
|
||||
}
|
||||
edited = true;
|
||||
AmplitudeChanged(points[point], port2);
|
||||
if(mode == CalibrationMode::OnlyPort1 && !port2) {
|
||||
// apply result from port 1 to port 2 as well
|
||||
points[point].correctionPort2 = points[point].correctionPort1;
|
||||
points[point].port2set = points[point].port1set;
|
||||
} else if(mode == CalibrationMode::OnlyPort2 && port2) {
|
||||
// apply result from port 2 to port 1 as well
|
||||
points[point].correctionPort1 = points[point].correctionPort2;
|
||||
points[point].port1set = points[point].port2set;
|
||||
}
|
||||
model.dataChanged(model.index(point, model.ColIndexCorrectionFactors), model.index(point, model.ColIndexPort2));
|
||||
UpdateSaveButton();
|
||||
}
|
||||
|
||||
void AmplitudeCalDialog::ReceivedPoint(Protocol::AmplitudeCorrectionPoint p)
|
||||
|
|
@ -61,7 +113,10 @@ void AmplitudeCalDialog::ReceivedPoint(Protocol::AmplitudeCorrectionPoint p)
|
|||
c.frequency = p.freq * 10.0;
|
||||
c.correctionPort1 = p.port1;
|
||||
c.correctionPort2 = p.port2;
|
||||
c.port1set = false;
|
||||
c.port2set = false;
|
||||
model.beginInsertRows(QModelIndex(), points.size(), points.size());
|
||||
UpdateAmplitude(c);
|
||||
points.push_back(c);
|
||||
model.endInsertRows();
|
||||
emit pointsUpdated();
|
||||
|
|
@ -69,15 +124,17 @@ void AmplitudeCalDialog::ReceivedPoint(Protocol::AmplitudeCorrectionPoint p)
|
|||
|
||||
void AmplitudeCalDialog::LoadFromDevice()
|
||||
{
|
||||
model.beginResetModel();
|
||||
points.clear();
|
||||
model.endResetModel();
|
||||
dev->SetIdle();
|
||||
RemoveAllPoints();
|
||||
qDebug() << "Asking for amplitude calibration";
|
||||
dev->SendCommandWithoutPayload(requestCommand());
|
||||
edited = false;
|
||||
ui->save->setEnabled(false);
|
||||
}
|
||||
|
||||
void AmplitudeCalDialog::SaveToDevice()
|
||||
{
|
||||
dev->SetIdle();
|
||||
for(unsigned int i=0;i<points.size();i++) {
|
||||
auto p = points[i];
|
||||
Protocol::PacketInfo info;
|
||||
|
|
@ -89,21 +146,134 @@ void AmplitudeCalDialog::SaveToDevice()
|
|||
info.amplitudePoint.pointNum = i;
|
||||
dev->SendPacket(info);
|
||||
}
|
||||
edited = false;
|
||||
ui->save->setEnabled(false);
|
||||
}
|
||||
|
||||
void AmplitudeCalDialog::RemovePoint()
|
||||
void AmplitudeCalDialog::RemovePoint(unsigned int i)
|
||||
{
|
||||
unsigned int row = ui->view->currentIndex().row();
|
||||
if(row < points.size()) {
|
||||
model.beginRemoveRows(QModelIndex(), row, row);
|
||||
points.erase(points.begin() + row);
|
||||
model.endInsertRows();
|
||||
model.beginRemoveRows(QModelIndex(), i, i);
|
||||
points.erase(points.begin() + i);
|
||||
model.endRemoveRows();
|
||||
edited = true;
|
||||
UpdateSaveButton();
|
||||
}
|
||||
|
||||
void AmplitudeCalDialog::RemoveAllPoints()
|
||||
{
|
||||
model.beginResetModel();
|
||||
points.clear();
|
||||
model.endResetModel();
|
||||
edited = true;
|
||||
ui->save->setEnabled(false);
|
||||
UpdateSaveButton();
|
||||
}
|
||||
|
||||
void AmplitudeCalDialog::AddPoint(double frequency)
|
||||
{
|
||||
if(points.size() >= Device::Info().limits_maxAmplitudePoints) {
|
||||
qWarning() << "Unable to add amplitude point, already maximum limit (" << Device::Info().limits_maxAmplitudePoints << ")";
|
||||
return;
|
||||
}
|
||||
// find position at which this frequency gets inserted
|
||||
auto index = upper_bound(points.begin(), points.end(), frequency, [](double value, const CorrectionPoint& p){
|
||||
return value < p.frequency;
|
||||
});
|
||||
model.beginInsertRows(QModelIndex(), index - points.begin(), index - points.begin());
|
||||
CorrectionPoint newPoint;
|
||||
newPoint.frequency = frequency;
|
||||
newPoint.correctionPort1 = 0;
|
||||
newPoint.correctionPort2 = 0;
|
||||
newPoint.port1set = false;
|
||||
newPoint.port2set = false;
|
||||
emit newPointCreated(newPoint);
|
||||
points.insert(index, newPoint);
|
||||
model.endInsertRows();
|
||||
edited = true;
|
||||
UpdateSaveButton();
|
||||
}
|
||||
|
||||
void AmplitudeCalDialog::AddPointDialog()
|
||||
{
|
||||
auto d = new QDialog();
|
||||
auto ui = new Ui::AddAmplitudePointsDialog();
|
||||
ui->setupUi(d);
|
||||
ui->frequency->setUnit("Hz");
|
||||
ui->frequency->setPrefixes(" kMG");
|
||||
ui->startFreq->setUnit("Hz");
|
||||
ui->startFreq->setPrefixes(" kMG");
|
||||
ui->stopFreq->setUnit("Hz");
|
||||
ui->stopFreq->setPrefixes(" kMG");
|
||||
ui->frequency->setValue(1000000000.0);
|
||||
ui->startFreq->setValue(Device::Info().limits_minFreq);
|
||||
ui->stopFreq->setValue(Device::Info().limits_maxFreq);
|
||||
connect(ui->singlePoint, &QRadioButton::toggled, [=](bool single) {
|
||||
ui->stopFreq->setEnabled(!single);
|
||||
ui->startFreq->setEnabled(!single);
|
||||
ui->numPoints->setEnabled(!single);
|
||||
ui->frequency->setEnabled(single);
|
||||
});
|
||||
ui->singlePoint->setChecked(true);
|
||||
ui->frequency->setFocus();
|
||||
|
||||
connect(ui->buttonBox, &QDialogButtonBox::accepted, [=](){
|
||||
// okay clicked, apply selected action
|
||||
if(ui->deleteExisting->isChecked()) {
|
||||
RemoveAllPoints();
|
||||
}
|
||||
if(ui->singlePoint->isChecked()) {
|
||||
AddPoint(ui->frequency->value());
|
||||
} else {
|
||||
double freq_start = ui->startFreq->value();
|
||||
double freq_stop = ui->stopFreq->value();
|
||||
unsigned int points = ui->numPoints->value();
|
||||
double freq_step = (freq_stop - freq_start) / (points - 1);
|
||||
for(unsigned int i=0;i<points;i++) {
|
||||
AddPoint(freq_start + i * freq_step);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
connect(d, &QDialog::rejected, ui->buttonBox, &QDialogButtonBox::rejected);
|
||||
connect(ui->buttonBox, &QDialogButtonBox::rejected, [=](){
|
||||
// aborted, nothing to do
|
||||
delete d;
|
||||
});
|
||||
d->show();
|
||||
}
|
||||
|
||||
bool AmplitudeCalDialog::ConfirmActionIfEdited()
|
||||
{
|
||||
if(edited) {
|
||||
auto reply = QMessageBox::question(this, "Confirm action", "Some points have been edited but not saved in the device yet. If you continue, all changes will be lost. Do you want to continue?",
|
||||
QMessageBox::Yes|QMessageBox::No);
|
||||
return reply == QMessageBox::Yes;
|
||||
} else {
|
||||
// not edited yet, nothing to confirm
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void AmplitudeCalDialog::AddPoint()
|
||||
void AmplitudeCalDialog::UpdateSaveButton()
|
||||
{
|
||||
bool enable = true;
|
||||
if(points.size() == 0) {
|
||||
// needs at least one point
|
||||
enable = false;
|
||||
}
|
||||
for(auto p : points) {
|
||||
if(!p.port1set || !p.port2set) {
|
||||
// some points are not set yet
|
||||
enable = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ui->save->setEnabled(enable);
|
||||
}
|
||||
|
||||
AmplitudeCalDialog::CalibrationMode AmplitudeCalDialog::getMode() const
|
||||
{
|
||||
return mode;
|
||||
}
|
||||
|
||||
AmplitudeModel::AmplitudeModel(AmplitudeCalDialog *c) :
|
||||
|
|
@ -134,10 +304,18 @@ QVariant AmplitudeModel::data(const QModelIndex &index, int role) const
|
|||
return QString::number(p.correctionPort1) + ", " + QString::number(p.correctionPort2);
|
||||
break;
|
||||
case ColIndexPort1:
|
||||
return Unit::ToString(p.amplitudePort1, "dbm", " ", 4);
|
||||
if (p.port1set) {
|
||||
return Unit::ToString(p.amplitudePort1, "dbm", " ", 4);
|
||||
} else {
|
||||
return "No data";
|
||||
}
|
||||
break;
|
||||
case ColIndexPort2:
|
||||
return Unit::ToString(p.amplitudePort2, "dbm", " ", 4);
|
||||
if (p.port2set) {
|
||||
return Unit::ToString(p.amplitudePort2, "dbm", " ", 4);
|
||||
} else {
|
||||
return "No data";
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -180,8 +358,16 @@ Qt::ItemFlags AmplitudeModel::flags(const QModelIndex &index) const
|
|||
{
|
||||
int flags = Qt::NoItemFlags;
|
||||
switch(index.column()) {
|
||||
case ColIndexPort1: flags |= Qt::ItemIsEnabled | Qt::ItemIsEditable; break;
|
||||
case ColIndexPort2: flags |= Qt::ItemIsEnabled | Qt::ItemIsEditable; break;
|
||||
case ColIndexPort1:
|
||||
if(c->getMode() != AmplitudeCalDialog::CalibrationMode::OnlyPort2) {
|
||||
flags |= Qt::ItemIsEnabled | Qt::ItemIsEditable;
|
||||
}
|
||||
break;
|
||||
case ColIndexPort2:
|
||||
if(c->getMode() != AmplitudeCalDialog::CalibrationMode::OnlyPort1) {
|
||||
flags |= Qt::ItemIsEnabled | Qt::ItemIsEditable;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return (Qt::ItemFlags) flags;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#ifndef AMPLITUDECALDIALOG_H
|
||||
#ifndef AMPLITUDECALDIALOG_H
|
||||
#define AMPLITUDECALDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
|
|
@ -48,30 +48,53 @@ public:
|
|||
class CorrectionPoint {
|
||||
public:
|
||||
double frequency;
|
||||
double correctionPort1;
|
||||
double correctionPort2;
|
||||
int16_t correctionPort1;
|
||||
int16_t correctionPort2;
|
||||
double amplitudePort1;
|
||||
double amplitudePort2;
|
||||
bool port1set;
|
||||
bool port2set;
|
||||
};
|
||||
std::vector<CorrectionPoint> getPoints() const;
|
||||
void setAmplitude(double amplitude, unsigned int point, bool port2);
|
||||
|
||||
enum class CalibrationMode {
|
||||
BothPorts,
|
||||
OnlyPort1,
|
||||
OnlyPort2,
|
||||
};
|
||||
|
||||
CalibrationMode getMode() const;
|
||||
|
||||
protected slots:
|
||||
void ReceivedPoint(Protocol::AmplitudeCorrectionPoint p);
|
||||
void LoadFromDevice();
|
||||
void SaveToDevice();
|
||||
void RemovePoint();
|
||||
void AddPoint();
|
||||
void RemovePoint(unsigned int i);
|
||||
void RemoveAllPoints();
|
||||
void AddPoint(double frequency);
|
||||
void AddPointDialog();
|
||||
signals:
|
||||
void pointsUpdated();
|
||||
void newPointCreated(CorrectionPoint& p);
|
||||
protected:
|
||||
bool ConfirmActionIfEdited();
|
||||
void UpdateSaveButton();
|
||||
virtual Protocol::PacketType requestCommand() = 0;
|
||||
virtual Protocol::PacketType pointType() = 0;
|
||||
// will get called whenever a new cell is selected (frequency=0 means invalid selection)
|
||||
virtual void SelectedPoint(double frequency, bool port2) = 0;
|
||||
// will get called whenever the amplitude is changed. Derived class is responsible for updating correction factor
|
||||
virtual void AmplitudeChanged(CorrectionPoint& point, bool port2) = 0;
|
||||
// called whenver the correction factor have been retrieved from the device and the amplitudes need to be updated
|
||||
virtual void UpdateAmplitude(CorrectionPoint& point) = 0;
|
||||
std::vector<CorrectionPoint> points;
|
||||
Ui::AmplitudeCalDialog *ui;
|
||||
Device *dev;
|
||||
Mode *activeMode;
|
||||
AmplitudeModel model;
|
||||
bool edited;
|
||||
CalibrationMode mode;
|
||||
};
|
||||
|
||||
#endif // SOURCECALDIALOG_H
|
||||
|
|
|
|||
|
|
@ -28,11 +28,11 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QPushButton" name="add">
|
||||
<property name="text">
|
||||
<string>Add Point</string>
|
||||
<string>Add Point(s)</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="list-add" resource="../icons.qrc">
|
||||
|
|
@ -57,7 +57,8 @@
|
|||
<string>Help</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme="help"/>
|
||||
<iconset theme="help">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
@ -74,6 +75,9 @@
|
|||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="save">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Save to Device</string>
|
||||
</property>
|
||||
|
|
@ -83,6 +87,101 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Calibration Mode</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="modeBoth">
|
||||
<property name="text">
|
||||
<string>Both Ports</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">groupMode</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>8</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Best accuracy</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="modePort1">
|
||||
<property name="text">
|
||||
<string>Only Port 1</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">groupMode</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>8</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Use same correction for port 2</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="modePort2">
|
||||
<property name="text">
|
||||
<string>Only Port 2</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">groupMode</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>8</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Use same correction for port 1</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
|
|
@ -104,4 +203,7 @@
|
|||
<include location="../icons.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
<buttongroups>
|
||||
<buttongroup name="groupMode"/>
|
||||
</buttongroups>
|
||||
</ui>
|
||||
|
|
|
|||
58
Software/PC_Application/Calibration/receivercaldialog.cpp
Normal file
58
Software/PC_Application/Calibration/receivercaldialog.cpp
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
#include "receivercaldialog.h"
|
||||
|
||||
ReceiverCalDialog::ReceiverCalDialog(Device *dev)
|
||||
: AmplitudeCalDialog(dev)
|
||||
{
|
||||
setWindowTitle("Receiver Calibration Dialog");
|
||||
LoadFromDevice();
|
||||
connect(dev, &Device::SpectrumResultReceived, [=](Protocol::SpectrumAnalyzerResult res) {
|
||||
if(res.pointNum == 1) {
|
||||
// store result in center of sweep of 3 points
|
||||
port1_result = 20*log10(res.port1);
|
||||
port2_result = 20*log10(res.port2);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void ReceiverCalDialog::SelectedPoint(double frequency, bool port2)
|
||||
{
|
||||
if(frequency > 0) {
|
||||
Protocol::PacketInfo p;
|
||||
p.type = Protocol::PacketType::SpectrumAnalyzerSettings;
|
||||
p.spectrumSettings.RBW = 10000;
|
||||
p.spectrumSettings.UseDFT = 0;
|
||||
// setup 3 points centered around the measurement frequency (zero span not supported yet)
|
||||
p.spectrumSettings.f_stop = frequency + 1.0;
|
||||
p.spectrumSettings.f_start = frequency - 1.0;
|
||||
p.spectrumSettings.pointNum = 3;
|
||||
p.spectrumSettings.Detector = 0;
|
||||
p.spectrumSettings.SignalID = 1;
|
||||
p.spectrumSettings.WindowType = 3;
|
||||
p.spectrumSettings.applyReceiverCorrection = 0;
|
||||
dev->SendPacket(p);
|
||||
} else {
|
||||
// invalid frequency, disable
|
||||
dev->SetIdle();
|
||||
}
|
||||
}
|
||||
|
||||
void ReceiverCalDialog::AmplitudeChanged(AmplitudeCalDialog::CorrectionPoint &point, bool port2)
|
||||
{
|
||||
auto *factor = port2 ? &point.correctionPort2 : &point.correctionPort1;
|
||||
const auto *amplitude = port2 ? &point.amplitudePort2 : &point.amplitudePort1;
|
||||
const auto *measured = port2 ? &port2_result : &port1_result;
|
||||
// calculate correction factor by comparing expected with measured amplitude
|
||||
*factor = (*measured - *amplitude) * 100.0;
|
||||
}
|
||||
|
||||
void ReceiverCalDialog::UpdateAmplitude(AmplitudeCalDialog::CorrectionPoint &point)
|
||||
{
|
||||
// This point was just received from the device, it is not possible to know the actual amplitude because the
|
||||
// applied power level during the calibration is not saved (only the correction value). This is not a problem
|
||||
// because the correction value is still valid but the missing values look weird in the GUI
|
||||
// TODO change this?
|
||||
point.amplitudePort1 = std::numeric_limits<double>::quiet_NaN();
|
||||
point.amplitudePort2 = std::numeric_limits<double>::quiet_NaN();
|
||||
point.port1set = true;
|
||||
point.port2set = true;
|
||||
}
|
||||
22
Software/PC_Application/Calibration/receivercaldialog.h
Normal file
22
Software/PC_Application/Calibration/receivercaldialog.h
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
#ifndef RECEIVERCALDIALOG_H
|
||||
#define RECEIVERCALDIALOG_H
|
||||
|
||||
#include "amplitudecaldialog.h"
|
||||
|
||||
class ReceiverCalDialog : public AmplitudeCalDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ReceiverCalDialog(Device *dev);
|
||||
protected:
|
||||
Protocol::PacketType requestCommand() override { return Protocol::PacketType::RequestReceiverCal; }
|
||||
Protocol::PacketType pointType() override { return Protocol::PacketType::ReceiverCalPoint; }
|
||||
void SelectedPoint(double frequency, bool port2) override;
|
||||
void AmplitudeChanged(CorrectionPoint &point, bool port2) override;
|
||||
void UpdateAmplitude(CorrectionPoint& point) override;
|
||||
private:
|
||||
static constexpr double excitationAmplitude = -20.0;
|
||||
double port1_result, port2_result; // raw (uncorrected) measurements from device
|
||||
};
|
||||
|
||||
#endif // RECEIVERCALDIALOG_H
|
||||
|
|
@ -1,8 +1,47 @@
|
|||
#include "sourcecaldialog.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
SourceCalDialog::SourceCalDialog(Device *dev)
|
||||
: AmplitudeCalDialog(dev)
|
||||
{
|
||||
setWindowTitle("Source Calibration Dialog");
|
||||
LoadFromDevice();
|
||||
}
|
||||
|
||||
void SourceCalDialog::SelectedPoint(double frequency, bool port2)
|
||||
{
|
||||
Protocol::PacketInfo p;
|
||||
p.type = Protocol::PacketType::Generator;
|
||||
|
||||
p.generator.frequency = frequency;
|
||||
p.generator.cdbm_level = excitationAmplitude * 100.0;
|
||||
if(frequency > 0) {
|
||||
if(port2) {
|
||||
p.generator.activePort = 2;
|
||||
} else {
|
||||
p.generator.activePort = 1;
|
||||
}
|
||||
} else {
|
||||
// invalid frequency, disable both ports
|
||||
p.generator.activePort = 0;
|
||||
}
|
||||
p.generator.applyAmplitudeCorrection = 0;
|
||||
dev->SendPacket(p);
|
||||
}
|
||||
|
||||
void SourceCalDialog::AmplitudeChanged(AmplitudeCalDialog::CorrectionPoint &point, bool port2)
|
||||
{
|
||||
auto *factor = port2 ? &point.correctionPort2 : &point.correctionPort1;
|
||||
const auto *amplitude = port2 ? &point.amplitudePort2 : &point.amplitudePort1;
|
||||
// calculate correction factor by comparing expected with measured amplitude
|
||||
*factor = (excitationAmplitude - *amplitude) * 100.0;
|
||||
}
|
||||
|
||||
void SourceCalDialog::UpdateAmplitude(AmplitudeCalDialog::CorrectionPoint &point)
|
||||
{
|
||||
point.amplitudePort1 = excitationAmplitude - (double) point.correctionPort1 / 100.0;
|
||||
point.amplitudePort2 = excitationAmplitude - (double) point.correctionPort2 / 100.0;
|
||||
point.port1set = true;
|
||||
point.port2set = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,11 @@ public:
|
|||
protected:
|
||||
Protocol::PacketType requestCommand() override { return Protocol::PacketType::RequestSourceCal; }
|
||||
Protocol::PacketType pointType() override { return Protocol::PacketType::SourceCalPoint; }
|
||||
void SelectedPoint(double frequency, bool port2) override;
|
||||
void AmplitudeChanged(CorrectionPoint &point, bool port2) override;
|
||||
void UpdateAmplitude(CorrectionPoint& point) override;
|
||||
private:
|
||||
static constexpr double excitationAmplitude = -20.0;
|
||||
};
|
||||
|
||||
#endif // SOURCECALDIALOG_H
|
||||
|
|
|
|||
|
|
@ -136,6 +136,7 @@ static constexpr Protocol::DeviceInfo defaultInfo = {
|
|||
.limits_cdbm_max = 1000,
|
||||
.limits_minRBW = 1,
|
||||
.limits_maxRBW = 1000000,
|
||||
.limits_maxAmplitudePoints = 255,
|
||||
};
|
||||
|
||||
Protocol::DeviceInfo Device::lastInfo = defaultInfo;
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ Protocol::GeneratorSettings SignalgeneratorWidget::getDeviceStatus()
|
|||
} else {
|
||||
s.activePort = 0;
|
||||
}
|
||||
s.applyAmplitudeCorrection = 1;
|
||||
return s;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -229,9 +229,6 @@ using namespace std;
|
|||
|
||||
void SpectrumAnalyzer::NewDatapoint(Protocol::SpectrumAnalyzerResult d)
|
||||
{
|
||||
// TODO level adjustment in device
|
||||
d.port1 /= 126500000.0;
|
||||
d.port2 /= 126500000.0;
|
||||
d = average.process(d);
|
||||
traceModel.addSAData(d, settings);
|
||||
emit dataChanged();
|
||||
|
|
@ -248,6 +245,7 @@ void SpectrumAnalyzer::SettingsChanged()
|
|||
} else {
|
||||
settings.pointNum = settings.f_stop - settings.f_start + 1;
|
||||
}
|
||||
settings.applyReceiverCorrection = 1;
|
||||
|
||||
auto pref = Preferences::getInstance();
|
||||
if(pref.Acquisition.useDFTinSAmode && settings.RBW <= pref.Acquisition.RBWLimitForDFT) {
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@
|
|||
#include "Generator/generator.h"
|
||||
#include "SpectrumAnalyzer/spectrumanalyzer.h"
|
||||
#include "Calibration/sourcecaldialog.h"
|
||||
#include "Calibration/receivercaldialog.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
|
@ -102,6 +103,7 @@ AppWindow::AppWindow(QWidget *parent)
|
|||
connect(ui->actionManual_Control, &QAction::triggered, this, &AppWindow::StartManualControl);
|
||||
connect(ui->actionFirmware_Update, &QAction::triggered, this, &AppWindow::StartFirmwareUpdateDialog);
|
||||
connect(ui->actionSource_Calibration, &QAction::triggered, this, &AppWindow::SourceCalibrationDialog);
|
||||
connect(ui->actionReceiver_Calibration, &QAction::triggered, this, &AppWindow::ReceiverCalibrationDialog);
|
||||
connect(ui->actionPreferences, &QAction::triggered, [=](){
|
||||
Preferences::getInstance().edit();
|
||||
// settings might have changed, update necessary stuff
|
||||
|
|
@ -187,6 +189,7 @@ void AppWindow::ConnectToDevice(QString serial)
|
|||
ui->actionManual_Control->setEnabled(true);
|
||||
ui->actionFirmware_Update->setEnabled(true);
|
||||
ui->actionSource_Calibration->setEnabled(true);
|
||||
ui->actionReceiver_Calibration->setEnabled(true);
|
||||
|
||||
Mode::getActiveMode()->initializeDevice();
|
||||
UpdateReference();
|
||||
|
|
@ -214,6 +217,7 @@ void AppWindow::DisconnectDevice()
|
|||
ui->actionManual_Control->setEnabled(false);
|
||||
ui->actionFirmware_Update->setEnabled(false);
|
||||
ui->actionSource_Calibration->setEnabled(false);
|
||||
ui->actionReceiver_Calibration->setEnabled(false);
|
||||
for(auto a : deviceActionGroup->actions()) {
|
||||
a->setChecked(false);
|
||||
}
|
||||
|
|
@ -362,6 +366,12 @@ void AppWindow::SourceCalibrationDialog()
|
|||
d->exec();
|
||||
}
|
||||
|
||||
void AppWindow::ReceiverCalibrationDialog()
|
||||
{
|
||||
auto d = new ReceiverCalDialog(device);
|
||||
d->exec();
|
||||
}
|
||||
|
||||
Device *AppWindow::getDevice() const
|
||||
{
|
||||
return device;
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ private slots:
|
|||
void StartFirmwareUpdateDialog();
|
||||
void DeviceNeedsUpdate(int reported, int expected);
|
||||
void SourceCalibrationDialog();
|
||||
void ReceiverCalibrationDialog();
|
||||
private:
|
||||
void DeviceConnectionLost();
|
||||
void CreateToolbars();
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@
|
|||
<addaction name="actionFirmware_Update"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionSource_Calibration"/>
|
||||
<addaction name="actionReceiver_Calibration"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuWindow">
|
||||
<property name="title">
|
||||
|
|
@ -161,6 +162,14 @@
|
|||
<string>Source Calibration</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionReceiver_Calibration">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Receiver Calibration</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="icons.qrc"/>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue