In / Out

Regular In/Outs

ADS1115

class crappy.inout.ADS1115(backend: str, device_address: int = 72, i2c_port: int = 1, sample_rate: int = 128, v_range: float = 2.048, multiplexer: str = 'A1', dry_pin: int | None = None, gain: float = 1, offset: float = 0)[source]

A class for controlling Adafruit’s ADS1115 16-bits ADC.

The ADS1115 InOut is meant for reading conversion values from a 16-bits ADS1115 ADC, using the I2C protocol. The output is in Volts by default, but a gain and an offset can be specified.

Various settings can be adjusted, like the sample rate, the input mode or the voltage range.

New in version 1.4.0.

Changed in version 2.0.0: renamed from Ads1115 to ADS1115

__init__(backend: str, device_address: int = 72, i2c_port: int = 1, sample_rate: int = 128, v_range: float = 2.048, multiplexer: str = 'A1', dry_pin: int | None = None, gain: float = 1, offset: float = 0) None[source]

Checks the validity of the arguments.

Parameters:
  • backend

    The backend for communicating with the ADS1115. Should be one of:

    'Pi4', 'blinka'
    

    The ‘Pi4’ backend is optimized but only works on boards supporting the smbus2 module, like the Raspberry Pis. The ‘blinka’ backend may be less performant and requires installing Adafruit-Blinka and adafruit-circuitpython-ads1x15, but these modules are compatible with and maintained on a wide variety of boards.

  • device_address – The I2C address of the ADS1115. The default address is 0x48, but it is possible to change this setting using the ADDR pin.

  • i2c_port – The I2C port over which the ADS1115 should communicate. On most Raspberry Pi models the default I2C port is 1.

  • sample_rate

    The sample rate for data conversion (in SPS). The available sample rates are:

    8, 16, 32, 64, 128, 250, 475, 860
    

  • v_range

    The value (in Volts) of the measured signal corresponding to the 0x7FFF output in bits, i.e. that saturates the sensor. A signal of -v_range Volts gives a 0x8000 output in bits. Available v_range values are:

    0.256, 0.512, 1.024, 2.048, 4.096, 6.144
    

  • multiplexer

    Choice of the inputs to consider. Single-input modes actually measure Ax - GND. The available multiplexer values are:

    'A0', 'A1', 'A2', 'A3',
    'A0 - A1',
    'A0 - A3',
    'A1 - A3',
    'A2 - A3'
    

  • dry_pin

    Optionally, reads the end of conversion signal from a GPIO rather than from an I2C message. Speeds up the reading and decreases the traffic on the I2C bus, but requires one extra wire. With the backend ‘Pi4’, give the index of the GPIO in BCM convention. This feature is not available with the ‘blinka’ backend.

    New in version 1.5.8.

  • gain – Allows to tune the output value according to the formula : \(output = gain * tension + offset\).

  • offset – Allows to tune the output value according to the formula : \(output = gain * tension + offset\).

Warning

AINx voltages should not be higher than VDD+0.3V nor lower than GND-0.3V. Setting high v_range values does not allow measuring voltages higher than VDD !!

Removed in version 2.0.0: ft232h_ser_num argument

open() None[source]

Initializes the I2C communication and the device.

get_data() List[float][source]

Reads the registers containing the conversion result.

The output is in Volts, unless a gain and offset are applied.

Returns:

A list containing the timestamp and the voltage value.

close() None[source]

Closes the I2C bus.

Agilent 34420A

class crappy.inout.Agilent34420a(mode: bytes = b'VOLT', device: str = '/dev/ttyUSB0', baudrate: int = 9600, timeout: float = 1)[source]

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.

New in version 1.4.0.

__init__(mode: bytes = b'VOLT', device: str = '/dev/ttyUSB0', baudrate: int = 9600, timeout: float = 1) None[source]

Sets the arguments and initializes the parent class.

Parameters:
  • mode – Measurement mode, as bytes. Should be either b’VOLT’ or b’RES’.

  • device – Path to the serial port to open, as a str.

  • baudrate – Desired baudrate for serial communication.

  • timeout – Timeout for the serial connection, as a float.

open() None[source]

Opens the serial connection, resets the Agilent and configures it to the desired mode.

get_data() List[float][source]

Asks the Agilent to acquire a value and returns it, except if an error occurs in which case 0 is returned.

close() None[source]

Closes the serial port.

Comedi

class crappy.inout.Comedi(device: str = '/dev/comedi0', sub_device: int = 0, channels: Iterable[int] | None = None, range_num: Iterable[int] | None = None, gain: Iterable[float] | None = None, offset: Iterable[float] | None = None, make_zero: Iterable[bool] | None = None, out_sub_device: int = 1, out_channels: Iterable[int] | None = None, out_range_num: Iterable[int] | None = None, out_gain: Iterable[float] | None = None, out_offset: Iterable[float] | None = None)[source]

This class can control acquisition boards relying on the Comedi driver.

It can read data from ADCs on input channels, and set voltages of DACs on output channels. Each channel can be tuned independently in terms of range, gan, offset, and for input channels it’s possible to decide whether they should be offset to 0 at the beginning of the test.

Communicates over serial. This class was implemented and tested on a USB-DUX sigma device. IT should work with other devices as well, but that was not tested.

Note

This class requires the libcomedi library to be installed on the computer.

New in version 1.4.0.

__init__(device: str = '/dev/comedi0', sub_device: int = 0, channels: Iterable[int] | None = None, range_num: Iterable[int] | None = None, gain: Iterable[float] | None = None, offset: Iterable[float] | None = None, make_zero: Iterable[bool] | None = None, out_sub_device: int = 1, out_channels: Iterable[int] | None = None, out_range_num: Iterable[int] | None = None, out_gain: Iterable[float] | None = None, out_offset: Iterable[float] | None = None) None[source]

Sets the arguments and initializes the parent class.

Parameters:
  • device – The address of the device, as a str.

  • sub_device

    The id of the subdevice to use for input channels, as an int.

    Changed in version 2.0.0: renamed from subdevice to sub_device

  • channels – An iterable (like a list or a tuple) containing the indexes of the channels to use as inputs, given as int.

  • range_num – An iterable (like a list or a tuple) containing for each input channel the index of the range to set for that channel, as an int. Refer to the documentation of the board to get the correspondence between range indexes and Volts. If not given, all input channels will be set to the range 0.

  • gain – An iterable (like a list or a tuple) containing for each input channel the gain to apply to the measured voltage, as a float. The returned voltage is calculated as follows : \(returned\_voltage = gain * measured\_voltage + offset\). If not given, no gain is applied to the measured values.

  • offset – An iterable (like a list or a tuple) containing for each input channel the offset to apply to the measured voltage, as a float. The returned voltage is calculated as follows : \(returned\_voltage = gain * measured\_voltage + offset\). If not given, no offset is applied to the measured values.

  • make_zero – An iterable (like a list or a tuple) containing for each input channel a bool indicating whether the channel should be zeroed or not. If so, data will be acquired on this channel before the test starts, and a compensation value will be deduced so that the offset of this channel is 0. It will only take effect if the make_zero_delay argument of the IOBlock controlling the Comedi is set ! If not given, the channels are by default not zeroed.

  • out_sub_device

    The id of the subdevice to use for output channels, as an int.

    Changed in version 2.0.0: renamed from out_subdevice to out_sub_device

  • out_channels – An iterable (like a list or a tuple) containing the indexes of the channels to use as outputs, given as int.

  • out_range_num – An iterable (like a list or a tuple) containing for each output channel the index of the range to set for that channel, as an int. Refer to the documentation of the board to get the correspondence between range indexes and Volts. If not given, all output channels will be set to the range 0.

  • out_gain

    An iterable (like a list or a tuple) containing for each output channel the gain to apply to the command voltage, as a float. The set voltage is calculated as follows : .. math:

    set_voltage = out_gain * command_voltage + out_offset
    

    If not given, no gain is applied to the command values.

  • out_offset

    An iterable (like a list or a tuple) containing for each output channel the offset to apply to the command voltage, as a float. The set voltage is calculated as follows : .. math:

    set_voltage = out_gain * command_voltage + out_offset
    

    If not given, no offset is applied to the command values.

Note

All the iterables given as arguments for the input channels should have the same length, and same for the output channels. If that’s not the case, all the given iterables are treated as if they had the same length as the shortest given one.

Changed in version 1.5.10: now explicitly listing the device, subdevice, channels, range_num, gain, offset, make_zero, out_subdevice, out_channels, out_range_num, out_gain and out_offset arguments

open() None[source]

Opening the Comedi board and setting up the input and output channels.

make_zero(delay: float) None[source]

Overriding the method of the parent class, because the user can choose which channels should be zeroed or not.

It simply performs the regular zeroing, and resets the compensation to zero for the channels that shouldn’t be zeroed.

set_cmd(*cmd: float) None[source]

Sets the command value on the output channels.

There should be as many commands as there are output channels. In case there would be fewer commands or channels, the extra commands/channels wouldn’t be considered/set.

get_data() List[float][source]

Reads and returns the value of each channel, adjusted with the given gain and offset.

close() None[source]

Closes the Comedi board and warns the user in case of failure.

DAQmx

class crappy.inout.DAQmx(device: str = 'Dev1', channels: Iterable[str] | None = None, gain: Iterable[float] | None = None, offset: Iterable[float] | None = None, ranges: Iterable[float] | None = None, make_zero: Iterable[bool] | None = None, sample_rate: float = 10000, out_channels: Iterable[str] | None = None, out_gain: Iterable[float] | None = None, out_offset: Iterable[float] | None = None, out_ranges: Iterable[float] | None = None)[source]

This class can drive data acquisition hardware from National Instruments.

It is similar to NIDAQmx InOut, except it relies on the PyDAQmx module. It was written and tested on a USB 6008 DAQ board, but should work with other instruments as well.

Note

This class requires the NIDAQmx C driver to be installed, as well as the PyDAQmx module.

New in version 1.4.0.

Changed in version 2.0.0: renamed from Daqmx to DAQmx

