Skip to content

GPIB¤

Prerequisites¤

Before communicating with equipment that use the General Purpose Interface Bus (GPIB), you must have a GPIB-compatible driver installed and the directory to the appropriate library file (e.g., ni4882, gpib-32, libgpib) must be available on the PATH environment variable.

Tip

You can create a GPIB_LIBRARY environment variable with the value being the full path to a GPIB library file to load. This variable can also be defined as a <gpib_library> element in a Configuration file.

Consult the manufacturer's website for the appropriate software to install for the GPIB hardware you are using. Some options may include installing one of the following software packages for your operating system,

or you may even want to build your own GPIB adaptor.

Debian/Ubuntu¤

If you are using Linux as your operating system, you may want to consider using the linux-gpib project to communicate with supported GPIB hardware.

Save the following bash script as, for example, install-linux-gpib.sh and (optionally) update the value of the VERSION parameter to be the latest linux-gpib release number.

install-linux-gpib.sh (click to expand)
#!/bin/bash

# The linux-gpib version to install (optional: update to be the latest release version)
VERSION="4.3.7"

# Prerequisites to build linux-gpib
sudo apt-get install --yes linux-headers-$(uname -r) wget automake libtool flex bison

# Download and extract the specified linux-gpib version
echo "Downloading linux-gpib-$VERSION.tar.gz source from https://sourceforge.net ..."
wget -q -O linux-gpib-$VERSION.tar.gz https://sourceforge.net/projects/linux-gpib/files/linux-gpib%20for%203.x.x%20and%202.6.x%20kernels/$VERSION/linux-gpib-$VERSION.tar.gz/download
tar -xf linux-gpib-$VERSION.tar.gz
cd linux-gpib-$VERSION

# Build and install the kernel files
tar -xf linux-gpib-kernel-$VERSION.tar.gz
cd linux-gpib-kernel-$VERSION
make
sudo make install
cd ..

# Build and install the user files
tar -xf linux-gpib-user-$VERSION.tar.gz
cd linux-gpib-user-$VERSION
./bootstrap
./configure --sysconfdir=/etc
make
sudo make install
sudo ldconfig

# Allow for access to the GPIB hardware without needing to be the root user
sudo addgroup gpib
sudo usermod -a -G gpib $(whoami)

echo "Installed, next steps:"
echo "1. Edit the value of 'board_type' in the 'interface' section of /etc/gpib.conf"
echo "   For the list of supported board types, see https://linux-gpib.sourceforge.io/doc_html/supported-hardware.html"
echo "   For example, for a NI GPIB-USB-HS+ controller set board_type = \"ni_usb_b\""
echo ""
echo "   $ sudo nano /etc/gpib.conf"
echo ""
echo "2. Plug in the GPIB-USB controller and make sure that it is listed as a USB device"
echo "   $ lsusb"
echo ""
echo "3. Check the GPIB configuration, the following command should run without displaying an error"
echo "   $ sudo gpib_config"
echo ""
echo "   If you get an error similar to:"
echo "     failed to configure boardtype: ni_pci"
echo "     failed to configure board"
echo "     main: Invalid argument"
echo "   that means you specified the wrong board_type in Step 1"
echo ""
echo "4. You may delete the linux-gpib-$VERSION directory and the linux-gpib-$VERSION.tar.gz file"

Make the script executable,

chmod +x ./install-linux-gpib.sh

then run it to install the linux-gpib driver and to allow for access to the GPIB hardware without needing to be the root user.

./install-linux-gpib.sh

GPIB (MessageBased) ¤

GPIB(equipment: Equipment)

Base class for GPIB communication.

Parameters:

Name Type Description Default
equipment Equipment

An Equipment instance.

required

A Connection instance supports the following properties for the GPIB communication protocol, as well as the properties defined in MessageBased.

Connection Properties:

Name Type Description
eos_mode int

Specifies the end-of-string character and mode (see eos for details). Default: 0

send_eoi bool

Whether to enable (True) or disable (False) the assertion of the EOI signal. Default: True

Source code in src/msl/equipment/interfaces/gpib.py
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
def __init__(self, equipment: Equipment) -> None:
    """Base class for GPIB communication.

    Args:
        equipment: An [Equipment][] instance.

    A [Connection][msl.equipment.schema.Connection] instance supports the following _properties_
    for the GPIB communication protocol, as well as the _properties_ defined in
    [MessageBased][msl.equipment.interfaces.message_based.MessageBased].

    Attributes: Connection Properties:
        eos_mode (int): Specifies the end-of-string character and mode
            (see [eos](https://linux-gpib.sourceforge.io/doc_html/reference-function-ibeos.html) for details).
            _Default: `0`_
        send_eoi (bool): Whether to enable (`True`) or disable (`False`) the assertion of the EOI signal.
            _Default: `True`_
    """
    self._own: bool = True
    self._handle: int = -1
    super().__init__(equipment)

    assert equipment.connection is not None  # noqa: S101
    info = parse_gpib_address(equipment.connection.address)
    if not info:
        msg = f"Invalid GPIB address {equipment.connection.address!r}"
        raise ValueError(msg)

    props = equipment.connection.properties
    _ = props.setdefault("read_termination", None)

    _load_library(self._error_check)
    assert GPIB.gpib_library is not None  # noqa: S101
    self._lib: Any = GPIB.gpib_library.lib

    if info.name:
        # a board or device object from a name in a gpib.conf file
        self._handle = self._get_ibfind_handle(info.name)
    elif info.pad is None:
        # a board object with the given board number
        self._handle = info.board
        self._own = False
    else:
        # a device object
        send_eoi = int(props.get("send_eoi", 1))
        eos_mode = int(props.get("eos_mode", 0))
        sad = 0 if info.sad is None else info.sad
        if sad != 0 and sad < 0x60:  # noqa: PLR2004
            sad += 0x60
        info.sad = sad
        timeout = _convert_timeout(props.get("timeout", None))
        self._handle = self._get_ibdev_handle(info.board, info.pad, sad, timeout, send_eoi, eos_mode)

    # keep this reference assignment after the if/else condition since the
    # value of the secondary address may have been updated
    self._address_info: ParsedGPIBAddress = info

    # check if the handle corresponds to a system controller (INTFC)
    self._is_board: bool
    try:
        self._is_board = bool(self.ask(0xA))  # IbaSC = 0xa
    except MSLConnectionError:
        # asking IbaSC for a GPIB device raises EHDL error
        self._is_board = False

    if not self._is_board:
        self._set_interface_timeout()

