Introduced multi-threading in order to keep the GUI smooth and snappy.

merge-requests/1/head
Teuniz 2015-08-29 17:13:34 +02:00
rodzic 58d1a622be
commit e6c4c49d73
18 zmienionych plików z 1425 dodań i 621 usunięć

Wyświetl plik

@ -36,7 +36,6 @@ struct tmcdev *tmc_device;
struct tmcdev * tmc_open_usb(const char *device)
{
tmc_connection_type = 0;

Wyświetl plik

@ -44,7 +44,6 @@
#include "utils.h"
struct tmcdev * tmc_open_usb(const char *);
void tmc_close(void);
int tmc_write(const char *);

Wyświetl plik

@ -29,6 +29,7 @@ HEADERS += tled.h
HEADERS += edflib.h
HEADERS += signalcurve.h
HEADERS += settings_dialog.h
HEADERS += screen_thread.h
SOURCES += main.cpp
SOURCES += mainwindow.cpp
@ -45,6 +46,7 @@ SOURCES += tled.cpp
SOURCES += edflib.c
SOURCES += signalcurve.cpp
SOURCES += settings_dialog.cpp
SOURCES += screen_thread.cpp
RESOURCES = images.qrc

Wyświetl plik

@ -29,15 +29,17 @@
#ifndef DSR_GLOBAL_H
#define DSR_GLOBAL_H
#include <QMutex>
#define PROGRAM_NAME "DSRemote"
#define PROGRAM_VERSION "0.20_1508250935"
#define PROGRAM_VERSION "0.30_1508291645"
#define MAX_PATHLEN 4096
#define MAX_CHNS 4
#define ADJDIAL_TIMER_IVAL_1 3000
#define ADJDIAL_TIMER_IVAL_1 4000
#define ADJDIAL_TIMER_IVAL_2 2000
#define SCRN_SHOT_BMP_SZ 1152054
@ -51,7 +53,7 @@
#define NAV_DIAL_FUNC_NONE 0
#define NAV_DIAL_FUNC_HOLDOFF 1
#define LABEL_TIMER_IVAL 1000
#define LABEL_TIMER_IVAL 1500
#define LABEL_ACTIVE_NONE 0
#define LABEL_ACTIVE_CHAN1 1
@ -62,6 +64,19 @@
#define TMC_GDS_DELAY 10000
#define TMC_CMD_CUE_SZ 1024
#define TMC_THRD_RESULT_NONE 0
#define TMC_THRD_RESULT_SCRN 1
#define TMC_THRD_RESULT_CMD 2
#define TMC_THRD_JOB_NONE 0
#define TMC_THRD_JOB_TRIGEDGELEV 1
#define TMC_THRD_JOB_TIMDELAY 2
#define TMC_DIAL_TIMER_DELAY 300
@ -148,7 +163,20 @@ struct device_settings
int screenupdates_on;
QMutex *mutexx;
int thread_error_stat;
int thread_error_line;
int thread_result;
int thread_job;
double thread_value;
struct waveform_preamble preamble;
char cmd_cue[TMC_CMD_CUE_SZ][128];
int cmd_cue_idx_in;
int cmd_cue_idx_out;
};

Wyświetl plik