__init__(device: str = 'Dev1', channels: Iterable[str] | None = None, gain: Iterable[float] | None = None, offset: Iterable[float] | None = None, ranges: Iterable[float] | None = None, make_zero: Iterable[bool] | None = None, sample_rate: float = 10000, out_channels: Iterable[str] | None = None, out_gain: Iterable[float] | None = None, out_offset: Iterable[float] | None = None, out_ranges: Iterable[float] | None = None) None[source]

Sets the arguments and initializes the parent class.

Parameters:
  • device – The name of the device to open, as a str.

  • channels – An iterable (like a list or a tuple) containing the names of the channels to use as inputs, given as str. Typical names for inputs are 'aiX'`, with X an integer.

  • gain – An iterable (like a list or a tuple) containing for each input channel the gain to apply to the measured voltage, as a float. The returned voltage is calculated as follows \(returned\_voltage = gain * measured\_voltage + offset\). If not given, no gain is applied to the measured values.

  • offset – An iterable (like a list or a tuple) containing for each input channel the offset to apply to the measured voltage, as a float. The returned voltage is calculated as follows \(returned\_voltage = gain * measured\_voltage + offset\). If not given, no offset is applied to the measured values.

  • ranges

    An iterable (like a list or a tuple) containing for each input channel the range to set for that channel, as a float. The possible range values are :

    0.5, 1., 2.5, 5.
    

    If not given, all input channels will be set to the range 5.

    Changed in version 1.5.10: renamed from range to ranges

  • make_zero – An iterable (like a list or a tuple) containing for each input channel a bool indicating whether the channel should be zeroed or not. If so, data will be acquired on this channel before the test starts, and a compensation value will be deduced so that the offset of this channel is 0. It will only take effect if the make_zero_delay argument of the IOBlock controlling the DAQ is set ! If not given, the channels are by default not zeroed.

  • sample_rate – The frequency of the acquisition, as a float. The higher this number, the more noise there is on the signal but the higher the acquisition frequency.

  • out_channels – An iterable (like a list or a tuple) containing the names of the channels to use as outputs, given as str. Typical names for outputs are 'aoX', with X an integer.

  • out_gain – An iterable (like a list or a tuple) containing for each output channel the gain to apply to the command voltage, as a float. The set voltage is calculated as follows : \(set\_voltage = out\_gain * command\_voltage + out\_offset\). If not given, no gain is applied to the command values.

  • out_offset – An iterable (like a list or a tuple) containing for each output channel the offset to apply to the command voltage, as a float. The set voltage is calculated as follows : \(set\_voltage = out\_gain * command\_voltage + out\_offset\). If not given, no offset is applied to the command values.

  • out_ranges

    An iterable (like a list or a tuple) containing for each output channel the range to set for that channel, as a float. The possible range values are :

    0.5, 1., 2.5, 5.
    

    If not given, all output channels will be set to the range 5.

    Changed in version 1.5.10: renamed from out_range to out_ranges

Note

All the iterables given as arguments for the input channels should have the same length, and same for the output channels. If that’s not the case, all the given iterables are treated as if they had the same length as the shortest given one.

Removed in version 1.5.10: nperscan argument

open() None[source]

Opens the device and initializes the input and output channels.

make_zero(delay: float) None[source]

Overriding the method of the parent class, because the user can choose which channels should be zeroed or not.

It simply performs the regular zeroing, and resets the compensation to zero for the channels that shouldn’t be zeroed.

get_data() List[float][source]

Creates and starts an acquisition task, and returns the acquired values.

set_cmd(*cmd: float) None[source]

Sets the command value on the output channels.

There should be as many commands as there are output channels. In case the numbers of channels and commands don’t match, an exception is raised.

close() None[source]

Closes the processes of the input and output channels.

Fake Inout

class crappy.inout.FakeInOut[source]

This class is a demonstration InOut object that does not require any hardware to run.

It can read and/or modify (to a certain extent) the memory usage of the computer.

New in version 1.5.5.

Changed in version 2.0.0: renamed from Fake_inout to FakeInOut

__init__() None[source]

Initializes the parent class.

open() None[source]

Creates the buffer allowing to modify the memory usage.

set_cmd(*cmd: float) None[source]

Modifies the memory usage of the computer.

If the command is higher than the current, adds big lists to the buffer in order to use more memory. If the command is lower than the current, empties the buffer.

Parameters:

*cmd – The target memory usage to set, in percent as a float.

get_data() List[float][source]

Just returns the timestamp and the current memory usage.

start_stream() None[source]

Defining this method to avoid getting warnings in the logs.

New in version 2.0.0.

stop_stream() None[source]

Defining this method to avoid getting warnings in the logs.

New in version 2.0.0.

get_stream() Tuple[ndarray, ndarray][source]

This method calls 10 times the get_data() method and returns the 10 values at once in the streamer format.

It is just a demo for showcasing the use of the streamer mode.

New in version 2.0.0.

close() None[source]

Deletes the buffer.

GPIO PWM

class crappy.inout.GPIOPWM(pin_out: int, duty_cycle: float | None = None, frequency: float | None = None)[source]

This class can drive a PWM output on a Raspberry Pi.

It allows controlling the duty cycle, the frequency, or both at the same time. When controlling both, the duty cycle should be first and the frequency second in the given commands.

Warning

Only works on Raspberry Pi !

New in version 1.4.0.

Changed in version 2.0.0: renamed from Gpio_pwm to GPIOPWM

__init__(pin_out: int, duty_cycle: float | None = None, frequency: float | None = None) None[source]

Checks the validity of the arguments.

Parameters:
  • pin_out – The index of GPIO pin to drive in BCM convention, as an int.

  • duty_cycle – If provided (as a float, in percent), sets a fixed duty cycle for the entire test. Only the frequency can then be tuned. If not provided, the duty cycle can be set as a command. The duty cycle will also be set to 0% until a first value is received.

  • frequency – If provided (as a float, in Hz), sets a fixed PWM frequency for the entire test. Only the duty cycle can then be tuned. If not provided, the frequency can be set as a command. The frequency will also be set to 10kHz until a first value is received. Note that the frequency inputs are clamped between 10Hz and 1MHz.

Note

Several values can be passed at once as a command. If both duty_cycle and frequency are provided, all the values are ignored. If only frequency is provided, the first command value sets the duty cycle and any other value is ignored. Same goes if only duty_cycle is provided. If none of the two arguments are provided, the first command value should set the duty cycle and the second command value should set the frequency.

Note

On the Raspberry Pi 4, only the GPIO pins 12, 13, 18 and 19 support hardware PWM. Trying to get a PWM output from other pins might work but may decrease the available frequency range.

open() None[source]

Sets the GPIOs and starts the PWM.

set_cmd(*cmd: float) None[source]

Modifies the PWM frequency and/or duty cycle.

Parameters:

*cmd – Values of duty cycle and/or frequency to set.

close() None[source]

Stops the PWM and releases the GPIOs.

GPIO Switch

class crappy.inout.GPIOSwitch(pin_out: int | str, backend: str)[source]

This class can drive a GPIO high or low on a single board computer.

When the command value is 1 the GPIO is turned high, when the command is 0 it is turned low. Any value other than 0 and 1 raises an error.

New in version 1.4.0.

Changed in version 2.0.0: renamed from Gpio_switch to GPIOSwitch

__init__(pin_out: int | str, backend: str) None[source]

Checks the validity of the arguments.

Parameters:
  • pin_out – The GPIO pin to be controlled. On Raspberry Pi, should be an int corresponding to a GPIO in BCM convention. With the ‘blinka’ backend, should be a string holding the name of the pin. Refer to blinka’s specific documentation for each board for more information.

  • backend

    Should be one of :

    'Pi4', 'blinka'
    

    The ‘Pi4’ backend only works on the Raspberry Pis. The ‘blinka’ backend requires installing Adafruit-Blinka, but this module is compatible with and maintained on a wide variety of boards.

    New in version 1.5.10.

New in version 1.5.10: ft232h_ser_num argument

Removed in version 2.0.0: ft232h_ser_num argument

open() None[source]

Initializes the GPIO.

set_cmd(*cmd: int) None[source]

Drives the GPIO according to the command.

Parameters:

cmd – 1 for driving the GPIO high, 0 for driving it low.

close() None[source]

Releases the GPIO.

Kollmorgen AKD PDMM

class crappy.inout.KollmorgenAKDPDMM(axes: Iterable[int], mode: str = 'position', host: str = '192.168.0.109', port: int = 502)[source]

This class can communicate with a KollMorgen AKD PDMM programmable multi-axis controller.

It can either drive it in speed or in position. Multiple axes can be driven. The values of the current speeds or positions can also be retrieved.

New in version 1.4.0.

Changed in version 2.0.0: renamed from Koll to KollmorgenAKDPDMM

__init__(axes: Iterable[int], mode: str = 'position', host: str = '192.168.0.109', port: int = 502) None[source]

Sets the arguments and initializes the parent class.

Parameters:
  • axes

    An iterable (like a list or a tuple) containing the motors/axes to drive, given as int.

    Changed in version 1.5.10: renamed from axis to axes

  • mode

    The driving mode, should be either ‘speed’ or ‘position’.

    Changed in version 1.5.10: renamed from data to mode

  • host – The IP address of the variator, given as a str.

  • port – The network port over which to communicate with the variator, as an int.

Removed in version 1.5.10: speed, acc, decc and labels arguments

open() None[source]

Connects to the variator over modbus.

get_data() List[float][source]

For each motor, reads its current speed or position depending on the selected mode.

The positions or speeds are returned in the same order as the motors were given in the axes argument.

set_cmd(*cmd: float) None[source]

Sets either the speed or the position of all motors depending on the selected mode.

If more commands than motors are given, the extra commands are ignored. If there are more motors than commands, only part of the motors will be set.

New in version 1.5.10.

close() None[source]

Closes the modbus connection to the variator.

Labjack T7

class crappy.inout.LabjackT7(channels: Iterable[Dict[str, Any]], device: str = 'ANY', connection: str = 'ANY', identifier: str = 'ANY', write_at_open: Iterable[tuple] | None = None, no_led: bool = False)[source]

This InOut allows controlling a Labjack T7 device. It can use any channel as input/output.

The Labjack T7 is a very complete DAQ board. It features several ADC, several DAC, as well as multiple GPIOs. It can also read thermocouples, and run LUA code on an integrated microcontroller. These features can all be controlled from Crappy.

This class is not capable of streaming. For higher frequency, refer to the T7Streamer class.

New in version 1.4.0.

Changed in version 2.0.0: renamed from Labjack_t7 to LabjackT7

__init__(channels: Iterable[Dict[str, Any]], device: str = 'ANY', connection: str = 'ANY', identifier: str = 'ANY', write_at_open: Iterable[tuple] | None = None, no_led: bool = False) None[source]

Sets the arguments and initializes the parent class.

Parameters:
  • channels – An iterable (like a list or a tuple) of the channels to interface with on the Labjack. Each object in this iterable should be a dict representing a single channel, and whose keys provide information on the channel to use. Refer to the note below for more information on the possible keys.

  • device

    The type of Labjack to open. Possible values include :

    'ANY', 'T7', 'T4', 'DIGIT'
    

    Only tested with ‘T7’ in Crappy.

  • connection

    The type of connection used for interfacing with the Labjack. Possible values include :

    'ANY', 'TCP', 'USB', 'ETHERNET', 'WIFI'
    

  • identifier – Any extra information allowing to further identify the Labjack to open, like a serial number, an IP address, or a device name.

  • write_at_open – If specific names or registers have to be written when opening the channel, they can be given here as an iterable (like a list or a tuple) of tuple. They will be written in the same order as in the given iterable. Refer to the note below for the accepted formats.

  • no_led – If True, turns off the LED on the Labjack. This led can generate noise on the channels AIN0 and AIN1.

Note

  • channels keys:

    • name: The name of the channel to interface with, as written on the Labjack’s case. Ex: ‘AIN0’. The available settings as well as the direction of the channel depend on the given name.

      The name can be:
      • AINx: Analog input, linked to an ADC. A gain and offset can be provided, and the range and resolution can be adjusted. It is always an input. These channels can also be used with thermocouples (see below).

      • (T)DACx: Analog output, linked to a DAC. A gain and an offset can be specified. It is always an output.

      • (E/F/C/M IOx): Digital inputs/outputs. A gain and an offset can be specified. It can be either an input or an output, the default is output.

    • gain: If the channel is an input, the measured value will be modified directly by the Labjack as follows : \(returned\_value = gain * measured\_value + offset\). If the channel is an output, the command value will be modified in Crappy as follows before being sent to the Labjack : \(sent\_value = gain * command + offset\).

    • offset: If the channel is an input, the measured value will be modified directly by the Labjack as follows : \(returned\_value = gain * measured\_value + offset\). If the channel is an output, the command value will be modified in Crappy as follows before being sent to the Labjack : \(sent\_value = gain * command + offset\).

    • make_zero: If True, data will be acquired on this channel before the test starts, and a compensation value will be deduced so that the offset of this channel is 0. The compensation is performed directly by the Labjack. This setting only has effect for AIN channels defined as inputs. It will only take effect if the make_zero_delay argument of the IOBlock controlling the Labjack is set !

    • direction: If True, the channel is considered as an output, else as an input. Only has effect for IO channels, the default is output.

    • resolution: The resolution of the acquisition as an integer, refer to Labjack documentation for more details. The higher this value the better the resolution, but the lower the speed. The possible range is either 1 to 8 or to 12 depending on the model. The default is 1. Only has effect for AIN channels.

    • range: The range of the acquisition in Volts. A range of x means that values can be read between -x and x Volts. The possible values are :

      0.01, 0.1, 1, 10
      

      Only has effect for AIN channels.

    • limits: A tuple containing the minimum and maximum allowed command values to set for this channel. After applying the gain and offset to the command, it is then clamped between these two values before being sent to the Labjack. Only has effect for output channels.

    • thermocouple: The type of thermocouple to read data from. Possible values are:

      'E', 'J', 'K', 'R', 'T', 'S', 'C'
      

      If specified, it will use the EF to read a temperature directly from the thermocouples. Only has effect for AIN channels.

    • write_at_open: A list containing commands for writing specific names or registers when opening the channel. The commands should be given as tuple either in the format (name (str), value (int/float)) or (register (int), type (int), value (float/int)).

Warning

Do not consider the limits key as a safety feature. It should not go beyond/below the given values, but this is not meant to replace hardware safety !

open() None[source]

Opens the Labjack, parses the commands to write at open, and sends them.

make_zero(delay: float) None[source]

Overriding the method of the parent class, because the Labjack T7 allows setting offsets directly on the board.

Setting the offsets on the Labjack is slightly quicker than correcting the received values afterward.

Parameters:

delay – The delay during which the data should be acquired for determining the offset.

New in version 1.5.10.

get_data() List[float][source]

Reads the signal on all pre-defined input channels, and returns the values along with a timestamp..

set_cmd(*cmd: float) None[source]

Sets the tension commands on the output channels.

The given gain and offset are first applied, then the commands are clamped to the given limits. The commands are then written to the Labjack, only if they differ from the last written ones.

close() None[source]

Closes the connection to the Labjack.

Labjack T7 Streamer

class crappy.inout.T7Streamer(channels: Iterable[Dict[str, Any]], device: str = 'ANY', connection: str = 'ANY', identifier: str = 'ANY', scan_rate: int = 100000, scan_per_read: int = 10000, resolution: int = 1)[source]

This InOut allows controlling a Labjack T7 device in stream mode.

It can only acquire data on the AIN channels. For single point mode, and acquisition on all channels, use the LabjackT7 InOut.

Compared with single point acquisition, the streaming mode can achieve much higher data rates and has a much greater regularity in the frequency of the acquisition. However, fewer options are available and not all types of channels can be read in the streamer mode.

For each channel, the voltage range can be tuned, and a gain and offset can be defined. Also, the user can decide whether the channel should be zeroed before starting the test or not.

Important

The streamer argument of the IOBlock controlling this InOut must be set to True to enable streaming in this class. Otherwise, only single point acquisition can be performed.

New in version 1.4.0.

Changed in version 2.0.0: renamed from T7_streamer to T7Streamer

__init__(channels: Iterable[Dict[str, Any]], device: str = 'ANY', connection: str = 'ANY', identifier: str = 'ANY', scan_rate: int = 100000, scan_per_read: int = 10000, resolution: int = 1) None[source]

Sets the arguments and initializes the parent class.

Parameters:
  • channels – An iterable (like a list or a tuple) of the channels to interface with on the Labjack. Each object in this iterable should be a dict representing a single channel, and whose keys provide information on the channel to use. Refer to the note below for more information on the possible keys.

  • device

    The type of Labjack to open. Possible values include :

    'ANY', 'T7', 'T4', 'DIGIT'
    

    Only tested with ‘T7’ in Crappy.

  • connection

    The type of connection used for interfacing with the Labjack. Possible values include :

    'ANY', 'TCP', 'USB', 'ETHERNET', 'WIFI'
    

  • identifier – Any extra information allowing to further identify the Labjack to open, like a serial number, an IP address, or a device name.

  • scan_rate – The acquisition frequency in Hz for all channels. Note that the sample rate (scan_rate * num of chan) cannot exceed 100000. If it is too high it will be lowered to the highest possible value.

  • scan_per_read – The number of points to read at each loop.

  • resolution – The resolution of the acquisition as an integer for all channels. Refer to Labjack documentation for more details. The higher this value the better the resolution, but the lower the speed. The possible range is either 1 to 8 or to 12 depending on the model. The default is 1.

Note

  • channels keys:

    • name: The name of the channel to interface with, as written on the Labjack’s case. Ex: ‘AIN0’. In streamer mode, only the AIN channels, i.e. the analog inputs, are available.

    • gain: The measured value will be modified in Crappy as follows : \(returned\_value = gain * measured\_value + offset\).

    • offset: The measured value will be modified in Crappy as follows : \(returned\_value = gain * measured\_value + offset\)

    • make_zero: If True, data will be acquired on this channel before the test starts, and a compensation value will be deduced so that the offset of this channel is 0. It will only take effect if the make_zero_delay argument of the IOBlock controlling the Labjack is set !

    • range: The range of the acquisition in Volts. A range of x means that values can be read between -x and x Volts. The possible values are :

      0.01, 0.1, 1, 10
      
open() None[source]

Opens the Labjack, parses the commands to write at open, and sends them.

Also checks whether the scan rate chosen by the Labjack is the same as requested by the user.

make_zero(delay: float) None[source]

Overriding the method of the parent class, because the user can choose which channels should be zeroed or not.

It simply performs the regular zeroing, and resets the compensation for the channels that shouldn’t be zeroed.

New in version 1.5.10.

start_stream() None[source]

Starts the stream, and saves the timestamp of the moment when the stream started.

get_data() List[float][source]

Reads single data points, applies the given gains and offsets, and returns the data along with a timestamp.

get_stream() List[ndarray] | None[source]

Acquires the stream, reshapes the data, applies the gains and offsets, and returns the data along with a time array.

stop_stream() None[source]

Stops the stream, if it was started.

close() None[source]

Closes the connection to the Labjack, if it was opened.

Labjack UE9

class crappy.inout.LabjackUE9(channels: Iterable[int], gain: Iterable[float] | None = None, offset: Iterable[float] | None = None, make_zero: Iterable[bool] | None = None, resolution: Iterable[int] | None = None)[source]

This class can read the analog input channels from a Labjack UE9 device.

It cannot read nor drive any of the other inout or output channels on the UE9. The UE9 model has been discontinued, and replaced by the T7 model (see LabjackT7). It is thus likely that this class won’t be further improved in the future.

New in version 1.4.0.

Changed in version 2.0.0: renamed from Labjack_ue9 to LabjackUE9

__init__(channels: Iterable[int], gain: Iterable[float] | None = None, offset: Iterable[float] | None = None, make_zero: Iterable[bool] | None = None, resolution: Iterable[int] | None = None) None[source]

Sets the arguments and initializes the parent class.

Parameters:
  • channels – An iterable (like a list or a tuple) containing all the channels to read, given as int. Only the AIN channels can be read by this class, so to read the channel AIN2 the integer 2 should be added to the iterable.

  • gain – An iterable (like a list or a tuple) containing for each channel the gain to apply to the measured voltage, as a float. The returned voltage is calculated as follows : \(returned\_voltage = gain * measured\_voltage + offset\). If not given, no gain is applied to the measured values.

  • offset – An iterable (like a list or a tuple) containing for each channel the offset to apply to the measured voltage, as a float. The returned voltage is calculated as follows : \(returned\_voltage = gain * measured\_voltage + offset\). If not given, no offset is applied to the measured values.

  • make_zero – An iterable (like a list or a tuple) containing for each channel a bool indicating whether the channel should be zeroed or not. If so, data will be acquired on this channel before the test starts, and a compensation value will be deduced so that the offset of this channel is 0. It will only take effect if the make_zero_delay argument of the IOBlock controlling the Labjack is set ! If not given, the channels are by default not zeroed.

  • resolution – An iterable (like a list or a tuple) containing for each channel the resolution of the acquisition as an integer. Refer to Labjack documentation for more details. The higher this value the better the resolution, but the lower the speed. The possible range is 1 to 12, and the default is 12.

Note

All the :iterables given as arguments for the channels should have the same length. If that’s not the case, all the given iterables are treated as if they had the same length as the shortest given one.

open() None[source]

Opens the connection to the Labjack.

make_zero(delay: float) None[source]

Overriding the method of the parent class, because the user can choose which channels should be zeroed or not.

It simply performs the regular zeroing, and resets the compensation to zero for the channels that shouldn’t be zeroed.

New in version 1.5.10.

get_data() List[float][source]

Reads sequentially the channels and returns the acquired values, corrected by the given gains and offsets.

close() None[source]

Closes the connection to the Labjack, if it was already opened.

MCP9600

class crappy.inout.MCP9600(backend: str, thermocouple_type: str, i2c_port: int = 1, device_address: int = 103, adc_resolution: int = 18, sensor_resolution: float = 0.0625, filter_coefficient: int = 0, mode: str = 'Hot Junction Temperature')[source]

This class can read temperature values from an MCP9600 thermocouple reader.

It communicates over the I2C protocol. The output is in °C, except for one operating mode that returns Volts. Several parameters can be tuned, like the thermocouple type, the reading resolution or the filter coefficient. Note that the MCP9600 can only achieve a data rate of a few Hz.

New in version 1.4.0.

Changed in version 2.0.0: renamed from Mcp9600 to MCP9600

__init__(backend: str, thermocouple_type: str, i2c_port: int = 1, device_address: int = 103, adc_resolution: int = 18, sensor_resolution: float = 0.0625, filter_coefficient: int = 0, mode: str = 'Hot Junction Temperature') None[source]

Checks the validity of the arguments.

Parameters:
  • backend

    The backend for communicating with the MCP9600. Should be one of:

    'Pi4', 'blinka'
    

    The ‘Pi4’ backend is optimized but only works on boards supporting the smbus2 module, like the Raspberry Pis. The ‘blinka’ backend may be less performant and requires installing Adafruit-Blinka, adafruit-circuitpython-busdevice and adafruit-circuitpython-mcp9600, but these modules are compatible with and maintained on a wide variety of boards.

  • thermocouple_type

    The type of thermocouple connected to the MCP9600. The possible types are:

    'J', 'K', 'T', 'N', 'S', 'E', 'B', 'R'
    

  • i2c_port – The I2C port over which the MCP9600 should communicate. On most Raspberry Pi models the default I2C port is 1.

  • device_address – The I2C address of the MCP9600. The default address is 0x67, but it is possible to change this setting using a specific setup involving the ADDR pin.

  • adc_resolution

    The number of bits the ADC output is encoded on. The greater the resolution, the lower the sample rate. The available resolutions are:

    12, 14, 16, 18
    

  • sensor_resolution – The temperature measurement resolution in °C. It should be either 0.0625 or 0.25. Setting the resolution to 0.25 will increase the sample rate, but the output temperature will be encoded on two bits less.

  • filter_coefficient – The MCP9600 features an integrated filter (see its documentation for the exact filter formula). When set to 0, the filter is inactive. It is maximal when set to 7. When active, the filter will prohibit fast temperature changes, thus limiting noise and smoothening the signal.

  • mode

    Four different values can be accessed when measuring a temperature: the temperature of the thermocouple (hot junction temperature), the temperature of the MCP9600 board (cold junction temperature), the temperature calculated from the ADC data and thermocouple type but not yet cold junction-compensated (junction temperature delta), and the raw ADC measurement of the voltage difference in the thermocouple (raw data ADC, in Volts). The available modes are thus:

    'Hot Junction Temperature',
    'Junction Temperature Delta',
    'Cold Junction Temperature',
    'Raw Data ADC'
    

Removed in version 2.0.0: ft232h_ser_num argument

open() None[source]

Initializes the I2C communication and the device.

get_data() List[float][source]

Reads the registers containing the conversion result.

The output is in °C for all modes except the raw data ADC one, which outputs Volts.

Returns:

A list – containing the timestamp and the output value.

close() None[source]

Switches the MCP9600 to shutdown mode and closes the I2C bus.

MPRLS

class crappy.inout.MPRLS(backend: str, eoc_pin: int | str | None = None, device_address: int = 24, i2c_port: int = 1)[source]

This class can read values from an MPRLS pressure sensor.

It communicates over I2C with the sensor.

New in version 1.4.0.

Changed in version 2.0.0: renamed from Mprls to MPRLS

__init__(backend: str, eoc_pin: int | str | None = None, device_address: int = 24, i2c_port: int = 1) None[source]

Initializes the parent class and opens the I2C bus.

Parameters:
  • backend

    Should be one of :

    'Pi4', 'blinka'
    

    The ‘Pi4’ backend is optimized but only works on boards supporting the smbus2 module, like the Raspberry Pis. The ‘blinka’ backend may be less performant and requires installing Adafruit-Blinka and adafruit-circuitpython-mprls, but these modules are compatible with and maintained on a wide variety of boards.

    New in version 1.5.8.

  • eoc_pin

    Optionally, reads the end of conversion signal from the polarity of a GPIO rather than from an I2C register. Speeds up the reading and decreases the traffic on the bus, but requires one extra wire. With the backend ‘Pi4’, give the index of the GPIO in BCM convention. With the backend ‘blinka’, it should be a string but the syntax varies according to the board. Refer to blinka’s documentation for more information.

    New in version 1.5.8.

  • device_address

    The I2C address of the MPRLS. The address of the devices sold by Adafruit is 0x18, but other suppliers may sell it with another address.

    New in version 1.5.8.

  • i2c_port

    The I2C port over which the MPRLS should communicate. On most Raspberry Pi models the default I2C port is 1.

    New in version 1.5.8.

New in version 1.5.8: ft232h_ser_num argument

Removed in version 2.0.0: ft232h_ser_num argument

open() None[source]

Opens the I2C bus.

get_data() List[float][source]

Reads the pressure value.

Returns:

The timestamp and the pressure value in hPa.

close() None[source]

Closes the I2C bus.

NAU7802

class crappy.inout.NAU7802(i2c_port: int = 1, device_address: int = 42, gain_hardware: int = 128, sample_rate: int = 80, int_pin: int | None = None, gain: float = 1, offset: float = 0)[source]

This class can read values from a NAU7802 load cell conditioner.

This load cell conditioner is a low-cost 24-bits, single-channel conditioner, that can read up to 320 samples per second. It communicates over the I2C protocol. The returned value of the InOut is in Volts by default, but can be converted to Newtons using the gain and offset arguments.

New in version 1.4.0.

Changed in version 2.0.0: renamed from Nau7802 to NAU7802

__init__(i2c_port: int = 1, device_address: int = 42, gain_hardware: int = 128, sample_rate: int = 80, int_pin: int | None = None, gain: float = 1, offset: float = 0) None[source]

Checks the validity of the arguments.

Parameters:
  • i2c_port – The I2C port over which the NAU7802 should communicate. On most Raspberry Pi models the default I2C port is 1.

  • device_address – The I2C address of the NAU7802. It is impossible to change this address, so it is not possible to have several NAU7802 connected on the same I2C bus.

  • gain_hardware

    The gain to be used by the programmable gain amplifier. Setting a high gain allows reading small voltages with a better precision, but it might saturate the sensor for higher voltages. Available gains are:

    1, 2, 4, 8, 16, 32, 64, 128
    

  • sample_rate

    The sample rate for data conversion. The higher the rate, the greater the noise. Available sample rates are:

    10, 20, 40, 80, 320
    

  • int_pin

    Optionally, reads the end of conversion signal from the polarity of a GPIO rather than from an I2C register. Speeds up the reading and decreases the traffic on the bus, but requires one extra wire. Give the index of the GPIO in BCM convention, as an int.

    New in version 1.5.8.

  • gain – Allows to tune the output value according to the formula : \(output = gain * tension + offset\).

  • offset – Allows to tune the output value according to the formula : \(output = gain * tension + offset\).

Removed in version 2.0.0: backend and ft232h_ser_num arguments

open() None[source]

Initializes the I2C communication and the device.

get_data() List[float][source]

Reads the registers containing the conversion result.

The output is in Volts by default, and can be converted to Newtons using gain and offset.

Returns:

A list containing the timeframe and the output value.

close() None[source]

Powers down the device.

NI DAQmx

class crappy.inout.NIDAQmx(channels: Iterable[Dict[str, Any]], sample_rate: float = 100, n_samples: int | None = None)[source]

This class can drive data acquisition hardware from National Instruments.

It is similar to DAQmx InOut, except it relies on the nidaqmx module. It was written and tested on a USB 6008 DAQ board, but should work with other instruments as well.

It can read single data points from digital and analog channels, read streams of data from analog channels, and set the voltage of analog and digital output channels. For analog input channels, several types of acquisition can be performed, like voltage, resistance, current, etc.

New in version 1.4.0.

Changed in version 2.0.0: renamed from Nidaqmx to NIDAQmx

__init__(channels: Iterable[Dict[str, Any]], sample_rate: float = 100, n_samples: int | None = None) None[source]

Sets the arguments and initializes the parent class.

Parameters:
  • channels – An iterable (like a list or a tuple) containing dict holding information on the channels to read data from or write data to. See below for the mandatory and optional keys for the dicts. Note that in streamer mode, the digital input channels are not available for reading. Also, only one type of analog input channel at a time can be read in streamer mode, with no restriction on the number of channels of this type.

  • sample_rate

    The target sample rate for data acquisition in streamer mode, given as a float. Default is 100 SPS.

    Changed in version 1.5.10: renamed from samplerate to sample_rate

  • n_samples

    The number of samples to acquire per chunk of data in streamer mode. Default is 20% of sample_rate.

    Changed in version 1.5.10: renamed from nsamples to n_samples

Note

  • channels keys:

    • name: The name of the channel to drive, given with the following syntax :

      'DevX/[a/d][i/o]Y'
      

      With X the index of the device, and Y the line on which the channel is. d stands for digital, a for analog, i for input and o for output. For digital channels, DevX/d[i/o]Y is internally converted to DevX/port<Y // 8>/line<Y % 8>. Example of a valid name : Dev1/ao3.

    • type: The type of data to read, for analog input channels. This field can take many different values, refer to the documentation of the nidaqmx for more details. This field is internally used for calling the method : nidaqmx.task.add_ai_[type]_chan(). The default for this field is ‘voltage’, possible values include ‘thrmcpl’, ‘bridge’, ‘current’ and ‘resistance’.

    • All the other keys will be given as kwargs to the nidaqmx.task.add_ai_[type]_chan() method for analog input channels, to the nidaqmx.task.add_ao_voltage_chan() for analog output channels, to nidaqmx.task.add_do_chan() for digital output channels, and to nidaqmx.task.add_di_chan() for digital input channels. Refer to nidaqmx documentation for the possible arguments and values. Note that for the ‘thrmcpl’ analog input channel type, the ‘thermocouple_type’ argument must be given as a letter, same for the ‘units’ argument. They will be parsed internally. Also note that for the analog output channels and the analog input channels of type ‘voltage’, the ‘min_val’ and ‘max_val’ arguments are internally set by default to 0 and 5.

open() None[source]

Creates tasks and streams for analog output, digital input, digital output, and each type of analog input channels.

start_stream() None[source]

Starts the streaming task for analog input channels.

Data can be acquired via streaming for multiple channels, but only for one type of channel.

get_data() List[float][source]

Reads data from the analog and digital input channels, and returns it along with a timestamp.

Data from the analog channels is read first, and then data from the digital channels. Data is returned in the same order as it was acquired.

get_stream() List[ndarray] | None[source]

Reads data from the device, and returns it in an array along with an array holding the timestamps.

Only data from analog input channels can be read, this method cannot read stream data from digital input channels.

set_cmd(*cmd: float) None[source]

Sets the analog and digital output channels according to the given command values.

The first command values correspond to the analog channels, the remaining ones correspond to the digital channels. It might be that not all channels are set if the number of commands doesn’t match the number of channels.

stop_stream() None[source]

Stops all the acquisition tasks.

close() None[source]

Stops all the acquisition tasks, and closes the connections to the device.

OpSens HandySens

class crappy.inout.HandySens(device: str = '/dev/ttyUSB0')[source]

This class allows reading data from an OpSens HandySens fiber optics signal conditioner.

It can read data from various fiber optics sensors like temperature, pressure, position or strain.

New in version 1.4.0.

Changed in version 2.0.0: renamed from Opsens to HandySens

__init__(device: str = '/dev/ttyUSB0') None[source]

Sets the argument and initializes the parent class.

Parameters:

device – Address of the serial connection for communicating with the OpSens.

open() None[source]

Opens the serial connection and configures the OpSens.

get_data() List[float][source]

Reads data from the OpSens and returns it.

close() None[source]

Closes the serial connection, if it was opened.

Phidget Wheatstone Bridge

class crappy.inout.PhidgetWheatstoneBridge(channel: int = 0, hardware_gain: int = 1, data_rate: float = 50, gain: float = 1, offset: float = 0, remote: bool = False)[source]

This class can read voltage ratio values from a Phidget Wheatstone Bridge.

It relies on the Phidget22 module to communicate with the load cell conditioner. It can acquire values up to 50Hz with possible gain values from 1 to 128.

New in version 2.0.4.

__init__(channel: int = 0, hardware_gain: int = 1, data_rate: float = 50, gain: float = 1, offset: float = 0, remote: bool = False) None[source]

Sets the args and initializes the parent class.

Parameters:
  • channel – The index of the channel from which to acquire data, as an int. Should be either 0 or 1.

  • hardware_gain – The gain used by the conditioner for data acquisition. The higher the gain, the better the resolution but the narrower the range. Should be a power of 2 between 1 and 128.

  • data_rate – The number of samples to acquire per second, as an int. Should be between 0.017 (one sample per minute) and 50.

  • gain – A gain to apply to the acquired value, following the formula : \(returned = gain * acquired + offset\)

  • offset – An offset to apply to the acquired value, following the formula : \(returned = gain * acquired + offset\)

  • remote – Set to True to drive the bridge via a network VINT Hub, or to False to drive it via a USB VINT Hub.

open() None[source]

Sets up the connection to the load cell conditioner as well as the various callbacks, and waits for the load cell conditioner to attach.

get_data() List[float] | None[source]

Returns the last known voltage ratio value, adjusted with the gain and the offset.

close() None[source]

Closes the connection to the load cell conditioner.

PiJuice

class crappy.inout.PiJuice(i2c_port: int = 1, address: int = 20, backend: str = 'Pi4')[source]

This class can read various information about a piJuice power platform, including the charge level and the power supply status.

Warning

Only available on Raspberry Pi !

New in version 1.4.0.

Changed in version 2.0.0: renamed from Pijuice to PiJuice

__init__(i2c_port: int = 1, address: int = 20, backend: str = 'Pi4') None[source]

Checks the validity of the arguments.

Parameters:
  • backend

    Should be one of :

    'Pi4', 'pijuice'
    

    The ‘Pi4’ backend is based on the smbus2 module, while the ‘pijuice’ backend is based on the pijuice module.

    New in version 1.5.10.

  • i2c_port – The I2C port over which the PiJuice should communicate.

  • address – The I2C address of the piJuice. The default address is 0x14.

open() None[source]

Opens the I2C port.

get_data() Dict[str, Any][source]

Reads all the available information on the battery status.

Returns:

Returns a dict containing
  • the timestamp in seconds as a float in label t(s)

  • the battery status as a str in label battery_status

  • the USB status as a str in label USB_status

  • the GPIO status as a str in label GPIO_status

  • the charge level as an int in label charge_level

  • the battery temperature in °C as an int in label battery_temperature

  • the battery voltage in mV as an int in label battery_voltage

  • the battery current in mA as an int in label battery_current

  • the GPIO voltage in mV as an int in label GPIO_voltage

  • the GPIO current in mA as an int in label GPIO_current

close() None[source]

Closes the I2C bus.

Sim868

class crappy.inout.Sim868(numbers: Iterable[str], port: str = '/dev/ttyUSB0', baudrate: int = 115200, pin_code: str | None = None, registration_timeout: float = 10)[source]

This class can drive a SIM868 cellular module so that it sends SMS to given phone numbers.

Important

This InOut should be associated with a Modifier to manage the messages to send.

New in version 1.4.0.

Changed in version 2.0.0: renamed from Gsm to Sim868

__init__(numbers: Iterable[str], port: str = '/dev/ttyUSB0', baudrate: int = 115200, pin_code: str | None = None, registration_timeout: float = 10) None[source]

Checks the validity of the arguments.

Parameters:
  • numbers

    An iterable (like a list or a tuple) of numbers the messages will be sent to. The syntax is the following :

    ["0611223344"]
    

  • port – Serial port the Sim868 is connected to.

  • baudrate – Serial baudrate, between 1200 and 115200.

  • pin_code

    Optionally, a pin code to use for activating the SIM card.

    New in version 2.0.0.

  • registration_timeout

    The maximum number of seconds to allow for the Sim868 to register to a network once the SIM card has the ready status.

    New in version 2.0.0.

open() None[source]

Initializes the Sim868 device and checks its network connection.

First, the serial connection is checked. Then, checking if the SIM card requires a PIN code. If so and if one is given, sets the PIN code on the SIM. Then, checks that the SIM is connected to a network. Finally, sets the input mode to Text for the SMS.

set_cmd(*cmd: str) None[source]

Sends an SMS whose text is the str received as command to all the phone numbers.

If multiple messages are received, sends them all in the received order. If the messages are not str, they are first converted to strings if possible.

close() None[source]

Closes the serial port.

Spectrum M2I 4711

class crappy.inout.SpectrumM2I4711(channels: Iterable[int], device: str = '/dev/spcm0', ranges: Iterable[int] | None = None, sample_rate: int = 100000, buff_size: int = 67108864, notify_size: int = 65536)[source]

This class can read data from a Spectrum high speed ADC interfacing over PCIe.

It can acquire data over multiple channels, and set for each channel a different voltage range. It is possible to tune the sample rate, the chunk size and the memory allocated to the data buffer.

This class can only acquire data by streaming, it cannot acquire single data points.

New in version 1.4.0.

Changed in version 2.0.0: renamed from Spectrum to SpectrumM2I4711

__init__(channels: Iterable[int], device: str = '/dev/spcm0', ranges: Iterable[int] | None = None, sample_rate: int = 100000, buff_size: int = 67108864, notify_size: int = 65536) None[source]

Sets the arguments and initializes the parent class.

Parameters:
  • channels – An iterable (like a list or a tuple) of all the channels to read data from, given as int. Refer to the documentation of the Spectrum board to know which combinations of channels are allowed.

  • device – The address of the device to read data from, as a str.

  • ranges – An iterable (like a list or a tuple) indicating for each channel the range of the acquisition in mV, as an int. There should be as many values in this iterable as there are channels. If not given, all ranges default to 10000 mV.

  • sample_rate

    The sample rate of the acquisition for all channels, in Hz. The default is 100KHz.

    Changed in version 1.5.10: renamed from samplerate to sample_rate

  • buff_size – The size of the memory allocated as a rolling buffer to copy the data from the card, in bytes. The default is 67MB.

  • notify_size – The size of each chunk of data to copy from the card, in bytes. The default is 65kB.

Removed in version 1.5.10: split_chan argument

open() None[source]

Opens and configures the Spectrum, and sets the ranges and the sample rate as requested.

start_stream() None[source]

Starts the streams and saves the corresponding timestamp.

get_stream() List[ndarray][source]

Waits for data to be available, and returns it along with an array of timestamps.

stop_stream() None[source]

Stops the stream, if it was started.

close() None[source]

Closes the connection to the Spectrum, if it was opened.

Waveshare AD/DA

class crappy.inout.WaveshareADDA(dac_channels: Iterable[str] | None = None, adc_channels: Iterable[str] | None = None, gain_hardware: int = 1, v_ref: float = 3.3, gain: float = 1, offset: float = 0, sample_rate: int | float = 100)[source]

Class for controlling Waveshare’s AD/DA Raspberry Pi hat.

It communicates over the SPI protocol and the GPIOs. It allows to read values from the 8-channels ADC and/or to set the 2-channels DAC. The hat can acquire up to 30000 samples per second, although this data rate is impossible to achieve using Crappy.

Important

This class is specifically meant to be used on a Raspberry Pi.

New in version 1.4.0.

Changed in version 2.0.0: renamed from Waveshare_ad_da to WaveshareADDA

__init__(dac_channels: Iterable[str] | None = None, adc_channels: Iterable[str] | None = None, gain_hardware: int = 1, v_ref: float = 3.3, gain: float = 1, offset: float = 0, sample_rate: int | float = 100) None[source]

Checks the validity of the arguments.

Parameters:
  • dac_channels – An iterable (like a list or a tuple) of str representing the channels to be set. The syntax for each string is ‘DACi’ with i being either 0 or 1.

  • adc_channels

    An iterable (like a list or a tuple) of str representing the channels to read. The syntax for all the strings is either:

    'ADi' (i in range(8))
    

    or else:

    'ADi - ADj' (i, j in range(8))
    

  • gain_hardware

    The gain to be used by the programmable gain amplifier. Setting a high gain allows to read small voltages with a better precision, but it might saturate the sensor for higher voltages. The available gain values are:

    1, 2, 4, 8, 16, 32, 64
    

  • v_ref – The voltage reference set by the VREF jumper. When reading single inputs, v_ref is the value the ADC compares the signals with. In a similar way, the maximum output voltage of the DAC is v_ref. 3.3 and 5 are the only possible values for this setting, as the Raspberry Pi can only provide 3.3V and 5V.

  • gain – Allows to tune the output values of the ADC according to the formula : \(output = gain * tension + offset\). The same gain applies to all the outputs.

  • offset – Allows to tune the output values of the ADC according to the formula : \(output = gain * tension + offset\). The same offset applies to all the outputs.

  • sample_rate

    The ADC data output rate in SPS. The available values are:

    2.5, 5, 10, 15, 25, 30, 50, 60, 100, 500,
    1000, 2000, 3750, 7500, 15000, 30000
    

Warning

  • adc_channels: For reading single inputs the JMP_AGND jumper should normally be connected, whereas it should be disconnected for reading differential inputs. It is however possible to set a different reference than AGND for single input measurements, in which case the JMP_AGND jumper should not be connected and the voltage reference should be plugged in the AINCOM pin.

    The AD/DA offers the possibility to read single inputs or differential inputs, but not both at the same time ! This is due to the JMP_AGND jumper. For measuring both input types simultaneously, is it necessary to connect AGND to one of the channels (for example AD0). Then all single inputs ‘ADi’ should be replaced by ‘ADi - AD0’. They are then considered as differential inputs.

    The ADC channels voltages should not be lower than AGND-0.1V, and not be greater than AGND+5.1V. This is independent of VREF value.

Note

  • adc_channels: If multiple channels to read are given, they are read in a sequential way. This means that there’s a small delay between each acquisition, and the timeframe is thus less accurate for the last channels than for the first ones. If time precision matters it is preferable to read as few channels as possible !

  • vref: VREF can be set independently of the chosen VCC value. The VCC value has no influence on the ADC behaviour as it is always powered up with 5V. Same goes for the DAC.

open() None[source]

Sets the SPI communication, the GPIOs and the device.

get_data() List[float][source]

Reads data from all the user-specified ADC channels, in a sequential way.

Data is returned in Volts, but this can be tuned using gain and offset.

Returns:

A list containing the timestamp, and then the values for each channel to read.

set_cmd(*cmd: float) None[source]

Sets the user-specified DAC channels according to the input values.

Parameters:

cmd – The input values as float, in Volts.

close() None[source]

Releases the GPIOs.

Waveshare High Precision

class crappy.inout.WaveshareHighPrecision(spi_port: int = 0, gain_hardware: int = 16, sample_rate: int | float = 50, channels: Iterable[str] | None = None, digital_filter: int = 4, gain: float = 1, offset: float = 0)[source]

This InOut allows acquiring data from Waveshare’s High Precision HAT.

This board features an ADS1263 32-bits ADC, which is what this InOut actually drives. The main specificities compared with driving just an ADS1263 are that the reference voltage is the board’s 5V supply, and that the differential acquisition is improved when using pairs of channels (0 & 1, 2 & 3, etc.).

The sample rate, hardware gain and digital filter can be adjusted. It is also possible to acquire data sequentially from several channels.

The Waveshare HAT is originally meant to be used with a Raspberry Pi, but it can be used with any device supporting SPI as long as the wiring is correct and the 3.3 and 5V power are supplied.

New in version 1.5.10.

Changed in version 2.0.0: renamed from Waveshare_high_precision to WaveshareHighPrecision

__init__(spi_port: int = 0, gain_hardware: int = 16, sample_rate: int | float = 50, channels: Iterable[str] | None = None, digital_filter: int = 4, gain: float = 1, offset: float = 0) None[source]

Sets the arguments and initializes the parent class.

Parameters:
  • spi_port – The SPI port for communicating with the Waveshare HAT.

  • gain_hardware

    A programmable gain for the signal. Should be one of :

    1, 2, 4, 8, 16, 32
    

    Allows increasing the resolution of the ADC, but also divides the full scale range and greatly reduces the noise performance when set greater than 8. This value applies to all the channels.

  • sample_rate

    The number of samples per second to acquire. Should be one of:

    2.5, 5, 10, 16?6, 20, 50, 60, 100, 400, 1200, 2400, 4800, 7200,
    14400, 19200, 38400
    

    The actual achieved sample rate might be lower depending on the capability of the PC and the load on the processor. Note that the greater the sample rate, the greater the noise. For multiple channels, the achieved sample rate is roughly the target sample rate divided by the number of channels.

  • channels

    An iterable (like a list or a tuple) containing strings representing the channels to acquire. Each channel must follow one of the two syntax :

    'INi', i in range(10)
    

    or else

    'INi-INj', i, j in range(10)
    

    With the first syntax, the output is the voltage difference between the acquired channel and the ground of the power supply. With the second syntax, the output value is simply the difference between the voltages of the channels i and j. It is preferable to use the channels in pair (0 & 1, 2 & 3, etc.) for differential acquisition. The data from the different channels is acquired sequentially, not all at once.

  • digital_filter – The Waveshare Hat features a digital filter that can accept different settings. Refer to the documentation of the ADS1263 for more detail.

  • gain – Allows to tune the output values of the ADC according to the formula : \(output = gain * tension + offset\). The same gain applies to all the channels.

  • offset – Allows to tune the output values of the ADC according to the formula : \(output = gain * tension + offset\). The same offset applies to all the channels.

Important

When the gain_hardware is greater than 1, the PGA cannot amplify above 4.7V or under 0.3V. For example a 2.8V signal read with a gain of 2 would be read as 4.7V after the PGA, not 4.8V ! Beware !

open() None[source]

Sets up the GPIO and the different parameters on the ADS1263.

get_data() List[float][source]

Reads the channels sequentially, and returns all the values along with a timestamp.

Time is returned first, and the values are then returned in the same order as the channels were given.

close() None[source]

Closes the SPI bus and resets the GPIOs.

FT232H In/Outs

ADS1115 FT232H

class crappy.inout.ADS1115FT232H(device_address: int = 72, sample_rate: int = 128, v_range: float = 2.048, multiplexer: str = 'A1', dry_pin: str | None = None, gain: float = 1, offset: float = 0, _ft232h_args: Tuple[int, RLock, FileIO, FileIO, RLock, Synchronized] = ())[source]

A class for controlling Adafruit’s ADS1115 16-bits ADC through an FT232H.

It is similar to the ADS1115 class, except this class is specific for use with an FT232H USB to I2C converter.

The ADS1115 InOut is meant for reading conversion values from a 16-bits ADS1115 ADC, using the I2C protocol. The output is in Volts by default, but a gain and an offset can be specified.

Various settings can be adjusted, like the sample rate, the input mode or the voltage range.

New in version 2.0.0.

__init__(device_address: int = 72, sample_rate: int = 128, v_range: float = 2.048, multiplexer: str = 'A1', dry_pin: str | None = None, gain: float = 1, offset: float = 0, _ft232h_args: Tuple[int, RLock, FileIO, FileIO, RLock, Synchronized] = ()) None[source]

Checks the validity of the arguments.

Parameters:
  • device_address – The I2C address of the ADS1115. The default address is 0x48, but it is possible to change this setting using the ADDR pin.

  • sample_rate

    The sample rate for data conversion (in SPS). The available sample rates are:

    8, 16, 32, 64, 128, 250, 475, 860
    

  • v_range

    The value (in Volts) of the measured signal corresponding to the 0x7FFF output in bits, i.e. that saturates the sensor. A signal of -v_range Volts gives a 0x8000 output in bits. Available v_range values are:

    0.256, 0.512, 1.024, 2.048, 4.096, 6.144
    

  • multiplexer

    Choice of the inputs to consider. Single-input modes actually measure Ax - GND. The available multiplexer values are:

    'A0', 'A1', 'A2', 'A3',
    'A0 - A1',
    'A0 - A3',
    'A1 - A3',
    'A2 - A3'
    

  • dry_pin – Optionally, reads the end of conversion signal from a GPIO rather than from an I2C message. Speeds up the reading and decreases the traffic on the I2C bus, but requires one extra wire. Give the name of the GPIO in the format Dx or Cx.

  • gain – Allows to tune the output value according to the formula : \(output = gain * tension + offset\).

  • offset – Allows to tune the output value according to the formula : \(output = gain * tension + offset\).

  • _ft232h_args – This argument is meant for internal use only and should not be provided by the user. It contains the information necessary for setting up the FT232H.

Warning

AINx voltages should not be higher than VDD+0.3V nor lower than GND-0.3V. Setting high v_range values does not allow measuring voltages higher than VDD !!

open() None[source]

Initializes the I2C communication and the device.

get_data() List[float][source]

Reads the registers containing the conversion result.

The output is in Volts, unless a gain and offset are applied.

Returns:

A list containing the timestamp and the voltage value.

close() None[source]

Closes the I2C bus.

GPIO Switch FT232H

class crappy.inout.GPIOSwitchFT232H(pin_out: int | str, _ft232h_args: Tuple[int, RLock, FileIO, FileIO, RLock, Synchronized] = ())[source]

This class can drive a GPIO high or low on a FT232H.

It is similar to the GPIOSwitch class, except this class is specific for use with an FT232H USB to GPIO converter.

When the command value is 1 the GPIO is turned high, when the command is 0 it is turned low. Any value other than 0 and 1 raises an error.

New in version 2.0.0.

__init__(pin_out: int | str, _ft232h_args: Tuple[int, RLock, FileIO, FileIO, RLock, Synchronized] = ()) None[source]

Checks the validity of the arguments.

Parameters:
  • pin_out – The GPIO pin to be controlled. On Raspberry Pi, should be an integer corresponding to a GPIO in BCM convention. On FT232H, should be a string corresponding to the name of a GPIO. With the ‘blinka’ backend, should be a string holding the name of the pin. Refer to blinka’s specific documentation for each board for more information.

  • _ft232h_args – This argument is meant for internal use only and should not be provided by the user. It contains the information necessary for setting up the FT232H.

open() None

This method should perform any action that’s required for initializing the hardware and the communication with it.

Communication with hardware should be avoided in the __init__() method, and this method is where it should start. This method is called after Crappy’s processes start, i.e. when the associated IOBlock already runs separately from all the other Blocks.

It is fine for this method not to perform anything.

New in version 1.5.10.

set_cmd(*cmd: int) None[source]

Drives the GPIO according to the command.

Parameters:

cmd – 1 for driving the GPIO high, 0 for driving it low.

close() None[source]

Releases the GPIO.

MCP9600 FT232H

class crappy.inout.MCP9600FT232H(thermocouple_type: str, device_address: int = 103, adc_resolution: int = 18, sensor_resolution: float = 0.0625, filter_coefficient: int = 0, mode: str = 'Hot Junction Temperature', _ft232h_args: Tuple[int, RLock, FileIO, FileIO, RLock, Synchronized] = ())[source]

This class can read temperature values from an MCP9600 thermocouple reader through an FT232H.

It is similar to the MCP9600 class, except this class is specific for use with an FT232H USB to I2C converter.

It communicates over the I2C protocol. The output is in °C, except for one operating mode that returns Volts. Several parameters can be tuned, like the thermocouple type, the reading resolution or the filter coefficient. Note that the MCP9600 can only achieve a data rate of a few Hz.

New in version 2.0.0.

__init__(thermocouple_type: str, device_address: int = 103, adc_resolution: int = 18, sensor_resolution: float = 0.0625, filter_coefficient: int = 0, mode: str = 'Hot Junction Temperature', _ft232h_args: Tuple[int, RLock, FileIO, FileIO, RLock, Synchronized] = ()) None[source]

Checks the validity of the arguments.

Parameters:
  • thermocouple_type

    The type of thermocouple connected to the MCP9600. The possible types are:

    'J', 'K', 'T', 'N', 'S', 'E', 'B', 'R'
    

  • device_address – The I2C address of the MCP9600. The default address is 0x67, but it is possible to change this setting using a specific setup involving the ADDR pin.

  • adc_resolution

    The number of bits the ADC output is encoded on. The greater the resolution, the lower the sample rate. The available resolutions are:

    12, 14, 16, 18
    

  • sensor_resolution – The temperature measurement resolution in °C. It should be either 0.0625 or 0.25. Setting the resolution to 0.25 will increase the sample rate, but the output temperature will be encoded on two bits less.

  • filter_coefficient – The MCP9600 features an integrated filter (see its documentation for the exact filter formula). When set to 0, the filter is inactive. It is maximal when set to 7. When active, the filter will prohibit fast temperature changes, thus limiting noise and smoothening the signal.

  • mode

    Four different values can be accessed when measuring a temperature: the temperature of the thermocouple (hot junction temperature), the temperature of the MCP9600 board (cold junction temperature), the temperature calculated from the ADC data and thermocouple type but not yet cold junction-compensated (junction temperature delta), and the raw ADC measurement of the voltage difference in the thermocouple (raw data ADC, in Volts). The available modes are thus:

    'Hot Junction Temperature',
    'Junction Temperature Delta',
    'Cold Junction Temperature',
    'Raw Data ADC'
    

  • _ft232h_args – This argument is meant for internal use only and should not be provided by the user. It contains the information necessary for setting up the FT232H.

open() None[source]

Initializes the I2C communication and the device.

get_data() List[float][source]

Reads the registers containing the conversion result.

The output is in °C for all modes except the raw data ADC one, which outputs Volts.

Returns:

A list – containing the timestamp and the output value.

close() None[source]

Switches the MCP9600 to shutdown mode and closes the I2C bus.

MPRLS FT232H

class crappy.inout.MPRLSFT232H(eoc_pin: str | None = None, device_address: int = 24, _ft232h_args: Tuple[int, RLock, FileIO, FileIO, RLock, Synchronized] = ())[source]

This class can read values from an MPRLS pressure sensor through an FT232H.

It is similar to the MPRLS class, except this class is specific for use with an FT232H USB to I2C converter.

It communicates over I2C with the sensor.

New in version 2.0.0.

__init__(eoc_pin: str | None = None, device_address: int = 24, _ft232h_args: Tuple[int, RLock, FileIO, FileIO, RLock, Synchronized] = ()) None[source]

Initializes the parent class and opens the I2C bus.

Parameters:
  • eoc_pin – Optionally, reads the end of conversion signal from the polarity of a GPIO rather than from an I2C register. Speeds up the reading and decreases the traffic on the bus, but requires one extra wire. Give the name of the GPIO in the format Dx or Cx.

  • device_address – The I2C address of the MPRLS. The address of the devices sold by Adafruit is 0x18, but other suppliers may sell it with another address.

  • _ft232h_args – This argument is meant for internal use only and should not be provided by the user. It contains the information necessary for setting up the FT232H.

open() None[source]

Opens the I2C bus.

get_data() List[float][source]

Reads the pressure value.

Returns:

The timestamp and the pressure value in hPa.

close() None[source]

Closes the I2C bus.

NAU7802 FT232H

class crappy.inout.NAU7802FT232H(device_address: int = 42, gain_hardware: int = 128, sample_rate: int = 80, int_pin: str | None = None, gain: float = 1, offset: float = 0, _ft232h_args: Tuple[int, RLock, FileIO, FileIO, RLock, Synchronized] = ())[source]

This class can read values from a NAU7802 load cell conditioner.

It is similar to the NAU7802 class, except this class is specific for use with an FT232H USB to I2C converter.

This load cell conditioner is a low-cost 24-bits, single-channel conditioner, that can read up to 320 samples per second. It communicates over the I2C protocol. The returned value of the InOut is in Volts by default, but can be converted to Newtons using the gain and offset arguments.

New in version 2.0.0.

__init__(device_address: int = 42, gain_hardware: int = 128, sample_rate: int = 80, int_pin: str | None = None, gain: float = 1, offset: float = 0, _ft232h_args: Tuple[int, RLock, FileIO, FileIO, RLock, Synchronized] = ()) None[source]

Checks the validity of the arguments.

Parameters:
  • device_address – The I2C address of the NAU7802. It is impossible to change this address, so it is not possible to have several NAU7802 connected on the same I2C bus.

  • gain_hardware

    The gain to be used by the programmable gain amplifier. Setting a high gain allows reading small voltages with a better precision, but it might saturate the sensor for higher voltages. Available gains are:

    1, 2, 4, 8, 16, 32, 64, 128
    

  • sample_rate

    The sample rate for data conversion. The higher the rate, the greater the noise. Available sample rates are:

    10, 20, 40, 80, 320
    

  • int_pin – Optionally, reads the end of conversion signal from the polarity of a GPIO rather than from an I2C register. Speeds up the reading and decreases the traffic on the bus, but requires one extra wire. Give the name of the GPIO in the format Dx or Cx.

  • gain – Allows to tune the output value according to the formula : \(output = gain * tension + offset\).

  • offset – Allows to tune the output value according to the formula : \(output = gain * tension + offset\).

  • _ft232h_args – This argument is meant for internal use only and should not be provided by the user. It contains the information necessary for setting up the FT232H.

open() None[source]

Initializes the I2C communication and the device.

get_data() List[float][source]

Reads the registers containing the conversion result.

The output is in Volts by default, and can be converted to Newtons using gain and offset.

Returns:

A list containing the timeframe and the output value.

close() None[source]

Powers down the device.

Waveshare AD/DA FT232H

class crappy.inout.WaveshareADDAFT232H(dac_channels: Iterable[str] | None = None, adc_channels: Iterable[str] | None = None, gain_hardware: int = 1, v_ref: float = 3.3, gain: float = 1, offset: float = 0, sample_rate: int | float = 100, _ft232h_args: Tuple[int, RLock, FileIO, FileIO, RLock, Synchronized] = (), rst_pin_ads: str = 'D7', cs_pin_ads: str = 'D4', drdy_pin_ads: str = 'D6', cs_pin_dac: str = 'D5')[source]

Class for controlling Waveshare’s AD/DA Raspberry Pi hat through an FT232H.

It is similar to the WaveshareADDA class, except this class is specific for use with an FT232H USB to I2C converter.

It communicates over the SPI protocol and the GPIOs. It allows to read values from the 8-channels ADC and/or to set the 2-channels DAC. The hat can acquire up to 30000 samples per second, although this data rate is impossible to achieve using Crappy.

New in version 2.0.0.

__init__(dac_channels: Iterable[str] | None = None, adc_channels: Iterable[str] | None = None, gain_hardware: int = 1, v_ref: float = 3.3, gain: float = 1, offset: float = 0, sample_rate: int | float = 100, _ft232h_args: Tuple[int, RLock, FileIO, FileIO, RLock, Synchronized] = (), rst_pin_ads: str = 'D7', cs_pin_ads: str = 'D4', drdy_pin_ads: str = 'D6', cs_pin_dac: str = 'D5') None[source]

Checks the validity of the arguments.

Parameters:
  • dac_channels – An iterable (like a list or a tuple) of str representing the channels to be set. The syntax for each string is ‘DACi’ with i being either 0 or 1.

  • adc_channels

    An iterable (like a list or a tuple) of str representing the channels to read. The syntax for all the strings is either:

    'ADi' (i in range(8))
    

    or else:

    'ADi - ADj' (i, j in range(8))
    

  • gain_hardware

    The gain to be used by the programmable gain amplifier. Setting a high gain allows to read small voltages with a better precision, but it might saturate the sensor for higher voltages. The available gain values are:

    1, 2, 4, 8, 16, 32, 64
    

  • v_ref – The voltage reference set by the VREF jumper. When reading single inputs, v_ref is the value the ADC compares the signals with. In a similar way, the maximum output voltage of the DAC is v_ref. 3.3 and 5 are the only possible values for this setting, as the FT232H can only provide 3.3V and 5V.

  • gain – Allows to tune the output values of the ADC according to the formula : \(output = gain * tension + offset\). The same gain applies to all the outputs.

  • offset – Allows to tune the output values of the ADC according to the formula : \(output = gain * tension + offset\). The same offset applies to all the outputs.

  • sample_rate

    The ADC data output rate in SPS. The available values are:

    2.5, 5, 10, 15, 25, 30, 50, 60, 100, 500,
    1000, 2000, 3750, 7500, 15000, 30000
    

  • _ft232h_args – This argument is meant for internal use only and should not be provided by the user. It contains the information necessary for setting up the FT232H.

  • rst_pin_ads – The pin for resetting the ADS1256.

  • cs_pin_ads – The chip select pin for the ADS1256.

  • drdy_pin_ads – The pin for knowing when a conversion result in ready.

  • cs_pin_dac – The chip select pin for the DAC8552.

Warning

  • adc_channels: For reading single inputs the JMP_AGND jumper should normally be connected, whereas it should be disconnected for reading differential inputs. It is however possible to set a different reference than AGND for single input measurements, in which case the JMP_AGND jumper should not be connected and the voltage reference should be plugged in the AINCOM pin.

    The AD/DA offers the possibility to read single inputs or differential inputs, but not both at the same time ! This is due to the JMP_AGND jumper. For measuring both input types simultaneously, is it necessary to connect AGND to one of the channels (for example AD0). Then all single inputs ‘ADi’ should be replaced by ‘ADi - AD0’. They are then considered as differential inputs.

    The ADC channels voltages should not be lower than AGND-0.1V, and not be greater than AGND+5.1V. This is independent of VREF value.

Note

  • adc_channels: If multiple channels to read are given, they are read in a sequential way. This means that there’s a small delay between each acquisition, and the timeframe is thus less accurate for the last channels than for the first ones. If time precision matters it is preferable to read as few channels as possible !

  • vref: VREF can be set independently of the chosen VCC value. The VCC value has no influence on the ADC behaviour as it is always powered up with 5V. Same goes for the DAC.

open() None[source]

Sets the SPI communication, the GPIOs and the device.

get_data() List[float][source]

Reads data from all the user-specified ADC channels, in a sequential way.

Data is returned in Volts, but this can be tuned using gain and offset.

Returns:

A list containing the timestamp, and then the values for each channel to read.

set_cmd(*cmd: float) None[source]

Sets the user-specified DAC channels according to the input values.

Parameters:

cmd – The input values as float, in Volts.

close() None[source]

Releases the GPIOs.

Parent In/Out

InOut

class crappy.inout.InOut(*_, **__)[source]

Base class for all InOut objects. Implements methods shared by all the InOuts, and ensures their dataclass is MetaIO.

The InOut objects are helper classes used by the IOBlock to interface with hardware.

New in version 1.4.0.

__init__(*_, **__) None[source]

Sets the attributes.

Changed in version 2.0.0: now accepts args and kwargs

log(level: int, msg: str) None[source]

Records log messages for the InOut.

Also instantiates the logger when logging the first message.

Parameters:
  • level – An int indicating the logging level of the message.

  • msg – The message to log, as a str.

New in version 2.0.0.

open() None[source]

This method should perform any action that’s required for initializing the hardware and the communication with it.

Communication with hardware should be avoided in the __init__() method, and this method is where it should start. This method is called after Crappy’s processes start, i.e. when the associated IOBlock already runs separately from all the other Blocks.

It is fine for this method not to perform anything.

New in version 1.5.10.

get_data() Iterable | Dict[str, Any] | None[source]

This method should acquire data from a device and return it along with a timestamp.

The data can be either returned as raw values in an iterable object (like a list or a tuple), or along with labels in a dict. Values can be of any type (float, int, str, bytes, etc.), but most Blocks in Crappy will expect numeric values.

If the data is returned in a dictionary, its keys will be the labels for sending data to downstream Blocks. The labels argument of the IOBlock is ignored. It is mandatory to use ‘t(s)’ as the label for the time value.

Example

return {'t(s)': time.time(), 'value_1': -3.5, 'value_2': 4.1}

If the data is returned as another type of iterable, the labels must be provided in the labels argument of the IOBlock. The number of labels must match the number of returned values. It is mandatory to return the time value first in the iterable.

Example

return time.time(), -3.5, 4.1

In both cases, there’s no limit to the number of returned values. The same number of values must always be returned, and each value must keep a consistent type throughout the test.

It is alright for this method to return None if there’s no data to acquire.

New in version 1.5.10.

set_cmd(*cmd) None[source]

This method should handle commands received from the upstream Blocks.

Among all the data received on the incoming Link(s), only the labels listed in the cmd_labels argument of the IOBlock are considered. The command values are passed as arguments to this method in the same order as the cmd_labels are given. They are passed as positional arguments, not keyword arguments.

Example

If {'t(s)': 20.5, 'value_1': 1.5, 'value_2': 3.6, 'value_3': 'OK'} is received from upstream Blocks, and cmd_labels=('value_3', 'value_1'), then the call will be set_cmd('OK', 1.5).

New in version 1.5.10.

start_stream() None[source]

This method should start the acquisition of the stream.

New in version 1.5.10.

get_stream() Iterable[ndarray] | Dict[str, ndarray] | None[source]

This method should acquire a stream as a numpy.array, and return it along with another array carrying the timestamps.

Two arrays should be created: one of dimension (m,) carrying the timestamps, and one of dimension (m, n) carrying the acquired data. They represent n channels acquired at m successive time points. There’s no maximum number of acquired channels, but this number must be constant throughout a test.

The two arrays can either be returned as is in an iterable object (like a list or a tuple), or along with labels in a dict.

If the arrays are returned in a dictionary, its keys will be the labels for sending data to downstream Blocks. The labels argument of the IOBlock is ignored. It is mandatory to use ‘t(s)’ as the label for the time array.

If the arrays are returned in another type of iterable, two labels must be provided in the labels argument of the IOBlock. The first label must be ‘t(s)’, the second can be anything. It is mandatory to return the time value first in the iterable.

It is alright for this method to return None if there’s no data to acquire.

Note

It is technically possible to return more than two arrays, or even objects that are not arrays, but it is not the intended use for this method and might interfere with some functionalities of Crappy.

New in version 1.5.10.

stop_stream() None[source]

This method should stop the acquisition of the stream.

New in version 1.5.10.

close() None[source]

This method should perform any action required for properly ending the test and closing the communication with hardware.

It will be called when the associated IOBlock receives the order to stop (usually because the user hit CTRL+C, or because a Generator Block reached the end of its path, or because an exception was raised in any of the Blocks).

It is fine for this method not to perform anything.

New in version 1.5.10.

make_zero(delay: float) None[source]

This method acquires data for a given delay and stores for each channel the average value.

These values are used for zeroing the channels, so that their values start at 0 in the beginning of the test.

Important

This method uses get_data() for acquiring the values, so it doesn’t work for pure streams. It also doesn’t work if the acquired values do not support arithmetic operations (like str).

New in version 1.5.10.

return_data() List[Any] | Dict[str, Any] | None[source]

Returns the data from get_data(), corrected by an offset if the make_zero_delay argument of the IOBlock is set.

New in version 1.5.10.

return_stream() List[ndarray] | Dict[str, ndarray] | None[source]

Returns the data from get_stream(), corrected by an offset if the make_zero_delay argument of the IOBlock is set.

New in version 1.5.10.

Meta InOut

class crappy.inout.MetaIO(name: str, bases: tuple, dct: dict)[source]

Metaclass ensuring that two InOuts don’t have the same name, and that all InOuts define the required methods. Also keeps track of all the InOut classes, including the custom user-defined ones.

New in version 1.4.0.

Changed in version 1.5.10: not checking anymore for mandatory methods in __init__()

__init__(name: str, bases: tuple, dct: dict) None[source]