analogdevicesinc / libsmu

Software abstractions for the analog signal exploration tools.
http://analogdevicesinc.github.io/libsmu/
BSD 3-Clause "New" or "Revised" License
32 stars 31 forks source link

Unable to set multiple constant voltages. Getting AttributeError: 'RuntimeError' object has no attribute 'message' #134

Closed thedude8 closed 4 years ago

thedude8 commented 4 years ago

Hi all,

I am trying to set a constant voltage at different time intervals. I am running the following code:

def main():
    session = Session()
    dev = session.devices[0]

    chan_a = dev.channels["A"]
    chan_b = dev.channels["B"]

    chan_a.mode = Mode.SVMI
    chan_b.mode = Mode.SVMI

    chan_a.constant(1.0)

    time.sleep(5)

    chan_a.constant(1.75)

    time.sleep(5)

    chan_a.constant(3.9)

    time.sleep(5)

However I keep receiving the following error:

Traceback (most recent call last):
  File "pysmu/libsmu.pyx", line 640, in pysmu.libsmu.SessionDevice.write
RuntimeError: data write timeout, no available queue space: Resource busy

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "read-write.py", line 18, in <module>
    chan_a.constant(1.75)
  File "pysmu/libsmu.pyx", line 891, in pysmu.libsmu.Channel.constant
  File "pysmu/libsmu.pyx", line 794, in pysmu.libsmu.Channel.write
  File "pysmu/libsmu.pyx", line 646, in pysmu.libsmu.SessionDevice.write
AttributeError: 'RuntimeError' object has no attribute 'message'

I am using the examples as my template for creating this, but always get this same error every time. It seems like I need to flush the buffer or do a read, but even when attempting that it isn't working. Can you explain the reason for this or how I should be flushing the buffers if that is the issue?

thedude8 commented 4 years ago

This is also the case for current mode as well.

cristi-iacob commented 4 years ago

Hi!

This behaviour appears because you are setting channel B in a mode which requires sourcing, but you are never generating input for channel B. Therefore libsmu is waiting for samples on channel B, but because they will never be generated, you will receive a timeout error.

You have two possibilities to avoid this situation:

  1. Set channel B mode on HI_Z, so that it will not wait for input samples anymore.
  2. Generate some samples on channel B as well. If you are not interested in the values on channel B, you can just generate some random samples, for example using chan_b.constant(1).
thedude8 commented 4 years ago

@cristi-iacob I tried setting channel b in HI_Z, but that didn't fix the issue:

Code snippet:

#!/usr/bin/env python
import time
from pysmu import Session, Mode

session = Session()
dev = session.devices[0]

chan_a = dev.channels["A"]
chan_b = dev.channels["B"]

chan_a.mode = Mode.SVMI
chan_b.mode = Mode.HI_Z

chan_a.constant(1.0)

time.sleep(5)

chan_a.constant(1.75)

time.sleep(5)

chan_a.constant(3.9)

time.sleep(5)

And the error I get is still the following:

Traceback (most recent call last):
  File "example.py", line 18, in <module>
    chan_a.constant(1.75)
  File "pysmu/libsmu.pyx", line 891, in pysmu.libsmu.Channel.constant
  File "pysmu/libsmu.pyx", line 794, in pysmu.libsmu.Channel.write
  File "pysmu/libsmu.pyx", line 650, in pysmu.libsmu.SessionDevice.write
pysmu.exceptions.WriteTimeout: data write timeout, no available queue space: Resource busy

I also tried doing this with setting channel b to the same values as channel a, but some issue. Do you have to call get_samples()?

cristi-iacob commented 4 years ago

Hi!

The problem is that you are not calling session.start(). Add session.start(0) after the line: dev = session.devices[0] and it should work properly. You must call session.start, because there is the point in which the data sampling is started. Without this, you can just ,,preset" the session's or device's attributes, with no effect (and it can cause undefined behaviours, like in your example).