@ -34,8 +34,6 @@ void UI_Mainwindow::navDialChanged(int npos)
double val, lefttime, righttime, delayrange;
scrn_timer->stop();
if(navDial->isSliderDown() == true)
{
navDial_timer->start(100);
@ -181,7 +179,7 @@ void UI_Mainwindow::navDialReleased()
sprintf(str, ":TRIG:HOLD %e", devparms.triggerholdoff);
tmc_write(str);
set_cue_cmd(str);
}
else if(devparms.timebasedelayenable)
{
@ -195,16 +193,9 @@ void UI_Mainwindow::navDialReleased()
sprintf(str, ":TIM:DEL:OFFS %e", devparms.timebasedelayoffset);
tmc_write(str);
set_cue_cmd(str);
}
adjDialFunc = ADJ_DIAL_FUNC_NONE;
if(devparms.screenupdates_on == 1)
{
scrn_timer->start(devparms.screentimerival);
}
waveForm->update();
}
@ -220,8 +211,6 @@ void UI_Mainwindow::adjDialChanged(int new_pos)
return;
}
scrn_timer->stop();
adjdial_timer->start(ADJDIAL_TIMER_IVAL_2);
diff = new_pos - old_pos;
@ -414,12 +403,16 @@ void UI_Mainwindow::trigAdjustDialChanged(int new_pos)
statusLabel->setText(str);
sprintf(str, ":TRIG:EDG:LEV %e", devparms.triggeredgelevel[chn]);
tmc_write(str);
trigAdjDial_timer->start(TMC_DIAL_TIMER_DELAY);
old_pos = new_pos;
waveForm->label_active = LABEL_ACTIVE_TRIG;
label_timer->start(LABEL_TIMER_IVAL);
waveForm->setTrigLineVisible();
waveForm->update();
}
@ -546,9 +539,7 @@ void UI_Mainwindow::horScaleDialChanged(int new_pos)
statusLabel->setText(str);
sprintf(str, ":TIM:DEL:SCAL %e", devparms.timebasedelayscale);
tmc_write(str);
horScaleDial_timer->start(TMC_DIAL_TIMER_DELAY);
old_pos = new_pos;
}
@ -622,9 +613,7 @@ void UI_Mainwindow::horScaleDialChanged(int new_pos)
statusLabel->setText(str);
sprintf(str, ":TIM:SCAL %e", devparms.timebasescale);
tmc_write(str);
horScaleDial_timer->start(TMC_DIAL_TIMER_DELAY);
old_pos = new_pos;
}
@ -714,9 +703,7 @@ void UI_Mainwindow::horPosDialChanged(int new_pos)
statusLabel->setText(str);
sprintf(str, ":TIM:DEL:OFFS %e", devparms.timebasedelayoffset);
tmc_write(str);
horPosDial_timer->start(TMC_DIAL_TIMER_DELAY);
old_pos = new_pos;
}
@ -757,9 +744,7 @@ void UI_Mainwindow::horPosDialChanged(int new_pos)
statusLabel->setText(str);
sprintf(str, ":TIM:OFFS %e", devparms.timebaseoffset);
tmc_write(str);
horPosDial_timer->start(TMC_DIAL_TIMER_DELAY);
old_pos = new_pos;
}
@ -857,9 +842,11 @@ void UI_Mainwindow::vertOffsetDialChanged(int new_pos)
statusLabel->setText(str);
sprintf(str, ":CHAN%i:OFFS %e", chn + 1, devparms.chanoffset[chn]);
waveForm->label_active = chn + 1;
tmc_write(str);
label_timer->start(LABEL_TIMER_IVAL);
vertOffsDial_timer->start(TMC_DIAL_TIMER_DELAY);
old_pos = new_pos;
@ -985,13 +972,7 @@ void UI_Mainwindow::vertScaleDialChanged(int new_pos)
sprintf(str, ":CHAN%i:SCAL %e", chn + 1, devparms.chanscale[chn]);
tmc_write(str);
tmc_write(":TRIG:EDG:LEV?");
tmc_read();
devparms.triggeredgelevel[chn] = atof(device->buf);
set_cue_cmd(str);
old_pos = new_pos;
@ -1124,13 +1105,13 @@ void UI_Mainwindow::set_memdepth(int mdepth)
{
statusLabel->setText("Memory depth: auto");
tmc_write(":ACQ:MDEP AUTO");
set_cue_cmd(":ACQ:MDEP AUTO");
devparms.timebaseoffset = 0;
usleep(20000);
tmc_write(":TIM:OFFS 0");
set_cue_cmd(":TIM:OFFS 0");
return;
}
@ -1143,13 +1124,13 @@ void UI_Mainwindow::set_memdepth(int mdepth)
sprintf(str, ":ACQ:MDEP %i", mdepth);
tmc_write(str);
set_cue_cmd(str);
devparms.timebaseoffset = 0;
usleep(20000);
tmc_write(":TIM:OFFS 0");
set_cue_cmd(":TIM:OFFS 0");
}
@ -1320,7 +1301,7 @@ void UI_Mainwindow::set_acq_normal()
statusLabel->setText("Acquire: normal");
tmc_write(":ACQ:TYPE NORM");
set_cue_cmd(":ACQ:TYPE NORM");
}
@ -1335,7 +1316,7 @@ void UI_Mainwindow::set_acq_peak()
statusLabel->setText("Acquire: peak");
tmc_write(":ACQ:TYPE PEAK");
set_cue_cmd(":ACQ:TYPE PEAK");
}
@ -1350,7 +1331,7 @@ void UI_Mainwindow::set_acq_hres()
statusLabel->setText("Acquire: high resolution");
tmc_write(":ACQ:TYPE HRES");
set_cue_cmd(":ACQ:TYPE HRES");
}
@ -1373,7 +1354,7 @@ void UI_Mainwindow::set_acq_average()
statusLabel->setText("Acquire: average");
tmc_write(":ACQ:TYPE AVER");
set_cue_cmd(":ACQ:TYPE AVER");
}
@ -1442,7 +1423,7 @@ void UI_Mainwindow::set_grid_type_vectors()
statusLabel->setText("Display type: vectors");
tmc_write(":DISP:TYPE VECT");
set_cue_cmd(":DISP:TYPE VECT");
}
@ -1457,7 +1438,7 @@ void UI_Mainwindow::set_grid_type_dots()
statusLabel->setText("Display type: dots");
tmc_write(":DISP:TYPE DOTS");
set_cue_cmd(":DISP:TYPE DOTS");
}
@ -1472,7 +1453,7 @@ void UI_Mainwindow::set_grid_full()
statusLabel->setText("Display grid: full");
tmc_write(":DISP:GRID FULL");
set_cue_cmd(":DISP:GRID FULL");
}
@ -1487,7 +1468,7 @@ void UI_Mainwindow::set_grid_half()
statusLabel->setText("Display grid: half");
tmc_write(":DISP:GRID HALF");
set_cue_cmd(":DISP:GRID HALF");
}
@ -1502,7 +1483,7 @@ void UI_Mainwindow::set_grid_none()
statusLabel->setText("Display grid: none");
tmc_write(":DISP:GRID NONE");
set_cue_cmd(":DISP:GRID NONE");
}
@ -1510,7 +1491,7 @@ void UI_Mainwindow::set_grading_min()
{
statusLabel->setText("Display grading: Minimum");
tmc_write(":DISP:GRAD:TIME MIN");
set_cue_cmd(":DISP:GRAD:TIME MIN");
}
@ -1518,7 +1499,7 @@ void UI_Mainwindow::set_grading_005()
{
statusLabel->setText("Display grading: 0.05 Sec.");
tmc_write(":DISP:GRAD:TIME 0.05");
set_cue_cmd(":DISP:GRAD:TIME 0.05");
}
@ -1526,7 +1507,7 @@ void UI_Mainwindow::set_grading_01()
{
statusLabel->setText("Display grading: 0.1 Sec.");
tmc_write(":DISP:GRAD:TIME 0.1");
set_cue_cmd(":DISP:GRAD:TIME 0.1");
}
@ -1534,7 +1515,7 @@ void UI_Mainwindow::set_grading_02()
{
statusLabel->setText("Display grading: 0.2 Sec.");
tmc_write(":DISP:GRAD:TIME 0.2");
set_cue_cmd(":DISP:GRAD:TIME 0.2");
}
@ -1542,7 +1523,7 @@ void UI_Mainwindow::set_grading_05()
{
statusLabel->setText("Display grading: 0.5 Sec.");
tmc_write(":DISP:GRAD:TIME 0.5");
set_cue_cmd(":DISP:GRAD:TIME 0.5");
}
@ -1550,7 +1531,7 @@ void UI_Mainwindow::set_grading_1()
{
statusLabel->setText("Display grading: 1 Sec.");
tmc_write(":DISP:GRAD:TIME 1");
set_cue_cmd(":DISP:GRAD:TIME 1");
}
@ -1558,7 +1539,7 @@ void UI_Mainwindow::set_grading_2()
{
statusLabel->setText("Display grading: 2 Sec.");
tmc_write(":DISP:GRAD:TIME 2");
set_cue_cmd(":DISP:GRAD:TIME 2");
}
@ -1566,7 +1547,7 @@ void UI_Mainwindow::set_grading_5()
{
statusLabel->setText("Display grading: 5 Sec.");
tmc_write(":DISP:GRAD:TIME 5");
set_cue_cmd(":DISP:GRAD:TIME 5");
}
@ -1574,7 +1555,7 @@ void UI_Mainwindow::set_grading_10()
{
statusLabel->setText("Display grading: 10 Sec.");
tmc_write(":DISP:GRAD:TIME 10");
set_cue_cmd(":DISP:GRAD:TIME 10");
}
@ -1582,7 +1563,7 @@ void UI_Mainwindow::set_grading_20()
{
statusLabel->setText("Display grading: 20 Sec.");
tmc_write(":DISP:GRAD:TIME 20");
set_cue_cmd(":DISP:GRAD:TIME 20");
}
@ -1590,7 +1571,7 @@ void UI_Mainwindow::set_grading_inf()
{
statusLabel->setText("Display grading: Infinite");
tmc_write(":DISP:GRAD:TIME INF");
set_cue_cmd(":DISP:GRAD:TIME INF");
}
@ -1617,10 +1598,12 @@ void UI_Mainwindow::show_howto_operate()
"In addition of using the dials to change the scale and offset of the traces and the trigger position,"
"you can use the mouse to drag the colored arrows aside of the plot.\n\n"
"Keyboard shortcuts:\n"
"PageUp: move trace 12 (or 14) divisions to the right.\n"
"PageDn: move trace 12 (or 14) divisions to the left.\n"
"Arrow left: move trace 1 division to the right.\n"
"Arrow right: move trace 1 division to the left.\n"
"PageUp: move traces 12 (or 14) divisions to the right.\n"
"PageDn: move traces 12 (or 14) divisions to the left.\n"
"Arrow left: move traces 1 division to the right.\n"
"Arrow right: move traces 1 division to the left.\n"
"Arrow up: move active trace 1 division up.\n"
"Arrow down: move active trace 1 division down.\n"
"Zoom In (decrease timebase): Ctl+\n"
"Zoom Out (increase timebase): Ctl-\n"
"Increase vertical scale: -\n"
@ -1660,7 +1643,7 @@ void UI_Mainwindow::vertScaleDialClicked(QPoint)
sprintf(str, ":CHAN%i:VERN 0", chn + 1);
tmc_write(str);
set_cue_cmd(str);
}
else
{
@ -1672,7 +1655,7 @@ void UI_Mainwindow::vertScaleDialClicked(QPoint)
sprintf(str, ":CHAN%i:VERN 1", chn + 1);
tmc_write(str);
set_cue_cmd(str);
}
}
@ -1687,7 +1670,7 @@ void UI_Mainwindow::ch1ButtonClicked()
statusLabel->setText("Channel 1 off");
tmc_write(":CHAN1:DISP 0");
set_cue_cmd(":CHAN1:DISP 0");
ch1Button->setStyleSheet(def_stylesh);
@ -1714,7 +1697,7 @@ void UI_Mainwindow::ch1ButtonClicked()
statusLabel->setText("Channel 1 on");
tmc_write(":CHAN1:DISP 1");
set_cue_cmd(":CHAN1:DISP 1");
ch1Button->setStyleSheet("background: #FFFF33;");
@ -1733,7 +1716,7 @@ void UI_Mainwindow::ch2ButtonClicked()
statusLabel->setText("Channel 2 off");
tmc_write(":CHAN2:DISP 0");
set_cue_cmd(":CHAN2:DISP 0");
ch2Button->setStyleSheet(def_stylesh);
@ -1760,7 +1743,7 @@ void UI_Mainwindow::ch2ButtonClicked()
statusLabel->setText("Channel 2 on");
tmc_write(":CHAN2:DISP 1");
set_cue_cmd(":CHAN2:DISP 1");
ch2Button->setStyleSheet("background: #33FFFF;");
@ -1779,7 +1762,7 @@ void UI_Mainwindow::ch3ButtonClicked()
statusLabel->setText("Channel 3 off");
tmc_write(":CHAN3:DISP 0");
set_cue_cmd(":CHAN3:DISP 0");
ch3Button->setStyleSheet(def_stylesh);
@ -1806,7 +1789,7 @@ void UI_Mainwindow::ch3ButtonClicked()
statusLabel->setText("Channel 3 on");
tmc_write(":CHAN3:DISP 1");
set_cue_cmd(":CHAN3:DISP 1");
ch3Button->setStyleSheet("background: #FF33FF;");
@ -1825,7 +1808,7 @@ void UI_Mainwindow::ch4ButtonClicked()
statusLabel->setText("Channel 4 off");
tmc_write(":CHAN4:DISP 0");
set_cue_cmd(":CHAN4:DISP 0");
ch4Button->setStyleSheet(def_stylesh);
@ -1852,7 +1835,7 @@ void UI_Mainwindow::ch4ButtonClicked()
statusLabel->setText("Channel 4 on");
tmc_write(":CHAN4:DISP 1");
set_cue_cmd(":CHAN4:DISP 1");
ch4Button->setStyleSheet("background: #0066CC;");
@ -1906,7 +1889,7 @@ void UI_Mainwindow::chan_coupling_ac()
sprintf(str, ":CHAN%i:COUP AC", devparms.activechannel + 1);
tmc_write(str);
set_cue_cmd(str);
}
@ -1922,7 +1905,7 @@ void UI_Mainwindow::chan_coupling_dc()
sprintf(str, ":CHAN%i:COUP DC", devparms.activechannel + 1);
tmc_write(str);
set_cue_cmd(str);
}
@ -1938,7 +1921,7 @@ void UI_Mainwindow::chan_coupling_gnd()
sprintf(str, ":CHAN%i:COUP GND", devparms.activechannel + 1);
tmc_write(str);
set_cue_cmd(str);
}
@ -1954,7 +1937,7 @@ void UI_Mainwindow::chan_bwl_off()
sprintf(str, ":CHAN%i:BWL OFF", devparms.activechannel + 1);
tmc_write(str);
set_cue_cmd(str);
}
@ -1970,7 +1953,7 @@ void UI_Mainwindow::chan_bwl_20()
sprintf(str, ":CHAN%i:BWL 20M", devparms.activechannel + 1);
tmc_write(str);
set_cue_cmd(str);
}
@ -1986,7 +1969,7 @@ void UI_Mainwindow::chan_bwl_250()
sprintf(str, ":CHAN%i:BWL 250M", devparms.activechannel + 1);
tmc_write(str);
set_cue_cmd(str);
}
@ -2007,7 +1990,7 @@ void UI_Mainwindow::chan_invert_on()
sprintf(str, ":CHAN%i:INV 1", devparms.activechannel + 1);
tmc_write(str);
set_cue_cmd(str);
}
@ -2028,7 +2011,7 @@ void UI_Mainwindow::chan_invert_off()
sprintf(str, ":CHAN%i:INV 0", devparms.activechannel + 1);
tmc_write(str);
set_cue_cmd(str);
}
@ -2062,7 +2045,7 @@ void UI_Mainwindow::vertOffsetDialClicked(QPoint)
sprintf(str, ":CHAN%i:OFFS %e", chn + 1, devparms.chanoffset[chn]);
tmc_write(str);
set_cue_cmd(str);
}
@ -2070,7 +2053,7 @@ void UI_Mainwindow::clearButtonClicked()
{
statusLabel->setText("Display cleared");
tmc_write(":DISP:CLE");
set_cue_cmd(":DISP:CLE");
waveForm->clear();
}
@ -2085,6 +2068,8 @@ void UI_Mainwindow::autoButtonClicked()
scrn_timer->stop();
scrn_thread->wait();
statusLabel->setText("Auto settings");
tmc_write(":AUT");
@ -2109,13 +2094,13 @@ void UI_Mainwindow::runButtonClicked()
{
statusLabel->setText("Trigger: run");
tmc_write(":RUN");
set_cue_cmd(":RUN");
}
else
{
statusLabel->setText("Trigger: stop");
tmc_write(":STOP");
set_cue_cmd(":STOP");
}
}
@ -2124,7 +2109,7 @@ void UI_Mainwindow::singleButtonClicked()
{
statusLabel->setText("Trigger: single");
tmc_write(":SING");
set_cue_cmd(":SING");
}
@ -2173,7 +2158,7 @@ void UI_Mainwindow::horizontal_delayed_on()
statusLabel->setText("Delayed timebase enabled");
tmc_write(":TIM:DEL:ENAB 1");
set_cue_cmd(":TIM:DEL:ENAB 1");
devparms.timebasedelayoffset = devparms.timebaseoffset;
}
@ -2190,7 +2175,7 @@ void UI_Mainwindow::horizontal_delayed_off()
statusLabel->setText("Delayed timebase disabled");
tmc_write(":TIM:DEL:ENAB 0");
set_cue_cmd(":TIM:DEL:ENAB 0");
}
@ -2202,31 +2187,15 @@ void UI_Mainwindow::horizontal_delayed_toggle()
statusLabel->setText("Delayed timebase disabled");
tmc_write(":TIM:DEL:ENAB 0");
set_cue_cmd(":TIM:DEL:ENAB 0");
}
else
{
scrn_timer->stop();
devparms.timebasedelayenable = 1;
statusLabel->setText("Delayed timebase enabled");
tmc_write(":TIM:DEL:ENAB 1");
tmc_write(":TIM:DEL:OFFS?");
tmc_read();
devparms.timebasedelayoffset = atof(device->buf);
tmc_write(":TIM:DEL:SCAL?");
tmc_read();
devparms.timebasedelayscale = atof(device->buf);
scrn_timer->start(devparms.screentimerival);
set_cue_cmd(":TIM:DEL:ENAB 1");
}
}
@ -2249,7 +2218,7 @@ void UI_Mainwindow::horPosDialClicked(QPoint)
sprintf(str, ":TIM:DEL:OFFS %e", devparms.timebasedelayoffset);
tmc_write(str);
set_cue_cmd(str);
}
else
{
@ -2265,7 +2234,7 @@ void UI_Mainwindow::horPosDialClicked(QPoint)
sprintf(str, ":TIM:OFFS %e", devparms.timebaseoffset);
tmc_write(str);
set_cue_cmd(str);
}
}
@ -2309,7 +2278,7 @@ void UI_Mainwindow::counter_off()
statusLabel->setText("Freq. counter off");
tmc_write(":MEAS:COUN:SOUR OFF");
set_cue_cmd(":MEAS:COUN:SOUR OFF");
}
@ -2319,7 +2288,7 @@ void UI_Mainwindow::counter_ch1()
statusLabel->setText("Freq. counter channel 1");
tmc_write(":MEAS:COUN:SOUR CHAN1");
set_cue_cmd(":MEAS:COUN:SOUR CHAN1");
}
@ -2329,7 +2298,7 @@ void UI_Mainwindow::counter_ch2()
statusLabel->setText("Freq. counter channel 2");
tmc_write(":MEAS:COUN:SOUR CHAN2");
set_cue_cmd(":MEAS:COUN:SOUR CHAN2");
}
@ -2339,7 +2308,7 @@ void UI_Mainwindow::counter_ch3()
statusLabel->setText("Freq. counter channel 3");
tmc_write(":MEAS:COUN:SOUR CHAN3");
set_cue_cmd(":MEAS:COUN:SOUR CHAN3");
}
@ -2349,7 +2318,7 @@ void UI_Mainwindow::counter_ch4()
statusLabel->setText("Freq. counter channel 4");
tmc_write(":MEAS:COUN:SOUR CHAN4");
set_cue_cmd(":MEAS:COUN:SOUR CHAN4");
}
@ -2364,17 +2333,17 @@ void UI_Mainwindow::trigModeButtonClicked()
case 0: trigModeAutoLed->setValue(true);
trigModeSingLed->setValue(false);
statusLabel->setText("Trigger auto");
tmc_write(":TRIG:SWE AUTO");
set_cue_cmd(":TRIG:SWE AUTO");
break;
case 1: trigModeNormLed->setValue(true);
trigModeAutoLed->setValue(false);
statusLabel->setText("Trigger norm");
tmc_write(":TRIG:SWE NORM");
set_cue_cmd(":TRIG:SWE NORM");
break;
case 2: trigModeSingLed->setValue(true);
trigModeNormLed->setValue(false);
statusLabel->setText("Trigger single");
tmc_write(":TRIG:SWE SING");
set_cue_cmd(":TRIG:SWE SING");
break;
}
}
@ -2434,7 +2403,7 @@ void UI_Mainwindow::trigger_source_ch1()
statusLabel->setText("Trigger source channel 1");
tmc_write(":TRIG:EDG:SOUR CHAN1");
set_cue_cmd(":TRIG:EDG:SOUR CHAN1");
}
@ -2444,7 +2413,7 @@ void UI_Mainwindow::trigger_source_ch2()
statusLabel->setText("Trigger source channel 2");
tmc_write(":TRIG:EDG:SOUR CHAN2");
set_cue_cmd(":TRIG:EDG:SOUR CHAN2");
}
@ -2454,7 +2423,7 @@ void UI_Mainwindow::trigger_source_ch3()
statusLabel->setText("Trigger source channel 3");
tmc_write(":TRIG:EDG:SOUR CHAN3");
set_cue_cmd(":TRIG:EDG:SOUR CHAN3");
}
@ -2464,7 +2433,7 @@ void UI_Mainwindow::trigger_source_ch4()
statusLabel->setText("Trigger source channel 4");
tmc_write(":TRIG:EDG:SOUR CHAN4");
set_cue_cmd(":TRIG:EDG:SOUR CHAN4");
}
@ -2474,7 +2443,7 @@ void UI_Mainwindow::trigger_source_ext()
statusLabel->setText("Trigger source extern");
tmc_write(":TRIG:EDG:SOUR EXT");
set_cue_cmd(":TRIG:EDG:SOUR EXT");
}
@ -2484,7 +2453,7 @@ void UI_Mainwindow::trigger_source_ext5()
statusLabel->setText("Trigger source extern 5");
tmc_write(":TRIG:EDG:SOUR EXT5");
set_cue_cmd(":TRIG:EDG:SOUR EXT5");
}
@ -2494,7 +2463,7 @@ void UI_Mainwindow::trigger_source_acl()
statusLabel->setText("Trigger source AC powerline");
tmc_write(":TRIG:EDG:SOUR ACL");
set_cue_cmd(":TRIG:EDG:SOUR ACL");
}
@ -2504,7 +2473,7 @@ void UI_Mainwindow::trigger_coupling_ac()
statusLabel->setText("Trigger coupling AC");
tmc_write(":TRIG:COUP AC");
set_cue_cmd(":TRIG:COUP AC");
}
@ -2514,7 +2483,7 @@ void UI_Mainwindow::trigger_coupling_dc()
statusLabel->setText("Trigger coupling DC");
tmc_write(":TRIG:COUP DC");
set_cue_cmd(":TRIG:COUP DC");
}
@ -2524,7 +2493,7 @@ void UI_Mainwindow::trigger_coupling_lfreject()
statusLabel->setText("Trigger LF reject");
tmc_write(":TRIG:COUP LFR");
set_cue_cmd(":TRIG:COUP LFR");
}
@ -2534,7 +2503,7 @@ void UI_Mainwindow::trigger_coupling_hfreject()
statusLabel->setText("Trigger HF reject");
tmc_write(":TRIG:COUP HFR");
set_cue_cmd(":TRIG:COUP HFR");
}
@ -2544,7 +2513,7 @@ void UI_Mainwindow::trigger_slope_pos()
statusLabel->setText("Trigger edge positive");
tmc_write(":TRIG:EDG:SLOP POS");
set_cue_cmd(":TRIG:EDG:SLOP POS");
}
@ -2554,7 +2523,7 @@ void UI_Mainwindow::trigger_slope_neg()
statusLabel->setText("Trigger edge negative");
tmc_write(":TRIG:EDG:SLOP NEG");
set_cue_cmd(":TRIG:EDG:SLOP NEG");
}
@ -2564,7 +2533,7 @@ void UI_Mainwindow::trigger_slope_rfal()
statusLabel->setText("Trigger edge positive /negative");
tmc_write(":TRIG:EDG:SLOP RFAL");
set_cue_cmd(":TRIG:EDG:SLOP RFAL");
}
@ -2586,7 +2555,7 @@ void UI_Mainwindow::trigForceButtonClicked()
{
statusLabel->setText("Trigger force");
tmc_write(":TFOR");
set_cue_cmd(":TFOR");
}
@ -2594,15 +2563,7 @@ void UI_Mainwindow::trig50pctButtonClicked()
{
statusLabel->setText("Trigger 50%");
tmc_write(":TLHA");
usleep(30000);
tmc_write(":TRIG:EDG:LEV?");
tmc_read();
devparms.triggeredgelevel[devparms.triggeredgesource] = atof(device->buf);
set_cue_cmd(":TLHA");
waveForm->setTrigLineVisible();
}
@ -2624,7 +2585,7 @@ void UI_Mainwindow::trigAdjustDialClicked(QPoint)
sprintf(str, ":TRIG:EDG:LEV %e", devparms.triggeredgelevel[devparms.triggeredgesource]);
tmc_write(str);
set_cue_cmd(str);
}
@ -2634,3 +2595,12 @@ void UI_Mainwindow::trigAdjustDialClicked(QPoint)