board property ¤

board: int

Returns the board descriptor (handle).

encoding property writable ¤

encoding: str

The encoding that is used for read and write operations.

equipment property ¤

equipment: Equipment

The Equipment associated with the interface.

handle property ¤

handle: int

Returns the handle of the instantiated board (INTFC) or device (INSTR).

max_read_size property writable ¤

max_read_size: int

The maximum number of bytes that can be read.

read_termination property writable ¤

read_termination: bytes | None

The termination character sequence that is used for the read method.

By default, reading stops when the EOI line is asserted.

rstrip property writable ¤

rstrip: bool

Whether to remove trailing whitespace from read messages.

timeout property writable ¤

timeout: float | None

The timeout, in seconds, for read and write operations.

A value <0 will set the timeout to be None (blocking mode).

write_termination property writable ¤

write_termination: bytes | None

The termination character sequence that is appended to write messages.

If you set the write_termination to be equal to a variable of type str, it will be encoded as bytes.

ask ¤

ask(option: int, *, handle: int | None = None) -> int

Get a GPIB configuration setting (board or device).

This method is the ibask function, it should not be confused with the query method.

Parameters:

Name Type Description Default
option int

A configuration setting to get the value of.

required
handle int | None

Board or device descriptor. Default is the handle of the instantiated class.

None

Returns:

Type Description
int

The value of the configuration setting.

Source code in src/msl/equipment/interfaces/gpib.py
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
def ask(self, option: int, *, handle: int | None = None) -> int:
    """Get a GPIB configuration setting (board or device).

    This method is the [ibask](https://linux-gpib.sourceforge.io/doc_html/reference-function-ibask.html)
    function, it should not be confused with the [query][msl.equipment.interfaces.message_based.MessageBased.query]
    method.

    Args:
        option: A configuration setting to get the value of.
        handle: Board or device descriptor. Default is the handle of the instantiated class.

    Returns:
        The value of the configuration setting.
    """
    if handle is None:
        handle = self._handle
    setting = c_int()
    self._lib.ibask(handle, option, byref(setting))
    return setting.value

clear ¤

clear(*, handle: int | None = None) -> int

Send the clear command (device).

This method is the ibclr function.

Parameters:

Name Type Description Default
handle int | None

Device descriptor. Default is the device handle of the instantiated class.

None

Returns:

Type Description
int

The status value (ibsta).

Source code in src/msl/equipment/interfaces/gpib.py
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
def clear(self, *, handle: int | None = None) -> int:
    """Send the clear command (device).

    This method is the [ibclr](https://linux-gpib.sourceforge.io/doc_html/reference-function-ibclr.html) function.

    Args:
        handle: Device descriptor. Default is the device handle of the instantiated class.

    Returns:
        The status value (`ibsta`).
    """
    if handle is None:
        handle = self._handle
    ibsta: int = self._lib.ibclr(handle)
    return ibsta

command ¤

command(data: bytes, *, handle: int | None = None) -> int

Write command bytes (board).

This method is the ibcmd function.

Parameters:

Name Type Description Default
data bytes

The commands to write to the bus.

required
handle int | None

Board descriptor. Default is the board handle of the instantiated class. The board must be the controller-in-charge.

None

Returns:

Type Description
int

The status value (ibsta).

Source code in src/msl/equipment/interfaces/gpib.py
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
def command(self, data: bytes, *, handle: int | None = None) -> int:
    """Write command bytes (board).

    This method is the [ibcmd](https://linux-gpib.sourceforge.io/doc_html/reference-function-ibcmd.html) function.

    Args:
        data: The [commands](https://linux-gpib.sourceforge.io/doc_html/gpib-protocol.html#REFERENCE-COMMAND-BYTES)
            to write to the bus.
        handle: Board descriptor. Default is the board handle of the instantiated class.
            The board must be the controller-in-charge.

    Returns:
        The status value (`ibsta`).
    """
    if handle is None:
        handle = self._address_info.board
    ibsta: int = self._lib.ibcmd(handle, data, len(data))
    return ibsta

config ¤

config(option: int, value: int, *, handle: int | None = None) -> int

Change configuration settings (board or device).

This method is the ibconfig function.

Parameters:

Name Type Description Default
option int

