Intro
Im dritten Jahr praktizierte ich in einem der Unternehmen der heimischen Raketen- und Raumfahrtindustrie. Ich war ein ehrgeiziger Praktikant und ziemlich aktiv,
bis ich die Routine in einem staatlichen russischen Unternehmen sah und auf meine Bitte der Abteilung zugewiesen wurde, die an der Entwicklung
von Testgeräten (im Folgenden:
KPA ) beteiligt war. Übrigens schreibt ein großer Teil der Entwicklung des
CPA den Softwareteil für die Ausrüstung. Zur Überprüfung der zu entwickelnden Hardware verfügt die Abteilung über verschiedene
Steuer- und Messgeräte , die alle mit einem gemeinsamen Netzwerk verbunden sind. Als eine meiner ersten Aufgaben war es daher, eine Anwendung zur Steuerung eines Signalgenerators zu schreiben.
Dies wird im Artikel besprochen.
Starten Sie
Alle Anwendungen in der Abteilung werden mit C ++ und der Qt-Bibliothek entwickelt. Ich hatte Erfahrung mit diesem Rahmen, daher gab es auf dieser Seite keine Schwierigkeiten. Darüber hinaus verfügt Qt über eine umfangreiche Dokumentation, und Sie können
den Code jederzeit
aus StackOverflow kopieren und einfügen, um einen Kurator
zu konsultieren.
Da alle Geräte mit demselben Netzwerk verbunden sind, wurde auch die Frage, wie eine Verbindung zu ihnen hergestellt werden soll, sehr schnell gelöst. Wir verwenden den Netzwerkteil von Qt in Form von QTcpSocket.
Die interessanteste Frage stellte sich, als ich mich entscheiden musste, wie ich mit diesen Geräten kommunizieren, die eine oder andere Funktion aktivieren und den einen oder anderen Wert übertragen soll. Dann stellte sich heraus, dass alles ziemlich trivial ist: Es gibt ein Protokoll von Standardbefehlen für programmierbare Instrumente - SCPI. Es ermöglicht die Verwendung von Standardbefehlen zur Steuerung aller Geräte, die diesen Standard unterstützen.
Starten Sie die Codierung
In der Header-Datei ist alles Standard und uninteressant:#ifndef SIGGENCONTROL_H #define SIGGENCONTROL_H #include <QMainWindow> #include <QTcpSocket> #include <QString> namespace Ui { class sigGenControl; } class sigGenControl : public QMainWindow { Q_OBJECT public: explicit sigGenControl(QWidget *parent = 0); ~sigGenControl(); // , QString host; //= "192.168.1.109"; ip int port;// = 5025; void clearErr(); // bool rfOn; // bool pset = false; bool hset = false; private: Ui::sigGenControl *ui; QTcpSocket* socket; private slots: //, .cpp void connectToHostSlot(); void sendToHostSlot(); void readyReadSlot(); void setFreq(); void setPow(); void activateRF(); void checkErrSlot(); void setPort(); void setHost(); void setDefault(); void dialValChangedSlot(); }; #endif // SIGGENCONTROL_H
Es wurde beschlossen, die Benutzeroberfläche folgendermaßen zu gestalten:

