EEVblog Electronics Community Forum
Products => Test Equipment => Topic started by: uliano on December 12, 2024, 12:57:44 pm
-
I'm having hard time to understand the SCPI interactions.
I "write" some command (for example to set a parameter or to switch to a mode) to the instrument and it does not answer anything. I have no idea if the command succeeded or not other than querying the instrument (for the parameter value or the current mode).
when sending sequences of commands I had *more than occasional* "command failures" that could be eventually amended by inserting a long enough delay between commands.
This delay is always (at least in my units, mostly Siglent) undocumented and differs not only among instruments but even between commands of the same unit.
Am I missing something?
How do you deal with this other than experimentally finding the "right" delay for each command?
(there should have been the *OPC? query that I expected returning 1 only AFTER previous command had been completed but it doesn't seem to cure, only time.sleep(the_right_amount) after each write has any success for me)
-
I don't think you are missing a lot.
Some commands allow setting and querying at the same time.
The timeout, or better defined delay, depends on the command and instrument state. If you set a DMM to read values with 100ms aperture time, it will only answer after 100ms. If you set autozero on it will take twice as long. It's not easy, larger companies have dedicated test engineers who write and optimize these tests, and make test setups. A good engineer might be able to do the same test 100x faster, if the right budget is given in time and equipment.
-
That is the joy of programming. Sometimes you just have to try over and over again. But you could also write a program, that finds out, how much the delay has to be.
Writing a program to write a program.
I have some SCPI stuff in my "homepage" link on my profile.
-
when sending sequences of commands I had *more than occasional* "command failures" that could be eventually amended by inserting a long enough delay between commands.
Some commands need you to wait for completion. You can do this by sending "*WAI".
Chapter 2.3 of the Rigol DHO800 programming manual (https://www.batterfly.com/PDF/RIGOL/dho800/DHO800-Series_programmingguide_EN.pdf) explains it.
(nb. the '*' commands are universal - should be the same on all devices).
(https://www.eevblog.com/forum/testgear/rigol-dho800900-new-firmware-v00-01-04-00-02-2024111/?action=dlattach;attach=2456225;image)
-
when sending sequences of commands I had *more than occasional* "command failures" that could be eventually amended by inserting a long enough delay between commands.
Some commands need you to wait for completion. You can do this by sending "*WAI".
it would have required SO LITTLE to implement that should have been made mandatory, unfortunately it's ignored by Siglent |O
-
it would have required SO LITTLE to implement that should have been made mandatory, unfortunately it's ignored by Siglent |O
Interesting... I thought that one would be universal. It's really basic and necessary.
-
I find this R&S document to be helpful:
https://scdn.rohde-schwarz.com/ur/pws/dl_downloads/dl_application/application_notes/1gp79/1GP79_1E_SCPI_Programming_Guide_SigGens.pdf
One technique is to tack on a ;OPC? query to the end of your command. But that can fail by timeout. Or in the case of old Tektronix scopes you just can't do that at all. So then you send a separate *OPC command, not a query, and run a loop querying *ESR? until bit 0 is a 1.
SCPI programming is a mess!
-
One technique is to tack on a ;OPC? query to the end of your command. But that can fail by timeout.
scanning the command list *OPC? drew immediatly my attention and therefore I interleaved every write with a query('*OPC?'), alas it dind't work: I didn't experience any timeout but many writes had no effect... until I replaced every query('*OPC?'), with time.sleep(some_time).
however, the documentation contradicts my experience:
Siglent:
The *OPC (Operation Complete) command sets the OPC bit (bit
0) in the standard Event Status Register (ESR). This command
has no other effect on the operation of the device because the
instrument starts parsing a command or query only after it has
completely processed the previous command or query. The
*OPC? query always responds with the ASCII character 1
because the device only responds to the query when the previous
command has been entirely executed.
No other access to ESR is mentioned
TTi:
*OPC? Query Operation Complete status. The response is always 1<RMT> and will be
available immediately the command is executed because all commands are
sequential.
Here at least I can query ESR and test the suggested approach
SCPI programming is a mess!
what is really puzzling me is that it seems a mess "by design". :palm:
-
@uliano
Which model ?
The App notes and Operating tips should provide guidance:
https://www.siglenteu.com/resources/ (https://www.siglenteu.com/resources/)
BTW, some programming manuals have been updated so be sure that you're working from the latest version.
-
Any command ending with a ? will send a answer back, other commands will not.
-
SDG 1000X, SDM3065X
from app notes:
def SocketQuery(Sock, cmd):
try:
Sock.sendall(cmd)
time.sleep(1)
except socket.error:
print('Send failed')
sys.exit()
reply = Sock.recv(4096)
return reply
def SocketSend(Sock, cmd):
try:
cmd = cmd + '\n'
Sock.sendall(cmd.encode('latin1'))
time.sleep(1)
except socket.error:
print('Send failed.')
sys.exit()
that 1s wait no matter what command you're issuing seems like overkill, to just set one parameter for example 0.1s or even less is enough.
so the alternatives are 2:
keep 1s and bloat the measurement time
or try to optimize by pausing a different time for different commands
if the semantic of "*OPC?" had been implemented as per manual description mentioned in the above post it would have been enough to follow each command by *OPC? thaw would have waited till the previous command was over and then only then returned 1
unfortunately it doesn't work like so, it seems that *OPC? is executed before completion of the previous command, in I queue many commands (eg. setting different paramenter) interleaved by *OPC? I observe tha only some parameter get changed if I don't insert some delay in between (and then *OPC? becomes completely useless)
-
Any command ending with a ? will send a answer back, other commands will not.
the problem is how to find a way to be sure that the command (without ?) has completed.
-
keep 1s and bloat the measurement time
or try to optimize by pausing a different time for different commands
You could use non-blocking receive. You check the receive buffer after a while and look for newline characters.
Same rules apply than an embedded systems communications. If you use the best practices from there you could make your setup faster.
If that's your goal. Sometimes it's just easier to get a cup of coffee while the test is running.
-
The problem with SCPI, if I'm on the the right track, is that after a write of a command ()without "?") you don't get anything back not even a "\n".
and, here I'm guessing, if I send another command before the previous has completed it gets ignored or misinterpreted.
-
It depends on the piece of equipment, when I was testing the limits of the SDS1204X-E, I believe the command buffer was 1MB before it started missing commands, so I could hit it with a few hundred commands and it would execute and reply in sequence, I don't recall anything being out of sequence, but i don't recall trying to use other commands why it ran a long capture or similar, things like reading out a channels voltage could be streamed at quite the rate.
(I was fuzzing the command interface for unknown commands)
-
The problem with SCPI, if I'm on the the right track, is that after a write of a command ()without "?") you don't get anything back not even a "\n".
Correct
and, here I'm guessing, if I send another command before the previous has completed it gets ignored or misinterpreted.
Usually not, but it is very device depend.
It can get rather complicated sometimes: Some devices may processed a command in background while other commands are processed in foreground. I have had some fun with that on some DMM's, I request a change to AC, but during the next couple of commands the meter is NOT in AC mode.
In TestController it is possible to use delays or *OPC (The advanced version), to handle this individually for each device.
-
The problem with SCPI, if I'm on the the right track, is that after a write of a command ()without "?") you don't get anything back not even a "\n".
Correct
and, here I'm guessing, if I send another command before the previous has completed it gets ignored or misinterpreted.
Usually not, but it is very device depend.
It can get rather complicated sometimes: Some devices may processed a command in background while other commands are processed in foreground. I have had some fun with that on some DMM's, I request a change to AC, but during the next couple of commands the meter is NOT in AC mode.
very close to my (limited) experience, and it is also command-dependent (or, possibly, some command are just exectuted fast enough).
In TestController it is possible to use delays or *OPC (The advanced version), to handle this individually for each device.
you mean "*OPC?" and wait for "1" as response or there is other uses of "*OPC" ?
It is really frustrating as it wouldn't have been much complex (for instrument designers) to implement some mechanism to enfoce a true sequential process.
-
you mean "*OPC?" and wait for "1" as response or there is other uses of *OPC ?
Another use:
Send a *OPC, then poll the device with *ESR?
This way there is no risk for timeout on the controller side, because the *ESR? is basically processed immediately.
It is really frustrating as it wouldn't have been much complex (for instrument designers) to implement some mechanism to enfoce a true sequential process.
It is not always a sequential process is a good solution. What would be nice is some minimum buffer requirements or a command to return remaining buffer space.
-
you mean "*OPC?" and wait for "1" as response or there is other uses of *OPC ?
Another use:
Send a *OPC, then poll the device with *ESR?
This way there is no risk for timeout on the controller side, because the *ESR? is basically processed immediately.
my siglents don't implement *ESR :'(
It is really frustrating as it wouldn't have been much complex (for instrument designers) to implement some mechanism to enfoce a true sequential process.
It is not always a sequential process is a good solution. What would be nice is some minimum buffer requirements or a command to return remaining buffer space.
I'm not saying -always- I'm saying that it should be possible to enforce the sequence -when needed-
(and it would have just been enough to implement a working *OPC? and not a fake one returning regardless of previous command completion)