Wyświetl plik

@ -245,6 +245,9 @@ void UI_Mainwindow::open_connection()
ch2Button->setVisible(false);
}
devparms.cmd_cue_idx_in = 0;
devparms.cmd_cue_idx_out = 0;
connect(adjDial, SIGNAL(valueChanged(int)), this, SLOT(adjDialChanged(int)));
connect(trigAdjustDial, SIGNAL(valueChanged(int)), this, SLOT(trigAdjustDialChanged(int)));
connect(horScaleDial, SIGNAL(valueChanged(int)), this, SLOT(horScaleDialChanged(int)));
@ -292,6 +295,8 @@ void UI_Mainwindow::open_connection()
statusLabel->setText("Connected");
scrn_thread->set_device(device);
devparms.connected = 1;
// test_timer->start(2000);
@ -300,6 +305,8 @@ void UI_Mainwindow::open_connection()
devparms.screenupdates_on = 1;
scrn_thread->h_busy = 0;
scrn_timer->start(devparms.screentimerival);
return;
@ -329,12 +336,28 @@ void UI_Mainwindow::close_connection()
adjdial_timer->stop();
devparms.connected = 0;
if(scrn_thread->wait(5000) == false)
{
scrn_thread->terminate();
scrn_thread->wait(5000);
devparms.mutexx->unlock();
scrn_thread->h_busy = 0;
}
devparms.screenupdates_on = 0;
setWindowTitle(PROGRAM_NAME " " PROGRAM_VERSION);
strcpy(devparms.modelname, "-----");
adjDialFunc = ADJ_DIAL_FUNC_NONE;
navDialFunc = NAV_DIAL_FUNC_NONE;
disconnect(adjDial, SIGNAL(valueChanged(int)), this, SLOT(adjDialChanged(int)));
disconnect(trigAdjustDial, SIGNAL(valueChanged(int)), this, SLOT(trigAdjustDialChanged(int)));
disconnect(horScaleDial, SIGNAL(valueChanged(int)), this, SLOT(horScaleDialChanged(int)));
@ -375,7 +398,7 @@ void UI_Mainwindow::close_connection()
disconnect(trigAdjustDial, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(trigAdjustDialClicked(QPoint)));
disconnect(adjDial, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(adjustDialClicked(QPoint)));
devparms.connected = 0;
scrn_thread->set_device(NULL);
waveForm->clear();
@ -389,13 +412,23 @@ void UI_Mainwindow::close_connection()
void UI_Mainwindow::closeEvent(QCloseEvent *cl_event)
{
devparms.connected = 0;
test_timer->stop();
scrn_timer->stop();
adjdial_timer->stop();
scrn_thread->wait(5000);
scrn_thread->terminate();
scrn_thread->wait(5000);
devparms.screenupdates_on = 0;
adjdial_timer->stop();
scrn_thread->set_device(NULL);
tmc_close();
@ -1994,9 +2027,7 @@ void UI_Mainwindow::former_page()
statusLabel->setText(str);
sprintf(str, ":TIM:DEL:OFFS %e", devparms.timebasedelayoffset);
tmc_write(str);
horPosDial_timer->start(TMC_DIAL_TIMER_DELAY);
}
else
{
@ -2025,9 +2056,7 @@ void UI_Mainwindow::former_page()
statusLabel->setText(str);
sprintf(str, ":TIM:OFFS %e", devparms.timebaseoffset);
tmc_write(str);
horPosDial_timer->start(TMC_DIAL_TIMER_DELAY);
}
waveForm->update();
@ -2065,9 +2094,7 @@ void UI_Mainwindow::next_page()
statusLabel->setText(str);
sprintf(str, ":TIM:DEL:OFFS %e", devparms.timebasedelayoffset);
tmc_write(str);
horPosDial_timer->start(TMC_DIAL_TIMER_DELAY);
}
else
{
@ -2096,9 +2123,7 @@ void UI_Mainwindow::next_page()
statusLabel->setText(str);
sprintf(str, ":TIM:OFFS %e", devparms.timebaseoffset);
tmc_write(str);
horPosDial_timer->start(TMC_DIAL_TIMER_DELAY);
}
waveForm->update();
@ -2136,9 +2161,7 @@ void UI_Mainwindow::shift_page_left()
statusLabel->setText(str);
sprintf(str, ":TIM:DEL:OFFS %e", devparms.timebasedelayoffset);
tmc_write(str);
horPosDial_timer->start(TMC_DIAL_TIMER_DELAY);
}
else
{
@ -2167,9 +2190,7 @@ void UI_Mainwindow::shift_page_left()
statusLabel->setText(str);
sprintf(str, ":TIM:OFFS %e", devparms.timebaseoffset);
tmc_write(str);
horPosDial_timer->start(TMC_DIAL_TIMER_DELAY);
}
waveForm->update();
@ -2207,9 +2228,7 @@ void UI_Mainwindow::shift_page_right()
statusLabel->setText(str);
sprintf(str, ":TIM:DEL:OFFS %e", devparms.timebasedelayoffset);
tmc_write(str);
horPosDial_timer->start(TMC_DIAL_TIMER_DELAY);
}
else
{
@ -2238,9 +2257,7 @@ void UI_Mainwindow::shift_page_right()
statusLabel->setText(str);
sprintf(str, ":TIM:OFFS %e", devparms.timebaseoffset);
tmc_write(str);
horPosDial_timer->start(TMC_DIAL_TIMER_DELAY);
}
waveForm->update();
@ -2301,7 +2318,7 @@ void UI_Mainwindow::zoom_in()
sprintf(str, ":TIM:DEL:SCAL %e", devparms.timebasedelayscale);
tmc_write(str);
set_cue_cmd(str);
}
else
{
@ -2348,7 +2365,7 @@ void UI_Mainwindow::zoom_in()
sprintf(str, ":TIM:SCAL %e", devparms.timebasescale);
tmc_write(str);
set_cue_cmd(str);
}
waveForm->update();
@ -2392,7 +2409,7 @@ void UI_Mainwindow::zoom_out()
sprintf(str, ":TIM:DEL:SCAL %e", devparms.timebasedelayscale);
tmc_write(str);
set_cue_cmd(str);
}
else
{
@ -2415,7 +2432,7 @@ void UI_Mainwindow::zoom_out()
sprintf(str, ":TIM:SCAL %e", devparms.timebasescale);
tmc_write(str);
set_cue_cmd(str);
}
waveForm->update();
@ -2473,13 +2490,87 @@ void UI_Mainwindow::chan_scale_plus()
sprintf(str, ":CHAN%i:SCAL %e", chn + 1, devparms.chanscale[chn]);
tmc_write(str);
set_cue_cmd(str);
tmc_write(":TRIG:EDG:LEV?");
waveForm->update();
}
tmc_read();
devparms.triggeredgelevel[chn] = atof(device->buf);
void UI_Mainwindow::shift_trace_up()
{
int chn;
char str[512];
if((device == NULL) || (!devparms.connected) || (devparms.activechannel < 0))
{
return;
}
chn = devparms.activechannel;
if(devparms.chanoffset[chn] >= 20)
{
devparms.chanoffset[chn] = 20;
return;
}
devparms.chanoffset[chn] += devparms.chanscale[chn];
sprintf(str, "Channel %i offset: ", chn + 1);
convert_to_metric_suffix(str + strlen(str), devparms.chanoffset[chn], 2);
strcat(str, "V");
statusLabel->setText(str);
waveForm->label_active = chn + 1;
label_timer->start(LABEL_TIMER_IVAL);
vertOffsDial_timer->start(TMC_DIAL_TIMER_DELAY);
waveForm->update();
}
void UI_Mainwindow::shift_trace_down()
{
int chn;
char str[512];
if((device == NULL) || (!devparms.connected) || (devparms.activechannel < 0))
{
return;
}
chn = devparms.activechannel;
if(devparms.chanoffset[chn] <= -20)
{
devparms.chanoffset[chn] = -20;
return;
}
devparms.chanoffset[chn] -= devparms.chanscale[chn];
sprintf(str, "Channel %i offset: ", chn + 1);
convert_to_metric_suffix(str + strlen(str), devparms.chanoffset[chn], 2);
strcat(str, "V");
statusLabel->setText(str);
waveForm->label_active = chn + 1;
label_timer->start(LABEL_TIMER_IVAL);
vertOffsDial_timer->start(TMC_DIAL_TIMER_DELAY);
waveForm->update();
}
@ -2543,13 +2634,7 @@ void UI_Mainwindow::chan_scale_minus()
sprintf(str, ":CHAN%i:SCAL %e", chn + 1, devparms.chanscale[chn]);
tmc_write(str);
tmc_write(":TRIG:EDG:LEV?");
tmc_read();
devparms.triggeredgelevel[chn] = atof(device->buf);
set_cue_cmd(str);
waveForm->update();
}
@ -2561,8 +2646,15 @@ void UI_Mainwindow::set_to_factory()
char str[256];
if((device == NULL) || (!devparms.connected))
{
return;
}
scrn_timer->stop();
scrn_thread->wait();
qApp->processEvents();
tmc_write("*RST");
@ -2673,6 +2765,181 @@ void UI_Mainwindow::set_to_factory()
}
// this function is called when screen_thread has finished
void UI_Mainwindow::screenUpdate()
{
int i, chns=0;
char str[512];
if(device == NULL)
{
devparms.mutexx->unlock();
return;
}
if(!devparms.connected)
{
devparms.mutexx->unlock();
return;
}
if(!devparms.screenupdates_on)
{
devparms.mutexx->unlock();
return;
}
scrn_thread->get_params(&devparms);
if(devparms.thread_error_stat)
{
scrn_timer->stop();
sprintf(str, "An error occurred while reading screen data from device.\n"
"File screen_thread.cpp line %i", devparms.thread_error_line);
QMessageBox msgBox;
msgBox.setIcon(QMessageBox::Critical);
msgBox.setText(str);
msgBox.exec();
devparms.mutexx->unlock();
close_connection();
return;
}
if(devparms.thread_result == TMC_THRD_RESULT_NONE)
{
devparms.mutexx->unlock();
return;
}
if(devparms.thread_result == TMC_THRD_RESULT_CMD)
{
if(devparms.thread_job == TMC_THRD_JOB_TRIGEDGELEV)
{
devparms.triggeredgelevel[devparms.triggeredgesource] = devparms.thread_value;
// waveForm->setTrigLineVisible();
}
devparms.mutexx->unlock();
return;
}
if(scrn_timer->isActive() == false)
{
devparms.mutexx->unlock();
return;
}
runButton->setStyleSheet(def_stylesh);
singleButton->setStyleSheet(def_stylesh);
if(devparms.triggerstatus == 0)
{
runButton->setStyleSheet("background: #66FF99;");
}
else if(devparms.triggerstatus == 1)
{
singleButton->setStyleSheet("background: #FF9966;");
}
else if(devparms.triggerstatus == 2)
{
runButton->setStyleSheet("background: #66FF99;");
}
else if(devparms.triggerstatus == 3)
{
runButton->setStyleSheet("background: #66FF99;");
}
else if(devparms.triggerstatus == 5)
{
runButton->setStyleSheet("background: #FF0066;");
}
if(devparms.triggersweep == 0)
{
trigModeAutoLed->setValue(true);
trigModeNormLed->setValue(false);
trigModeSingLed->setValue(false);
}
else if(devparms.triggersweep == 1)
{
trigModeAutoLed->setValue(false);
trigModeNormLed->setValue(true);
trigModeSingLed->setValue(false);
}
else if(devparms.triggersweep == 2)
{
trigModeAutoLed->setValue(false);
trigModeNormLed->setValue(false);
trigModeSingLed->setValue(true);
}
if(waveForm->hasMoveEvent() == true)
{
devparms.mutexx->unlock();
return;
}
for(i=0; i<MAX_CHNS; i++)
{
if(!devparms.chandisplay[i]) // Display data only when channel is switched on
{
continue;
}
chns++;
}
if(!chns)
{
waveForm->clear();
devparms.mutexx->unlock();
return;
}
if(devparms.triggerstatus != 1) // Don't plot waveform data when triggerstatus is "wait"
{
waveForm->drawCurve(&devparms, device, devparms.wavebufsz);
}
else
{
waveForm->update();
}
devparms.mutexx->unlock();
}
void UI_Mainwindow::set_cue_cmd(const char *str)
{
strncpy(devparms.cmd_cue[devparms.cmd_cue_idx_in], str, 128);
devparms.cmd_cue[devparms.cmd_cue_idx_in][127] = 0;
devparms.cmd_cue_idx_in++;
devparms.cmd_cue_idx_in %= TMC_CMD_CUE_SZ;
scrn_timer_handler();
}

