working SSA3000X driver

This commit is contained in:
Jan Käberich 2023-02-08 22:57:17 +01:00
parent b701479e87
commit ad9e19c102
5 changed files with 157 additions and 3 deletions

View File

@ -1,17 +1,28 @@
#include "ssa3000xdriver.h"
#include "CustomWidgets/informationbox.h"
#include "Util/util.h"
#include <QTcpSocket>
#include <QDateTime>
SSA3000XDriver::SSA3000XDriver()
{
diffGen = new TraceDifferenceGenerator<SpectrumPoint, 10>([=](const SpectrumPoint &p){
SAMeasurement m;
m.pointNum = p.index;
m.frequency = p.frequency;
m.measurements["PORT1"] = pow(10.0, p.dBm / 20.0);
emit SAmeasurementReceived(m);
});
searchAddresses.push_back(QHostAddress("192.168.22.2"));
connect(&traceTimer, &QTimer::timeout, this, &SSA3000XDriver::extractTracePoints);
traceTimer.setSingleShot(true);
}
SSA3000XDriver::~SSA3000XDriver()
{
delete diffGen;
}
std::set<QString> SSA3000XDriver::GetAvailableDevices()
@ -81,6 +92,8 @@ bool SSA3000XDriver::connectTo(QString serial)
return false;
}
connect(&dataSocket, qOverload<QAbstractSocket::SocketError>(&QTcpSocket::error), this, &SSA3000XDriver::ConnectionLost, Qt::QueuedConnection);
// grab model information
dataSocket.write("*IDN?\r\n");
dataSocket.waitForReadyRead(100);
@ -188,6 +201,9 @@ bool SSA3000XDriver::setSA(const DeviceDriver::SASettings &s, std::function<void
if(!connected) {
return false;
}
startFreq = s.freqStart;
stopFreq = s.freqStop;
write(":FREQ:STAR "+QString::number(s.freqStart));
write(":FREQ:STOP "+QString::number(s.freqStop));
write(":BWID "+QString::number(s.RBW));
@ -235,12 +251,17 @@ bool SSA3000XDriver::setSA(const DeviceDriver::SASettings &s, std::function<void
write(":OUTP:STAT " + (s.trackingGenerator ? QString("ON") : QString("OFF")));
write(":SOUR:POW "+QString::number((int) s.trackingPower));
traceTimer.start(100);
if(cb) {
cb(true);
}
return true;
}
unsigned int SSA3000XDriver::getSApoints()
{
return 0;
return 751;
}
QStringList SSA3000XDriver::availableSGPorts()
@ -269,6 +290,7 @@ bool SSA3000XDriver::setIdle(std::function<void (bool)> cb)
if(!connected) {
return false;
}
traceTimer.stop();
write("*RST\r\n");
if(cb) {
cb(true);
@ -293,4 +315,42 @@ bool SSA3000XDriver::setExtRef(QString option_in, QString option_out)
void SSA3000XDriver::write(QString s)
{
dataSocket.write(QString(s + "\r\n").toLocal8Bit());
dataSocket.readAll();
}
void SSA3000XDriver::extractTracePoints()
{
if(!connected) {
return;
}
write(":TRAC? 1");
auto start = QDateTime::currentDateTimeUtc();
while(!dataSocket.canReadLine()) {
dataSocket.waitForReadyRead(100);
if(start.msecsTo(QDateTime::currentDateTimeUtc()) >= 100) {
// timed out
qWarning() << "Timed out waiting for trace data response";
return;
}
}
QString line = QString(dataSocket.readLine());
QStringList values = line.split(",");
// line contains a trailing comma, remove last item
values.pop_back();
std::vector<SpectrumPoint> trace;
for(unsigned int i=0;i<values.size();i++) {
SpectrumPoint p;
p.index = i;
p.frequency = Util::Scale((double) i, (double) 0, (double) values.size() - 1, startFreq, stopFreq);
bool ok = false;
p.dBm = values[i].toDouble(&ok);
if(!ok) {
// parsing failed, abort
return;
}
trace.push_back(p);
}
diffGen->newTrace(trace);
traceTimer.start(100);
}

View File

@ -3,8 +3,11 @@
#include "../devicedriver.h"
#include "../tracedifferencegenerator.h"
#include <QHostAddress>
#include <QTcpSocket>
#include <QTimer>
class SSA3000XDriver : public DeviceDriver
{
@ -139,6 +142,8 @@ public:
*/
virtual bool setExtRef(QString option_in, QString option_out) override;
private slots:
void extractTracePoints();
private:
void write(QString s);
QString serial;
@ -147,6 +152,21 @@ private:
bool connected;
Info info;
double startFreq, stopFreq;
class SpectrumPoint {
public:
unsigned int index;
double frequency;
double dBm;
bool operator==(const SpectrumPoint& rhs) {
return index == rhs.index && frequency == rhs.frequency && dBm == rhs.dBm;
}
};
QTimer traceTimer;
TraceDifferenceGenerator<SpectrumPoint, 10> *diffGen;
std::vector<QHostAddress> searchAddresses;
std::map<QString, QHostAddress> detectedDevices;
};

View File

@ -352,7 +352,7 @@ public:
};
// S parameter measurements
// Key: S parameter name, e.g. "PORT1"
// Value: measurement in mW (linear, not in dB). A value of 1.0 means 0dBm
// Value: measurement in linear voltage (linear, not in dB). A value of 1.0 means 0dBm
std::map<QString, double> measurements;
};

View File

@ -0,0 +1,73 @@
#ifndef TRACEDIFFERENCEGENERATOR_H
#define TRACEDIFFERENCEGENERATOR_H
#include <vector>
#include <functional>
#include <QDebug>
template<typename T, int minUnchanged>
class TraceDifferenceGenerator {
public:
TraceDifferenceGenerator(std::function<void(const T&)> changeCallback) :
last{},
callback(changeCallback),
nextCallbackIndex(0)
{}
void reset() {
last.clear();
nextCallbackIndex = 0;
}
void newTrace(const std::vector<T> &trace) {
if(trace.size() > last.size()) {
// definitely got more points than last time. Find first point that is hasn't been transmitted and generate callbacks for it and all subsequent points
unsigned int i=nextCallbackIndex;
while(i < trace.size()) {
callback(trace[i]);
i++;
}
nextCallbackIndex = 0;
} else if(trace.size() < last.size()) {
// got less points than last time. This must be a completely new trace, generate callbacks for all points
for(auto &i : trace) {
callback(i);
}
nextCallbackIndex = 0;
} else {
// still the same amount of points.
unsigned int i = nextCallbackIndex;
unsigned int changedPoints = 0;
do {
if(i > 0) {
i--;
} else {
i = trace.size() - 1;
}
bool unchanged = last[i] == trace[i];
if(!unchanged) {
changedPoints = (i + trace.size() - nextCallbackIndex + 1);
if(changedPoints > trace.size()) {
changedPoints -= trace.size();
}
break;
}
} while (i != nextCallbackIndex);
i = nextCallbackIndex;
while(changedPoints--) {
callback(trace[i]);
i = (i + 1) % trace.size();
}
nextCallbackIndex = i;
}
last = trace;
}
private:
unsigned int nextCallbackIndex;
std::vector<T> last;
std::function<void(const T&)> callback;
};
#endif // TRACEDIFFERENCEGENERATOR_H

View File

@ -37,6 +37,7 @@ HEADERS += \
Device/devicelog.h \
Device/deviceusblog.h \
Device/deviceusblogview.h \
Device/tracedifferencegenerator.h \
Device/virtualdevice.h \
Generator/generator.h \
Generator/signalgenwidget.h \