Working source and receiver calibration

This commit is contained in:
Jan Käberich 2020-11-17 23:03:13 +01:00
parent 875f3b0170
commit 026fffd588
23 changed files with 722 additions and 68 deletions

View file

@ -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 \

View 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>

View file

@ -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 &current, 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;
}

View file

@ -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

View file

@ -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>

View 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;
}

View 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

View file

@ -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;
}

View file

@ -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

View file

@ -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;

View file

@ -53,6 +53,7 @@ Protocol::GeneratorSettings SignalgeneratorWidget::getDeviceStatus()
} else {
s.activePort = 0;
}
s.applyAmplitudeCorrection = 1;
return s;
}

View file

@ -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) {

View file

@ -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;

View file

@ -45,6 +45,7 @@ private slots:
void StartFirmwareUpdateDialog();
void DeviceNeedsUpdate(int reported, int expected);
void SourceCalibrationDialog();
void ReceiverCalibrationDialog();
private:
void DeviceConnectionLost();
void CreateToolbars();

View file

@ -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"/>