Wyświetl plik

@ -82,6 +82,7 @@
#include "edflib.h"
#include "signalcurve.h"
#include "settings_dialog.h"
#include "screen_thread.h"
@ -102,6 +103,8 @@ public:
void read_settings(void);
void write_settings(void);
void set_cue_cmd(const char *);
struct device_settings devparms;
QLabel *statusLabel;
@ -115,6 +118,8 @@ public:
QTimer *scrn_timer,
*label_timer;
screenThread *scrn_thread;
private:
QMenuBar *menubar;
@ -125,6 +130,11 @@ private:
QTimer *adjdial_timer,
*navDial_timer,
*horPosDial_timer,
*trigAdjDial_timer,
*vertOffsDial_timer,
*horScaleDial_timer,
*vertScaleDial_timer,
*test_timer;
QStatusBar *statusBar;
@ -195,7 +205,9 @@ private:
*zoom_in_act,
*zoom_out_act,
*chan_scale_plus_act,
*chan_scale_minus_act;
*chan_scale_minus_act,
*shift_trace_up_act,
*shift_trace_down_act;
struct tmcdev *device;
@ -213,10 +225,15 @@ private:
private slots:
void scrn_timer_handler();
void stat_timer_handler();
void screenUpdate();
void adjdial_timer_handler();
void label_timer_handler();
void test_timer_handler();
void horPosDial_timer_handler();
void trigAdjDial_timer_handler();
void vertOffsDial_timer_handler();
void horScaleDial_timer_handler();
void vertScaleDial_timer_handler();
void show_about_dialog();
void show_howto_operate();
@ -364,6 +381,8 @@ private slots:
void zoom_out();
void chan_scale_plus();
void chan_scale_minus();
void shift_trace_up();
void shift_trace_down();
void set_to_factory();

