Skip to content

PO8eStreaming

PO8eStreaming is a library of methods for accessing data on one or several PO8e interfaces through a custom Windows or Linux application. See PO8e Streaming Interface for more hardware-related information.

The PO8eStreaming libraries and examples for C++, Python, and MATLAB install with the TDT drivers into:

C:\TDT\RPvdsEx\Examples\PO8e\

Users should be mindful of using good 'closed loop' access when working with PO8eStreaming. This means always releasing any open connections to PO8e cards.

A typical PO8e access session for a client consists of five main steps:

  1. Call connectToCard to get a pointer to an available PO8e card.
  2. Call startCollecting to begin reading from PO8e card.
  3. Run the circuit on the RZ device that streams to the PO8e card.
  4. Perform any number of buffer operations.
  5. Call releaseCard to release the card object from memory.

Setup and Control

The methods in this group are used to setup access to any PO8e card(s) in the system.

cardCount

Returns the number of PO8e cards detected in the system. Call this first to determine the possible values for the cardIndex passed to the constructor.

static int cardCount();
int cardCount();
Returns Type Values
totalCards int 0-4, total number of cards in the system

Example

int totalCards = PO8e::cardCount();
int totalCards = cardCount();

connectToCard

Returns a pointer to the specified card index. Note that the index will be consistent across system boots and is dependent on the PCIe bus layout, so if you move the cards between slots their respective indices can change.

static PO8e* connectToCard(unsigned int cardIndex = 0);
void* connectToCard(unsigned int cardIndex = 0);
Inputs Type Values
cardIndex unsigned int 0-3, target card index
Returns
pointer to PO8e instance

Example

This code sample creates a PO8e object pointing to the first card identified in the system.

PO8e *card = PO8e::connectToCard(0);
void *card = connectToCard(0);

releaseCard

Free the PO8e card objects through this interface. It is done this way to ensure that in Windows the objects are freed from the correct heap context.

static void releaseCard(PO8e *card);
void releaseCard(void* card);
Inputs Type
card pointer to PO8e object

Example

This code sample releases the card object memory.

PO8e::releaseCard(card);
releaseCard(card);

Hardware Data Access

The methods in this group are used to read data from PO8e card(s).

startCollecting

Call this to start collecting a data stream from the PO8e card. Collected data will be buffered as needed.

bool startCollecting(bool detectStops = true);
bool startCollecting(void* card, bool detectStops = true);
Inputs Type Description
detectStops bool Tell the PO8e to detect when the stream from the RZ is stopped
Returns
pointer to PO8e instance

Example

This code sample tells an existing PO8e object to begin collecting data.

card->startCollecting(true);
startCollecting(card, true);

stopCollecting

Call this to stop collecting a data stream from the PO8e card.

void stopCollecting();
void stopCollecting(void* card);

Example

This code sample stops data collection on a PO8e object.

card->stopCollecting(true);
stopCollecting(card, true);

waitForDataReady

This function provides a means to efficiently wait for data to arrive from the RZ unit.

size_t waitForDataReady(int timeout = 0xFFFFFFFF);
int waitForDataReady(void* card, int timeout = 0xFFFFFFFF);
Inputs Type Description
timeout int Maximum duration (in ms) to wait for streaming to begin.

Example

This code sample blocks execution until buffered data is ready on the card.

card->waitForDataReady();
waitForDataReady(card);

samplesReady

Returns the number of samples (per channel) that are currently buffered.

size_t samplesReady(bool *stopped = 0);
int samplesReady(void* card, bool *stopped = 0);
Inputs Type Description
stopped bool pointer The value pointed to will be set to true if the underlying
mechanisms detect that data has stopped flowing.
Returns
numSamples size_t or int Number of samples (per channel) that are currently buffered

Example

This code returns the number of samples (per channel) currently buffered on the card and detects if streaming has stopped.

bool stopped;
size_t numSamples = card->samplesReady(&stopped);
if (stopped)
    PO8e::releaseCard(card);
bool stopped;
int numSamples = samplesReady(card, &stopped);
if (stopped)
    releaseCard(card);

readChannel

Copy the data buffered for an individual channel. Note that this call does not advance the data pointer. Use calls to flushBufferedData to discard the data copied using this function.

The user is responsible for ensuring that the buffer is large enough to hold nSamples * dataSampleSize() bytes.

The optional offsets array should be nSamples long and will be populated with the data offset of each block. This allows a user to detect if the buffer on the RZ unit has overflowed.

int readChannel(int chanIndex, void *buffer, int nSamples, int64_t *offsets = NULL);
int readChannel(void* card, int chanIndex, void *buffer, int nSamples, int64_t *offsets);
Inputs Type Description
chanIndex int The channel to read data from (1-based)
buffer void pointer The location to write buffered data to
nSamples int The number of samples to read
offsets int64_t pointer The location to write the buffer indices to
Returns
numSamples int Number of samples that were read

Example

This code sample reads 1 sample from channel 2 and stores it in buff.

short buff[8192];
card->readChannel(2, buff, 1);
short buff[8192];
readChannel(card, 2, buff, 1);

