Measurement Computing DAQ

pybarst.mcdaq

MCDAQ channel

The Barst Measurement Computing DAQ device interface. A MC DAQ channel is a interface to a MC DAQ device, such as a Switch & Sense 8/8 which has 8 input channels and 8 output channels. See MCDAQChannel for details.

This channel only supports MC DAQ devices that have ports that are permenataly input and/or output, but not those in which a single port can be configured for input or output.

For example, the Switch & Sense 8/8 has 8 input lines and 8 separate output lines. There can be a maximum of 16 input and 16 output lines in a single device. The state of each line can be controlled independently. However, not all devices must have all 16 lines, e.g. the Switch & Sense 8/8 only has 8 input and 8 output lines.

Driver requirements

In order to create MC DAQ channels, the MC InstaCal drivers (http://www.mccdaq.com/daq-software/instacal.aspx) must be installed. In particular, the server dynamically loads either CBW32.dll or CBW64.dll, depending if the server is a 64-bit or 32-bit compiled binary, respectively from the system path.

When installing from a wheel, the server comes with these dlls preinstalled.

If driver errors arise, either, the driver is not installed, an older version of the driver is installed, or the incorrect 64/32-bit version is installed. The dlls seem to be installed in C:Program FilesMeasurement ComputingDAQ. If this path is not in the system path and the dlls fail to be loaded, one can manually copy the dlls to the same folder as Barst.exe file, making it available for Barst.

Finally, in order to be able to use a particular device, that device must be loaded from InstaCal and assigned a channel number. Then channel number is then used in MCDAQChannel to create a MCDAQChannel channel controlling the device.

Typical usage

For the MCDAQChannel channel, once a channel is created on the server, it’s always active. That means that there’s no need to set the state with set_state().

Typically, a client creates a MCDAQChannel and then calls MCDAQChannel.open_channel() on it to create the channel on the server. Once created, the client can read and write to it through the server using MCDAQChannel.read() and MCDAQChannel.write().

Other clients can do similarly; they create a new MCDAQChannel instance and then call MCDAQChannel.open_channel() on it to open a new connection to the existing channel. Those new clients can then read/write to the channel as well.

Finally, existing clients can call close_channel_client() to simply close this client while leaving the channel on the server, or close_channel_server() to delete the channel from the server as well as for all the clients. If MCDAQChannel.continuous is True, a client can also call MCDAQChannel.cancel_read() to cancel the continuous read triggered by this client.

class pybarst.mcdaq.MCDAQChannel(int chan, BarstServer server, direction='rw', init_val=0, continuous=False, **kwargs)

Bases: pybarst.core.server.BarstChannel

An Measurement Computing interface channel.

A Measurement Computing DAQ channel controls a single Measurement Computing DAQ device. See module description for details.

Parameters:
chan: int

The channel number of the device. Before an MC DAQ device can be used, one has to load it and assign a channel number to it using InstaCal. Using a particular channel number here, will select which DAQ device to read / write to.

server: BarstServer

An instance of a server through which this channel is opened.

direction: str

Whether this channel can read, write, or do both. See direction. Defaults to ‘rw’.

init_val: unsigned short

If this this channel can write, the value to initialize the channel with after it’s created. See init_val. Defaults to 0.

continuous: str

If this channel can read, whether when reading from it, data will be sent back to the client continuously. See continuous. Defaults to False.

For example with a Switch & Sense 8/8 connected and enumerated as port 0:

>>> # open the channel, which supports both input / output
>>> daq = MCDAQChannel(chan=0, server=server, direction='rw', init_val=0)
>>> # create it on the server
>>> daq.open_channel()
>>> print(daq)
<pybarst.mcdaq._mcdaq.MCDAQChannel object at 0x02269EF8>
>>> # now read the port
>>> print(daq.read())
(4.913095627208118, 0)
>>> # all ports at the input are low
>>> # now set output line 1 to high
>>> print(daq.write(mask=0x00FF, value=0x0002))
4.91410123958
cancel_read(self, flush=False)

See cancel_read() for details.

This method is only callable when continuous is True.

Note

When flush is False, the server will continue sending data that has already been queued, but it will not add new data to the queue. After the last valid read, read() will return with an error indicating there’s no new data coming. After that error, a further call to read() will cause a new read request and data will start coming again.

If flush is True, the server will discard all data waiting to be sent, and the client will not receive the final error message when calling read(). Instead, a subsequent call to read() will cause a new read request to be sent to the server and data will start coming again.

close_channel_client(self)

See close_channel_client() for details.

continuous

continuous: ‘int’

Whether, when reading, the server should continuously read and send data back to the client. This is only used for a input device (direction contains ‘r’). When True, a single call to read() after the channel is opened will start the server reading the device continuously and sending the data back to this client. This will result in a high sampling rate of the device. If it’s False, each call to read() will trigger a new read resulting in a possibly slower reading rate.

direction

direction: object

Whether this channel can read, write, or do both. A single MC DAQ device can have both read and write ports. This attribute indicates if the device has a output port, a input port, or both. ‘w’ means it only has an output port, ‘r’ means it only has an input port, and ‘rw’ or ‘wr’ means that it has both a output and input port.

init_val

init_val: ‘unsigned short’

What values (high/low) the output pins (if it supports output) will be set to when the channel is initially created on the server.

open_channel(self)

Opens the, possibly existing, channel on the server and connects the client to it. If the channel already exists, a new client connection will be opened to the channel.

See open_channel() for more details.

Note

If the channel already exists on the server, the settings used to initialize this client, e.g. direction will be overwritten by their values received from the existing server channel.

read(self)

Requests the server to read the states of the pins of the DAQ device. This method will wait until the server sends data, or an error message, thereby tying up this thread.

If continuous is False, each call triggers the server to read from the device which is then sent to the client. If continuous is True, after the first call to read() the server will continuously read from the device and send the results back to the client. This means that if the client doesn’t call read() frequently enough data will accumulate in the pipe. Also, the data returned might have been acquired before the current read() was called.

To cancel a read request while the read is still waiting, from another thread you must call close_channel_client(), or close_channel_server(), or just delete the server, which will cause this method to return with an error.

When continuous is True, a more gentle way of canceling a read request while not currently waiting in read(), is to call cancel_read() which will cause a subsequent read operation to return with an error, but will not delete/close the channel. However, once read() returns with an error, a further call to read() will cause the reading to start again. See those methods for more details.

Before this method can be called, open_channel() must be called.

Returns:2-tuple of (time, data). time is the time that the data was read in server time, pybarst.core.server.BarstServer.clock(). data is a unsigned short (16-bit) value indicating the states of each pin of the input port. See class description.

For example:

>>> print(daq.read())
(3.5920170227303707, 15)
>>> # input lines 0-3 are high
set_state(self, int state, flush=False)

See set_state() for details.

Note

For a Measurement Computing DAQ channel, this method doesn’t do anything, since after creation, the state of the channel on the server is always active.

write(self, unsigned short mask, unsigned short value)

Tells the server to update the states of some digital pins on the DAQ device.

Before this method can be called, FTDIPin.open_channel() must be called.

Parameters:
mask: unsigned short (16-bit)

The mask which controls which port’s state will be changed by value. E.g. a value of 0b01000001 means that only pin 0, and pin 6 can be changed by value, all the other lines will remain unchanged no matter their value in value.

value: unsigned short (16-bit)

The 16-bit value which will be written to the port controlled by this channel according to the mask mask. Only bits which have a high value in mask will be changed by the values in value, the others will remain the same.

Each element in buffer is similar to data ‘s, value parameter. A high value for the corresponding pin will set the pin high, and low otherwise.

Returns:

float. The server time, pybarst.core.server.BarstServer.clock(), when the data was written.

For example:

>>> # set the lines 0-3 to high
>>> print(daq.write(mask=0x00FF, value=0x000F))
3.58502208323
>>> # set only line 0 low, the remaining lines are unchanged
>>> print(daq.write(mask=0x0001, value=0x0000))
3.58652372654