MasterScan
Lab_Matlab_control Master Branch
|
Implement digital outputs using mexHID() and the 1208FS USB device.
dotsDOut1208FS is an implementation of the dotsAllDOutObjects interface for doing digital outputs. It uses the mexHID() mex function to locate and control the "1208FS" USB device from Measurement Computing. dotsAllDOutObjects uses only a few features of the 1208FS:
The description of each interface method contains specific information about which device function and pins it expects to use.
Since timing is a key part of the dotsAllDOutObjects interface, some general timng considerations for mexHID() and the 1208FS follow. The description of each interface method contains additional, specific timing considerations.
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 mexHID(), timing considerations have the flavor of "During which frame was that command sent?" and "What time did that frame occurr?". 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 timetsamp. 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 behavior (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 onboard behavior mexHID() can exchange data and commands with the HID front-end of the 1208FS device. The device also has an onboard microcontroller and memory with which it can do significant behaviors which are beyond the scope of the HID protocol and normal "human interfaces".
dotsDOut1208FS uses these onboard behaviors to send TTL signals and pulses with deterministic timing: it sends a sequence of voltage samples to be buffered in the device's memory and tells the microprocessor to output the samples at a regular frequency. Since the onboard microprocessor is removed from Matlab and its multitasking host opertating system, dotsDOut1208FS expects the samples to be output with deterministic timing.
Thus, the timestamps returned from dotsDOut1208FS are estimates to the nearest 1ms of when an onboard behavior was initiated. dotsDOut1208FS leaves detailed control of ongoing behaviors up to the device's microprocessor.
From tests, it appears that the 1208FS could buffer 512 unique voltage samples after whcih it would overwrite older samples. Thus, dotsDOut1208FS will only attempt to output TTL signals that are this long or shorter. The span of time over which the device outputs the samples depends on the specified sample frequency, which may range from about 0.5Hz through 10,000Hz. Note that 10,000Hz is well beyond the realm of 1ms USB frames!
Properties and Events | |
Property | vendorID = 2523 |
USB vendor ID for the 1208FS device. | |
Property | productID = 130 |
USB product ID for the 1208FS device. | |
Property | channels = [0 1] |
valid output channels for TTL pulses and signals | |
Property | ports = 0 |
valid output ports for strobed words | |
Property | dPortConfigID = 1 |
HID report ID for digital port setup. | |
Property | dPortOutID = 4 |
HID report ID for digital port output. | |
Property | pulseWidth = .001 |
width of TTL pulse in seconds | |
Property | pulseSignal = [true false] |
TTL signal containing a single pulse. | |
Property | signalStartID = 21 |
HID report ID to start analog output scans. | |
Property | signalStatusCookie = 8 |
HID element cookie for analog output status. | |
Property | signalStatusRunning = 0 |
"still running" status returned from 1208FS device | |
Property | signalStatusDone = 2 |
"all done" status returned from 1208FS device | |
Property | signalStopID = 22 |
HID report ID to stop analog output scans. | |
Property | signalSamplesID = 0 |
HID report ID to sending analog output samples. | |
Property | signalSamplesPerReport = 32 |
number of analog output samples to send per report | |
Property | signalMaxSamples = 512 |
max number of samples that the 1208FS can buffer | |
Property | signalPrescanReports = 7 |
number of reports the 1208FS may buffer before initiating scan | |
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 | |
![]() | |
null | timestamp = sendStrobedWord(self, word, port) |
Send a strobed digital word. More... | |
null | status = close(self) |
Release resources. More... | |
Property | isAvailable = false |
true or false, whether the object is ready to use. More... | |
Protected Properties | |
Property | deviceIDs |
mexHID() device IDs for all the 1208FS sub-devices | |
Property | primaryID |
mexHID() device ID for the primary 1208FS device | |
Property | outputID |
mexHID() device ID for the output 1208FS device | |
Methods | |
self | dotsDOut1208FS (properties) |
Open and configure the 1208FS device with mexHID(). More... | |
timestamp | sendStrobedWord (self, word, port) |
Send a 15-bit strobed word spanning digial ports A and B. More... | |
timestamp ref | sendTTLPulse (self, channel) |
Send a TTL pulse, using a short TTL signal. More... | |
timestamp ref | sendTTLSignal (self, channel, signal, frequency) |
Send a TTL signal using an analog output scan. More... | |
status | close (self) |
Release the mexHID() device. More... | |
Protected Methods | |
report | formatSignalConfig (self, channel, signal, frequency) |
Format a HID report to configure an analog output scan. | |
report | formatSignalStop (self) |
Format a HID report to end an analog output scan. | |
report | formatSignalData (self, signal) |
Format a HID report to send analog out sample byte data. | |
report | formatDigitalConfig (self, port, isInput) |
Format a HID report to configure digital port direction. | |
report | formatDigitalOutput (self, port, byte) |
Format a HID report to send digital port byte. | |
signalStatus | waitForRunningSignal (self) |
Block as long as the device reports "still running". | |
status timing ref | writeSignalSamples (self, channel, signal, frequency) |
Write configuration and samples to analog output scan. | |
self dotsDOut1208FS | ( | 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 by 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).
Configures both digital output ports, A and B, for doing outputs. Stops any analog output scan that might be in progress, and sets intial low (0V nominal) values to both analog output channels.
timestamp sendStrobedWord | ( | self | , |
word | , | ||
port | |||
) |
Send a 15-bit strobed word spanning digial ports A and B.
word | unsigned integer representing a word or code to send |
port | ignored, always uses ports A and B |
Uses both digital output ports of the 1208FS, A and B, to send a 15-bit strobed word. Sets the 8 lowest bits of word to port A. Sets the next 7 bits of word to port B. Ignores any higher bits of word. Uses the 8th bit of port B as a strobe bit.
Makes four mexHID() transactions to write the bits of word to the digital ports and flash the strobe bit.
The four transactions makes sure that all word bits are in place before the strobe bit is set, and that the strobe bit is cleared before continuing. Thus, the strobe bit may remain set for as long as it takes to complete a transaction. From tests, it appears this takes about 2ms.
Returns the mexHID() pre-transaction timestamp from the 3rd transaction, when the strobe bit was set.
Here are the word bits, digital port bits, and phisical device pins that dotsDOut1208FS expects to match:
word bit | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | (strobe) |
port bit | A0 | A1 | A2 | A3 | A4 | A5 | A6 | A7 | B0 | B1 | B2 | B3 | B4 | B5 | B6 | B7 |
pin | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 |
timestamp ref sendTTLPulse | ( | self | , |
channel | |||
) |
Send a TTL pulse, using a short TTL signal.
channel | 0 or 1, from which analog output to send the TTL pulse |
Uses sendTTLSignal() to send a single TTL pulse. The signal is specified in the pulseSignal property and should contain a single region of true, followed by false. This assumes that channel begins at a low value and will transition to high and back to low during the pulse.
The pulseWidth property specifies the duration of each sample in pulseSignal: output sample frequency is equal to 1/pulseWidth.
Returns the timestamp returned from sendTTLSignal(). As long as pulseSignal begins with a true value, the timestamp will be an estimate of when channel transitioned to a high value. See sendTTLSignal() for timing details and other details.
timestamp ref sendTTLSignal | ( | self | , |
channel | , | ||
signal | , | ||
frequency | |||
) |
Send a TTL signal using an analog output scan.
channel | 0 or 1, from which analog output to send signal |
signal | logical array specifying a sequence of TTL values to output from channel, with true->high and false->low |
frequency | frequency in Hz at which to move through elements of signal |
Outputs the given TTL signal, at the given sample frequency, from the given analog output channel, under control of the 1208FS device's onboard microprocessor. If signal is too long to fit in the device's onboard memory, returns immediately with a negative error code. From tests, it appears that the onboard memory holds 512 samples.
Before outputting a new TTL signal, blocks until the 1208FS deivce reports that the previous signal is all done. Otherwise, the previous signal would be truncated. The device reports the status of the previous signal as a HID element value which mexHID() can read.
Once ready, makes 1 mexHID() transaction to configure the given channel to ouput n samples at the given frequency, where n is the number of elements in signal. Then makes m additional transactions to write signal data to the 1208fs device's onboard memory. Since each transaction contains 32 samples, m is equal to n/32, rounded up.
From tests, it appears that the 1208FS begins outputting signal upon receipt of one of the m signal data transactions. There are two apparent patterns:
Returns the mexHID() pre-transaction timestamp from either the last or the 8th transaction, as above. From tests, it appears that this pre-transaction timestamp preceeds signal onset by about 3.5ms when the scan frequency is 1000Hz and about 1.5ms when the scan frequency is 10,000Hz. The size of the preceeding interval did not seem to depend on the length of signal. Further testing would be warranted.
Here are the channels, "signal name"s and physical device pins that dotsDOut1208FS expects to match:
channel | 0 | 1 |
name | D/A OUT 0 | D/A OUT 1 |
pin | 13 | 14 |
status close | ( | self | ) |
Release the mexHID() device.
Stops any analog output scan that might be in progress, and releases all four sub-devices of the 1208FS.
Does not attempt to terminate mexHID().