Wyświetl plik

@ -64,7 +64,7 @@ UI_Mainwindow::UI_Mainwindow()
devparms.screenshot_buf = (char *)malloc(1024 * 1024 * 2);
for(i=0; i< MAX_CHNS; i++)
for(i=0; i<MAX_CHNS; i++)
{
devparms.wavebuf[i] = (short *)malloc(WAVFRM_MAX_BUFSZ);
@ -90,6 +90,11 @@ UI_Mainwindow::UI_Mainwindow()
strcpy(devparms.modelname, "-----");
devparms.mutexx = new QMutex();
scrn_thread = new screenThread;
scrn_thread->set_device(NULL);
menubar = menuBar();
devicemenu = new QMenu(this);
@ -349,6 +354,16 @@ UI_Mainwindow::UI_Mainwindow()
connect(former_page_act, SIGNAL(triggered()), this, SLOT(former_page()));
addAction(former_page_act);
shift_trace_up_act = new QAction(this);
shift_trace_up_act->setShortcut(QKeySequence::MoveToPreviousLine);
connect(shift_trace_up_act, SIGNAL(triggered()), this, SLOT(shift_trace_up()));
addAction(shift_trace_up_act);
shift_trace_down_act = new QAction(this);
shift_trace_down_act->setShortcut(QKeySequence::MoveToNextLine);
connect(shift_trace_down_act, SIGNAL(triggered()), this, SLOT(shift_trace_down()));
addAction(shift_trace_down_act);
shift_page_left_act = new QAction(this);
shift_page_left_act->setShortcut(QKeySequence::MoveToPreviousChar);
connect(shift_page_left_act, SIGNAL(triggered()), this, SLOT(shift_page_left()));
@ -414,13 +429,29 @@ UI_Mainwindow::UI_Mainwindow()
navDial_timer->setSingleShot(true);
label_timer = new QTimer(this);
test_timer = new QTimer(this);
horPosDial_timer = new QTimer(this);
horPosDial_timer->setSingleShot(true);
trigAdjDial_timer = new QTimer(this);
trigAdjDial_timer->setSingleShot(true);
vertOffsDial_timer = new QTimer(this);
vertOffsDial_timer->setSingleShot(true);
horScaleDial_timer = new QTimer(this);
horScaleDial_timer->setSingleShot(true);
vertScaleDial_timer = new QTimer(this);
vertScaleDial_timer->setSingleShot(true);
connect(scrn_timer, SIGNAL(timeout()), this, SLOT(scrn_timer_handler()));
connect(adjdial_timer, SIGNAL(timeout()), this, SLOT(adjdial_timer_handler()));
connect(navDial, SIGNAL(sliderReleased()), this, SLOT(navDialReleased()));
connect(navDial_timer, SIGNAL(timeout()), this, SLOT(navDial_timer_handler()));
connect(label_timer, SIGNAL(timeout()), this, SLOT(label_timer_handler()));
connect(test_timer, SIGNAL(timeout()), this, SLOT(test_timer_handler()));
connect(scrn_timer, SIGNAL(timeout()), this, SLOT(scrn_timer_handler()));
connect(scrn_thread, SIGNAL(finished()), this, SLOT(screenUpdate()));
connect(adjdial_timer, SIGNAL(timeout()), this, SLOT(adjdial_timer_handler()));
connect(navDial, SIGNAL(sliderReleased()), this, SLOT(navDialReleased()));
connect(navDial_timer, SIGNAL(timeout()), this, SLOT(navDial_timer_handler()));
connect(label_timer, SIGNAL(timeout()), this, SLOT(label_timer_handler()));
connect(test_timer, SIGNAL(timeout()), this, SLOT(test_timer_handler()));
connect(horPosDial_timer, SIGNAL(timeout()), this, SLOT(horPosDial_timer_handler()));
connect(trigAdjDial_timer, SIGNAL(timeout()), this, SLOT(trigAdjDial_timer_handler()));
connect(vertOffsDial_timer, SIGNAL(timeout()), this, SLOT(vertOffsDial_timer_handler()));
connect(horScaleDial_timer, SIGNAL(timeout()), this, SLOT(horScaleDial_timer_handler()));
connect(vertScaleDial_timer, SIGNAL(timeout()), this, SLOT(vertScaleDial_timer_handler()));
///// TEST /////////////////////////////////////
// DPRwidget->setEnabled(true);
@ -472,8 +503,10 @@ UI_Mainwindow::~UI_Mainwindow()
settings.setValue("path/savedir", recent_savedir);
delete scrn_thread;
delete appfont;
delete monofont;
delete devparms.mutexx;
free(devparms.screenshot_buf);

Wyświetl plik

@ -1,12 +1,16 @@
DSRemote 0.11
DSRemote 0.30
-------------
This is the first version that is using a separate thread for the communication with the oscilloscope.
This is done to keep the graphical user interface smooth and responsive.
When opening a connection, the program reads the settings from the device.
It does not lock the device, so it's still possible to change settings on the device.
This will cause a mismatch between the programs settings and the device settings.
This can be solved by letting the program re-read the settings of the device.
At this moment, the only way to do that is to disconnect and connect again.
Either, disconnect and connect again, or click on the "Factory" setting in the "Save" menu of the program.
Some settings are checked regularly and will always be synchronized:
- trigger status
- trigger sweep
@ -26,7 +30,7 @@ Reading a screenshot in BMP format is slow, approx. 3 seconds.
Needs a usbtmc driver patch, needs to add an udev rule.
DS1054Z: (softversion 00.04.02.SP4, boardversion 0.1.1)
DS1054Z: (softversion 00.04.03.SP1, boardversion 0.1.1)
=======
USB connection: high speed (480 Mbit)
@ -36,33 +40,35 @@ Reading a screenshot in BMP format is faster, less than one second.
It's plug and play. No need to patch the usbtmc driver, no need to add an udev rule.
How to operate:
==============
Use the mousewheel to change the dials. In order to simulate a push on a dial,
click on it with the right mouse button.
Use the mousewheel to change the dials. In order to simulate a push on a dial,click on it with the right mouse button.
To toggle the delayed timebase, right-click on the timebase dial.
To set the horizontal position to zero, right-click on the horizontal position dial.
To set the vertical offset to zero, right-click on the vertical position dial.
In addition of using the dials to change the scale and offset of the traces and the trigger position,
you can use the mouse to drag the yellow and orange arrows aside of the plot.
In addition of using the dials to change the scale and offset of the traces and the trigger position,you can use the mouse to drag the colored arrows aside of the plot.
Keyboard shortcuts:
PageUp: move trace 12 (or 14) divisions to the right.
PageDn: move trace 12 (or 14) divisions to the left.
Arrow left: move trace 1 division to the right.
Arrow right: move trace 1 division to the left.
PageUp: move traces 12 (or 14) divisions to the right.
PageDn: move traces 12 (or 14) divisions to the left.
Arrow left: move traces 1 division to the right.
Arrow right: move traces 1 division to the left.
Arrow up: move active trace 1 division up.
Arrow down: move active trace 1 division down.
Zoom In (decrease timebase): Ctl+
Zoom Out (increase timebase): Ctl-
Increase vertical scale: -
Decrease vertical scale: +
What's implemented so far:
--------------------------
- horizontal timebase
- horizontal offset
- horizontal timebase delay on/off
(display is not yet implemented)
- horizontal vernier
@ -81,7 +87,7 @@ What's implemented so far:
- trigger source (chan1/4, ext, ext5, ac)
- trigger edge (positive, negative, rising edge & falling edge)
- trigger level
- trigger level 50%
- trigger level 50% (DS6000 series only)
- trigger force
@ -108,7 +114,7 @@ What's implemented so far:
fileformat for waveform data is EDF, these files can be read by lots
of viewers and analyzing software like EDFbrowser, Scilab, Octave, Matlab, Labview, etc.
- Set to factory settings

Wyświetl plik

@ -48,6 +48,8 @@ void UI_Mainwindow::save_screenshot()
scrn_timer->stop();
scrn_thread->wait();
tmc_write(":DISP:DATA?");
QApplication::setOverrideCursor(Qt::WaitCursor);
@ -179,6 +181,8 @@ void UI_Mainwindow::save_memory_waveform()
scrn_timer->stop();
scrn_thread->wait();
wavbuf[0] = NULL;
wavbuf[1] = NULL;
wavbuf[2] = NULL;
@ -777,6 +781,8 @@ void UI_Mainwindow::save_screen_waveform()
scrn_timer->stop();
scrn_thread->wait();
if(devparms.timebasedelayenable)
{
rec_len = devparms.timebasedelayscale * devparms.hordivisions;

561
screen_thread.cpp 100644
Wyświetl plik

@ -0,0 +1,561 @@
/*
***************************************************************************
*
* Author: Teunis van Beelen
*
* Copyright (C) 2015 Teunis van Beelen
*
* Email: teuniz@gmail.com
*
***************************************************************************
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
***************************************************************************
*/
#include "screen_thread.h"
void screenThread::set_device(struct tmcdev *tmdev)
{
params.cmd_cue_idx_in = 0;
params.cmd_cue_idx_out = 0;
params.connected = 0;
device = tmdev;
}
screenThread::screenThread()
{
int i;
device = NULL;
h_busy = 0;
for(i=0; i<MAX_CHNS; i++)
{
params.wavebuf[i] = (short *)malloc(WAVFRM_MAX_BUFSZ);
}
params.cmd_cue_idx_in = 0;
params.cmd_cue_idx_out = 0;
params.connected = 0;
}
screenThread::~screenThread()
{
int i;
for(i=0; i<MAX_CHNS; i++)
{
free(params.wavebuf[i]);
}
}
void screenThread::set_params(struct device_settings *dev_parms)
{
deviceparms = dev_parms;
params.connected = deviceparms->connected;
params.chandisplay[0] = deviceparms->chandisplay[0];
params.chandisplay[1] = deviceparms->chandisplay[1];
params.chandisplay[2] = deviceparms->chandisplay[2];
params.chandisplay[3] = deviceparms->chandisplay[3];
params.countersrc = deviceparms->countersrc;
params.cmd_cue_idx_in = deviceparms->cmd_cue_idx_in;
params.debug_str[0] = 0;
}
void screenThread::get_params(struct device_settings *dev_parms)
{
int i;
dev_parms->connected = params.connected;
dev_parms->triggerstatus = params.triggerstatus;
dev_parms->triggersweep = params.triggersweep;
dev_parms->samplerate = params.samplerate;
dev_parms->memdepth = params.memdepth;
dev_parms->counterfreq = params.counterfreq;
dev_parms->wavebufsz = params.wavebufsz;
for(i=0; i<MAX_CHNS; i++)
{
if(params.chandisplay[i])
{
memcpy(dev_parms->wavebuf[i], params.wavebuf[i], params.wavebufsz * sizeof(short));
}
}
dev_parms->thread_error_stat = params.error_stat;
dev_parms->thread_error_line = params.error_line;
dev_parms->cmd_cue_idx_out = params.cmd_cue_idx_out;
dev_parms->thread_result = params.result;
dev_parms->thread_job = params.job;
if(dev_parms->thread_job == TMC_THRD_JOB_TRIGEDGELEV)
{
dev_parms->thread_value = params.triggeredgelevel;
}
if(dev_parms->thread_job == TMC_THRD_JOB_TIMDELAY)
{
dev_parms->timebasedelayoffset = params.timebasedelayoffset;
dev_parms->timebasedelayscale = params.timebasedelayscale;
}
if(params.debug_str[0])
{
params.debug_str[1023] = 0;
printf("params.debug_str: ->%s<-\n", params.debug_str);
}
}
int screenThread::get_devicestatus()
{
int line;
if(tmc_write(":TRIG:STAT?") != 11)
{
line = __LINE__;
goto OUT_ERROR;
}
if(tmc_read() < 1)
{
line = __LINE__;
goto OUT_ERROR;
}
if(!strcmp(device->buf, "TD"))
{
params.triggerstatus = 0;
}
else if(!strcmp(device->buf, "WAIT"))
{
params.triggerstatus = 1;
}
else if(!strcmp(device->buf, "RUN"))
{
params.triggerstatus = 2;
}
else if(!strcmp(device->buf, "AUTO"))
{
params.triggerstatus = 3;
}
else if(!strcmp(device->buf, "FIN"))
{
params.triggerstatus = 4;
}
else if(!strcmp(device->buf, "STOP"))
{
params.triggerstatus = 5;
}
else
{
line = __LINE__;
goto OUT_ERROR;
}
if(tmc_write(":TRIG:SWE?") != 10)
{
line = __LINE__;
goto OUT_ERROR;
}
if(tmc_read() < 1)
{
line = __LINE__;
goto OUT_ERROR;
}
if(!strcmp(device->buf, "AUTO"))
{
params.triggersweep = 0;
}
else if(!strcmp(device->buf, "NORM"))
{
params.triggersweep = 1;
}
else if(!strcmp(device->buf, "SING"))
{
params.triggersweep = 2;
}
else
{
line = __LINE__;
goto OUT_ERROR;
}
if(tmc_write(":ACQ:SRAT?") != 10)
{
line = __LINE__;
goto OUT_ERROR;
}
if(tmc_read() < 1)
{
line = __LINE__;
goto OUT_ERROR;
}
params.samplerate = atof(device->buf);
if(tmc_write(":ACQ:MDEP?") != 10)
{
line = __LINE__;
goto OUT_ERROR;
}
if(tmc_read() < 1)
{
line = __LINE__;
goto OUT_ERROR;
}
params.memdepth = atoi(device->buf);
if(params.countersrc)
{
if(tmc_write(":MEAS:COUN:VAL?") != 15)
{
line = __LINE__;
goto OUT_ERROR;
}
if(tmc_read() < 1)
{
line = __LINE__;
goto OUT_ERROR;
}
params.counterfreq = atof(device->buf);
}
params.debug_str[0] = 0;
return 0;
OUT_ERROR:
strncpy(params.debug_str, device->hdrbuf, 1024);
params.debug_str[1023] = 0;
params.error_line = line;
return -1;
}
void screenThread::run()
{
int i, j, n=0, chns=0, line, cmd_sent=0;
char str[128];
params.error_stat = 0;
params.result = TMC_THRD_RESULT_NONE;
params.job = TMC_THRD_JOB_NONE;
params.wavebufsz = 0;
if(device == NULL)
{
return;
}
if(h_busy)
{
return;
}
if(!params.connected)
{
h_busy = 0;
return;
}
h_busy = 1;
while(params.cmd_cue_idx_out != params.cmd_cue_idx_in)
{
tmc_write(deviceparms->cmd_cue[params.cmd_cue_idx_out]);
if((!strncmp(deviceparms->cmd_cue[params.cmd_cue_idx_out], ":TLHA", 5)) ||
((!strncmp(deviceparms->cmd_cue[params.cmd_cue_idx_out], ":CHAN", 5)) &&
(!strncmp(deviceparms->cmd_cue[params.cmd_cue_idx_out] + 6, ":SCAL ", 6))))
{
if(tmc_write(":TRIG:EDG:LEV?") != 14)
{
printf("Can not write to device.\n");
line = __LINE__;
goto OUT_ERROR;
}
if(tmc_read() < 1)
{
printf("Can not read from device.\n");
line = __LINE__;
goto OUT_ERROR;
}
params.triggeredgelevel = atof(device->buf);
params.job = TMC_THRD_JOB_TRIGEDGELEV;
}
else if(!strncmp(deviceparms->cmd_cue[params.cmd_cue_idx_out], ":TIM:DEL:ENAB 1", 15))
{
if(tmc_write(":TIM:DEL:OFFS?") != 14)
{
printf("Can not write to device.\n");
line = __LINE__;
goto OUT_ERROR;
}
if(tmc_read() < 1)
{
printf("Can not read from device.\n");
line = __LINE__;
goto OUT_ERROR;
}
params.timebasedelayoffset = atof(device->buf);
if(tmc_write(":TIM:DEL:SCAL?") != 14)
{
printf("Can not write to device.\n");
line = __LINE__;
goto OUT_ERROR;
}
if(tmc_read() < 1)
{
printf("Can not read from device.\n");
line = __LINE__;
goto OUT_ERROR;
}
params.timebasedelayscale = atof(device->buf);
params.job = TMC_THRD_JOB_TIMDELAY;
}
params.cmd_cue_idx_out++;
params.cmd_cue_idx_out %= TMC_CMD_CUE_SZ;
cmd_sent = 1;
}
if(cmd_sent)
{
h_busy = 0;
params.result = TMC_THRD_RESULT_CMD;
return;
}
params.error_stat = get_devicestatus();
if(params.error_stat)
{
h_busy = 0;
return;
}
if(!params.connected)
{
h_busy = 0;
return;
}
for(i=0; i<MAX_CHNS; i++)
{
if(!params.chandisplay[i]) // Download data only when channel is switched on
{
continue;
}
chns++;
}
if(!chns)
{
h_busy = 0;
return;
}
params.result = TMC_THRD_RESULT_SCRN;
//struct waveform_preamble wfp;
if(params.triggerstatus != 1) // Don't download waveform data when triggerstatus is "wait"
{
for(i=0; i<MAX_CHNS; i++)
{
if(!params.chandisplay[i]) // Download data only when channel is switched on
{
continue;
}
///////////////////////////////////////////////////////////
// tmc_write(":WAV:PRE?");
//
// n = tmc_read();
//
// if(n < 0)
// {
// strcpy(str, "Can not read from device.");
// goto OUT_ERROR;
// }
//
// printf("waveform preamble: %s\n", device->buf);
//
// if(parse_preamble(device->buf, device->sz, &wfp, i))
// {
// strcpy(str, "Preamble parsing error.");
// goto OUT_ERROR;
// }
//
// printf("waveform preamble:\n"
// "format: %i\n"
// "type: %i\n"
// "points: %i\n"
// "count: %i\n"
// "xincrement: %e\n"
// "xorigin: %e\n"
// "xreference: %e\n"
// "yincrement: %e\n"
// "yorigin: %e\n"
// "yreference: %i\n",
// wfp.format, wfp.type, wfp.points, wfp.count,
// wfp.xincrement[i], wfp.xorigin[i], wfp.xreference[i],
// wfp.yincrement[i], wfp.yorigin[i], wfp.yreference[i]);
//
// printf("chanoffset[] is %e\n", params.chanoffset[i]);
// rec_len = wfp.xincrement[i] * wfp.points;
///////////////////////////////////////////////////////////
sprintf(str, ":WAV:SOUR CHAN%i", i + 1);
if(tmc_write(str) != 15)
{
printf("Can not write to device.\n");
line = __LINE__;
goto OUT_ERROR;
}
if(tmc_write(":WAV:FORM BYTE") != 14)
{
printf("Can not write to device.\n");
line = __LINE__;
goto OUT_ERROR;
}
if(tmc_write(":WAV:MODE NORM") != 14)
{
printf("Can not write to device.\n");
line = __LINE__;
goto OUT_ERROR;
}
if(tmc_write(":WAV:DATA?") != 10)
{
printf("Can not write to device.\n");
line = __LINE__;
goto OUT_ERROR;
}
n = tmc_read();
if(n < 0)
{
printf("Can not read from device.\n");
line = __LINE__;
goto OUT_ERROR;
}
if(n > WAVFRM_MAX_BUFSZ)
{
printf("Datablock too big for buffer.\n");
line = __LINE__;
goto OUT_ERROR;
}
if(n < 32)
{
n = 0;
}
for(j=0; j<n; j++)
{
params.wavebuf[i][j] = (int)(((unsigned char *)device->buf)[j]) - 127;
}
}
params.wavebufsz = n;
}
else // triggerstatus is "wait"
{
params.wavebufsz = 0;
}
h_busy = 0;
return;
OUT_ERROR:
params.result = TMC_THRD_RESULT_NONE;
sprintf(str, "An error occurred while reading screen data from device.\n"
"File %s line %i", __FILE__, line);
h_busy = 0;
params.error_line = line;
params.error_stat = -1;
return;
}

105
screen_thread.h 100644
Wyświetl plik

@ -0,0 +1,105 @@
/*
***************************************************************************
*
* Author: Teunis van Beelen
*
* Copyright (C) 2015 Teunis van Beelen
*
* Email: teuniz@gmail.com
*
***************************************************************************
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
***************************************************************************
*/
#ifndef DEF_SCREEN_THREAD_H
#define DEF_SCREEN_THREAD_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <QObject>
#include <QThread>
#include "global.h"
#include "utils.h"
#include "connection.h"
#include "tmc_dev.h"
class screenThread : public QThread
{
Q_OBJECT
public:
screenThread();
~screenThread();
int h_busy;
void set_device(struct tmcdev *);
void set_params(struct device_settings *);
void get_params(struct device_settings *);
private:
struct {
int connected;
int chandisplay[MAX_CHNS];
int triggerstatus;
int triggersweep;
double samplerate;
int memdepth;
int countersrc;
double counterfreq;
int wavebufsz;
short *wavebuf[MAX_CHNS];
int error_stat;
int error_line;
int cmd_cue_idx_in;
int cmd_cue_idx_out;
int result;
int job;
double triggeredgelevel;
double timebasedelayoffset;
double timebasedelayscale;
char debug_str[1024];
} params;
struct tmcdev *device;
struct device_settings *deviceparms;
void run();
int get_devicestatus();
};
#endif

Wyświetl plik

@ -1339,11 +1339,6 @@ void SignalCurve::mouseReleaseEvent(QMouseEvent *release_event)
return;
}
if(devparms->screenupdates_on == 1)
{
mainwindow->scrn_timer->start(devparms->screentimerival);
}
if(trig_pos_arrow_moving)
{
trig_pos_arrow_pos = mouse_x;
@ -1394,7 +1389,7 @@ void SignalCurve::mouseReleaseEvent(QMouseEvent *release_event)
sprintf(str, ":TIM:DEL:OFFS %e", devparms->timebasedelayoffset);
tmc_write(str);
mainwindow->set_cue_cmd(str);
}
else
{
@ -1414,7 +1409,7 @@ void SignalCurve::mouseReleaseEvent(QMouseEvent *release_event)
sprintf(str, ":TIM:OFFS %e", devparms->timebaseoffset);
tmc_write(str);
mainwindow->set_cue_cmd(str);
}
}
else if(trig_level_arrow_moving)
@ -1456,12 +1451,9 @@ void SignalCurve::mouseReleaseEvent(QMouseEvent *release_event)
sprintf(str, ":TRIG:EDG:LEV %e", devparms->triggeredgelevel[devparms->triggeredgesource]);
if(device != NULL)
{
tmc_write(str);
}
mainwindow->set_cue_cmd(str);
trig_line_timer->start(1000);
trig_line_timer->start(1300);
}
else
{
@ -1505,10 +1497,7 @@ void SignalCurve::mouseReleaseEvent(QMouseEvent *release_event)
sprintf(str, ":CHAN%i:OFFS %e", chn + 1, devparms->chanoffset[chn]);
if(device != NULL)
{
tmc_write(str);
}
mainwindow->set_cue_cmd(str);
devparms->activechannel = chn;
@ -1526,6 +1515,11 @@ void SignalCurve::mouseReleaseEvent(QMouseEvent *release_event)
use_move_events = 0;
setMouseTracking(false);
if(devparms->screenupdates_on == 1)
{
mainwindow->scrn_timer->start(devparms->screentimerival);
}
update();
}
@ -1640,7 +1634,7 @@ void SignalCurve::setTrigLineVisible(void)
{
trig_line_visible = 1;
trig_line_timer->start(1000);
trig_line_timer->start(1300);
}
@ -1734,6 +1728,27 @@ void SignalCurve::paintCounterLabel(QPainter *painter, int xpos, int ypos)
}
bool SignalCurve::hasMoveEvent(void)
{
if(use_move_events)
{
return true;
}
return false;
}