Es ist ganz einfach und intuitiv. Bei den zwei Zeilenänderungen werden der Host und der Port des Geräts oben festgelegt. Es ist auch möglich, Standardwerte auszuwählen, die dann die folgende Form annehmen:
port = 5025; host = "192.168.1.109";
Als nächstes folgt das Textfeld für das Protokoll, die Antwort vom Gerät (Fehler werden dort gesendet, falls vorhanden). Etwas tiefer befinden sich die Tasten zum Herstellen einer Verbindung zum Gerät, zum Senden eines Befehls und zum Überprüfen von Fehlern. In den letzten drei Zeilenänderungen können Sie entweder Ihren eigenen Befehl festlegen und an das Gerät senden oder die Frequenz und Amplitude separat einstellen. Das Optionsfeld rechts schaltet den HF-Ausgang ein / aus. Der Spinner passt die Frequenz an, wenn das Kontrollkästchen deaktiviert ist, und die Amplitude, wenn sie aktiviert ist.
Wir fahren fort und beenden
Der ganze Spaß beginnt in der CPP-Datei: #include "siggencontrol.h" #include "ui_siggencontrol.h" #include "qdebug.h" #include <QTime> sigGenControl::sigGenControl(QWidget *parent) : QMainWindow(parent), ui(new Ui::sigGenControl) { ui->setupUi(this); ui->history->setReadOnly(true); ui->history->setText("host : not set\nport : not set"); ui->history->append(QTime::currentTime().toString() + " : No connection"); socket = new QTcpSocket(this); // // - // , // connect(ui->connPb,QPushButton::clicked,this,sigGenControl::connectToHostSlot); connect(ui->sendToHostPb,QPushButton::clicked,this,sigGenControl::sendToHostSlot); connect(ui->input,QLineEdit::returnPressed,this,sigGenControl::sendToHostSlot); connect(socket,QTcpSocket::readyRead,this,sigGenControl::readyReadSlot); connect(ui->freqEdit,QLineEdit::returnPressed,this,sigGenControl::setFreq); connect(ui->amptdEdit,QLineEdit::returnPressed,this,sigGenControl::setPow); connect(ui->radioButton,QRadioButton::clicked,this,sigGenControl::activateRF); connect(ui->errPb,QPushButton::clicked,this,sigGenControl::clearErr); connect(ui->hostEdit,QLineEdit::returnPressed,this,sigGenControl::setHost); connect(ui->portEdit,QLineEdit::returnPressed,this,sigGenControl::setPort); connect(ui->checkBox,QCheckBox::clicked,this,sigGenControl::setDefault); connect(ui->dial, QDial::valueChanged,this,sigGenControl::dialValChangedSlot); ui->hist->setReadOnly(true); QString deactRF = ":OUTP 0\n"; // SCPI , socket->write(deactRF.toLocal8Bit()); // this->rfOn = false; // ui->input->setReadOnly(true); ui->freqEdit->setReadOnly(true); ui->amptdEdit->setReadOnly(true); ui->radioButton->setEnabled(false); ui->sendToHostPb->setEnabled(false); ui->errPb->setEnabled(false); ui->connPb->setDisabled(true); } sigGenControl::~sigGenControl() { delete ui; } void sigGenControl::connectToHostSlot(){ socket->connectToHost(host,port); // // qDebug() if (socket->waitForConnected(1000)) qDebug("Connected!"); ui->history->append(QTime::currentTime().toString() + " : Connected"); // ui->input->setReadOnly(false); ui->freqEdit->setReadOnly(false); ui->amptdEdit->setReadOnly(false); ui->radioButton->setEnabled(true); ui->sendToHostPb->setEnabled(true); ui->errPb->setEnabled(true); ui->input->setText("*IDN?"); // } void sigGenControl::sendToHostSlot(){ // socket->write(ui->input->text().toLocal8Bit()+"\n"); } void sigGenControl::readyReadSlot(){ // qDebug("ready read!"); QByteArray dataArr; // dataArr = socket->readAll(); // ui->hist->append(QTime::currentTime().toString() + " " + dataArr); } void sigGenControl::clearErr(){ // , , , QString errTxt = ":SYST:ERR?\n"; socket->write(errTxt.toLocal8Bit()); } void sigGenControl::setFreq(){ QString fr = " kHz"; QString cmd = ":FREQ "; // QString command = cmd+ui->freqEdit->text()+fr+"\n"; // qDebug() << command; socket->write(command.toLocal8Bit()); // } void sigGenControl::setPow(){ QString amp = " dBm"; QString cmd = ":POW "; // socket->write(cmd.toLocal8Bit() + ui->amptdEdit->text().toLocal8Bit() + amp.toLocal8Bit() + "\n"); // } void sigGenControl::activateRF(){ // // QString actRF = ":OUTP 1\n"; // QString deactRF = ":OUTP 0\n"; // if(this->rfOn == false){ socket->write(actRF.toLocal8Bit()); rfOn = true; }else{ socket->write(deactRF.toLocal8Bit()); rfOn = false; } } void sigGenControl::checkErrSlot(){ clearErr(); } void sigGenControl::setHost(){ // this->host = ui->hostEdit->text(); ui->history->append("host: " + host); ui->checkBox->setEnabled(true); hset = true; // if((pset && hset) == true){ ui->connPb->setEnabled(true); } } void sigGenControl::setPort(){ // this->port = ui->portEdit->text().toInt(); ui->history->append("port: " + QString::number(port)); ui->checkBox->setEnabled(true); pset = true; // if((pset && hset) == true){ ui->connPb->setEnabled(true); } } void sigGenControl::setDefault(){ // port = 5025; host = "192.168.1.109"; ui->history->append(QTime::currentTime().toString() + " " + "host: " + host); ui->history->append(QTime::currentTime().toString() + " " + "port: " + QString::number(port)); ui->checkBox->setDisabled(true); ui->connPb->setEnabled(true); ui->hostEdit->setText(host); ui->portEdit->setText(QString::number(port)); } void sigGenControl::dialValChangedSlot(){ // , qDebug()<< "value : " << ui->dial->value(); if(ui->amplCheckBox->isChecked() == false){ // , ui->dial->setMinimum(100); ui->dial->setMaximum(20000000); QString fr = " kHz"; QString cmd = ":FREQ "; // QString command = cmd+QString::number(ui->dial->value())+fr+"\n"; qDebug() << command; socket->write(command.toLocal8Bit()); ui->label->setText("FREQUENCY :" + QString::number(ui->dial->value()) + " kHz" ); }else if(ui->amplCheckBox->isChecked() == true){ // , ui->dial->setMinimum(-130); ui->dial->setMaximum(15); QString pw = " dBm"; QString cmd = ":POW "; // QString command = cmd+QString::number(ui->dial->value())+pw+"\n"; qDebug() << command; socket->write(command.toLocal8Bit()); ui->label->setText("AMPLITUDE :" + QString::number(ui->dial->value()) + " dBm" ); } }
Nach dem Lesen
Ich verstehe, dass der Artikel für eine große Anzahl von Lesern vom Leben und der Realität getrennt zu sein scheint, aber die Fernsteuerung von Instrumenten im Bereich der Technik ist ein ziemlich häufiges Thema, das viel Nutzen und Komfort bringt (zum Beispiel müssen Sie nicht zu Geräten laufen und Tasten drücken). .
Im Übrigen ist dieser Artikel informativer und unterhaltsamer Natur und richtet sich eher an Enthusiasten und an Personen, die an der Entwicklung und dem Testen von Boards und anderer Hardware beteiligt sind. Ich möchte nur den Rest über meine kleinen Erfahrungen bei der Entwicklung von Software für solche spezifischen Zwecke erzählen.