Protocol - Oscilloscope over UDP (port 2117)
Units are physical units, defined at physics.nist.gov.
's' is for seconds
'V' is for volts
'A' is for amperes.
Datatypes are described in (ie, blatently stolen from) Python's struct module:
'b' signed 8-bit int
'B' unsigned 8-bit int
'h' signed 16-bit int
'H' unsigned 16-bit int
'i' or 'l' signed 32-bit int
'I' or 'L' unsigned 32-bit int
'q' signed 64-bit int
'Q' unsigned 64-bit int
'f' (for "float") 32-bit float
'd' (for "double") 64-bit float
Data order is always big-endian (the usual for network protocols).
TOC - Triggered Oscilloscope Command
00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
'e' | 'F' | 'i' | 'r' | ||||||||||||||||||||||||||||
'm' | 'a' | 't' | 'a' | ||||||||||||||||||||||||||||
'T' | 'O' | 'C' | Version = 0 | ||||||||||||||||||||||||||||
Reserved = 0 | |||||||||||||||||||||||||||||||
Trigger Mode | Trigger Channel | Trigger Datatype | Reserved = 0 | ||||||||||||||||||||||||||||
Trigger Threshold (always 32 bits reserved) | |||||||||||||||||||||||||||||||
Number of samples requested |
Trigger Threshold is done in the "data datatype" (see the section on Channel Descriptors). ie, the value is the ADC value, not the real, physical value.
The eFirmata device MUST immediately respond with a meta-data packet.
(Or perhaps "operation failed"?... etc).
TOM - Triggered Oscilloscope Metadata
00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
'T' | 'O' | 'M' | Version = 0 | ||||||||||||||||||||||||||||
INV | Domain Units | Step-size datatype | Number of Channels | Bytes per Descriptor | |||||||||||||||||||||||||||
Domain Step-size (always 64 bits of space reserved) |
|||||||||||||||||||||||||||||||
Channel descriptor(s)... ... |
Domain Units are typically "s" for seconds. The Step-size datatype is normally 'f' for float or 'd' for double. If inv is set, then the units become 1/unit. (For example, 0x73 is "seconds per sample", but 0xf3 is "samples per second".)
For example, to specify "2.5E-6 seconds per sample":
Domain Units - 's'
Step-size datatype - 'f', for float
Domain Step-size - 2.5E-6
For example, to specify "44100 samples per second":
Domain Units - 0xf3 ('s', with the msb set to 1)
Step-size datatype - 'H', for unsigned 16 bit int
Domain Step-size - 44100
We then include a meta-data description of each channel:
Channel descriptor
00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Units | Data datatype | Real datatype | Scale type (enum) = 1 | ||||||||||||||||||||||||||||
Error type = 0 | unused = 0 | ||||||||||||||||||||||||||||||
Data Value A (always 32 bits reserved) | |||||||||||||||||||||||||||||||
Real Value A (always 64 bits of space reserved) |
|||||||||||||||||||||||||||||||
Data Value B (always 32 bits reserved) | |||||||||||||||||||||||||||||||
Real Value B (always 64 bits of space reserved) |
|||||||||||||||||||||||||||||||
Error Parameters (not implemented yet) = 0 |
Error type and error parameters are not implemented yet. (In the future, they will specify things like "gaussian" and "std dev = xxx" etc..)
Scale type is how we convert ADC values into real measurements. Right now, there's only one Scale type: "two-point linear". For example:
Example of a "two-point linear" channel descriptor
Converting ADC values to real measurementsFor this example:
Field | Example Value | meaning of this value |
---|---|---|
Units | 'V' | volts |
Data datatype | 'H' | 16-bit unsigned int |
Real datatype | 'f' | 32-bit float |
Scale type | 1 | "two-point linear" |
Data Value A | 0 | |
Real Value A | -5.0 | |
Data Value B | 0x0fff | |
Real Value B | 5.0 |
The eFirmata SHOULD choose dataValueA and dataValueB to be the minimum and maximum values from the ADC, respectively.
TOD - Triggered Oscilloscope Data
00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
'T' | 'O' | 'D' | Version = 0 | ||||||||||||||||||||||||||||
Octets per Sample | unused | Total # of Samples (in this packet) | |||||||||||||||||||||||||||||
Starting sample number (in this packet, count from 0) | |||||||||||||||||||||||||||||||
... data ... ... |
(Octets per Sample) * (Total # Samples) MUST equal the length of the data.
The data is striped. For example, if we have three channels, the data will be:
Channel_0_sample_0, Channel_1_sample_0, Channel_2_sample_0,The channels occur in the same order as the channel descriptors in the meta-data packet.
Channel_0_sample_1, Channel_1_sample_1, Channel_2_sample_1,
Channel_0_sample_2, Channel_1_sample_2, Channel_2_sample_2,
Channel_0_sample_3, Channel_1_sample_3, ..., etc
The data per channel is organized according to their own channel decriptors from the meta-data packet. (Always big-endian.)
The PC will re-assemble all of the data from the TOD packets.