AnalogOut

class picodaq.dac.AnalogOut(rate: Frequency | None = None, port: str | None = None, maxahead: int | Time | None = None, serno: str | None = None)

Main interface for stimulating through analog channels

Parameters:
  • rate – Sampling frequency for output

  • port – Serial port to open

  • maxahead – Max. number of samples to preload

The rate may be specified in Hz or kHz. When using multiple streams, the rates must all be the same and only need to be specified on the first-opened stream.

The port specifies which serial port to open. Use picodaq.devices() to retrieve the list of available ports. If you do not specify a port, the most recently opened device is used, or the first device on the system if none was opened before.

The maxahead parameter specifies the maximum number of samples preloaded to the device during open() and through poll(). If omitted, this is optimized to reduce risk of underruns. The most common reason to set it explicitly is to reduce latency for dynamically generated “sampled” outputs.

The stimuli themselves are added by calling the stimulus() or sampled() methods on the individual channels, which may be accessed using indexing syntax, as in the following example:

pulse1 = stimulus.Sawtooth(-3*V, 3*V, 80*ms)
train1 = stimulus.Train(pulse1, 5, pulseperiod=100*ms)
with AnalogOut(rate=30*kHz) as ao:
    ao[2].stimulus(train1)
    ao.run()
__getitem__(channel: int)

Access to a single channel.

This provides a convenient syntax for specifying stimulation sequences.

Example:

pulse = Monophasic(1*V, 10*ms)
train = Train(pulse, pulsecount=5, pulseperiod=20*ms)
with AnalogOut(rate=10*kHz) as ao:
    ao[1].stimulus(train)
close()

Close the stream

The underlying device is automatically closed once the last stream is closed.

commit()

Send all defined stimulus sequences to the device.

In most cases, you do not need to use this method, as it is called automatically by start() and run() as needed.

That said, committing takes several milliseconds, or more if long waves need to be transmitted. By calling commit() explicitly before calling start() or run(), you can control the timing of the start of the stimulation more precisely.

If you make any changes to stimulation parameters, you will have to re-commit. The system understands that and will do it for you upon start() or run(). However, relying on this behavior is not recommended, if only because it negates any timing advantage of calling commit() ahead of time.

continuous()

Select continuous recording mode

This cancels a previous episodic(...) call. You normally do not need to call this, as continuous recording is the default.

episodic(duration: Time | None = None, period: Time | None = None, count: int | None = None)

Select episodic recording mode

Parameters:
  • duration – Duration of each episode

  • period – start-to-start time between episodes

  • count – number of episodes before automatically stopping

The period is measured start-to-start and is optional if triggering is enabled, in which cases it specifies the minimum period.

The count parameter, if given, specifies that the recording will stop automatically after that number of episodes have been recorded. Otherwise, it continues until the user stops the recording.

The specified duration of each episode may be internally lengthened slightly so that it constitutes an even number of USB transfer chunks.

In episodic mode, the timing of any stimuli is modified such that there is one train per episode and the defined inter-train intervals are ignored. The timing between start of the episode and the first pulse of a stimulus is determined by the delay parameter on the stimulus.

See also continuous.

immediate()

Disable triggering

This cancels a preceding trigger(...) call, so recording commences immediately upon start(). You normally do not have to call this, as immediate start is the default operation.

open()

Open the stream

This automatically opens the underlying picoDAQ device. If more than one stream is associated with a single device, each stream must be individually opened and the device remains open as long as any streams are open.

Often, with ... as syntax is more convenient than calling open() yourself. If you do call open() yourself, you must match it with close().

poll() bool

Send some data, if space available in buffer

Returns:

True if the last chunk has been sent

You must call start and stop yourself.

run()

Convenience function to run through an entire stimulus sequence.

This starts the device running. Once stimulation is complete, concurrently recorded data may be retrieved using the readall() methods of AnalogIn and DigitalIn.

This method may be called whether or not the output stream was opened and returns the stream to the original state at the end of the stimulation sequence. That means that the device is left running at the end of the sequence if the output stream was previously opened, and stopped if it was not.

If using both AnalogOut and DigitalOut, calling run() on either has the same effect.

Example:

ao = AnalogOut(...)
ao[0].stimulus(...)
...
with AnalogIn(channels=..., rate=...) as ai:
    ao.run()
    # The device is now in "stopped" state.
    data = ai.alldata()
start()

Start data acquisition

You typically do not have to call this directly, as read() calls it for you. If more than one stream is associated with a single PicoDAQ device, calling start() on one stream suffices to start all of them.

The streams must be open before being started.

Commits stimulation sequences if still needed.

stop()

Stop data acquisition

You typically do not have to call this directly, as close() (or the end of a with ... as block) calls it for you.

If more than one stream is associated with a single PicoDAQ device, calling stop() on one stream suffices to stop all of them.

trigger(source: int, polarity: int)

Define triggering

Parameters:
  • source – the digital line to monitor

  • polarity – edge on which to trigger

The recording (whether continuous or episodic) is not actually started until the given trigger condition is met. The source parameter (0, 1, 2, or 3) specifies a digital channel. The polarity parameter specifies whether the system triggers on rising edge (polarity > 0) or on falling edge (polarity < 0).

See also immediate.

Specifying stimuli

To specify stimuli for a given output channel, use indexing syntax on an AnalogOut object (i.e., something like ao[1]), then use the stimulus() or samples() methods on the returned OutRef object. See also Recipes for using picoDAQ as a pulse generator, Recipes for using picoDAQ as a function generator and Recipes for generating nonparametric (“sampled”) output in the Cookbook section of the picoDAQ documentation.

class picodaq.dac.OutRef(stream: Stream, idx: int)

Helper class to allow access to stimuli for a single channel or line.

sampled(data: ArrayLike | Iterable[ArrayLike], scale: Voltage = 1 * V, offset: Voltage = 0 * V, raw: bool = False)

Define raw data to be sent to a single output channel

Parameters:
  • data – output data for the channel

  • scale – scale factor to apply to the data

  • offset – offset to be added after scaling

  • raw – data represent raw binary values

You may either specify prepared data as an array (T-vector) or specify a callable that generates the data on the fly and that “yields” data in arbitrary quantities.

The data (whether predefined or generated) are multiplied by the given scale factor. Then, the given offset is added and the result is converted to digital units. By default, the scale is one volt and the offset is zero. Alternatively, if you specify raw = True, you may specify data as raw binary values (16-bit signed integers). In that case, scale and offset may not be specified.

When digital data are represented as a Sampled, nonzero values map to digital 1 and zero values to digital 0. In this case, the scale, offset, and raw parameters are ignored.

stimulus(stim: Pulse | Train | Series, delay: Time = 0 * s, repeat: Time | None = None, offset: Voltage = 0 * V)

Define a parametrized stimulation sequence for a single output

Parameters:
  • stim – a Series, a Train, or a single Pulse (or derivative).

  • delay – delay to first pulse

  • repeat – repeat period for the stimulus or None

  • offset – offset voltage for the channel

The delay is measured from the start of the recording to the first pulse in continuous mode, or from the start of each episode to its first pulse in episodic mode.

The repeat period, if given, is the start-to-start period for repeating the entire sequence. If not given, the stimulus does not repeat.

If a stimulus is used on an AnalogOut channel, the offset voltage is applied continuously, even outside of pulses and trains. On DigitalOut lines, the offset is ignored.