A configuration setting to change the value of.

required
value int

The new configuration setting value.

required
handle int | None

Board or device descriptor. Default is the handle of the instantiated class.

None

Returns:

Type Description
int

The status value (ibsta).

Source code in src/msl/equipment/interfaces/gpib.py
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
def config(self, option: int, value: int, *, handle: int | None = None) -> int:
    """Change configuration settings (board or device).

    This method is the [ibconfig](https://linux-gpib.sourceforge.io/doc_html/reference-function-ibconfig.html)
    function.

    Args:
        option: A configuration setting to change the value of.
        value: The new configuration setting value.
        handle: Board or device descriptor. Default is the handle of the instantiated class.

    Returns:
        The status value (`ibsta`).
    """
    if handle is None:
        handle = self._handle
    ibsta: int = self._lib.ibconfig(handle, option, value)
    return ibsta

control_atn ¤

control_atn(state: ATNState | str | int) -> int

Set the state of the GPIB Attention (ATN) line.

This method mimics the PyVISA-py implementation.

Parameters:

Name Type Description Default
state ATNState | str | int

The state of the ATN line of the active controller. Can be an enum member name (case insensitive) or value.

required

Returns:

Type Description
int

The status value (ibsta).

Source code in src/msl/equipment/interfaces/gpib.py
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
def control_atn(self, state: ATNState | str | int) -> int:
    """Set the state of the GPIB Attention (ATN) line.

    This method mimics the PyVISA-py implementation.

    Args:
        state: The state of the ATN line of the active controller. Can be
            an enum member name (case insensitive) or value.

    Returns:
        The status value (`ibsta`).
    """
    handle = self._address_info.board
    atn = to_enum(state, ATNState, to_upper=True)
    if atn == ATNState.ASSERT:
        return int(self._lib.ibcac(handle, 0))
    if atn == ATNState.DEASSERT:
        return int(self._lib.ibgts(handle, 0))
    if atn == ATNState.ASSERT_IMMEDIATE:
        return int(self._lib.ibcac(handle, 1))
    return int(self._lib.ibgts(handle, 1))  # ATNState.DEASSERT_HANDSHAKE

control_ren ¤

control_ren(mode: RENMode | str | int) -> int

Controls the state of the GPIB Remote Enable (REN) line.

Optionally the remote/local state of the device is also controlled.

This method mimics the PyVISA-py implementation.

Parameters:

Name Type Description Default
mode RENMode | str | int

The mode of the REN line and optionally the device remote/local state. Can be an enum member name (case insensitive) or value. Allowed values are:

required

Returns:

Type Description
int

The status value (ibsta).

Source code in src/msl/equipment/interfaces/gpib.py
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
def control_ren(self, mode: RENMode | str | int) -> int:
    """Controls the state of the GPIB Remote Enable (REN) line.

    Optionally the remote/local state of the device is also controlled.

    This method mimics the PyVISA-py implementation.

    Args:
        mode: The mode of the REN line and optionally the device remote/local state.
            Can be an enum member name (case insensitive) or value.
            Allowed values are:

    Returns:
        The status value (`ibsta`).
    """
    ibsta = 0
    ren = to_enum(mode, RENMode, to_upper=True)

    if self._is_board and ren not in (RENMode.ASSERT, RENMode.DEASSERT, RENMode.ASSERT_LLO):
        msg = f"Invalid mode {ren!r} for INTFC"
        raise MSLConnectionError(self, msg)

    if ren == RENMode.DEASSERT_GTL:
        ibsta |= self.command(b"\x01")  # GTL = 0x1

    if ren in {RENMode.DEASSERT, RENMode.DEASSERT_GTL}:
        ibsta |= self.remote_enable(state=False)

    if ren == RENMode.ASSERT_LLO:
        ibsta |= self.command(b"\x11")  # LLO = 0x11
    elif ren == RENMode.ADDRESS_GTL:
        ibsta |= self.command(b"\x01")  # GTL = 0x1
    elif ren == RENMode.ASSERT_ADDRESS_LLO:
        pass
    elif ren in {RENMode.ASSERT, RENMode.ASSERT_ADDRESS}:
        ibsta |= self.remote_enable(state=True)
        if not self._is_board and ren == RENMode.ASSERT_ADDRESS:
            assert self._address_info.pad is not None  # noqa: S101
            _ = self.listener(self._address_info.pad, sad=self._address_info.sad or 0)

    return ibsta

count ¤

count() -> int

Get the number of bytes sent or received.

This method is the ibcntl function.

Returns:

Type Description
int

The number of bytes sent or received.

Source code in src/msl/equipment/interfaces/gpib.py
633
634
635
636
637
638
639
640
641
def count(self) -> int:
    """Get the number of bytes sent or received.

    This method is the [ibcntl](https://linux-gpib.sourceforge.io/doc_html/reference-globals-ibcnt.html) function.

    Returns:
        The number of bytes sent or received.
    """
    return int(self._lib.ibcntl())

disconnect ¤

disconnect() -> None

Close the GPIB connection.

Source code in src/msl/equipment/interfaces/gpib.py
643
644
645
646
647
648
649
def disconnect(self) -> None:  # pyright: ignore[reportImplicitOverride]
    """Close the GPIB connection."""
    if self._own and self._handle > 0:
        with contextlib.suppress(MSLConnectionError):
            _ = self.online(state=False, handle=self._handle)
        self._handle = -1
        super().disconnect()