readBlock

Copy the data buffered for all channels. Note that this call does not advance the data pointer. Use calls to flushBufferedData to discard the data copied using this function.

The data will be grouped by channel and the number of samples returned applies to all channels. The user is responsible for ensuring that the buffer is large enough to hold nSamples * numChannels() * dataSampleSize() bytes.

The optional offsets array should be nSamples long and will be populated with the data offset of each block. This allows a user to detect if the buffer on the RZ unit has overflowed.

int readBlock(void *buffer, int nSamples, int64_t *offsets = NULL);
int readBlock(void* card, void *buffer, int nSamples, int64_t *offsets);
Inputs Type Description
buffer void pointer The location to write buffered data to
nSamples int The number of samples to read
offsets int64_t pointer The location to write the buffer indices to
Returns
numSamples int Number of samples that were read

Example

This code sample reads 1 sample from all channels, stores it in a buffer, and flushes that data from the card.

short buff[1024];
card->readBlock(buff, 1);
card->flushBufferedData(1);
short buff[1024];
readBlock(card, buff, 1);
flushBufferedData(card, 1);

flushBufferedData

Releases samples from each buffered channel.

void flushBufferedData(int numSamples = -1, bool freeBuffers = false);
void flushBufferedData(void* card, int numSamples = -1, bool freeBuffers = false);
Inputs Type Description
numSamples int Number of samples to release. Passing -1 releases all buffered samples
freeBuffers bool Controls the optional freeing of the underlying data buffers

Example

This code sample flushes one sample from all channels.

card->flushBufferedData(1);
flushBufferedData(card, 1);

Hardware Information Retrieval

The methods in this group access information pertaining to the current data stream, including number of channels and sample size in bytes.

numChannels

Counts the number of channels in the current stream. This value is set in the PO8e HAL in Synapse (or Stream_Remote_MC macro in RPvdsEx). Changing the number of channels mid-stream triggers an error condition.

int numChannels();
int numChannels(void* card);
Returns Type Description
nChannels int Number of channels in the current data stream

Example

This code determines how many channels are in the current stream.

int nChannels = card->numChannels();
int nChannels = numChannels(card);

numBlocks

Counts the number of blocks that the current stream is divided into. This value will always be 1 when using Synapse, or can be set in the Stream_Remote_MC macro in RPvdsEx.

Each block will contain the same number of channels, so dividing the value from numChannels() by this value will leave no remainder. Changing the number of blocks mid-stream triggers an error condition.

int numBlocks();
int numBlocks(void* card);
Returns Type Description
nBlocks int Number of blocks the current data stream is divided into

Example

This code determines how many blocks are in the current stream.

int nBlocks = card->numBlocks();
int nBlocks = numBlocks(card);

dataSampleSize

Returns the size in bytes of each data sample (per channel). This value is set in the PO8e HAL in Synapse (or Stream_Remote_MC macro in RPvdsEx). Changing the data type mid-stream triggers an error condition.

int dataSampleSize();
int dataSampleSize(void* card);
Returns Type Description
dataSize int Size of each data sample in bytes

Example

This code determines how many bytes are in each sample.

int dataSize = card->dataSampleSize(); 
int dataSize = dataSampleSize(card);

getLastError

This returns the most recent error.

int getLastError();
int getLastError(void* card);
Returns Type Description
errCode int The most recent error code

Example

This code returns the most recent error code.

int errCode = card->getLastError(); 
int errCode = getLastError(card);

Examples

The example files below are installed with the TDT drivers package.

PO8eTest

C:\TDT\RPvdsEx\Examples\PO8e\PO8eTest.rcx
C:\TDT\RPvdsEx\Examples\PO8e\PO8eTest.exe

PO8eTest.exe connects to any PO8e card(s) in the PC, waits for a stream then displays the data rate that each PO8e card is receiving.

PO8eTest.rcx streams 256 channels of floats to the PO8e card at 6.1 kHz.

  1. Run PO8eTest.exe test application first.
  2. Verify that it connected to the PO8e card.
  3. Open PO8eTest.rcx in RPvdsEx.
  4. Assign the circuit to the DSPU or DSPS in your RZ.
  5. Run the circuit.
  6. Set the zBusA trigger high to begin streaming.
  7. Verify that PO8eTest.exe sees data.
  8. Set the zBusA trigger low to stop streaming.

Source Files:

C:\TDT\RPvdsEx\Examples\PO8e\Example\
C:\TDT\RPvdsEx\Examples\PO8e\Include\

MATLAB

C:\TDT\RPvdsEx\Examples\PO8e\Matlab\

The PO8e_4card.m class wraps the PO8e Streaming Library. The PO8e_4cardTest.m example demonstrates reading from PO8e card(s) in MATLAB.

Python

C:\TDT\RPvdsEx\Examples\PO8e\Python64

The PO8e.py class wraps the PO8e Streaming Library and contains demo code for reading from PO8e card(s) in Python.

Linux Support

Some Linux library files and example build instructions are installed to:

C:\TDT\RPvdsEx\Examples\PO8e\Linux

Please contact TDT if you need assistance.