diff --git a/clients/tde/src/part/scope/layout.ui b/clients/tde/src/part/scope/layout.ui
index ee3bb81..a104177 100644
--- a/clients/tde/src/part/scope/layout.ui
+++ b/clients/tde/src/part/scope/layout.ui
@@ -104,7 +104,23 @@
Capture Controls
-
+
+
+ runControlStartButton
+
+
+ Run
+
+
+
+
+ runControlStopButton
+
+
+ Stop
+
+
+
traceControlLayoutWidget
diff --git a/clients/tde/src/part/scope/part.cpp b/clients/tde/src/part/scope/part.cpp
index 17c137d..03b6b25 100644
--- a/clients/tde/src/part/scope/part.cpp
+++ b/clients/tde/src/part/scope/part.cpp
@@ -53,10 +53,12 @@ enum connectionStates {
ScopeState_TraceSecondsDivRequest = 18,
ScopeState_TriggerChannelRequest = 20,
ScopeState_TriggerLevelRequest = 22,
+ ScopeState_RunningRequest = 24,
ScopeState_TraceRequest = 50,
ScopeState_ChannelActiveStateUpdate = 100,
ScopeState_TraceVoltsDivUpdate = 102,
ScopeState_TriggerLevelUpdate = 104,
+ ScopeState_RunningUpdate = 106,
ScopeState_ExternalCommandRequest = 255
};
@@ -175,6 +177,7 @@ ScopePart::ScopePart( TQWidget *parentWidget, const char *widgetName, TQObject *
m_channelActiveSet[traceno] = false;
}
m_triggerLevelSet = false;
+ m_runningSet = false;
// Create widgets
m_base = new ScopeBase(widget());
@@ -222,6 +225,8 @@ ScopePart::ScopePart( TQWidget *parentWidget, const char *widgetName, TQObject *
connect(m_base->acqStart, SIGNAL(clicked()), this, SLOT(startDAQ()));
connect(m_base->acqStop, SIGNAL(clicked()), this, SLOT(stopDAQ()));
+ connect(m_base->runControlStartButton, SIGNAL(clicked()), this, SLOT(startScope()));
+ connect(m_base->runControlStopButton, SIGNAL(clicked()), this, SLOT(stopScope()));
connect(m_base->waveformSave, SIGNAL(clicked()), this, SLOT(saveWaveforms()));
connect(m_base->waveformRecall, SIGNAL(clicked()), this, SLOT(recallWaveforms()));
@@ -291,6 +296,14 @@ void ScopePart::processLockouts() {
m_base->waveformSave->setEnabled(false);
m_base->waveformRecall->setEnabled(false);
}
+ if (m_running) {
+ m_base->runControlStartButton->setEnabled(false);
+ m_base->runControlStopButton->setEnabled(true);
+ }
+ else {
+ m_base->runControlStartButton->setEnabled(true);
+ m_base->runControlStopButton->setEnabled(false);
+ }
}
void ScopePart::disconnectFromServerCallback() {
@@ -324,6 +337,7 @@ void ScopePart::setTickerMessage(TQString message) {
if (m_channelActiveSet[i]) updatesPending = true;
if (m_voltsDivSet[i]) updatesPending = true;
if (m_triggerLevelSet) updatesPending = true;
+ if (m_runningSet) updatesPending = true;
}
m_connectionActiveAndValid = true;
@@ -883,6 +897,50 @@ void ScopePart::mainEventLoop() {
updateGraticule();
}
+ if (result == "ACK") {
+ SET_NEXT_STATE(ScopeState_RunningRequest)
+ EXEC_NEXT_STATE_IMMEDIATELY
+ }
+ else {
+ COMMUNICATIONS_FAILED
+ }
+ }
+ else {
+ if (!m_updateTimeoutTimer->isActive()) {
+ UPDATEDISPLAY_TIMEOUT
+ }
+ }
+ }
+ else if (m_commHandlerState == ScopeState_RunningRequest) {
+ // Get running, step 1
+ ds << TQString("GETRUNNING");
+ ds << m_currentOpChannel;
+ m_socket->writeEndOfFrame();
+
+ SET_NEXT_STATE(ScopeState_RunningRequest+1)
+ EXEC_NEXT_STATE_IMMEDIATELY
+ }
+ else if (m_commHandlerState == ScopeState_RunningRequest+1) {
+ // Get response data
+ if (m_socket->canReadFrame()) {
+ PAT_WATCHDOG_TIMER
+ setTickerMessage(i18n("Loading [Received run status]"));
+
+ // Get running, step 2
+ TQString result;
+ ds >> result;
+ if (result == "ACK") {
+ TQ_INT16 status;
+ ds >> status;
+ m_running = (status != 0);
+ }
+ m_socket->clearFrameTail();
+
+ if (result == "ACK") {
+ // Update display widget(s)
+ updateGraticule();
+ }
+
if (result == "ACK") {
m_currentOpChannel = getNextActiveChannel(0, m_channelActive, m_maxNumberOfTraces);
SET_NEXT_STATE(ScopeState_TraceRequest)
@@ -942,6 +1000,7 @@ void ScopePart::mainEventLoop() {
&& (m_channelActiveSet[m_currentOpChannel] == false)
&& (m_voltsDivSet[m_currentOpChannel] == false)
&& (m_triggerLevelSet == false)
+ && (m_runningSet == false)
) {
SET_NEXT_STATE(ScopeState_TraceRequest)
}
@@ -1108,6 +1167,48 @@ void ScopePart::mainEventLoop() {
ds >> result;
m_socket->clearFrameTail();
+ if (result == "ACK") {
+ SET_NEXT_STATE(ScopeState_RunningUpdate)
+ EXEC_NEXT_STATE_IMMEDIATELY
+ }
+ else {
+ COMMUNICATIONS_FAILED
+ }
+ }
+ else {
+ if (!m_updateTimeoutTimer->isActive()) {
+ UPDATEDISPLAY_TIMEOUT
+ }
+ }
+ }
+ else if (m_commHandlerState == ScopeState_RunningUpdate) {
+ if (m_runningSet) {
+ // Set running, step 1
+ ds << TQString("SETRUNNING");
+ TQ_INT16 running = (m_running)?1:0;
+ ds << running;
+ m_socket->writeEndOfFrame();
+
+ m_runningSet = false;
+ SET_NEXT_STATE(ScopeState_RunningUpdate+1)
+ }
+ else {
+ m_currentOpChannel = getNextActiveChannel(0, m_channelActive, m_maxNumberOfTraces);
+ SET_NEXT_STATE(ScopeState_TraceRequest)
+ }
+ EXEC_NEXT_STATE_IMMEDIATELY
+ }
+ else if (m_commHandlerState == ScopeState_RunningUpdate+1) {
+ // Get response data
+ if (m_socket->canReadFrame()) {
+ PAT_WATCHDOG_TIMER
+ setTickerMessage(i18n("Updating [Set run status]"));
+
+ // Set running, step 2
+ TQString result;
+ ds >> result;
+ m_socket->clearFrameTail();
+
if (result == "ACK") {
m_currentOpChannel = getNextActiveChannel(0, m_channelActive, m_maxNumberOfTraces);
SET_NEXT_STATE(ScopeState_TraceRequest)
@@ -1211,6 +1312,7 @@ void ScopePart::stopDAQ() {
m_voltsDivSet[i] = false;
}
m_triggerLevelSet = false;
+ m_runningSet = false;
m_commHandlerMode = 1;
m_commHandlerCommandState = 3;
mainEventLoop();
@@ -1447,6 +1549,16 @@ void ScopePart::cursorLevelChanged(uint cursor, double level) {
}
}
+void ScopePart::startScope() {
+ m_running = true;
+ m_runningSet = true;
+}
+
+void ScopePart::stopScope() {
+ m_running = false;
+ m_runningSet = true;
+}
+
KAboutData* ScopePart::createAboutData() {
return new KAboutData( APP_NAME, I18N_NOOP( APP_PRETTYNAME ), APP_VERSION );
}
diff --git a/clients/tde/src/part/scope/part.h b/clients/tde/src/part/scope/part.h
index 24e2c84..c559f1e 100644
--- a/clients/tde/src/part/scope/part.h
+++ b/clients/tde/src/part/scope/part.h
@@ -89,6 +89,8 @@ namespace RemoteLab
void traceControlEnableChanged(bool enabled);
void traceControlVDivChanged(double vdiv);
void cursorLevelChanged(uint cursor, double level);
+ void startScope();
+ void stopScope();
void saveWaveforms();
void recallWaveforms();
virtual void postProcessTrace();
@@ -110,6 +112,7 @@ namespace RemoteLab
TQ_INT16 m_hdivs;
TQ_INT16 m_vdivs;
TQ_INT16 m_triggerChannel;
+ bool m_running;
double m_triggerLevel;
TQ_INT32 m_samplesInTrace[MAXTRACES+1];
bool m_channelActive[MAXTRACES+1];
@@ -117,6 +120,7 @@ namespace RemoteLab
double m_secsDiv[MAXTRACES+1];
TraceControlWidget* m_traceControlWidgetList[MAXTRACES];
bool m_triggerLevelSet;
+ bool m_runningSet;
bool m_voltsDivSet[MAXTRACES+1];
bool m_channelActiveSet[MAXTRACES+1];
bool m_lastChangesRequireFullUpdate;
diff --git a/servers/gpib_server_lin/src/gpib_conn.cpp b/servers/gpib_server_lin/src/gpib_conn.cpp
index dc081a3..6f20316 100644
--- a/servers/gpib_server_lin/src/gpib_conn.cpp
+++ b/servers/gpib_server_lin/src/gpib_conn.cpp
@@ -368,7 +368,7 @@ void GPIBSocket::commandLoop() {
}
}
else if (m_instrumentCommand == "SETRUNNING") { // Want to change run status
- TQ_INT32 value;
+ TQ_INT16 value;
ds >> value;
if (scope_set_acquisition(value, m_serverParent->m_scopeType.ascii(), m_serverParent->m_scopeDeviceSocket) == 0) {
ds << TQString("ACK");
@@ -379,6 +379,20 @@ void GPIBSocket::commandLoop() {
writeEndOfFrame();
}
}
+ else if (m_instrumentCommand == "GETRUNNING") { // Want to get run status
+ int running;
+ if (scope_get_acquisition(&running, m_serverParent->m_scopeType.ascii(), m_serverParent->m_scopeDeviceSocket) == 0) {
+ TQ_INT16 safeRunning;
+ safeRunning = running;
+ ds << TQString("ACK");
+ ds << safeRunning;
+ writeEndOfFrame();
+ }
+ else {
+ ds << TQString("NCK");
+ writeEndOfFrame();
+ }
+ }
else if (m_instrumentCommand == "SETCHANNELACTIVE") { // Want to change channel enable
TQ_INT32 value1;
ds >> value1;
@@ -537,6 +551,8 @@ void GPIBSocket::commandLoop() {
}
else {
printf("[WARNING] Received unknown command %s from host %s\n\r", m_instrumentCommand.ascii(), m_remoteHost.ascii()); fflush(stdout);
+ ds << TQString("NCK");
+ writeEndOfFrame();
}
}
else if (m_activeDeviceType == 3) {
diff --git a/servers/gpib_server_lin/src/scope_functions.cpp b/servers/gpib_server_lin/src/scope_functions.cpp
index 0ba0bc1..3385a1e 100644
--- a/servers/gpib_server_lin/src/scope_functions.cpp
+++ b/servers/gpib_server_lin/src/scope_functions.cpp
@@ -350,6 +350,55 @@ int scope_set_acquisition(int status,const char * scopeType, int gpibDevice) {
}
}
+int scope_get_acquisition(int * retval, const char * scopeType, int gpibDevice) {
+ char floatstring[1024];
+ long ai;
+ int max_num_bytes = 0;
+
+ if (strcmp("HP54600OS", scopeType) == 0) {
+ // FIXME
+ // Not supported (yet)
+ return -1;
+ }
+ else if (strcmp("TDS744AOS", scopeType) == 0) {
+ // Send request
+ printf("[INFO] Getting run state\n\r");
+ sprintf(falpha,"ACQUIRE:STATE?");
+ #ifdef ENABLE_EXTRA_DEBUGGING
+ printf("[DEBG] Writing: %s\n\r", falpha);
+ #endif
+ if (gpib_write(gpibDevice, falpha) == 0) {
+ max_num_bytes = 24; // Request more bytes than are possible to ensure no bytes are left behind
+ }
+ else {
+ return 2;
+ }
+
+ // Read response
+ #ifdef ENABLE_EXTRA_DEBUGGING
+ printf("[DEBG] Trying to read %i bytes from GPIB device...\n", max_num_bytes);
+ #endif
+
+ ai = gpib_read_array(gpibDevice, max_num_bytes, floatstring);
+ if (ai == -1) {
+ return 1;
+ }
+ else {
+ floatstring[ai]=0;
+ *retval = atoi(floatstring);
+ }
+
+ #ifdef ENABLE_EXTRA_DEBUGGING
+ printf("[DEBG] Read %li bytes from GPIB device\n", ai);
+ #endif
+
+ return 0;
+ }
+ else {
+ return -1;
+ }
+}
+
int scope_set_channel_state(int desired_channel, int status,const char * scopeType, int gpibDevice) {
if ((strcmp("HP54600OS", scopeType) == 0) || (strcmp("TDS744AOS", scopeType) == 0)) {
printf("[INFO] Setting channel %d state to %i\n\r", desired_channel, status);
@@ -387,7 +436,7 @@ int scope_set_channel_state(int desired_channel, int status,const char * scopeTy
printf("[DEBG] Writing: %s\n\r", falpha);
#endif
if (gpib_write(gpibDevice, falpha) == 0) {
- usleep(2*1000000); // The scope is slow to respond, and also blind to commands during the update window! [RAJA TESTME]
+ usleep(2*1000000); // The scope is slow to respond, and also blind to commands during the update window! This makes sure that the scope will actually process subsequent commands
return 0;
}
else {
diff --git a/servers/gpib_server_lin/src/scope_functions.h b/servers/gpib_server_lin/src/scope_functions.h
index a83ab9a..e6f9ad4 100644
--- a/servers/gpib_server_lin/src/scope_functions.h
+++ b/servers/gpib_server_lin/src/scope_functions.h
@@ -35,7 +35,8 @@ int scope_perform_initial_setup(const char * scopeType, int gpibDevice);
int scope_set_timebase(float desired_timebase,const char * scopeType, int gpibDevice);
int scope_set_volts_div(int desired_channel, double desired_volts, const char * scopeType, int gpibDevice);
int scope_set_acquisition(int status,const char * scopeType, int gpibDevice);
-int scope_set_channel_state(int desired_channel, int status,const char * scopeType, int gpibDevice);
+int scope_get_acquisition(int * retval, const char * scopeType, int gpibDevice);
+int scope_set_channel_state(int desired_channel, int status, const char * scopeType, int gpibDevice);
int scope_get_channel_state(int * retval, int desired_channel, const char * scopeType, int gpibDevice);
int scope_set_trigger_channel(int desired_channel,const char * scopeType, int gpibDevice);
int scope_set_trigger_level(float desired_level,const char * scopeType, int gpibDevice);