Fork me on GitHub


Connecting the real world to the digital world.


Compatable Hardware:


Example Projects:


Installing the Binary

About / Credits / Contact

Protocol - Oscilloscope over UDP (port 2117)

Units are physical units, defined at
'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

TOC Command from PC to eFirmata
0001020304050607 0809101112131415 1617181920212223 2425262728293031
'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

TOM Metadata from eFirmata to PC
0001020304050607 0809101112131415 1617181920212223 2425262728293031
'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

Channel descriptor (one per channel)
0001020304050607 0809101112131415 1617181920212223 2425262728293031
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 measurements

For this example:
FieldExample Valuemeaning of this value
Data datatype'H'16-bit unsigned int
Real datatype'f'32-bit float
Scale type1"two-point linear"
Data Value A0
Real Value A-5.0
Data Value B0x0fff
Real Value B5.0
(Error type and error parameters are all 0. Not implemented yet.)

The eFirmata SHOULD choose dataValueA and dataValueB to be the minimum and maximum values from the ADC, respectively.

TOD - Triggered Oscilloscope Data

TOD Data from eFirmata to PC (zero or more packets)
0001020304050607 0809101112131415 1617181920212223 2425262728293031
'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,
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 channels occur in the same order as the channel descriptors in the meta-data packet.

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.