1 #include "mainwindow.h"
2 #include "ui_mainwindow.h"
3 #include "workerthread.h"
4 #include <QString>
5 #include <QClipboard>
6 #include <QAction>
7 #include <QMessageBox>
8 #include <QFileDialog>
9 #include <QDesktopServices>
10 #include <QtCharts/QChartView>
11 #include <QtCharts/QLineSeries>
12 #include <QtCharts/QValueAxis>
13 #include <QTimer>
14 #include <QTime>
15 #include <QThread>
16 #include <QInputDialog>
17 #include <QTextStream>
18 #include <iostream>
19 #include <lxi.h>
20 #include "../../include/config.h"
21 #include "../../include/scpi.h"
22 #include "../../include/benchmark.h"
23 #include "../../include/screenshot.h"
24
25 extern void lxi_discover_(int timeout, lxi_discover_t type);
26 extern void benchmark_progress(void);
27
28 QT_CHARTS_USE_NAMESPACE
29
MainWindow(QWidget * parent)30 MainWindow::MainWindow(QWidget *parent) :
31 QMainWindow(parent),
32 ui(new Ui::MainWindow)
33 {
34 ui->setupUi(this);
35
36 // Create message box for error messages etc.
37 messageBox = new QMessageBox(this);
38
39 // Setup instrument table widget
40 ui->tableWidget_InstrumentList->setEditTriggers(QAbstractItemView::NoEditTriggers);
41 ui->tableWidget_InstrumentList->verticalHeader()->setVisible(false);
42 ui->tableWidget_InstrumentList->setShowGrid(false);
43 ui->tableWidget_InstrumentList->setContextMenuPolicy(Qt::ActionsContextMenu);
44 QAction* copyIDAction = new QAction("Copy ID", this);
45 QAction* copyIPAction = new QAction("Copy IP", this);
46 QAction* openBrowserAction = new QAction("Open in browser", this);
47 connect(copyIDAction, SIGNAL(triggered()), this, SLOT(InstrumentList_copyID()));
48 connect(copyIPAction, SIGNAL(triggered()), this, SLOT(InstrumentList_copyIP()));
49 connect(openBrowserAction, SIGNAL(triggered()), this, SLOT(InstrumentList_openBrowser()));
50 ui->tableWidget_InstrumentList->addAction(copyIDAction);
51 ui->tableWidget_InstrumentList->addAction(copyIPAction);
52 ui->tableWidget_InstrumentList->addAction(openBrowserAction);
53
54 // Set up SCPI send action for line edit box
55 lineEdit = ui->comboBox_SCPI_Command->lineEdit();
56 connect(lineEdit, SIGNAL(returnPressed()), this, SLOT(SCPIsendCommand()));
57
58 // Setup Screenshot page
59 ui->graphicsView_Screenshot->setStyleSheet("background: transparent");
60 q_pixmap = new QPixmap(":/images/photo-camera.png");
61 scene = new QGraphicsScene();
62 ui->graphicsView_Screenshot->setScene(scene);
63 scene->addPixmap(*q_pixmap);
64 ui->graphicsView_Screenshot->show();
65 live_view_active = false;
66
67 // Set up About page labels
68 ui->label_10->setText("<a href=\"https://lxi-tools.github.io/\"><span style=\"color:darkorange;\">Website</span></a>");
69 ui->label_10->setTextFormat(Qt::RichText);
70 ui->label_10->setTextInteractionFlags(Qt::TextBrowserInteraction);
71 ui->label_10->setOpenExternalLinks(true);
72 QString string_version;
73 string_version.sprintf("%s (BETA)", VERSION);
74 ui->label_11->setText(string_version);
75
76 // Set search button icon
77 //ui->pushButton->setIcon(ui->pushButton->style()->standardIcon(QStyle::SP_DialogApplyButton));
78
79 // Setup Data Recorder page
80 datarecorder_chart = new QChart();
81 datarecorder_chart->legend()->hide();
82 datarecorder_chart->setBackgroundVisible(false);
83 datarecorder_chart->setPlotAreaBackgroundVisible(true);
84 datarecorder_chart->setContentsMargins(0, 0, 0, 0);
85 datarecorder_chart->setBackgroundRoundness(0);
86 QBrush brush;
87 brush.setStyle(Qt::SolidPattern);
88 brush.setColor(Qt::white);
89 datarecorder_chart->setPlotAreaBackgroundBrush(brush);
90 line_series0 = new QLineSeries();
91 line_series1 = new QLineSeries();
92 line_series0->setName("Series 0");
93 line_series1->setName("Series 1");
94 datarecorder_chart->addSeries(line_series0);
95 datarecorder_chart->addSeries(line_series1);
96 axisX = new QValueAxis();
97 axisX->setTitleText("Time [s]");
98 datarecorder_chart->setAxisX(axisX, line_series0);
99 datarecorder_chart->setAxisX(axisX, line_series1);
100 axisX->setRange(0, 1);
101 axisY = new QValueAxis();
102 //axisY->setTitleText("Value");
103 datarecorder_chart->setAxisY(axisY, line_series0);
104 datarecorder_chart->setAxisY(axisY, line_series1);
105 axisY->setRange(0, 1);
106 //datarecorder_chart->setTitle("Data recorder chart");
107 ui->chartView->setChart(datarecorder_chart);
108 timer = new QTimer(this);
109 connect(timer, SIGNAL(timeout()), this, SLOT(DataRecorder_Update()));
110 data_recorder_active = false;
111 data_recorder_sample_counter = 0;
112 ui->chartView->setRenderHint(QPainter::Antialiasing);
113 ui->chartView->setRubberBand(QChartView::HorizontalRubberBand);
114 ui->chartView->setContextMenuPolicy(Qt::ActionsContextMenu);
115 QPalette pal;
116 pal.setColor(QPalette::Window, QColor(0,0,0,0));
117 ui->chartView->setPalette(pal);
118 ui->chartView->setBackgroundRole(QPalette::Window);
119 QAction* zoomInAction = new QAction("Zoom In", this);
120 QAction* zoomOutAction = new QAction("Zoom Out", this);
121 QAction* zoomResetAction = new QAction("Zoom Reset", this);
122 connect(zoomInAction, SIGNAL(triggered()), this, SLOT(DataRecorder_zoomIn()));
123 connect(zoomOutAction, SIGNAL(triggered()), this, SLOT(DataRecorder_zoomOut()));
124 connect(zoomResetAction, SIGNAL(triggered()), this, SLOT(DataRecorder_zoomReset()));
125 ui->chartView->addAction(zoomInAction);
126 ui->chartView->addAction(zoomOutAction);
127 ui->chartView->addAction(zoomResetAction);
128 ui->pushButton_DataRecorder_Save->setEnabled(false);
129
130 // Register screenshot plugins
131 screenshot_register_plugins();
132 }
133
134 // Handle resize events
resizeEvent(QResizeEvent * event)135 void MainWindow::resizeEvent(QResizeEvent *event)
136 {
137 resize();
138 QMainWindow::resizeEvent(event);
139 }
140
141 // Handle resize
resize()142 void MainWindow::resize()
143 {
144 ui->tableWidget_InstrumentList->setColumnWidth(0, ui->tableWidget_InstrumentList->width()*4/5);
145 ui->tableWidget_InstrumentList->setColumnWidth(1, ui->tableWidget_InstrumentList->width()/5-1);
146 }
147
148 // Connect
LXI_connect()149 int MainWindow::LXI_connect()
150 {
151 int timeout = ui->spinBox_SCPITimeout->value() * 1000;
152 char *ip = (char *) IP.toUtf8().data();
153
154 // Connect
155 lxi_device = lxi_connect(ip, 0, NULL, timeout, VXI11);
156 if (lxi_device == LXI_ERROR)
157 {
158 messageBox->critical(this, "Error", "Failed to connect!");
159 return -1;
160 }
161
162 return 0;
163 }
164
165 // Send command
LXI_send_receive(QString * command,QString * response,int timeout)166 int MainWindow::LXI_send_receive(QString *command, QString *response, int timeout)
167 {
168 char response_buffer[10000] = "";
169 char command_buffer[10000] = "";
170 int length;
171
172 if (command->size() > 0)
173 {
174 // Prepare SCPI command string
175 strcpy(command_buffer, command->toUtf8().constData());
176 strip_trailing_space(command_buffer);
177
178 // Send command
179 lxi_send(lxi_device, command_buffer, strlen(command_buffer), timeout);
180
181 // If command is a question then receive response
182 if (question(command_buffer))
183 {
184 length = lxi_receive(lxi_device, response_buffer, 10000, timeout);
185 if (length < 0)
186 {
187 messageBox->critical(this, "Error", "Failed to receive message!");
188 lxi_disconnect(lxi_device);
189 return -1;
190 }
191
192 // Return response
193 *response = QString::fromStdString(response_buffer);
194 }
195 }
196
197 return 0;
198 }
199
200 // Disconnect
LXI_disconnect()201 int MainWindow::LXI_disconnect()
202 {
203 if (lxi_disconnect(lxi_device) != LXI_OK)
204 return -1;
205 else
206 return 0;
207 }
208
SCPIsendCommand(QString * command)209 void MainWindow::SCPIsendCommand(QString *command)
210 {
211 int timeout = ui->spinBox_SCPITimeout->value() * 1000;
212 QString request, response;
213 int status;
214
215 if (IP.isEmpty())
216 {
217 messageBox->warning(this, "Warning", "Please select instrument!");
218 return;
219 }
220
221 LXI_connect();
222
223 // Print request
224 request = "<span style=\" font-size:10pt; font-weight:600; color:#808080;\">";
225 request.append(*command);
226 request.append("<br></span>");
227 ui->textBrowser_SCPI_Response->insertHtml(request);
228 ui->textBrowser_SCPI_Response->ensureCursorVisible();
229
230 status = LXI_send_receive(command, &response, timeout);
231 if (status == 0)
232 {
233 if (response.size() > 0)
234 {
235 // Print response
236 response.insert(0, "<span style=\" font-size:10pt; font-weight:600; color:#000000;\">");
237 response.append("<br></span>");
238 ui->textBrowser_SCPI_Response->insertHtml(response);
239 ui->textBrowser_SCPI_Response->ensureCursorVisible();
240 }
241
242 LXI_disconnect();
243 }
244 }
245
SCPIsendCommand()246 void MainWindow::SCPIsendCommand()
247 {
248 if (IP.isEmpty())
249 {
250 messageBox->warning(this, "Warning", "Please select instrument!");
251 return;
252 }
253
254 QString command(ui->comboBox_SCPI_Command->currentText());
255 SCPIsendCommand(&command);
256 }
257
SCPIsendCommand(const char * command)258 void MainWindow::SCPIsendCommand(const char *command)
259 {
260 if (IP.isEmpty())
261 {
262 messageBox->warning(this, "Warning", "Please select instrument!");
263 return;
264 }
265
266 QString *command_ = new QString(command);
267 SCPIsendCommand(command_);
268 }
269
InstrumentList_copyID()270 void MainWindow::InstrumentList_copyID()
271 {
272 QClipboard *clipboard = QApplication::clipboard();
273 QTableWidgetItem *item = ui->tableWidget_InstrumentList->item(ui->tableWidget_InstrumentList->currentRow(), 0);
274 clipboard->setText(item->text());
275 }
276
InstrumentList_copyIP()277 void MainWindow::InstrumentList_copyIP()
278 {
279 QClipboard *clipboard = QApplication::clipboard();
280 QTableWidgetItem *item = ui->tableWidget_InstrumentList->item(ui->tableWidget_InstrumentList->currentRow(), 1);
281 clipboard->setText(item->text());
282 }
283
InstrumentList_openBrowser()284 void MainWindow::InstrumentList_openBrowser()
285 {
286 QTableWidgetItem *item = ui->tableWidget_InstrumentList->item(ui->tableWidget_InstrumentList->currentRow(), 1);
287 QString URL = "http://" + item->text();
288 QDesktopServices::openUrl(QUrl(URL));
289 }
290
~MainWindow()291 MainWindow::~MainWindow()
292 {
293 delete ui;
294 }
295
296 // Search button
on_pushButton_Search_clicked()297 void MainWindow::on_pushButton_Search_clicked()
298 {
299 int timeout = ui->spinBox_SearchTimeout->value() * 1000;
300
301 ui->tableWidget_InstrumentList->clearContents();
302 ui->tableWidget_InstrumentList->setRowCount(0);
303 ui->pushButton_Search->setText("Searching");
304 ui->pushButton_Search->repaint();
305 lxi_discover_(timeout, ui->checkBox_mDNS->isChecked() ? DISCOVER_MDNS : DISCOVER_VXI11);
306 ui->statusBar->clearMessage();
307 ui->pushButton_Search->setText("Search");
308 IP.clear();
309 }
310
add_instrument(const char * id,const char * address)311 void MainWindow::add_instrument(const char *id, const char *address)
312 {
313 QString instrument_id = QString::fromStdString(id);
314 QString instrument_address = QString::fromStdString(address);
315
316 ui->tableWidget_InstrumentList->insertRow(0);
317 ui->tableWidget_InstrumentList->setItem(0,0, new QTableWidgetItem(instrument_id));
318 ui->tableWidget_InstrumentList->setItem(0,1, new QTableWidgetItem(instrument_address));
319 ui->tableWidget_InstrumentList->item(0,1)->setTextAlignment(Qt::AlignCenter);
320 }
321
update_statusbar(const char * message)322 void MainWindow::update_statusbar(const char *message)
323 {
324 QString status_message = QString::fromStdString(message);
325 ui->statusBar->showMessage(status_message);
326 }
327
328 // SCPI Send button
on_pushButton_SCPI_Send_clicked()329 void MainWindow::on_pushButton_SCPI_Send_clicked()
330 {
331 SCPIsendCommand();
332 }
333
on_tableWidget_InstrumentList_cellClicked(int row,int column)334 void MainWindow::on_tableWidget_InstrumentList_cellClicked(__attribute__((unused)) int row, __attribute__((unused)) int column)
335 {
336 QTableWidgetItem *item = ui->tableWidget_InstrumentList->item(ui->tableWidget_InstrumentList->currentRow(), 1);
337
338 // Update IP
339 IP = item->text();
340 }
341
update_progressbar()342 void MainWindow::update_progressbar()
343 {
344 ui->progressBar->setValue(ui->progressBar->value() + 1);
345 }
346
347 // Benchmark start
on_pushButton_Benchmark_Start_clicked()348 void MainWindow::on_pushButton_Benchmark_Start_clicked()
349 {
350 double result;
351 QString q_result;
352 QMessageBox messageBox(this);
353
354 if (IP.isEmpty())
355 {
356 messageBox.warning(this, "Warning", "Please select instrument!");
357 return;
358 }
359
360 // Reset
361 ui->label_6->clear();
362 ui->progressBar->setValue(0);
363 ui->progressBar->setMaximum(ui->spinBox_BenchmarkRequests->value());
364
365 // Run benchmark
366 ui->pushButton_Benchmark_Start->setText("Testing");
367 ui->pushButton_Benchmark_Start->repaint();
368 benchmark(IP.toUtf8().data(), 0, 1000, VXI11, ui->spinBox_BenchmarkRequests->value(), false, &result, benchmark_progress);
369 ui->pushButton_Benchmark_Start->setText("Start");
370 ui->pushButton_Benchmark_Start->repaint();
371
372 // Print result
373 q_result = QString::number(result, 'f', 1);
374 ui->label_6->setText(q_result + " requests/second");
375 }
376
Screenshot_UpdateUI(QPixmap pixmap,QString image_format,QString image_filename)377 void MainWindow::Screenshot_UpdateUI(QPixmap pixmap, QString image_format, QString image_filename)
378 {
379 // Update UI
380 // TODO: Refactor common screenshot code
381
382 int width = ui->graphicsView_Screenshot->width();
383 int height = ui->graphicsView_Screenshot->height() - 2;
384
385 screenshotImageFormat.clear();
386 screenshotImageFormat.append(image_format);
387
388 screenshotImageFilename.clear();
389 screenshotImageFilename.append(image_filename);
390
391 pixmap = pixmap.scaled(QSize(std::min(width, pixmap.width()), std::min(height, pixmap.height())), Qt::KeepAspectRatio, Qt::SmoothTransformation);
392 *q_pixmap = pixmap;
393
394 if (!pixmapItem)
395 pixmapItem = scene->addPixmap(pixmap);
396 else
397 pixmapItem->setPixmap(pixmap);
398
399 ui->graphicsView_Screenshot->show();
400 }
401
402 // Live View
on_pushButton_Screenshot_LiveView_clicked()403 void MainWindow::on_pushButton_Screenshot_LiveView_clicked()
404 {
405 static WorkerThread *workerthread;
406 QMessageBox messageBox(this);
407
408 if (IP.isEmpty())
409 {
410 messageBox.warning(this, "Warning", "Please select instrument!");
411 return;
412 }
413
414 if (live_view_active)
415 {
416 // Stop live view
417
418 // Wait for worker thread to finish
419 workerthread->live = false;
420 workerthread->wait();
421 delete workerthread;
422
423 ui->pushButton_Screenshot_LiveView->setText("Live View");
424 ui->pushButton_Screenshot_LiveView->repaint();
425
426 // Enable buttons
427 ui->pushButton_Screenshot_Save->setEnabled(true);
428 ui->pushButton_Screenshot_TakeScreenshot->setEnabled(true);
429
430 live_view_active = false;
431 } else
432 {
433 // Start live view
434 ui->pushButton_Screenshot_LiveView->setText("Stop");
435 ui->pushButton_Screenshot_LiveView->repaint();
436
437 // Disable buttons
438 ui->pushButton_Screenshot_Save->setEnabled(false);
439 ui->pushButton_Screenshot_TakeScreenshot->setEnabled(false);
440
441 // Start worker thread
442 int timeout = ui->spinBox_ScreenshotTimeout->value() * 1000;
443 workerthread = new WorkerThread;
444 connect(workerthread, SIGNAL(requestUpdateUI(QPixmap, QString, QString)), this, SLOT(Screenshot_UpdateUI(QPixmap, QString, QString)));
445 workerthread->startLiveUpdate(IP, timeout);
446
447 live_view_active = true;
448 }
449 }
450
451 // Take screenshot
on_pushButton_Screenshot_TakeScreenshot_clicked()452 void MainWindow::on_pushButton_Screenshot_TakeScreenshot_clicked()
453 {
454 char image_buffer[0x200000];
455 int image_size = 0;
456 char image_format[10];
457 char image_filename[1000];
458 int timeout = ui->spinBox_ScreenshotTimeout->value() * 1000;
459
460 QMessageBox messageBox(this);
461
462 if (IP.isEmpty())
463 {
464 messageBox.warning(this, "Warning", "Please select instrument!");
465 return;
466 }
467
468 // Capture screenshot
469 screenshot(IP.toUtf8().data(), "", "", timeout, false, image_buffer, &image_size, image_format, image_filename);
470
471 screenshotImageFormat.clear();
472 screenshotImageFormat.append(image_format);
473
474 screenshotImageFilename.clear();
475 screenshotImageFilename.append(image_filename);
476
477 int width = ui->graphicsView_Screenshot->width();
478 int height = ui->graphicsView_Screenshot->height() - 2;
479
480 q_pixmap->loadFromData((const uchar*) image_buffer, image_size, "", Qt::AutoColor);
481 *q_pixmap = q_pixmap->scaled(QSize(std::min(width, q_pixmap->width()), std::min(height, q_pixmap->height())), Qt::KeepAspectRatio, Qt::SmoothTransformation);
482
483 if (!pixmapItem)
484 pixmapItem = scene->addPixmap(*q_pixmap);
485 else
486 pixmapItem->setPixmap(*q_pixmap);
487
488 ui->graphicsView_Screenshot->show();
489
490 // Enable buttons
491 ui->pushButton_Screenshot_Save->setEnabled(true);
492 }
493
494 // Save screenshot
on_pushButton_Screenshot_Save_clicked()495 void MainWindow::on_pushButton_Screenshot_Save_clicked()
496 {
497 QString filename = QFileDialog::getSaveFileName(this, "Save file", screenshotImageFilename, "." + screenshotImageFormat);
498 QFile file(filename);
499 file.open(QIODevice::WriteOnly);
500 q_pixmap->save(&file, screenshotImageFormat.toUtf8().constData());
501 file.close();
502 }
503
504 // *CLS
on_pushButton_SCPI_CLS_clicked()505 void MainWindow::on_pushButton_SCPI_CLS_clicked()
506 {
507 SCPIsendCommand("*CLS");
508 }
509
510 // *ESE
on_pushButton_SCPI_ESE_clicked()511 void MainWindow::on_pushButton_SCPI_ESE_clicked()
512 {
513 QString command;
514 bool ok;
515 int i = QInputDialog::getInt(this, "*ESE <value>", "Value:", 0, 0, 255, 1, &ok);
516 if (ok)
517 {
518 command = tr("*ESE %1").arg(i);
519 SCPIsendCommand(&command);
520 }
521 }
522
523 // *ESE?
on_pushButton_SCPI_ESEQuestion_clicked()524 void MainWindow::on_pushButton_SCPI_ESEQuestion_clicked()
525 {
526 SCPIsendCommand("*ESE?");
527 }
528
529 // *ESR?
on_pushButton_SCPI_ESRQuestion_clicked()530 void MainWindow::on_pushButton_SCPI_ESRQuestion_clicked()
531 {
532 SCPIsendCommand("*ESR?");
533 }
534
535 // *IDN?
on_pushButton_SCPI_IDNQuestion_clicked()536 void MainWindow::on_pushButton_SCPI_IDNQuestion_clicked()
537 {
538 SCPIsendCommand("*IDN?");
539 }
540
541 // *OPC
on_pushButton_SCPI_OPC_clicked()542 void MainWindow::on_pushButton_SCPI_OPC_clicked()
543 {
544 SCPIsendCommand("*OPC");
545 }
546
547 // *OPC?
on_pushButton_SCPI_OPCQuestion_clicked()548 void MainWindow::on_pushButton_SCPI_OPCQuestion_clicked()
549 {
550 SCPIsendCommand("*OPC?");
551 }
552
553 // Blank button
on_pushButton_SCPI_Blank_clicked()554 void MainWindow::on_pushButton_SCPI_Blank_clicked()
555 {
556 }
557
558 // *RST
on_pushButton_SCPI_RST_clicked()559 void MainWindow::on_pushButton_SCPI_RST_clicked()
560 {
561 SCPIsendCommand("*RST");
562 }
563
564 // *SRE
on_pushButton_SCPI_SRE_clicked()565 void MainWindow::on_pushButton_SCPI_SRE_clicked()
566 {
567 QString command;
568 bool ok;
569 int i = QInputDialog::getInt(this, "*SRE <value>", "Value:", 0, 0, 255, 1, &ok);
570 if (ok)
571 {
572 command = tr("*SRE %1").arg(i);
573 SCPIsendCommand(&command);
574 }
575 }
576
577 // *SRE?
on_pushButton_SCPI_SREQuestion_clicked()578 void MainWindow::on_pushButton_SCPI_SREQuestion_clicked()
579 {
580 SCPIsendCommand("*SRE?");
581 }
582
583 // *STB?
on_pushButton_SCPI_STBQuestion_clicked()584 void MainWindow::on_pushButton_SCPI_STBQuestion_clicked()
585 {
586 SCPIsendCommand("*STB?");
587 }
588
589 // *TST?
on_pushButton_SCPI_TSTQuestion_clicked()590 void MainWindow::on_pushButton_SCPI_TSTQuestion_clicked()
591 {
592 SCPIsendCommand("*TST?");
593 }
594
595 // *WAI
on_pushButton_SCPI_WAI_clicked()596 void MainWindow::on_pushButton_SCPI_WAI_clicked()
597 {
598 SCPIsendCommand("*WAI");
599 }
600
on_pushButton_SCPI_SystemVersionQuery_clicked()601 void MainWindow::on_pushButton_SCPI_SystemVersionQuery_clicked()
602 {
603 SCPIsendCommand(":SYSTem:VERSion?");
604 }
605
on_pushButton_SCPI_SystemErrorQuery_clicked()606 void MainWindow::on_pushButton_SCPI_SystemErrorQuery_clicked()
607 {
608 SCPIsendCommand(":SYSTem:ERRor?");
609 }
610
on_pushButton_SCPI_SystemErrorNextQuery_clicked()611 void MainWindow::on_pushButton_SCPI_SystemErrorNextQuery_clicked()
612 {
613 SCPIsendCommand(":SYSTem:ERRor:NEXT?");
614 }
615
on_pushButton_SCPIP_StatusOperationQuery_clicked()616 void MainWindow::on_pushButton_SCPIP_StatusOperationQuery_clicked()
617 {
618 SCPIsendCommand(":STATus:OPERation?");
619 }
620
on_pushButton_SCPI_StatusPreset_clicked()621 void MainWindow::on_pushButton_SCPI_StatusPreset_clicked()
622 {
623 SCPIsendCommand(":SYSTem:PRESet");
624 }
625
626 // Data recorder start
on_pushButton_DataRecorder_Start_clicked()627 void MainWindow::on_pushButton_DataRecorder_Start_clicked()
628 {
629 if (IP.isEmpty())
630 {
631 messageBox->warning(this, "Warning", "Please select instrument!");
632 return;
633 }
634
635 if (data_recorder_active)
636 {
637 // Stop recording
638 timer->stop();
639 ui->pushButton_DataRecorder_Start->setText("Start");
640 LXI_disconnect();
641
642 // Enable inputs
643 ui->lineEdit->setEnabled(true);
644 ui->lineEdit_2->setEnabled(true);
645 if (line_series0->count() || line_series1->count())
646 ui->pushButton_DataRecorder_Save->setEnabled(true);
647 else
648 ui->pushButton_DataRecorder_Save->setEnabled(false);
649 ui->spinBox_DataRecorderRate->setEnabled(true);
650 }
651 else
652 {
653 // Reset
654 line_series0->clear();
655 line_series1->clear();
656 axisX->setRange(0, 1);
657 axisY->setRange(0, 1);
658 data_recorder_first_sample = true;
659 data_recorder_sample_counter = 0;
660
661 // Start recording
662 time.start();
663 data_recorder_time_slice = 1000 / ui->spinBox_DataRecorderRate->value();
664 timer->start(data_recorder_time_slice);
665 ui->pushButton_DataRecorder_Start->setText("Stop");
666
667 LXI_connect();
668
669 // Disable inputs
670 ui->lineEdit->setEnabled(false);
671 ui->lineEdit_2->setEnabled(false);
672 ui->pushButton_DataRecorder_Save->setEnabled(false);
673 ui->spinBox_DataRecorderRate->setEnabled(false);
674 }
675
676 ui->pushButton_DataRecorder_Start->repaint();
677
678 data_recorder_active = !data_recorder_active;
679 }
680
DataRecorder_Update()681 void MainWindow::DataRecorder_Update()
682 {
683 QString response;
684 double elapsed_time = 0;
685 double sample_max, sample0 = 0, sample1 = 0;
686
687 if (!ui->lineEdit->text().isEmpty())
688 {
689 // Retrieve sample 1
690 QString command = ui->lineEdit->text();
691 LXI_send_receive(&command, &response, 1000);
692 elapsed_time = ((double) time.elapsed()) / 1000;
693 sample0 = response.toDouble();
694 line_series0->append(elapsed_time, sample0);
695 }
696
697 if (!ui->lineEdit_2->text().isEmpty())
698 {
699 // Retrieve sample 2
700 QString command = ui->lineEdit_2->text();
701 LXI_send_receive(&command, &response, 1000);
702 elapsed_time = ((double) time.elapsed()) / 1000;
703 sample1 = response.toDouble();
704 line_series1->append(elapsed_time, sample1);
705 }
706
707 // Update chart
708 sample_max = sample0 < sample1 ? sample1 : sample0;
709
710 if (data_recorder_first_sample)
711 {
712 axisY->setMax(sample_max);
713 data_recorder_first_sample = false;
714 }
715
716 if (sample_max > axisY->max())
717 {
718 axisY->setMax(sample_max);
719 axisY->applyNiceNumbers();
720 }
721
722 axisX->setMax(elapsed_time);
723
724 data_recorder_sample_counter++;
725 }
726
727 // Data recorder save
on_pushButton_DataRecorder_Save_clicked()728 void MainWindow::on_pushButton_DataRecorder_Save_clicked()
729 {
730 int i;
731
732 QString filename = QFileDialog::getSaveFileName(this, "Save file", "data.csv", "Text CSV (.csv)");
733 QFile file(filename);
734 file.open(QIODevice::WriteOnly|QFile::Truncate);
735 QTextStream stream(&file);
736 for (i=0;i<data_recorder_sample_counter; i++)
737 {
738 stream << line_series0->at(i).x();
739
740 if (line_series0->count())
741 stream << "," << line_series0->at(i).y();
742
743 if (line_series1->count())
744 stream << "," << line_series1->at(i).y();
745
746 stream << "\n";
747 }
748 file.close();
749 }
750
DataRecorder_zoomOut()751 void MainWindow::DataRecorder_zoomOut()
752 {
753 ui->chartView->chart()->zoomOut();
754 }
755
DataRecorder_zoomIn()756 void MainWindow::DataRecorder_zoomIn()
757 {
758 ui->chartView->chart()->zoomIn();
759 }
760
DataRecorder_zoomReset()761 void MainWindow::DataRecorder_zoomReset()
762 {
763 ui->chartView->chart()->zoomReset();
764 }
765
on_pushButton_SCPI_Clear_clicked()766 void MainWindow::on_pushButton_SCPI_Clear_clicked()
767 {
768 ui->comboBox_SCPI_Command->lineEdit()->clear();
769 }
770