interface_clear ¤

interface_clear(*, handle: int | None = None) -> int

Perform interface clear (board).

Resets the GPIB bus by asserting the interface clear (IFC) bus line for a duration of at least 100 microseconds.

This method is the ibsic function.

Parameters:

Name Type Description Default
handle int | None

Board descriptor. Default is the board handle of the instantiated class.

None

Returns:

Type Description
int

The status value (ibsta).

Source code in src/msl/equipment/interfaces/gpib.py
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
def interface_clear(self, *, handle: int | None = None) -> int:
    """Perform interface clear (board).

    Resets the GPIB bus by asserting the *interface clear* (IFC) bus line for a duration of at
    least 100 microseconds.

    This method is the [ibsic](https://linux-gpib.sourceforge.io/doc_html/reference-function-ibsic.html)
    function.

    Args:
        handle: Board descriptor. Default is the board handle of the instantiated class.

    Returns:
        The status value (`ibsta`).
    """
    if handle is None:
        handle = self._address_info.board
    ibsta: int = self._lib.ibsic(handle)
    return ibsta

lines ¤

lines(*, handle: int | None = None) -> int

Returns the status of the control and handshaking bus lines (board).

This method is the iblines function.

Parameters:

Name Type Description Default
handle int | None

Board descriptor. Default is the board handle of the instantiated class.

None

Returns:

Type Description
int

The status of the control and handshaking bus lines.

Source code in src/msl/equipment/interfaces/gpib.py
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
def lines(self, *, handle: int | None = None) -> int:
    """Returns the status of the control and handshaking bus lines (board).

    This method is the [iblines](https://linux-gpib.sourceforge.io/doc_html/reference-function-iblines.html)
    function.

    Args:
        handle: Board descriptor. Default is the board handle of the instantiated class.

    Returns:
        The status of the control and handshaking bus lines.
    """
    if handle is None:
        handle = self._address_info.board
    status = c_short()
    self._lib.iblines(handle, byref(status))
    return status.value

listener ¤

listener(pad: int, sad: int = 0, *, handle: int | None = None) -> bool

Check if a listener is present (board or device).

This method is the ibln function.

Parameters:

Name Type Description Default
pad int

Primary address of the GPIB device.

required
sad int

Secondary address of the GPIB device.

0
handle int | None

Board or device descriptor. Default is the handle of the instantiated class.

None

Returns:

Type Description
bool

Whether a listener is present.

Source code in src/msl/equipment/interfaces/gpib.py
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
def listener(self, pad: int, sad: int = 0, *, handle: int | None = None) -> bool:
    """Check if a listener is present (board or device).

    This method is the [ibln](https://linux-gpib.sourceforge.io/doc_html/reference-function-ibln.html)
    function.

    Args:
        pad: Primary address of the GPIB device.
        sad: Secondary address of the GPIB device.
        handle: Board or device descriptor. Default is the handle of the instantiated class.

    Returns:
        Whether a listener is present.
    """
    if handle is None:
        handle = self._handle
    listener = c_short()
    self._lib.ibln(handle, pad, sad, byref(listener))
    return bool(listener.value)

local ¤

local(*, handle: int | None = None) -> int

Go to local mode (board or device).

This method is the ibloc function.

Parameters:

Name Type Description Default
handle int | None

Board or device descriptor. Default is the handle of the instantiated class.

None

Returns:

Type Description
int

The status value (ibsta).

Source code in src/msl/equipment/interfaces/gpib.py
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
def local(self, *, handle: int | None = None) -> int:
    """Go to local mode (board or device).

    This method is the [ibloc](https://linux-gpib.sourceforge.io/doc_html/reference-function-ibloc.html)
    function.

    Args:
        handle: Board or device descriptor. Default is the handle of the instantiated class.

    Returns:
        The status value (`ibsta`).
    """
    if handle is None:
        handle = self._handle
    ibsta: int = self._lib.ibloc(handle)
    return ibsta

online ¤

online(*, state: bool, handle: int | None = None) -> int

Close or reinitialize descriptor (board or device).

This method is the ibonl function.

If you want to close the connection for the GPIB board or device that was instantiated, use disconnect.

Parameters:

Name Type Description Default
state bool

If False, closes the connection. If True, then all settings associated with the descriptor (GPIB address, end-of-string mode, timeout, etc.) are reset to their default values. The default values are the settings the descriptor had when it was first obtained.

required
handle int | None

Board or device descriptor. Default is the handle of the instantiated class.

None

Returns:

Type Description
int

The status value (ibsta).

Source code in src/msl/equipment/interfaces/gpib.py
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
def online(self, *, state: bool, handle: int | None = None) -> int:
    """Close or reinitialize descriptor (board or device).

    This method is the [ibonl](https://linux-gpib.sourceforge.io/doc_html/reference-function-ibonl.html)
    function.

    If you want to close the connection for the GPIB board or device that was instantiated,
    use [disconnect][msl.equipment.interfaces.gpib.GPIB.disconnect].

    Args:
        state: If `False`, closes the connection. If `True`, then all settings associated with the
            descriptor (GPIB address, end-of-string mode, timeout, etc.) are reset to their *default*
            values. The *default* values are the settings the descriptor had when it was first obtained.
        handle: Board or device descriptor. Default is the handle of the instantiated class.

    Returns:
        The status value (`ibsta`).
    """
    if handle is None:
        handle = self._handle
    ibsta: int = self._lib.ibonl(handle, int(state))
    return ibsta

