Problem with decoding binary on a oscilloscope

Dear friends,

I am programming a oscilloscope (Waverunner 64Xi) using the programming manual and pyvisa library. A common request (query) is to ask for a waveform in 8bit or 16bit.

the code for such a request is using a query as following:

‘WF=dso.query(“C1:WAVEFORM?”)’

However I get a decode error:

‘Cell In[21], line 1’
‘WF=dso.query(“C1:WAVEFORM?”)’

‘File ~\anaconda3\Lib\site-packages\pyvisa\resources\messagebased.py:647 in query
return self.read()’

’ File ~\anaconda3\Lib\site-packages\pyvisa\resources\messagebased.py:485 in read
message = self._read_raw().decode(enco)’

‘UnicodeDecodeError: ‘ascii’ codec can’t decode byte 0xd1 in position 113: ordinal not in range(128)’

So up to now I have resorted to reading the raw binary data with the following code which works for 8bit data using a write then read_raw():

'dso.write(“{}:WAVEFORM?”.format(Channel)) ’
‘C=dso._read_raw()’

However it is no longer sufficient for 16bit. Has anyone encountered such a problem? Does anyone know of a solution to this?

Since the mechanics is hidden inside a pyvisa function call which does the decoding, I can’t manually force it to read it as a bites. That was the idea behind using read_raw

Thank you,
Nate

1 Like

Hi,

it appears that you have to use unicode utf-8 vs. ascii. Note that ascii only covers values up to 127. The value 0xd1 corresponds to a value of 209 - out of the range covered by ascii point values . You have to tell the system explicitly that you want to use unicode utf-8 point values. I am not familiar with PyVisa (have heard about it - to control test equipment).

To get the symbol represented by the unicode point value of 209, type:

chr(209)

taking a guess here:

message = self._read_raw().decode(encoding = 'utf-8')

You might also have to tell it explicitly at the sending front end to send the binary data using utf-8 encoding if not already (or if it is using some other type by default, i.e., ascii).

1 Like

the code for such a request is using a query as following:

‘WF=dso.query(“C1:WAVEFORM?”)’

Have you looked at query_binary_values?
https://pyvisa.readthedocs.io/en/latest/api/resources.html#pyvisa.resources.SerialInstrument.query_binary_values

So up to now I have resorted to reading the raw binary data with the
following code which works for 8bit data using a write then read_raw():

'dso.write(“{}:WAVEFORM?”.format(Channel)) ’
‘C=dso._read_raw()’

However it is no longer sufficient for 16bit. Has anyone encountered such a problem? Does anyone know of a solution to this?

Can you say why it isn’t enough for 16 bit values?

Note that I don’t know what you should expect to get back from your
query.

Care to explain why you think this? There’s nothing in the OP’s post
which suggests that they are receiving UTF-8 text as a response. Merely
that the response bytes were attempted to be decoded as if they were
ASCII.

1 Like

Hi,

like I stated above, as you know, ASCII is only limited for point values up to 127. UFT-8 is much more extensive.

The error that was generated:

From a little research on the matter:

The following is an encoding error … but related.

and

(refer to user MatthieuDartiailh post … scroll down near the end)

Additionally:

All three suggest a potential solution as setting the encoding type to utf-8 for similar errors.

Sure, there are more encoding schemes but from my understanding, utf-8 is by bar the most widespread. Its worth looking into at the OPs end.

The OP will have to read the PyVISA documentation on how to best resolve this issue.

All three of these assume they’re getting text. The OP’s post suggests they’re getting binary data in 8-bit or 16-bit samples.

Only your middle reference has anything specific to pyvisa, and it is decoding an error message, which might be expected to be text in some form.

The OP is trying to decode the waveform response, not an error message.

1 Like

Well, you can encode text into binary. I don’t know what is being sent by the oscilloscope. It can be strictly numerical data. It can also be both, numerical and text data. I have actually used oscilloscopes during my career. Perhaps additional information is being sent, including settings information: time per division, timescale, volt per unit, peak-to-peak, amplitude, waveform name (if defined - with today’s fancy oscilloscopes, you can do many things). Maybe a time stamp. I (we) don’t know. Since we aren’t sitting in front of the oscilloscope, the best that we can do is offer the OP suggestions to resolve his issue.

Well, yes. The oscilloscope doesn’t produce data that represents text, so you shouldn’t use an interface that tries to interpret the data as text.

What exactly does this mean?

What result do you get back when you try using read_raw? What result do you think you should get back instead, and how is that different?

No; we can (and should) ask for information and clarifications so that we can properly understand the goal of the code, what sort of input and output is expected, etc.

Ok so I am in good route to solving the issue and the making the programm work. I still cannot obtain the waveform directly with the Waveform? query.

However I am able to use the _read_raw() function which gives me a byte array and imposing the 16bit format beforehand with the command COMM_FORMAT DEF9,WORD,BIN (LEcroy Oscilloscope WR command) -WORD being the keyword for defining 16 bit acquisition.

Afterwards the problem is resolved with the use of struct.unpack() -and defining it for 16bits.

Thank you everyone for your messages

Glad to hear it.

My quick glance at the query_binary_values function suggested that it
folders this kind of thing (the struct.unpack bit) into the call, a
bit like read folds a bytes.decode into its call.