MasterScan
Lab_Matlab_control Master Branch
|
Implement analog input scans with mexHID() and the 1208FS USB device.
Note that AInScan1208FS requires MCCFormatReport.m and the mexHID() mex-function for USB communictaion.
AInScan1208FS uses the mexHID() mex function to locate and control the "1208FS" USB device from Measurement Computing. AInScan1208FS uses a subset of features of the 1208FS:
Timing is a key part of interpreting input scan results. For AInScan1208FS, good timing depends on mexHID(), the function that provides USB support, as well as the 1208FS device itself. Here are some general timing considerations for mexHID() and the 1208FS.
mexHID() timing
mexHID() exposes to Matlab the USB and HID functionality of its host operating system (so far only OS X). Thus it allows Matlab to exchange data with USB "Human Interface Devices", including the 1208FS. USB data exchanges are called "transactions", which take place during USB "frames", which are regular chunks of time. So for USB devices, timing considerations have the flavor of "During which frame was that command sent?" and "What time did that frame occur?". mexHID() makes this kind of information available.
In particular, for each transaction that it initiates, mexHID() returns a pre- and post-transaction frame number, each with its own timestamp. The pre-post interval indicates how many frames (usually 2) or seconds it took to carry out a transaction. Large intervals might indicate a problem. The post-transaction timestamps tend to align with the discrete USB frame edges.
For the 1208FS device, each USB frame is 1ms long, and this is the timing precision available for controlling the device and accounting for its interactions with the operating system (but not for its onboard behavior, see below).
As an aside, note that learning when a transaction happened is not the same as controlling when it will happen. Such control is not available from mexHID(), nor is it natural to implement in Matlab. But in many cases, as long as the timing information is accurate, it doesn't matter whether it's "past tense" or "future tense".
1208FS HID and onboard behaviors HID is a protocol for working with some types of USB device. mexHID() can exchange data and commands with the HID front-end of the 1208FS device. These exchanges are limited by 1ms USB frames. The device also has an onboard microcontroller and memory which enable significant behaviors which are beyond the scope of the HID protocol and normal "human interfaces".
AInScan1208FS uses these onboard behaviors to scan analog inputs with deterministic timing: it sets values in the device's memory which control input channel selection and gain, scan frequency, duration, starting, and stopping. Scanned voltage samples are buffered in the device's memory. Since the onboard microprocessor is removed from Matlab and its multitasking host opertating system, AInScan1208FS expects the samples to be taken with deterministic timing. Also, since the internal workings of the device are distinct from its HID interface, it may scan at frequencies which are well beyond the reach of 1ms USB frames. That's why it can support 50kHz sample rates.
Timing reconstruction Once buffered on the device, samples can be transferred to Matlab in batches. Note that the time when each batch of samples was transferred to Matlab is quite distinct from the time when each sample was stored onboard the 1208FS. Thus, AInScan1208FS must reconstruct sample timing after each batch has been transferred, based on channel and scan configuration.
Here are a few considerations for interpreting the sample times that AInScan1208FS reports from getScanWaveform():
Properties and Events | |
Property | vendorID = 2523 |
GAIN SETTINGS low precision, big range 0 -> 1x +-20V 1 -> 2x +-10V 2 -> 4x +-5V 3 -> 5x +-4V 4 -> 8x +-2.5V 5 -> 10x +-2V 6 -> 16x +-1.25V 7 -> 20x +-1V high precision, small range. More... | |
Property | productID = 130 |
USB product ID for the 1208FS device. | |
Property | channels = [0 1] |
differential(0-7) or single-ended(8:15) input channels to scan | |
Property | gains = [7 7] |
precision-and-range selection for differential channels | |
Property | frequency = 1000 |
input sample frequency (0-50000Hz), same for each channel | |
Property | nSamples = inf |
number of samples to gather in a scan, total among all channels | |
Property | externalTrigger = false |
whether an external trigger will initiate the first scan | |
Property | externalRetrigger = false |
whether an external trigger will initiate multiple scans | |
Property | queueDepth = 10000 |
sample bytes the OS can hold between transfers to Matlab | |
Property | waitTimeout = 0.1 |
seconds to wait for some new data during waitForData() | |
Property | clockFrequency = 10e6 |
clock frequency used by the 1208FS microcontroller | |
Property | clockMaxPreload = 65535 |
maximum counter size used by the 1208FS microcontroller | |
Property | clockMaxPrescale = 8 |
maximum clock scale exponent used by the 1208FS microcontroller | |
Property | sampleValueCookies = 3:64 |
HID element cookies for input sample values. | |
Property | sampleCountCookies = 65 |
HID element cookie for input sample counting. | |
Property | bytesPerSample = 2 |
number of bytes in an input sample | |
Property | samplesPerReport = 31 |
number of samples in an input batch transfer | |
Property | maxBufferSize = 50000 |
maximum size of cvtu buffer | |
Property | cvtu = [] |
stored waveforms (channel, volts, time, unsigned data) | |
Property | oldDataSelector |
logical array indicating the data that has already come in | |
Protected Properties | |
Property | isAvailable |
whether the 1208FS was found and configured | |
Property | isScanning =false |
whether it is currently scanning | |
Property | deviceIDs |
mexHID() device IDs for all the 1208FS sub-devices | |
Property | primaryID |
mexHID() device ID for the primary 1208FS device | |
Property | helperID |
mexHID() device ID for the 1208FS helper devices | |
Property | nHelpers |
number of 1208FS helper devices | |
Property | scanConfigReport |
struct of HID report and metadata for device configuration | |
Property | scanStartReport |
HID report ID to start analog input scans. | |
Property | scanStopReport |
HID report ID to stop analog input scans. | |
Property | allInputCookies |
HID element cookies for all input data. | |
Property | sampleIntMagnitude |
place values for signed input bytes | |
Property | sampleUIntMagnitude |
place values for unsigned input bytes | |
Property | sampleBytesPerReport |
array size of input batch transfers | |
Property | zeroTime |
USB frame time for the 0th input sample. | |
Property | transferredData |
containers.Map of new, unprocessed sample data | |
Property | baseElementCache |
Matlab-side cache of raw HID report data. | |
Property | reportNumbers = zeros(2^8,1) |
Keep track of each time a particular 8-bit report number happens. | |
Methods | |
self | AInScan1208FS (properties) |
Open and configure the 1208FS device with mexHID(). More... | |
status | close (self) |
Release the mexHID() devices. More... | |
timestamp | prepareToScan (self) |
Configure the 1208FS for a new scan. More... | |
timestamp | startScan (self) |
Initiate a prepared scan. More... | |
timestamp | stopScan (self) |
Terminate an ongoing scan. More... | |
c v t u | getScanWaveform (self, waitFlag, getLatestFlag) |
Process data from a previous scan. More... | |
gotNewData startTime finishTime | waitForData (self) |
Wait for new data to arrive, or timeout. More... | |
preview (self, dur, ax) | |
Plot waveforms as data arrive. More... | |
Protected Methods | |
buildHIDReports (self) | |
Remake the config, start, and stop output reports. | |
c v t u n | channelsFromCache (self, cache) |
Reconstruct the samples in a given cache of element byte data. | |
waveformsFromTransfers (self) | |
Reconstruct all the samples in all the transferred data. | |
Static Methods | |
static | mexHIDQueueCallback (context, newData) |
Transfer buffered sample data and keep track of helper devices. More... | |
self AInScan1208FS | ( | properties | ) |
Open and configure the 1208FS device with mexHID().
properties | optional struct of HID device properties for locating a particular 1208FS device |
Initializes mexHID() if necessary and locates the 1208FS deivce using VendorID, ProductID, and any additional properties specified (e.g. SerialNumber). Opens the four sub-devices of the 1208FS and determines which is the primary front-end (primaryID) and which is the analog output scan device (outputID).
status close | ( | self | ) |
Release the mexHID() devices.
Stops any analog input scan that might be in progress, and releases all four sub-devices of the 1208FS.
Does not attempt to terminate mexHID().
timestamp prepareToScan | ( | self | ) |
Configure the 1208FS for a new scan.
Configures the 1208FS device to do a new scan with the current values of channels, gains, frequency, nSamples, externalTrigger, and externalRetrigger. Also clears old data from transferredData and baseElementCache.
Once prepared, initiate the scan with startScan() and stop it, if necessary, with stopScan(). Get scan data in a useable form with getScanWaveform().
Returns a positive timestamp for when the "prepare" command was acknowleged by the device, as measured with the host CPU clock. This timestamp corresponds to a USB frame and has 1ms granularity. Returns a negative value if there was an error.
timestamp startScan | ( | self | ) |
Initiate a prepared scan.
Commands the 1208FS device to initiate a continuous scan with the current values of channels, gains, frequency, nSamples, externalTrigger, and externalRetrigger.
Configire the scan beforehand, with prepareToScan. Stop it, if necessary, with stopScan(). Get scan data in a useable form with getScanWaveform().
If the scan might go on for a long time, call mexHID('check') periodocally during the scan. This may prevent new data from overwriting older data in operating system buffers.
Returns a positive timestamp for when the "start" command was acknowleged by the device, as measured with the host's CPU clock. This timestamp corresponds to a USB frame and has 1ms granularity. The first sample recorded during the scan is interpreted to occur at this same time. Returns a negative value if there was an error.
timestamp stopScan | ( | self | ) |
Terminate an ongoing scan.
Commands the 1208FS device to terminate any ongoing scan. Get scan data in a useable form with getScanWaveform().
Returns a positive timestamp for when the "stop" command was acknowleged by the device, as measured with the host CPU clock. This timestamp corresponds to a USB frame and has 1ms granularity. Returns a negative value if there was an error.
c v t u getScanWaveform | ( | self | , |
waitFlag | , | ||
getLatestFlag | |||
) |
Process data from a previous scan.
Reads buffered data from a previous scan and reconstructs sample byte values and timing for use in Matlab. Reconstruction may be a slow operation.
Returns sampled waveforms in several parallel arrays. The number of elements in each array may be equal to nSamples, if a finite scan was completed. Otherwise, the nubmer of elements depends on how long the scan has been running and the sample frequency, and "garbage" samples may appear near the end of the waveforms.
The iith element of each array contains a different type of information about the iith sample:
The arrays are returned in the order [c, v, t, u]. Arguments: waitFlag ... boolean, whether or not to call waitForData getLatestFlag ... boolean, whether to just return latest data
gotNewData startTime finishTime waitForData | ( | self | ) |
Wait for new data to arrive, or timeout.
Blocks until new data are transferred from the OS to Matlab, or until waitTimeout elapses. waitForData() does not wait for all available data to be transferred, only for some new data.
Returns up to three outputs. The first output is logical, whether or not any new data arrived. The second is a timestamp from when waitForData() started waiting. The third is a timestamp from when waitForData() finished waiting. The timestamps correspond to USB frame times.
preview | ( | self | , |
dur | , | ||
ax | |||
) |
Plot waveforms as data arrive.
ax | optional axes to plot into |
Plots a live view of data during a scan. If ax is provided, plots data into @ax. Otherwise, opens a new figure and plots into new axes.
The plot contains timestamp and voltage data obtained with getScanWaveform(). Since getScanWaveform() must run each time the plot is updated, preview() might be unsuitable for gathering data in time-sensitive situations.
preview() invokes prepareToScan(), startScan(), and stopScan(). It discards data from any previous scan, but data gathered during the preview() scan will remain afterwards.
If nSamples is finite, preview() attempts to return as soon as nSamples have been transferred to Matlab. Otherwise, preview() blocks while the plot axes and parent figure remin open, or until the figure records a "q" button press.
|
static |
Transfer buffered sample data and keep track of helper devices.
newData is matrix with rows as samples, columns: 1: cookie 2: value 3: timestamp 4: device helper index
Property vendorID = 2523 |
GAIN SETTINGS low precision, big range 0 -> 1x +-20V 1 -> 2x +-10V 2 -> 4x +-5V 3 -> 5x +-4V 4 -> 8x +-2.5V 5 -> 10x +-2V 6 -> 16x +-1.25V 7 -> 20x +-1V high precision, small range.
To test, use preview method USB vendor ID for the 1208FS device