pass_control ¤

pass_control(
    *,
    handle: int | None = None,
    name: str | None = None,
    board: int | None = None,
    pad: int = 0,
    sad: int | None = None
) -> int

Set a GPIB board or device to become the controller-in-charge (CIC).

This method is the ibpct function.

If no arguments are specified, the instantiated class becomes the CIC.

Parameters:

Name Type Description Default
handle int | None

Board or device descriptor. If specified, name, board, pad and sad are ignored.

None
name str | None

The name of a GPIB board or device. If specified, board, pad and sad are ignored.

None
board int | None

Index of the GPIB interface board.

None
pad int

Primary address of the GPIB device.

0
sad int | None

Secondary address of the GPIB device.

None

Returns:

Type Description
int

The handle of the board or device that became CIC.

Source code in src/msl/equipment/interfaces/gpib.py
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
def pass_control(
    self,
    *,
    handle: int | None = None,
    name: str | None = None,
    board: int | None = None,
    pad: int = 0,
    sad: int | None = None,
) -> int:
    """Set a GPIB board or device to become the controller-in-charge (CIC).

    This method is the [ibpct](https://linux-gpib.sourceforge.io/doc_html/reference-function-ibpct.html)
    function.

    If no arguments are specified, the instantiated class becomes the CIC.

    Args:
        handle: Board or device descriptor. If specified, `name`, `board`, `pad` and `sad` are ignored.
        name: The name of a GPIB board or device. If specified, `board`, `pad` and `sad` are ignored.
        board: Index of the GPIB interface board.
        pad: Primary address of the GPIB device.
        sad: Secondary address of the GPIB device.

    Returns:
        The handle of the board or device that became CIC.
    """
    if handle is not None:
        pass
    elif name is not None:
        handle = self._get_ibfind_handle(name)
    elif board is not None:
        if sad is None:
            sad = 0xFFFF  # NO_SEC_ADDR
        handle = self._get_ibdev_handle(board, pad, sad, 13, 1, 0)  # T10s = 13
    else:
        handle = self._handle

    self._lib.ibpct(handle)
    return handle

query ¤

query(
    message: bytes | str,
    *,
    delay: float = 0.0,
    decode: Literal[True] = True,
    dtype: None = None,
    fmt: MessageFormat = ...,
    size: int | None = ...
) -> str
query(
    message: bytes | str,
    *,
    delay: float = 0.0,
    decode: Literal[False] = False,
    dtype: None = None,
    fmt: MessageFormat = ...,
    size: int | None = ...
) -> bytes
query(
    message: bytes | str,
    *,
    delay: float = 0.0,
    decode: bool = ...,
    dtype: MessageDataType = ...,
    fmt: MessageFormat = ...,
    size: int | None = ...
) -> NumpyArray1D
query(
    message: bytes | str,
    *,
    delay: float = 0.0,
    decode: bool = True,
    dtype: MessageDataType | None = None,
    fmt: MessageFormat = None,
    size: int | None = None
) -> bytes | str | NumpyArray1D

Convenience method for performing a write followed by a read.

Parameters:

Name Type Description Default
message bytes | str

The message to write to the equipment.

required
delay float

Time delay, in seconds, to wait between the write and read operations.

0.0
decode bool

Whether to decode the returned message (i.e., convert the message to a str) or keep the message as bytes. Ignored if dtype is not None.

True
dtype MessageDataType | None

The data type of the elements in the returned message. Can be any object that numpy dtype supports. For messages that are of scalar type (i.e., a single number) it is more efficient to not specify dtype but to pass the returned message to the int or float class to convert the message to the appropriate numeric type. See MessageDataType for more details.

None
fmt MessageFormat

The format that the returned message data is in. Ignored if dtype is None. See MessageFormat for more details.

None
size int | None

The number of bytes to read. Ignored if the value is None.

None

Returns:

Type Description
bytes | str | NumpyArray1D

The message from the equipment. If dtype is specified, then the message is returned as a numpy ndarray, if decode is True then the message is returned as a str, otherwise the message is returned as bytes.

Source code in src/msl/equipment/interfaces/message_based.py
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
def query(
    self,
    message: bytes | str,
    *,
    delay: float = 0.0,
    decode: bool = True,
    dtype: MessageDataType | None = None,
    fmt: MessageFormat = None,
    size: int | None = None,
) -> bytes | str | NumpyArray1D:
    """Convenience method for performing a [write][msl.equipment.interfaces.message_based.MessageBased.write]
    followed by a [read][msl.equipment.interfaces.message_based.MessageBased.read].

    Args:
        message: The message to write to the equipment.
        delay: Time delay, in seconds, to wait between the _write_ and _read_ operations.
        decode: Whether to decode the returned message (i.e., convert the message to a [str][])
            or keep the message as [bytes][]. Ignored if `dtype` is not `None`.
        dtype: The data type of the elements in the returned message. Can be any object that numpy
            [dtype][numpy.dtype] supports. For messages that are of scalar type (i.e., a single number)
            it is more efficient to not specify `dtype` but to pass the returned message to the
            [int][] or [float][] class to convert the message to the appropriate numeric type.
            See [MessageDataType][msl.equipment._types.MessageDataType] for more details.
        fmt: The format that the returned message data is in. Ignored if `dtype` is `None`.
            See [MessageFormat][msl.equipment._types.MessageFormat] for more details.
        size: The number of bytes to read. Ignored if the value is `None`.

    Returns:
        The message from the equipment. If `dtype` is specified, then the message is
            returned as a numpy [ndarray][numpy.ndarray], if `decode` is `True` then the message
            is returned as a [str][], otherwise the message is returned as [bytes][].
    """  # noqa: D205
    _ = self.write(message)
    if delay > 0:
        time.sleep(delay)
    if dtype:
        return self.read(dtype=dtype, fmt=fmt, size=size)
    return self.read(decode=decode, size=size)