Wyświetl plik

@ -69,7 +69,10 @@ public:
QSize sizeHint() const {return minimumSizeHint(); }
QSize minimumSizeHint() const {return QSize(30,10); }
int label_active;
int label_active,
trig_line_visible;
unsigned int scr_update_cntr;
void setSignalColor1(QColor);
void setSignalColor2(QColor);
@ -85,8 +88,7 @@ public:
void setUpdatesEnabled(bool);
void setTrigLineVisible(void);
void setDeviceParameters(struct device_settings *);
unsigned int scr_update_cntr;
bool hasMoveEvent(void);
signals: void chan1Clicked();
void chan2Clicked();
@ -126,7 +128,6 @@ private:
chan_arrow_pos[MAX_CHNS],
trig_level_arrow_pos,
trig_pos_arrow_pos,
trig_line_visible,
trig_stat_flash,
mouse_x,
mouse_y,

Wyświetl plik

@ -58,11 +58,6 @@ void UI_Mainwindow::navDial_timer_handler()
{
adjDialFunc = ADJ_DIAL_FUNC_NONE;
}
if(devparms.screenupdates_on == 1)
{
scrn_timer->start(devparms.screentimerival);
}
}
}
@ -91,13 +86,13 @@ void UI_Mainwindow::adjdial_timer_handler()
sprintf(str, ":TRIG:HOLD %e", devparms.triggerholdoff);
tmc_write(str);
set_cue_cmd(str);
if(devparms.modelserie == 6)
{
usleep(20000);
tmc_write(":CLE");
set_cue_cmd(":CLE");
}
}
else if(adjDialFunc == ADJ_DIAL_FUNC_ACQ_AVG)
@ -108,7 +103,7 @@ void UI_Mainwindow::adjdial_timer_handler()
sprintf(str, ":ACQ:AVER %i", devparms.acquireaverages);
tmc_write(str);
set_cue_cmd(str);
}
adjDialFunc = ADJ_DIAL_FUNC_NONE;
@ -117,344 +112,110 @@ void UI_Mainwindow::adjdial_timer_handler()
{
navDialFunc = NAV_DIAL_FUNC_NONE;
}
if(devparms.screenupdates_on == 1)
{
scrn_timer->start(devparms.screentimerival);
}
}
void UI_Mainwindow::stat_timer_handler()
{
int line;
char str[512];
if(tmc_write(":TRIG:STAT?") != 11)
{
line = __LINE__;
goto OUT_ERROR;
}
if(tmc_read() < 1)
{
line = __LINE__;
goto OUT_ERROR;
}
// old_stat = devparms.triggerstatus;
runButton->setStyleSheet(def_stylesh);
singleButton->setStyleSheet(def_stylesh);
if(!strcmp(device->buf, "TD"))
{
devparms.triggerstatus = 0;
runButton->setStyleSheet("background: #66FF99;");
}
else if(!strcmp(device->buf, "WAIT"))
{
devparms.triggerstatus = 1;
singleButton->setStyleSheet("background: #FF9966;");
}
else if(!strcmp(device->buf, "RUN"))
{
devparms.triggerstatus = 2;
runButton->setStyleSheet("background: #66FF99;");
}
else if(!strcmp(device->buf, "AUTO"))
{
devparms.triggerstatus = 3;
runButton->setStyleSheet("background: #66FF99;");
}
else if(!strcmp(device->buf, "FIN"))
{
devparms.triggerstatus = 4;
}
else if(!strcmp(device->buf, "STOP"))
{
devparms.triggerstatus = 5;
runButton->setStyleSheet("background: #FF0066;");
}
else
{
line = __LINE__;
goto OUT_ERROR;
}
if(tmc_write(":TRIG:SWE?") != 10)
{
line = __LINE__;
goto OUT_ERROR;
}
if(tmc_read() < 1)
{
line = __LINE__;
goto OUT_ERROR;
}
if(!strcmp(device->buf, "AUTO"))
{
devparms.triggersweep = 0;
trigModeAutoLed->setValue(true);
trigModeNormLed->setValue(false);
trigModeSingLed->setValue(false);
}
else if(!strcmp(device->buf, "NORM"))
{
devparms.triggersweep = 1;
trigModeAutoLed->setValue(false);
trigModeNormLed->setValue(true);
trigModeSingLed->setValue(false);
}
else if(!strcmp(device->buf, "SING"))
{
devparms.triggersweep = 2;
trigModeAutoLed->setValue(false);
trigModeNormLed->setValue(false);
trigModeSingLed->setValue(true);
}
else
{
line = __LINE__;
goto OUT_ERROR;
}
if(tmc_write(":ACQ:SRAT?") != 10)
{
line = __LINE__;
goto OUT_ERROR;
}
if(tmc_read() < 1)
{
line = __LINE__;
goto OUT_ERROR;
}
devparms.samplerate = atof(device->buf);
if(tmc_write(":ACQ:MDEP?") != 10)
{
line = __LINE__;
goto OUT_ERROR;
}
if(tmc_read() < 1)
{
line = __LINE__;
goto OUT_ERROR;
}
devparms.memdepth = atoi(device->buf);
if(devparms.countersrc)
{
if(tmc_write(":MEAS:COUN:VAL?") != 15)
{
line = __LINE__;
goto OUT_ERROR;
}
if(tmc_read() < 1)
{
line = __LINE__;
goto OUT_ERROR;
}
devparms.counterfreq = atof(device->buf);
}
return;
OUT_ERROR:
sprintf(str, "An error occurred while reading status from device.\n"
"File %s line %i", __FILE__, line);
QMessageBox msgBox;
msgBox.setIcon(QMessageBox::Critical);
msgBox.setText(str);
msgBox.exec();
close_connection();
}
void UI_Mainwindow::scrn_timer_handler()
{
int i, j, n=0, chns=0, line;
char str[128];
static int h_busy=0;
if(device == NULL)
if(devparms.mutexx->tryLock() == false)
{
return;
}
if(h_busy)
scrn_thread->set_params(&devparms);
scrn_thread->start();
}
void UI_Mainwindow::horPosDial_timer_handler()
{
char str[256];
if(devparms.timebasedelayenable)
{
sprintf(str, ":TIM:DEL:OFFS %e", devparms.timebasedelayoffset);
}
else
{
sprintf(str, ":TIM:OFFS %e", devparms.timebaseoffset);
}
set_cue_cmd(str);
}
void UI_Mainwindow::trigAdjDial_timer_handler()
{
int chn;
char str[256];
chn = devparms.triggeredgesource;
if((chn < 0) || (chn > 3))
{
return;
}
h_busy = 1;
sprintf(str, ":TRIG:EDG:LEV %e", devparms.triggeredgelevel[chn]);
stat_timer_handler();
set_cue_cmd(str);
}
if(!devparms.connected)
void UI_Mainwindow::vertOffsDial_timer_handler()
{
int chn;
char str[256];
if(devparms.activechannel < 0)
{
h_busy = 0;
return;
}
for(i=0; i<MAX_CHNS; i++)
{
if(!devparms.chandisplay[i]) // Download data only when channel is switched on
{
continue;
}
chn = devparms.activechannel;
chns++;
sprintf(str, ":CHAN%i:OFFS %e", chn + 1, devparms.chanoffset[chn]);
set_cue_cmd(str);
}
void UI_Mainwindow::horScaleDial_timer_handler()
{
char str[256];
if(devparms.timebasedelayenable)
{
sprintf(str, ":TIM:DEL:SCAL %e", devparms.timebasedelayscale);
}
else
{
sprintf(str, ":TIM:SCAL %e", devparms.timebasescale);
}
if(!chns)
set_cue_cmd(str);
}
void UI_Mainwindow::vertScaleDial_timer_handler()
{
int chn;
char str[256];
if(devparms.activechannel < 0)
{
waveForm->clear();
h_busy = 0;
return;
}
//struct waveform_preamble wfp;
chn = devparms.activechannel;
if(devparms.triggerstatus != 1) // Don't download waveform data when triggerstatus is "wait"
{
for(i=0; i<MAX_CHNS; i++)
{
if(!devparms.chandisplay[i]) // Download data only when channel is switched on
{
continue;
}
sprintf(str, ":CHAN%i:SCAL %e", chn + 1, devparms.chanscale[chn]);
///////////////////////////////////////////////////////////
// tmc_write(":WAV:PRE?");
//
// n = tmc_read();
//
// if(n < 0)
// {
// strcpy(str, "Can not read from device.");
// goto OUT_ERROR;
// }
//
// printf("waveform preamble: %s\n", device->buf);
//
// if(parse_preamble(device->buf, device->sz, &wfp, i))
// {
// strcpy(str, "Preamble parsing error.");
// goto OUT_ERROR;
// }
//
// printf("waveform preamble:\n"
// "format: %i\n"
// "type: %i\n"
// "points: %i\n"
// "count: %i\n"
// "xincrement: %e\n"
// "xorigin: %e\n"
// "xreference: %e\n"
// "yincrement: %e\n"
// "yorigin: %e\n"
// "yreference: %i\n",
// wfp.format, wfp.type, wfp.points, wfp.count,
// wfp.xincrement[i], wfp.xorigin[i], wfp.xreference[i],
// wfp.yincrement[i], wfp.yorigin[i], wfp.yreference[i]);
//
// printf("chanoffset[] is %e\n", devparms.chanoffset[i]);
// rec_len = wfp.xincrement[i] * wfp.points;
///////////////////////////////////////////////////////////
sprintf(str, ":WAV:SOUR CHAN%i", i + 1);
tmc_write(str);
tmc_write(":WAV:FORM BYTE");
tmc_write(":WAV:MODE NORM");
tmc_write(":WAV:DATA?");
n = tmc_read();
if(n < 0)
{
printf("Can not read from device.\n");
line = __LINE__;
goto OUT_ERROR;
}
if(n > WAVFRM_MAX_BUFSZ)
{
printf("Datablock too big for buffer.\n");
line = __LINE__;
goto OUT_ERROR;
}
if(n < 32)
{
n = 0;
}
for(j=0; j<n; j++)
{
devparms.wavebuf[i][j] = (int)(((unsigned char *)device->buf)[j]) - 127;
}
}
devparms.wavebufsz = n;
waveForm->drawCurve(&devparms, device, n);
}
else // triggerstatus is "wait"
{
waveForm->update();
}
h_busy = 0;
return;
OUT_ERROR:
scrn_timer->stop();
sprintf(str, "An error occurred while reading screen data from device.\n"
"File %s line %i", __FILE__, line);
QMessageBox msgBox;
msgBox.setIcon(QMessageBox::Critical);
msgBox.setText(str);
msgBox.exec();
h_busy = 0;
set_cue_cmd(str);
}
@ -470,12 +231,6 @@ OUT_ERROR:

Wyświetl plik

@ -29,6 +29,8 @@
#ifndef TMC_DEV_H
#define TMC_DEV_H
#ifdef __cplusplus
extern "C" {
#endif

Wyświetl plik

@ -34,56 +34,97 @@
#define MAX_RESP_LEN (1024 * 1024 * 2)
QTcpSocket *sck;
int sockfd;
struct sockaddr_in inet_address;
struct timeval timeout, temp_timeout;
fd_set tcp_fds, temp_tcp_fds; /* filedescriptor pool */
struct tmcdev * tmclan_open(const char *address)
static int tmclan_send(const char *str)
{
int n, len;
len = strlen(str);
n = send(sockfd, str, len, MSG_NOSIGNAL);
if(n == len)
{
return n;
}
else
{
return -1;
}
}
static int tmclan_recv(char *buf, int sz)
{
temp_tcp_fds = tcp_fds; /* because select overwrites the arguments */
temp_timeout = timeout;
if(select(sockfd + 1, &temp_tcp_fds, 0, 0, &temp_timeout))
{
if(FD_ISSET(sockfd, &temp_tcp_fds)) /* check if our file descriptor is set */
{
return recv(sockfd, buf, sz, MSG_NOSIGNAL);
}
}
return -1;
}
struct tmcdev * tmclan_open(const char *ip_address)
{
struct tmcdev *tmc_device;
sck = new QTcpSocket;
QApplication::setOverrideCursor(Qt::WaitCursor);
qApp->processEvents();
sck->connectToHost(address, 5555);
qApp->processEvents();
if(sck->waitForConnected(TMC_LAN_TIMEOUT) == false)
sockfd = socket(PF_INET, SOCK_STREAM, 0);
if(sockfd == -1)
{
sck->abort();
delete sck;
sck = NULL;
QApplication::restoreOverrideCursor();
return NULL;
}
QApplication::restoreOverrideCursor();
FD_ZERO(&tcp_fds); /* clear file descriptor pool */
FD_SET(sockfd, &tcp_fds); /* add our filedescriptor to pool */
qApp->processEvents();
timeout.tv_sec = 0;
timeout.tv_usec = TMC_LAN_TIMEOUT;
timeout.tv_usec *= 1000;
memset(&inet_address, 0, sizeof(struct sockaddr_in));
inet_address.sin_family = AF_INET;
if(inet_aton(ip_address, &inet_address.sin_addr) == 0)
{
return NULL;
}
inet_address.sin_port = htons(5555);
if(connect(sockfd, (struct sockaddr *) &inet_address, sizeof(struct sockaddr)) < 0)
{
return NULL;
}
tmc_device = (struct tmcdev *)calloc(1, sizeof(struct tmcdev));
if(tmc_device == NULL)
{
sck->abort();
delete sck;
sck = NULL;
close(sockfd);
sockfd = -1;
return NULL;
}
tmc_device->hdrbuf = (char *)calloc(1, MAX_RESP_LEN + 1024);
if(tmc_device->hdrbuf == NULL)
{
free(tmc_device);
sck->abort();
delete sck;
sck = NULL;
close(sockfd);
sockfd = -1;
return NULL;
}
@ -95,13 +136,10 @@ struct tmcdev * tmclan_open(const char *address)
void tmclan_close(struct tmcdev *tmc_device)
{
if(sck != NULL)
if(sockfd != -1)
{
sck->abort();
delete sck;
sck = NULL;
close(sockfd);
sockfd = -1;
}
if(tmc_device != NULL)
@ -117,31 +155,33 @@ void tmclan_close(struct tmcdev *tmc_device)
int tmclan_write(struct tmcdev *tmc_device __attribute__ ((unused)), const char *cmd)
{
int qry=0;
int n, len, qry=0;
char buf[MAX_CMD_LEN + 16],
str[256];
if(sck == NULL)
if(sockfd == -1)
{
return -1;
}
if(strlen(cmd) > MAX_CMD_LEN)
len = strlen(cmd);
if(len > MAX_CMD_LEN)
{
printf("tmc_lan error: command too long\n");
return -1;
}
if(strlen(cmd) < 2)
if(len < 2)
{
printf("tmc_lan error: command too short\n");
return -1;
}
if(cmd[strlen(cmd) - 1] == '?')
if(cmd[len - 1] == '?')
{
qry = 1;
}
@ -166,9 +206,9 @@ int tmclan_write(struct tmcdev *tmc_device __attribute__ ((unused)), const char
printf("tmc_lan write: %s", buf);
}
sck->write(buf);
n = tmclan_send(buf);
if(sck->waitForBytesWritten(TMC_LAN_TIMEOUT) == false)
if(n != (len + 1))
{
return -1;
}
@ -179,19 +219,12 @@ int tmclan_write(struct tmcdev *tmc_device __attribute__ ((unused)), const char
{
usleep(50000);
sck->write("*OPC?\n");
if(sck->waitForBytesWritten(TMC_LAN_TIMEOUT) == false)
if(tmclan_send("*OPC?\n") != 6)
{
return -1;
}
if(sck->waitForReadyRead(TMC_LAN_TIMEOUT) == false)
{
return -1;
}
if(sck->read(str, 128) == 2)
if(tmclan_recv(str, 128) == 2)
{
if(str[0] == '1')
{
@ -201,7 +234,7 @@ int tmclan_write(struct tmcdev *tmc_device __attribute__ ((unused)), const char
}
}
return strlen(cmd);
return len;
}
@ -216,11 +249,11 @@ int tmclan_write(struct tmcdev *tmc_device __attribute__ ((unused)), const char
*/
int tmclan_read(struct tmcdev *tmc_device)
{
int size, size2, len;
int n, size, size2, len;
char blockhdr[32];
if(sck == NULL)
if(sockfd == -1)
{
return -1;
}
@ -233,12 +266,14 @@ int tmclan_read(struct tmcdev *tmc_device)
while(1)
{
if(sck->waitForReadyRead(TMC_LAN_TIMEOUT) == false)
n = tmclan_recv(tmc_device->hdrbuf + size, MAX_RESP_LEN - size);
if(n < 1)
{
return -1;
return -2;
}
size += sck->read(tmc_device->hdrbuf + size, MAX_RESP_LEN - size);
size += n;
if(tmc_device->hdrbuf[size - 1] == '\n')
{
@ -252,7 +287,7 @@ int tmclan_read(struct tmcdev *tmc_device)
tmc_device->buf[0] = 0;
return -1;
return -3;
}
if(size >= 0)

Wyświetl plik

@ -29,11 +29,6 @@
#ifndef TMC_LAN_H
#define TMC_LAN_H
#include <QtGlobal>
#include <QApplication>
#include <QObject>
#include <QTcpSocket>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -42,6 +37,12 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <sys/time.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stropts.h>
#include "global.h"
#include "tmc_dev.h"