From 592594bb7c774f8fb97a4c39c9041da31226fb62 Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Wed, 18 Jul 2012 16:56:50 -0500 Subject: [PATCH] Add run controls to scope --- clients/tde/src/part/scope/layout.ui | 18 ++- clients/tde/src/part/scope/part.cpp | 112 ++++++++++++++++++ clients/tde/src/part/scope/part.h | 4 + servers/gpib_server_lin/src/gpib_conn.cpp | 18 ++- .../gpib_server_lin/src/scope_functions.cpp | 51 +++++++- servers/gpib_server_lin/src/scope_functions.h | 3 +- 6 files changed, 202 insertions(+), 4 deletions(-) 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);