read ¤

read(
    *,
    decode: Literal[True] = True,
    dtype: None = None,
    fmt: MessageFormat = ...,
    size: int | None = ...
) -> str
read(
    *,
    decode: Literal[False] = False,
    dtype: None = None,
    fmt: MessageFormat = ...,
    size: int | None = ...
) -> bytes
read(
    *,
    decode: bool = ...,
    dtype: MessageDataType = ...,
    fmt: MessageFormat = ...,
    size: int | None = ...
) -> NumpyArray1D
read(
    *,
    decode: bool = True,
    dtype: MessageDataType | None = None,
    fmt: MessageFormat = None,
    size: int | None = None
) -> bytes | str | NumpyArray1D

Read a message from the equipment.

This method will block until one of the following conditions is fulfilled:

  1. size bytes have been received — only if size is not None.
  2. the read_termination byte(s) is(are) received — only if read_termination is not None.
  3. a timeout occurs — only if timeout is not None. If a timeout occurs, an MSLTimeoutError is raised.
  4. max_read_size bytes have been received. If the maximum number of bytes have been read, an MSLConnectionError is raised.

Tip

You may also want to set the rstrip value for the class instance.

Parameters:

Name Type Description Default
decode bool

Whether to decode the message (i.e., convert the message to a str) or keep the message as bytes. Ignored if dtype is not None.

True
dtype MessageDataType | None

The data type of the elements in the returned message. Can be any object that numpy dtype supports. For messages that are of scalar type (i.e., a single number) it is more efficient to not specify dtype but to pass the returned message to the int or float class to convert the message to the appropriate numeric type. See MessageDataType for more details.

None
fmt MessageFormat

The format that the returned message data is in. Ignored if dtype is None. See MessageFormat for more details.

None
size int | None

The number of bytes to read. Ignored if the value is None.

None

Returns:

Type Description
bytes | str | NumpyArray1D

The message from the equipment. If dtype is specified, then the message is returned as a numpy ndarray, if decode is True then the message is returned as a str, otherwise the message is returned as bytes.

Source code in src/msl/equipment/interfaces/message_based.py
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
def read(
    self,
    *,
    decode: bool = True,
    dtype: MessageDataType | None = None,
    fmt: MessageFormat = None,
    size: int | None = None,
) -> bytes | str | NumpyArray1D:
    """Read a message from the equipment.

    This method will block until one of the following conditions is fulfilled:

    1. `size` bytes have been received &mdash; only if `size` is not `None`.
    2. the [read_termination][msl.equipment.interfaces.message_based.MessageBased.read_termination]
       byte(s) is(are) received &mdash; only if
       [read_termination][msl.equipment.interfaces.message_based.MessageBased.read_termination]
       is not `None`.
    3. a timeout occurs &mdash; only if [timeout][msl.equipment.interfaces.message_based.MessageBased.timeout]
       is not `None`. If a timeout occurs, an
       [MSLTimeoutError][msl.equipment.interfaces.message_based.MSLTimeoutError] is raised.
    4. [max_read_size][msl.equipment.interfaces.message_based.MessageBased.max_read_size]
       bytes have been received. If the maximum number of bytes have been read, an
       [MSLConnectionError][msl.equipment.interfaces.message_based.MSLConnectionError] is raised.

    !!! tip
        You may also want to set the [rstrip][msl.equipment.interfaces.message_based.MessageBased.rstrip]
        value for the class instance.

    Args:
        decode: Whether to decode the message (i.e., convert the message to a [str][])
            or keep the message as [bytes][]. Ignored if `dtype` is not `None`.
        dtype: The data type of the elements in the returned message. Can be any object that numpy
            [dtype][numpy.dtype] supports. For messages that are of scalar type (i.e., a single number)
            it is more efficient to not specify `dtype` but to pass the returned message to the
            [int][] or [float][] class to convert the message to the appropriate numeric type.
            See [MessageDataType][msl.equipment._types.MessageDataType] for more details.
        fmt: The format that the returned message data is in. Ignored if `dtype` is `None`.
            See [MessageFormat][msl.equipment._types.MessageFormat] for more details.
        size: The number of bytes to read. Ignored if the value is `None`.

    Returns:
        The message from the equipment. If `dtype` is specified, then the message is returned
            as a numpy [ndarray][numpy.ndarray], if `decode` is `True` then the message
            is returned as a [str][], otherwise the message is returned as [bytes][].
    """
    if size is not None and size > self._max_read_size:
        msg = f"max_read_size is {self._max_read_size} bytes, requesting {size} bytes"
        raise MSLConnectionError(self, msg)

    try:
        message = self._read(size)
    except (serial.SerialTimeoutException, socket.timeout, TimeoutError, USBTimeoutError):
        raise MSLTimeoutError(self) from None
    except Exception as e:  # noqa: BLE001
        msg = f"{e.__class__.__name__}: {e}"
        raise MSLConnectionError(self, msg) from None

    if size is None:
        if dtype:
            logger.debug("%s.read(dtype=%r, fmt=%r) -> %r", self, dtype, fmt, message)
        else:
            logger.debug("%s.read() -> %r", self, message)
    else:
        if len(message) != size:
            msg = f"received {len(message)} bytes, requested {size} bytes"
            raise MSLConnectionError(self, msg)
        logger.debug("%s.read(size=%s) -> %r", self, size, message)

    if self._rstrip:
        message = message.rstrip()

    if dtype:
        return from_bytes(message, fmt=fmt, dtype=dtype)

    if decode:
        return message.decode(encoding=self._encoding)

    return message

