# coding: utf-8
from time import time
from typing import List
import logging
from warnings import warn
from .meta_inout import InOut
from .._global import OptionalModule
try:
import serial
except (ModuleNotFoundError, ImportError):
serial = OptionalModule("pyserial")
[docs]
class Agilent34420a(InOut):
"""This class can read resistance and voltage values from an Agilent 34420A
multimeter.
It communicates over serial.
May also work on similar devices from the same manufacturer, although that
was not tested.
.. versionadded:: 1.4.0
"""
[docs]
def __init__(self,
mode: bytes = b"VOLT",
device: str = '/dev/ttyUSB0',
baudrate: int = 9600,
timeout: float = 1) -> None:
"""Sets the arguments and initializes the parent class.
Args:
mode: Measurement mode, as :obj:`bytes`. Should be either `b'VOLT'` or
`b'RES'`.
device: Path to the serial port to open, as a :obj:`str`.
baudrate: Desired baudrate for serial communication.
timeout: Timeout for the serial connection, as a :obj:`float`.
"""
warn(f"Starting from version 2.1.0, {type(self).__name__} will be moved "
f"to crappy.collection. Your code that uses it will still work as "
f"is, except you will now need to import crappy.collection at the "
f"top of your script.", FutureWarning)
self._ser = None
super().__init__()
self._device = device
self._baudrate = baudrate
self._timeout = timeout
self._mode = mode
[docs]
def open(self) -> None:
"""Opens the serial connection, resets the Agilent and configures it to the
desired mode."""
self.log(logging.INFO, f"Opening the serial port {self._device} with "
f"baudrate {self._baudrate}")
self._ser = serial.Serial(port=self._device, baudrate=self._baudrate,
timeout=self._timeout)
self.log(logging.DEBUG, f"Writing b'*RST;*CLS;*OPC?\\n' to port "
f"{self._device}")
self._ser.write(b"*RST;*CLS;*OPC?\n")
self.log(logging.DEBUG, f"Writing b'SENS:FUNC \"{self._mode}\"; \\n' "
f"to port {self._device}")
self._ser.write(b"SENS:FUNC \"" + self._mode + b"\"; \n")
self.log(logging.DEBUG, f"Writing b'SENS:{self._mode}:NPLC 2 \\n' "
f"to port {self._device}")
self._ser.write(b"SENS:" + self._mode + b":NPLC 2 \n")
self.log(logging.DEBUG, f"Writing b'SYST:REM\\n' to port {self._device}")
self._ser.write(b"SYST:REM\n")
[docs]
def get_data(self) -> List[float]:
"""Asks the Agilent to acquire a value and returns it, except if an error
occurs in which case `0` is returned."""
self.log(logging.DEBUG, f"Writing b'READ? \\n' to port {self._device}")
self._ser.write(b"READ? \n")
t = time()
try:
return [t, float(self._ser.readline())]
except (serial.SerialException, ValueError):
self._ser.flush()
return [t, 0]
[docs]
def close(self) -> None:
"""Closes the serial port."""
if self._ser is not None:
self.log(logging.INFO, f"Closing the serial port {self._device}")
self._ser.close()