pyvisa / pyvisa-py

A pure python PyVISA backend
https://pyvisa-py.readthedocs.io
MIT License
281 stars 119 forks source link

ibgpib: invalid descriptor, but PyVISA can communication with the instrument. #282

Open HideharuYamauchi opened 3 years ago

HideharuYamauchi commented 3 years ago

Hello,

I try to communicate with FLUKE RPM4 using GPIB-USB-HS on CentOS8 and I installed pyvisa-py and linux-gpib. Here is the output of PyVISA. Screenshot from 2020-10-16 05-21-33 Screenshot from 2020-10-16 05-17-45 As you can see, the line >>> rm.list_resources() gives me libgpib: invalid descriptor errors but finally it gives me a correct address of the instrument ('GPIB0::1::INSTR') . So I can communicate with the instrument for now, but I want to deal with this error. Do you have any idea?

The following is the output of pyvisa-info. Screenshot from 2020-10-16 05-09-01

MatthieuDartiailh commented 3 years ago

The spurious logging messages are emitted by Linux GPIB when probing invalid addresses. However I am not aware of any way to assess if an address is valid or not without doing this and hence generating such warnings. Feel free to look for a workaround, I do not have an easy access to a linux-gpib system currently.

HideharuYamauchi commented 3 years ago

It's very helpful information for me. Thank you very much.

jakeogh commented 2 years ago

Same issue as https://github.com/pyvisa/pyvisa-py/issues/249

I tried using contextlib.redirect_stderr but no luck. Would like to understand why.

$ cat ~/cfg/python/gpib_invalid_descriptor.py 
#!/usr/bin/env python3

from contextlib import redirect_stderr
from contextlib import redirect_stdout

import pyvisa

if __name__ == '__main__':
    with redirect_stderr(None):
        with redirect_stdout(None):
            resource_manager = pyvisa.ResourceManager()
            resources = resource_manager.list_resources()
    print('resources:', resources)

$ ~/cfg/python/gpib_invalid_descriptor.py
libgpib: invalid descriptor
libgpib: invalid descriptor
<snip>
libgpib: invalid descriptor
resources: ('ASRL/dev/ttyS0::INSTR', 'GPIB0::1::INSTR')

$ ~/cfg/python/gpib_invalid_descriptor.py > /dev/null
libgpib: invalid descriptor
libgpib: invalid descriptor
<snip>
libgpib: invalid descriptor

$ ~/cfg/python/gpib_invalid_descriptor.py > /dev/null 2>&1
tonyzzz321 commented 2 years ago

@jakeogh

Linux-gpib, the library spitting out the "invalid descriptor" messages, is a C library. Therefore, redirecting the python sys.stderr has no effect, because the messages are not going through it. We need to go a layer deeper and play with the os file descriptor of stderr. The following should mute the "invalid descriptor" messages.

import os, pyvisa
from contextlib import contextmanager

@contextmanager
def _Shhhhhhh():
   original_stderr = os.dup(2)  # stderr stream is linked to file descriptor 2, save a copy of the real stderr so later we can restore it
   blackhole = os.open(os.devnull, os.O_WRONLY)  # anything written to /dev/null will be discarded
   os.dup2(blackhole, 2)  # duplicate the blackhole to file descriptor 2, which the C library uses as stderr
   os.close(blackhole)  # blackhole was duplicated from the line above, so we don't need this anymore
   yield
   os.dup2(original_stderr, 2)  # restoring the original stderr
   os.close(original_stderr)

with _Shhhhhhh():
   resource_manager = pyvisa.ResourceManager()
   resources = resource_manager.list_resources() # should not see the "invalid descriptor" messages anymore

This will stop showing anything written to stderr inside the "with" block. If you want to only filter out "invalid descriptor" messages (in case there are other important messages being written to stderr), you can redirect the stream to a temporary file (as opposed to /dev/null), then after restoring the original stderr, read the temporary file, filter out the unwanted messages, and print them back.

Skroder commented 10 months ago

I had good results with the method tonyzzz321 posted, except there is a typo that took me a while to find. The 3rd line "@contextmanger" omitted an 'a' in manager and should be "@contextmanager" but thanks for the script. It works fine with that edit.

tonyzzz321 commented 10 months ago

Thanks for pointing it out @Skroder. I've updated my previous comment and fixed it.

kellenic2016 commented 2 months ago

Reviving this to add a lower-level fix to this. After cloning the source code for linux-gpib version 4.3.6 through svn here, you can modify the linux-gpib-user/lib/ibutil.c file and remove/comment out the fprintf stderr inside of ibCheckDescriptor. Doing this removed those messages without impacting the functionality of the rest of the library.