working SSA3000X driver
This commit is contained in:
parent
b701479e87
commit
ad9e19c102
@ -1,17 +1,28 @@
|
|||||||
#include "ssa3000xdriver.h"
|
#include "ssa3000xdriver.h"
|
||||||
|
|
||||||
#include "CustomWidgets/informationbox.h"
|
#include "CustomWidgets/informationbox.h"
|
||||||
|
#include "Util/util.h"
|
||||||
|
|
||||||
#include <QTcpSocket>
|
#include <QTcpSocket>
|
||||||
|
#include <QDateTime>
|
||||||
|
|
||||||
SSA3000XDriver::SSA3000XDriver()
|
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"));
|
searchAddresses.push_back(QHostAddress("192.168.22.2"));
|
||||||
|
connect(&traceTimer, &QTimer::timeout, this, &SSA3000XDriver::extractTracePoints);
|
||||||
|
traceTimer.setSingleShot(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
SSA3000XDriver::~SSA3000XDriver()
|
SSA3000XDriver::~SSA3000XDriver()
|
||||||
{
|
{
|
||||||
|
delete diffGen;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set<QString> SSA3000XDriver::GetAvailableDevices()
|
std::set<QString> SSA3000XDriver::GetAvailableDevices()
|
||||||
@ -81,6 +92,8 @@ bool SSA3000XDriver::connectTo(QString serial)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
connect(&dataSocket, qOverload<QAbstractSocket::SocketError>(&QTcpSocket::error), this, &SSA3000XDriver::ConnectionLost, Qt::QueuedConnection);
|
||||||
|
|
||||||
// grab model information
|
// grab model information
|
||||||
dataSocket.write("*IDN?\r\n");
|
dataSocket.write("*IDN?\r\n");
|
||||||
dataSocket.waitForReadyRead(100);
|
dataSocket.waitForReadyRead(100);
|
||||||
@ -188,6 +201,9 @@ bool SSA3000XDriver::setSA(const DeviceDriver::SASettings &s, std::function<void
|
|||||||
if(!connected) {
|
if(!connected) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
startFreq = s.freqStart;
|
||||||
|
stopFreq = s.freqStop;
|
||||||
|
|
||||||
write(":FREQ:STAR "+QString::number(s.freqStart));
|
write(":FREQ:STAR "+QString::number(s.freqStart));
|
||||||
write(":FREQ:STOP "+QString::number(s.freqStop));
|
write(":FREQ:STOP "+QString::number(s.freqStop));
|
||||||
write(":BWID "+QString::number(s.RBW));
|
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(":OUTP:STAT " + (s.trackingGenerator ? QString("ON") : QString("OFF")));
|
||||||
write(":SOUR:POW "+QString::number((int) s.trackingPower));
|
write(":SOUR:POW "+QString::number((int) s.trackingPower));
|
||||||
|
|
||||||
|
traceTimer.start(100);
|
||||||
|
if(cb) {
|
||||||
|
cb(true);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int SSA3000XDriver::getSApoints()
|
unsigned int SSA3000XDriver::getSApoints()
|
||||||
{
|
{
|
||||||
return 0;
|
return 751;
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList SSA3000XDriver::availableSGPorts()
|
QStringList SSA3000XDriver::availableSGPorts()
|
||||||
@ -269,6 +290,7 @@ bool SSA3000XDriver::setIdle(std::function<void (bool)> cb)
|
|||||||
if(!connected) {
|
if(!connected) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
traceTimer.stop();
|
||||||
write("*RST\r\n");
|
write("*RST\r\n");
|
||||||
if(cb) {
|
if(cb) {
|
||||||
cb(true);
|
cb(true);
|
||||||
@ -293,4 +315,42 @@ bool SSA3000XDriver::setExtRef(QString option_in, QString option_out)
|
|||||||
void SSA3000XDriver::write(QString s)
|
void SSA3000XDriver::write(QString s)
|
||||||
{
|
{
|
||||||
dataSocket.write(QString(s + "\r\n").toLocal8Bit());
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -3,8 +3,11 @@
|
|||||||
|
|
||||||
#include "../devicedriver.h"
|
#include "../devicedriver.h"
|
||||||
|
|
||||||
|
#include "../tracedifferencegenerator.h"
|
||||||
|
|
||||||
#include <QHostAddress>
|
#include <QHostAddress>
|
||||||
#include <QTcpSocket>
|
#include <QTcpSocket>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
class SSA3000XDriver : public DeviceDriver
|
class SSA3000XDriver : public DeviceDriver
|
||||||
{
|
{
|
||||||
@ -139,6 +142,8 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual bool setExtRef(QString option_in, QString option_out) override;
|
virtual bool setExtRef(QString option_in, QString option_out) override;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void extractTracePoints();
|
||||||
private:
|
private:
|
||||||
void write(QString s);
|
void write(QString s);
|
||||||
QString serial;
|
QString serial;
|
||||||
@ -147,6 +152,21 @@ private:
|
|||||||
bool connected;
|
bool connected;
|
||||||
Info info;
|
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::vector<QHostAddress> searchAddresses;
|
||||||
std::map<QString, QHostAddress> detectedDevices;
|
std::map<QString, QHostAddress> detectedDevices;
|
||||||
};
|
};
|
||||||
|
@ -352,7 +352,7 @@ public:
|
|||||||
};
|
};
|
||||||
// S parameter measurements
|
// S parameter measurements
|
||||||
// Key: S parameter name, e.g. "PORT1"
|
// 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;
|
std::map<QString, double> measurements;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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
|
@ -37,6 +37,7 @@ HEADERS += \
|
|||||||
Device/devicelog.h \
|
Device/devicelog.h \
|
||||||
Device/deviceusblog.h \
|
Device/deviceusblog.h \
|
||||||
Device/deviceusblogview.h \
|
Device/deviceusblogview.h \
|
||||||
|
Device/tracedifferencegenerator.h \
|
||||||
Device/virtualdevice.h \
|
Device/virtualdevice.h \
|
||||||
Generator/generator.h \
|
Generator/generator.h \
|
||||||
Generator/signalgenwidget.h \
|
Generator/signalgenwidget.h \
|
||||||
|
Loading…
Reference in New Issue
Block a user