remote_enable ¤

remote_enable(state: bool, *, handle: int | None = None) -> int

Set remote enable (board).

This method is the ibsre function.

Parameters:

Name Type Description Default
state bool

If True, the board asserts the REN line. Otherwise, the REN line is not asserted. The board must be the system controller.

required
handle int | None

Board descriptor. Default is the board handle of the instantiated class.

None

Returns:

Type Description
int

The status value (ibsta).

Source code in src/msl/equipment/interfaces/gpib.py
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
def remote_enable(self, state: bool, *, handle: int | None = None) -> int:  # noqa: FBT001
    """Set remote enable (board).

    This method is the [ibsre](https://linux-gpib.sourceforge.io/doc_html/reference-function-ibsre.html)
    function.

    Args:
        state: If `True`, the board asserts the REN line. Otherwise, the REN line is not asserted.
            The board must be the system controller.
        handle: Board descriptor. Default is the board handle of the instantiated class.

    Returns:
        The status value (`ibsta`).
    """
    # ibsre was removed from ni4882.dll, use ibconfig instead (IbcSRE = 0xb)
    if handle is None:
        handle = self._address_info.board
    return self.config(0xB, int(state), handle=handle)

serial_poll ¤

serial_poll(*, handle: int | None = None) -> int

Read status byte / serial poll (device).

This method is the ibrsp function.

Parameters:

Name Type Description Default
handle int | None

Device descriptor. Default is the device handle of the instantiated class.

None

Returns:

Type Description
int

The status byte.

Source code in src/msl/equipment/interfaces/gpib.py
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
def serial_poll(self, *, handle: int | None = None) -> int:
    """Read status byte / serial poll (device).

    This method is the [ibrsp](https://linux-gpib.sourceforge.io/doc_html/reference-function-ibrsp.html)
    function.

    Args:
        handle: Device descriptor. Default is the device handle of the instantiated class.

    Returns:
        The status byte.
    """
    if handle is None:
        handle = self._handle
    status = c_ubyte()
    self._lib.ibrsp(handle, byref(status))
    return status.value

spoll_bytes ¤

spoll_bytes(*, handle: int | None = None) -> int

Get the length of the serial poll bytes queue (device).

This method is the ibspb function.

Parameters:

Name Type Description Default
handle int | None

Device descriptor. Default is the device handle of the instantiated class.

None

Returns:

Type Description
int

The number of serial poll bytes queued for the device.

Source code in src/msl/equipment/interfaces/gpib.py
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
def spoll_bytes(self, *, handle: int | None = None) -> int:
    """Get the length of the serial poll bytes queue (device).

    This method is the [ibspb](https://linux-gpib.sourceforge.io/doc_html/reference-function-ibspb.html)
    function.

    Args:
        handle: Device descriptor. Default is the device handle of the instantiated class.

    Returns:
        The number of serial poll bytes queued for the device.
    """
    if handle is None:
        handle = self._handle
    length = c_short()
    self._lib.ibspb(handle, byref(length))
    return length.value

status ¤

status() -> int

Get the status value ibsta.

Returns:

Type Description
int

The status value.

Source code in src/msl/equipment/interfaces/gpib.py
873
874
875
876
877
878
879
880
def status(self) -> int:
    """Get the status value [ibsta](https://linux-gpib.sourceforge.io/doc_html/reference-globals-ibsta.html).

    Returns:
        The status value.
    """
    status: int = self._lib.ThreadIbsta()
    return status

trigger ¤

trigger(*, handle: int | None = None) -> int

Trigger a device (device).

This method is the ibtrg function.

Parameters:

Name Type Description Default
handle int | None

Device descriptor. Default is the device handle of the instantiated class.

None

Returns:

Type Description
int

The status value (ibsta).

Source code in src/msl/equipment/interfaces/gpib.py
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
def trigger(self, *, handle: int | None = None) -> int:
    """Trigger a device (device).

    This method is the [ibtrg](https://linux-gpib.sourceforge.io/doc_html/reference-function-ibtrg.html)
    function.

    Args:
        handle: Device descriptor. Default is the device handle of the instantiated class.

    Returns:
        The status value (`ibsta`).
    """
    if handle is None:
        handle = self._handle
    ibsta: int = self._lib.ibtrg(handle)
    return ibsta

version ¤

version() -> str

Get the version of the GPIB library.

Returns:

Type Description
str

The version number (if using the linux-gpib library), otherwise an empty string.

