Intro
Pada tahun ketiga, saya datang untuk berlatih di salah satu perusahaan industri roket dan ruang angkasa domestik. Saya adalah pekerja magang yang ambisius dan cukup aktif
sampai saya melihat rutinitas di perusahaan milik negara Rusia dan, atas permintaan saya, ditugaskan ke departemen yang terlibat dalam pengembangan
alat uji (selanjutnya disebut
KPA ). Omong-omong, sebagian besar pengembangan
CPA menulis bagian perangkat lunak untuk peralatan. Termasuk, untuk memeriksa perangkat keras yang sedang dikembangkan, departemen memiliki berbagai
perangkat kontrol dan pengukuran , semuanya terhubung ke jaringan bersama. Akibatnya, sebagai salah satu tugas pertama saya adalah menulis aplikasi untuk mengendalikan generator sinyal.
Ini akan dibahas dalam artikel.
Mulai
Semua aplikasi di departemen dikembangkan menggunakan C ++ dan perpustakaan Qt. Saya memiliki pengalaman dengan kerangka kerja ini, jadi tidak ada kesulitan di sisi ini. Selain itu, Qt memiliki dokumentasi yang luas, dan Anda selalu dapat
menyalin-menempelkan kode dari StackOverflow untuk berkonsultasi dengan kurator.
Karena semua perangkat terhubung ke jaringan yang sama, pertanyaan tentang bagaimana menghubungkannya juga diselesaikan dengan sangat cepat - kami menggunakan bagian jaringan Qt dalam bentuk QTcpSocket.
Pertanyaan paling menarik muncul ketika saya harus memutuskan bagaimana berkomunikasi dengan perangkat ini, bagaimana mengaktifkan satu atau fungsi lainnya, untuk mentransfer satu atau nilai yang lain. Kemudian ternyata semuanya cukup sepele: ada protokol perintah standar untuk instrumen yang dapat diprogram - SCPI. Ini memungkinkan penggunaan perintah standar untuk mengontrol perangkat apa pun yang mendukung standar ini.
Mulai koding
Semuanya standar dan tidak menarik pada file header:#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
Diputuskan untuk membuat antarmuka seperti ini:

Ini cukup sederhana dan intuitif. Dalam dua pengeditan baris, host dan port perangkat diatur di bagian atas. Dimungkinkan juga untuk memilih nilai standar, maka mereka akan mengambil bentuk berikut:
port = 5025; host = "192.168.1.109";
Berikutnya adalah kotak teks untuk log, respons dari perangkat (kesalahan akan dikirim ke sana, jika ada). Sedikit lebih rendah adalah tombol untuk menghubungkan ke perangkat, mengirim perintah, memeriksa kesalahan. Dalam tiga pengeditan baris terakhir, Anda dapat mengatur perintah Anda sendiri dan mengirimkannya ke perangkat, atau secara terpisah mengatur frekuensi dan amplitudo. Tombol radio di sebelah kanan mengaktifkan / menonaktifkan output RF. Spinner menyesuaikan frekuensi ketika kotak centang dimatikan dan amplitudo saat diaktifkan.
Kami melanjutkan dan menyelesaikan
Semua kesenangan dimulai pada file .cpp: #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" ); } }
Setelah membaca
Saya mengerti bahwa artikel itu mungkin tampak terpisah dari kehidupan dan kenyataan bagi sejumlah besar pembaca, tetapi kendali jarak jauh instrumentasi di bidang teknik adalah topik yang cukup umum yang membawa banyak manfaat dan kenyamanan (misalnya, Anda tidak perlu lari ke perangkat dan tombol tekan) .
Untuk selebihnya, artikel ini bersifat informatif dan menghibur dan lebih ditujukan untuk penggemar dan orang-orang yang terlibat dalam pengembangan dan pengujian papan dan perangkat keras lainnya. Saya hanya ingin memberi tahu sisanya tentang sedikit pengalaman saya dalam mengembangkan perangkat lunak untuk tujuan spesifik tersebut.