QTcpSocket और SCPI के माध्यम से एक सिग्नल जनरेटर के साथ संचार करने के अनुभव के बारे में

परिचय


तीसरे वर्ष में, मैं घरेलू रॉकेट और अंतरिक्ष उद्योग के उद्यमों में से एक में अभ्यास करने आया। मैं एक महत्वाकांक्षी प्रशिक्षु था और काफी सक्रिय था जब तक कि मैंने एक रूसी राज्य के स्वामित्व वाले उद्यम में नियमित काम नहीं देखा था और मेरे अनुरोध पर, परीक्षण उपकरण (इसके बाद केपीए ) के विकास में शामिल विभाग को सौंपा गया था। वैसे, सीपीए के विकास का एक बड़ा हिस्सा उपकरण के लिए सॉफ्टवेयर भाग लिख रहा है। विशेष रूप से, विकसित किए जा रहे हार्डवेयर की जांच करने के लिए, विभाग के पास विभिन्न नियंत्रण और माप उपकरण हैं , ये सभी एक सामान्य नेटवर्क से जुड़े हैं। नतीजतन, मेरे पहले कार्यों में से एक सिग्नल जनरेटर को नियंत्रित करने के लिए एक आवेदन लिख रहा था।

इस पर लेख में चर्चा की जाएगी।

शुरुआत


विभाग में सभी एप्लिकेशन C ++ और Qt लाइब्रेरी का उपयोग करके विकसित किए गए हैं। मुझे इस ढांचे के साथ अनुभव था, इसलिए इस तरफ कोई कठिनाई नहीं थी। इसके अलावा, Qt के पास व्यापक दस्तावेज हैं, और आप क्यूरेटर से परामर्श करने के लिए हमेशा StackOverflow से कोड को कॉपी-पेस्ट कर सकते हैं।

चूंकि सभी डिवाइस एक ही नेटवर्क से जुड़े हुए हैं, इसलिए उन्हें कैसे कनेक्ट किया जाए इसका सवाल भी बहुत जल्दी हल हो गया था - हम क्यूटीपीसी सॉकेट के रूप में क्यूटी के नेटवर्क भाग का उपयोग करते हैं।

सबसे दिलचस्प सवाल तब पैदा हुआ जब मुझे यह तय करना था कि इन उपकरणों के साथ कैसे संवाद किया जाए, एक या दूसरे फ़ंक्शन को कैसे सक्रिय किया जाए, एक या दूसरे मूल्य को स्थानांतरित करने के लिए। फिर यह पता चला कि सब कुछ बहुत मामूली है: प्रोग्रामेबल इंस्ट्रूमेंट्स के लिए मानक कमांड का एक प्रोटोकॉल है - एससीपीआई। यह इस मानक का समर्थन करने वाले किसी भी उपकरण को नियंत्रित करने के लिए मानक कमांड का उपयोग करने की अनुमति देता है।

कोडिंग शुरू करें


हेडर फ़ाइल में सब कुछ मानक और निर्बाध है:
#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 


इस तरह इंटरफ़ेस बनाने का निर्णय लिया गया:



यह काफी सरल और सहज है। दो पंक्ति के संपादन में, डिवाइस का होस्ट और पोर्ट शीर्ष पर सेट किया गया है। मानक मानों का चयन करना भी संभव है, फिर वे निम्नलिखित रूप लेंगे:

 port = 5025; host = "192.168.1.109"; 

अगला लॉग के लिए पाठ बॉक्स है, डिवाइस से प्रतिक्रिया (त्रुटियों को वहां भेजा जाएगा, यदि कोई हो)। डिवाइस को जोड़ने, कमांड भेजने, त्रुटियों की जांच करने के लिए थोड़ा कम बटन हैं। अंतिम तीन पंक्ति-संपादन में, आप या तो अपनी खुद की कमांड सेट कर सकते हैं और इसे डिवाइस पर भेज सकते हैं, या अलग से आवृत्ति और आयाम सेट कर सकते हैं। दाईं ओर स्थित रेडियो बटन RF आउटपुट को चालू / बंद करता है। स्पिनर आवृत्ति को समायोजित करता है जब चेकबॉक्स बंद होता है और सक्रिय होने पर आयाम।

हम जारी रखते हैं और खत्म करते हैं


सभी मजेदार .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" ); } } 


पढ़ने के बाद


मैं समझता हूं कि लेख बड़ी संख्या में पाठकों के लिए जीवन और वास्तविकता से तलाकशुदा लग सकता है, लेकिन इंजीनियरिंग के क्षेत्र में इंस्ट्रूमेंटेशन का रिमोट कंट्रोल एक काफी सामान्य विषय है जो बहुत अधिक लाभ और सुविधा लाता है (उदाहरण के लिए, आपको डिवाइस और प्रेस बटन चलाने की आवश्यकता नहीं है) ।

बाकी के लिए, यह लेख एक सूचनात्मक और मनोरंजक प्रकृति का है और इसका उद्देश्य उत्साही लोगों और बोर्डों और अन्य हार्डवेयर के विकास और परीक्षण में शामिल लोगों पर अधिक संभावना है। मैं इस तरह के विशिष्ट उद्देश्यों के लिए सॉफ्टवेयर के विकास में अपने छोटे से अनुभव के बारे में बाकी बताना चाहूंगा।

Source: https://habr.com/ru/post/hi435448/


All Articles