Source code in src/msl/equipment/interfaces/gpib.py
899
900
901
902
903
904
905
906
907
908
909
910
911
def version(self) -> str:
    """Get the version of the GPIB library.

    Returns:
        The version number (if using the `linux-gpib` library), otherwise an empty string.
    """
    try:
        version = c_char_p()
        self._lib.ibvers(byref(version))
        assert version.value is not None  # noqa: S101
        return version.value.decode()
    except AttributeError:
        return ""

wait ¤

wait(mask: int, *, handle: int | None = None) -> int

Wait for an event (board or device).

This method is the ibwait function.

Parameters:

Name Type Description Default
mask int

Wait until one of the conditions specified in mask is true.

required
handle int | None

Board or device descriptor. Default is the handle of the instantiated class.

None

Returns:

Type Description
int

The status value (ibsta).

Source code in src/msl/equipment/interfaces/gpib.py
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
def wait(self, mask: int, *, handle: int | None = None) -> int:
    """Wait for an event (board or device).

    This method is the [ibwait](https://linux-gpib.sourceforge.io/doc_html/reference-function-ibwait.html)
    function.

    Args:
        mask: Wait until one of the conditions specified in `mask` is true.
        handle: Board or device descriptor. Default is the handle of the instantiated class.

    Returns:
        The status value (`ibsta`).
    """
    if handle is None:
        handle = self._handle
    ibsta: int = self._lib.ibwait(handle, mask)
    return ibsta

wait_for_srq ¤

wait_for_srq(*, handle: int | None = None) -> int

Wait for the SRQ interrupt (SRQI, 0x1000) line to be asserted (board).

This method will return when the board receives a service request from any device. If there are multiple devices connected to the board, you must determine which device asserted the service request.

Parameters:

Name Type Description Default
handle int | None

Board descriptor. Default is the board handle of the instantiated class.

None

Returns:

Type Description
int

The status value (ibsta).

Source code in src/msl/equipment/interfaces/gpib.py
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
def wait_for_srq(self, *, handle: int | None = None) -> int:
    """Wait for the SRQ interrupt (SRQI, 0x1000) line to be asserted (board).

    This method will return when the board receives a service request from *any* device.
    If there are multiple devices connected to the board, you must determine which
    device asserted the service request.

    Args:
        handle: Board descriptor. Default is the board handle of the instantiated class.

    Returns:
        The status value (`ibsta`).
    """
    if handle is None:
        handle = self._address_info.board
    return self.wait(0x1000, handle=handle)  # SRQI = 0x1000

write ¤

write(
    message: bytes | str,
    *,
    data: Sequence1D | None = None,
    dtype: MessageDataType = "<f",
    fmt: MessageFormat = "ieee"
) -> int

Write a message to the equipment.

Parameters:

Name Type Description Default
message bytes | str

The message to write to the equipment.

required
data Sequence1D | None

The data to append to message.

None
dtype MessageDataType

The data type to use to convert each element in data to bytes. Ignored if data is None. See MessageDataType for more details.

'<f'
fmt MessageFormat

The format to use to convert data to bytes. Ignored if data is None. See MessageFormat for more details.

'ieee'

Returns:

Type Description
int

The number of bytes written.

Source code in src/msl/equipment/interfaces/message_based.py
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
def write(
    self,
    message: bytes | str,
    *,
    data: Sequence1D | None = None,
    dtype: MessageDataType = "<f",
    fmt: MessageFormat = "ieee",
) -> int:
    """Write a message to the equipment.

    Args:
        message: The message to write to the equipment.
        data: The data to append to `message`.
        dtype: The data type to use to convert each element in `data` to bytes. Ignored
            if `data` is `None`. See [MessageDataType][msl.equipment._types.MessageDataType]
            for more details.
        fmt: The format to use to convert `data` to bytes. Ignored if `data` is `None`.
            See [MessageFormat][msl.equipment._types.MessageFormat] for more details.

    Returns:
        The number of bytes written.
    """
    if not isinstance(message, bytes):
        message = message.encode(encoding=self._encoding)

    if data is not None:
        message += to_bytes(data, fmt=fmt, dtype=dtype)

    if self._write_termination and not message.endswith(self._write_termination):
        message += self._write_termination

    logger.debug("%s.write(%r)", self, message)

    try:
        return self._write(message)
    except (serial.SerialTimeoutException, socket.timeout, TimeoutError, USBTimeoutError):
        raise MSLTimeoutError(self) from None
    except Exception as e:  # noqa: BLE001
        raise MSLConnectionError(self, str(e)) from None

write_async ¤

write_async(message: bytes, *, handle: int | None = None) -> int

Write a message asynchronously (board or device).

This method is the ibwrta function.

Parameters:

Name Type Description Default
message bytes

The data to send.

required
handle int | None

Board or device descriptor. Default is the handle of the instantiated class.

None

Returns:

Type Description
int

The status value (ibsta).

Source code in src/msl/equipment/interfaces/gpib.py
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
def write_async(self, message: bytes, *, handle: int | None = None) -> int:
    """Write a message asynchronously (board or device).

    This method is the [ibwrta](https://linux-gpib.sourceforge.io/doc_html/reference-function-ibwrta.html) function.

    Args:
        message: The data to send.
        handle: Board or device descriptor. Default is the handle of the instantiated class.

    Returns:
        The status value (`ibsta`).
    """
    if handle is None:
        handle = self._handle
    ibsta: int = self._lib.ibwrta(handle, message, len(message))
    return ibsta