You can see more examples about this in the examples section from this repository (https://github.com/analogdevicesinc/libsmu/tree/master/bindings/python/examples).

Thanks!

thedude8 commented 4 years ago

Hey,

I have added that line to no avail. Code snippet:

#!/usr/bin/env python
import time
from pysmu import Session, Mode

session = Session()
dev = session.devices[0]
session.start(0)

chan_a = dev.channels["A"]
chan_b = dev.channels["B"]

chan_a.mode = Mode.SVMI
chan_b.mode = Mode.HI_Z

chan_a.constant(1.0)

time.sleep(5)

chan_a.constant(1.75)

time.sleep(5)

chan_a.constant(3.9)

time.sleep(5)

I still receive this error given the following code you suggested.

Traceback (most recent call last):
  File "pysmu/libsmu.pyx", line 618, in pysmu.libsmu.SessionDevice.write
RuntimeError: data sample dropped: Device or resource busy

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "libsmu/bindings/python/examples/try_this.py", line 19, in <module>
    chan_a.constant(0.0400)
  File "pysmu/libsmu.pyx", line 869, in pysmu.libsmu.Channel.constant
  File "pysmu/libsmu.pyx", line 772, in pysmu.libsmu.Channel.write
  File "pysmu/libsmu.pyx", line 624, in pysmu.libsmu.SessionDevice.write
AttributeError: 'RuntimeError' object has no attribute 'message'

I went through the examples, and ran the read-write.py which yields a similar result if you comment out the get_samples lines here:


            # Read incoming samples in a blocking fashion.
            # samples = dev.get_samples(num_samples)
            # for x in samples:
            #     output("{: 6f} {: 6f} {: 6f} {: 6f}".format(x[0][0], x[0][1], x[1][0], x[1][1]))

Once I do that, I then get the following errors:

Traceback (most recent call last):
  File "pysmu/libsmu.pyx", line 618, in pysmu.libsmu.SessionDevice.write
RuntimeError: data write timeout, no available queue space: Device or resource busy

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "libsmu/bindings/python/examples/read-write.py", line 62, in <module>
    chan_a.write(refill_data(num_samples, i % 6))
  File "pysmu/libsmu.pyx", line 772, in pysmu.libsmu.Channel.write
  File "pysmu/libsmu.pyx", line 624, in pysmu.libsmu.SessionDevice.write
AttributeError: 'RuntimeError' object has no attribute 'message'

It seems like you cannot do consecutive writes without calling the get_samples method, and when calling that method, the constant voltage I am expecting to source dips, which makes me not want to call this. All I am trying to do is set a constant voltage or current at different time intervals.

Any ideas?

thedude8 commented 4 years ago

Also, it seems like the python3 bindings are still relying on exceptions to have the .message attribute but that was depreciated.

Example:

    def write(self, data, unsigned channel, bint cyclic=False):
        """Write data to a specified channel of the device.

        Args:
            data: iterable of sample values
            channel (0 or 1): channel to write samples to
            cyclic (bool, optional): continuously iterate over the same buffer

        Raises: DeviceError on writing failures.
        """
        # don't waste time writing empty data sets
        if len(data) == 0:
            return

        cdef int ret = 0
        cdef vector[float] buf = data

        try:
            ret = self._device.write(buf, channel, cyclic)
        except SystemError as e:
            raise DeviceError(str(e))
        except RuntimeError as e:
            write_timeout_err = 'data write timeout'
            sample_drop_err = 'data sample dropped'
            if e.message[:len(sample_drop_err)] == sample_drop_err:
                if not self.ignore_dataflow:
                    raise SampleDrop(e.message)
            elif e.message[:len(write_timeout_err)] == write_timeout_err:
                raise WriteTimeout(e.message)
            else:
                raise DeviceError(str(e))

        if ret < 0:
            raise DeviceError('failed writing to device', ret)

This function still has e.message sprinkled around.

cristi-iacob commented 4 years ago

Hi,

It looks like the compatibility between libsmu and Python3 was broken. We'll fix it as soon as possible. I assume you have been using Python3 the entire time. We tested the initial issue with Python2, that's why we suggested to use session.start(0). On Python3 we experience the same problem and it seems to be a problem with linking libsmu with Python3.

If it's not a problem for you to use Python2, you can clean up the build folder, rebuild and reinstall libsmu (libsmu cmake uses Python2 by default). Don't forget to export it to PYTHONPATH, using the following command $ export PYTHONPATH=/usr/lib/python2.7/site-packages:${PYTHONPATH}

Can you let us know if this works? We'll come back with updates soon on the Python3 compatibility.

Thank you!

thedude8 commented 4 years ago

Hey @cristi-iacob, any update on this?

cristi-iacob commented 4 years ago

Hi!

The fix is still in development. Have you tried to use Python 2? Or is Python 3 absolutely necessary for you?

Thanks!

thedude8 commented 4 years ago

Python3 is necessary as all of our tools are in written in python 3.

Support for python 2 will end in 2 weeks anyways, so we would prefer to stay updated. Do you by chance have a timeline on the fix?

Thanks for the support!

cristi-iacob commented 4 years ago

Hi!

We have made some modifications. Can you please test them now and tell us if they work for you? The modifications are on this branch.

I have tested it with the following Python script (using Python3):

from pysmu import *
import time

session = Session()
dev = session.devices[0]

session.start(0)

chan_a = dev.channels["A"]
chan_b = dev.channels["B"]

chan_a.mode = Mode.SVMI
chan_b.mode = Mode.HI_Z

chan_a.constant(1.0)
time.sleep(5)

chan_a.constant(1.75)
time.sleep(5)

chan_a.constant(3.9)
time.sleep(5)

Please let us know if this works for you! Thank you!

thedude8 commented 4 years ago

Hey @cristi-iacob ,

I checked out your branch and reinstalled the package, but I'm still getting the AttributeError: 'RuntimeError' object has no attribute 'message' error. I went through pysmu/libsmu.pyx to confirm the changes you made to remove e.message are in there and it seems fine, so I'm not actually sure why it's spitting this error out. I'm assuming it's a setup issue, but here were my steps:

Traceback (most recent call last):
  File "pysmu/libsmu.pyx", line 618, in pysmu.libsmu.SessionDevice.write

RuntimeError: data sample dropped: Device or resource busy

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "examples/try_this.py", line 18, in <module>
    chan_a.constant(1.75)
  File "pysmu/libsmu.pyx", line 869, in pysmu.libsmu.Channel.constant
    3.9054107666015625,
  File "pysmu/libsmu.pyx", line 772, in pysmu.libsmu.Channel.write
    cyclic (bool, optional): continuously iterate over the same buffer
  File "pysmu/libsmu.pyx", line 624, in pysmu.libsmu.SessionDevice.write
    write_timeout_err = 'data write timeout'
AttributeError: 'RuntimeError' object has no attribute 'message'

Any ideas?

AlexandraTrifan commented 4 years ago

Hello,

We discovered there is an issue when rebuilding the Python bindings. We are working on a fix for this. In the libsmu folder, go to bindings/python/pysmu and remove thelibsmu.cpp file. That file is generated at the first build. The issue is that is generated in the source folder. If it were generated in the build folder, we could clean it up when we remove the previous build folder. We'll add a fix for this soon.

Please let us know if you manage to rebuild it this way.

Thank you, -Alexandra

thedude8 commented 4 years ago

@AlexandraTrifan ,

That did it! I tested setting multiple constant current/voltage set points and it is reliably working now.

I did both exercises of setting up to confirm the build issues:

  1. First build

    • Clone repo from scatch
    • Checkout the python 3 fix branch
    • Cmake and python install
    • Set multiple currents
  2. Second build

    • Build without the python 3 branch
    • Check out the python 3 branch
    • Remove the libsmu.cpp file in bindings/python/pysmu
    • Rebuild the package and reinstall it

Thanks for working on this, you have both been a huge help!

AlexandraTrifan commented 4 years ago

Hi,

Happy to know everything works fine. We'll merge the fixes into master.

-Alexandra

AlexandraTrifan commented 4 years ago

I think we can close this. Can be reopened if anything new appears.