The HighSpeedPort protocol is designed to have a fast binary, easy and fixed interface to the Gantner controller (e.series and Q.series)
-
'Fixed interface' means that the interface is always available and not configurable. which guarantees that every controller can be accessed in the same way.
-
Up to 10 clients can use this interface simultaneously.
-
Commands and themes are used to select different types of data.
-
Reading and writing of channels can be done within one request.
Please take note of the compatibility issues when working with a Q.station.
The eGateHighSpeedPort API is a DLL that provides a list of functions based on the HighSpeedPort protocol that can be used as a data interface to common programming languages and software tools, like Matlab, LabVIEW, and Python.
Configuration
Fixed configuration:
-
IP address = broadcast IP address of used network or devices with a known IP address (e.g., existing network IP address = 192.168.1.18 and subnet mask = 255.255.255.0 ⇒ broadcast IP address = 192.168.1.255
-
Port = 8000 (UDP)
-
Port = 8001 (TCP/IP)
Protocol description
This section explains the general coding of request frames and response frames.
Request frame:
[LengthOfFrame -- 2Bytes Integer] ... without this bytes
[Command -- 1Byte Integer]
[OffsetWrite -- 2Bytes Integer]
[LengthWrite -- 2Byte Integer]
[DataWrite -- LengthWrite Bytes]
[OffsetRead -- 2Bytes Integer]
[LengthRead -- 2Byte Integer]
Response frame:
[LengthOfFrame -- 2Bytes Integer] ... without this bytes
([LengthOfFrameEx -- 4Byte Integer]) ... **Extended Length
[ReturnState -- 1Byte Integer]
[DataRead -- LengthRead Bytes]
Extended Length:
These bytes are added only if LengthOfFrame = FF FF to enable the reading of more than 65534 bytes of data. LengthOfFrameEx will then be the byte count for additional data and LengthOfFrame must be ignored.
ReturnState is coded as follows:
0 ……… OK
1 ……… Command error (unknown command recognized)
2 ……… Decoding error (command OK but wrong request frame for this command)
3 ……… Handling error (e.g.: file not existing)
All elements of the HSP structure have to be transferred in the network byte order (big-endian).
Generally, everything that is not marked as BinaryData has to be seen as part of the protocol itself and is therefore transferred in network byte order. Use for example the htonl() function to convert u_long from host to TCP/IP network order.
Measurement data is transferred by the controller in the CPU depending on byte order. See #summary.sta – parameter IsBigEndian (default = 1) or the first element of the UDBF header data (see Universal Data Bin File format).
Debugging with Wireshark
If there is something wrong with the communication, or if the HighSpeedPort Protocol should be implemented in a custom application, it is helpful to be able to analyze the communication. Wireshark is a tool that is able to capture HighspeedPort communication by setting a capture filter port 8001 or host $device_ip_address.
There is also a Wireshark protocol script available that can decode the HighSpeedPort layer and visualize most of the files in a convenient way.
Usage:
-
Download the file to the Plugins directory in the Wireshark installation directory and rename it to “HighSpeedPort.lua”.
-
Edit (as administrator) the file init.lua from the Wireshark installation. Check if enable_lua = true and add dofile(DATA_DIR..”HighSpeedPort.lua“) at the end of the file.
-
Launch Wireshark. In the Analyze menu, select Enable Protocols… and verify that the HighSpeedPort protocol appears.
Command description
This chapter explains the possible commands for HighSpeedPort TCP/UDP.
Command 0x00: Variables
This command is used to read a single online data frame. All data is coded binary and has to be decoded according to information from the #summary.sta file.
- Input and output data have to be regarded separately for reading and writing. The input data frame contains all data with I and I/O data direction. The output data frame includes all data with Output and Input / Output data direction.
- In the #summary.sta file, the offsets for input and/or output data frames are defined for every value with inSplitDataFieldOffset and/or outSplitDataFieldOffset.
- LengthWrite and LengthRead in parallel to the corresponding offsets are also depending on this configuration and cannot be overlapping these set values.
- To enable precision also for integer data, the #summary.sta file contains the precision (part of format) for every channel.
- For decoding, the integer value has to be multiplied with 10e^x
- All data is processed with a big-endian CPU, so maybe a byte swap at multi-byte elements needs to be done before working with it.
Request
Bytes |
Data type |
Description |
ii ii |
Int16 |
LengthOfFrame |
00 |
Int8 |
Command = variables |
ii ii |
Int16 |
OffsetWrite = binary offset in the controller output data frame where DataWrite will be written to |
00 00 |
Int16 |
LengthWrite = length of data to be written |
bb bb bb |
Binary |
DataWrite = binary data to be written |
ii ii |
Int16 |
OffsetRead = binary offset in the controller input data frame for data to be read |
00 00 |
Int16 |
LengthRead = length of data to be read |
Response
Bytes |
Data type |
Description |
ii ii |
Int16 |
LengthOfFrame |
00 |
Int8 |
ReturnState |
bb bb bb |
Binary |
A binary input data frame with length LengthOfFrame. |
Command 0x01: States
This command is used to receive state information from the controller. Requests and responses have both fixed offsets and lengths. The states are delivered as integer values, which have to be interpreted as bit sets. If a bit according to the state coding format is set, the state is active.
Request
Bytes |
Data type |
Description |
00 09 |
Int16 |
The length of the request is always 9 bytes for this command |
01 |
Int8 |
Command = States |
00 00 |
Int16 |
OffsetWrite is not accessible |
00 00 |
Int16 |
LengthWrite is not accessible |
Binary |
DataWrite is not accessible! |
|
00 00 |
Int16 |
OffsetRead = 0 |
FF FF |
Int16 |
LengthRead = Read all data |
Response
Bytes |
Data Type |
Description |
00 0D |
Int16 |
LengthOfFrame is always 13 bytes for this command. |
00 |
Int8 |
ReturnState |
gg gg gg gg |
Int32 |
General states: Bit0: InitActive |
rr rr rr rr |
Int32 |
Run states: Bit0: HostConfigBusRS485Active Bit15: DataLoggerActive |
ee ee ee ee |
Int32 |
Error states: Bit0: ConfigFilesError |
Command 0x02: RealTimeClock
This command is used to read and write date & time information. The data frame for reading and writing has a fixed format.
Date/Time frame:
[Year -- 2 Bytes Integer]
[Month -- 1 Byte Integer]
[Day -- 1 Byte Integer]
[Hour -- 1 Byte Integer]
[Minute -- 1 Byte Integer]
[Second -- 1 Byte Integer]
[Millisecond -- 2 Bytes Integer]
Controllers with an internal clock will not accept impossible values like 0000.00.00 00:00:00.
Request
Bytes |
Data Type |
Description |
ii ii |
Int16 |
LengthOfFrame |
02 |
Int8 |
Command = RealTimeClock |
00 00 |
Int16 |
OffsetWrite = 0 fixed |
00 00 |
Int16 |
LengthWrite = 9 to write date/time frame, 0 to read-only |
bb bb bb |
Binary |
Date/Time frame of 9 bytes |
00 00 |
Int16 |
OffsetRead = 0 fixed |
ii ii |
Int16 |
LengthRead = FF FF to Read all data, 0 to write only |
Response
Bytes |
Data Type |
Description |
ii ii |
Int16 |
LengthOfFrame |
00 |
Int8 |
ReturnState |
bb bb bb |
Binary |
Date/Time frame of 9 bytes if LengthRead = FF FF, empty if 0 |
Command 0x03: CircleBuffer
This command is supported only by the TCP part of this port. HighSpeedPort TCP/IP CircleBuffer is used to read out the circular buffer of a controller. The circular buffer can contain a block of input data frames stored within the synchronization cycle time of the controller or lower if a divider for data reduction is defined. Requests and responses do not always conform to the protocol:
-
LengthRead parameter is used to identify an additional sub-command and.
-
OffsetRead is used as a buffer index.
The following subcommands are available with the right LengthRead setup:
Buffer States:
This subcommand reads state information from a defined buffer on the controller. Also to read the header size, which is needed for reading header data.
Request
Bytes |
Data Type |
Description |
ii ii |
Int16 |
LengthOfFrame |
03 |
Int8 |
Command = 3 … CircleBuffer |
00 00 |
Int16 |
OffsetWrite = 0 fixed |
00 00 |
Int16 |
LengthWrite = 0 fixed |
DataWrite = empty |
||
00 00 |
Int16 |
OffsetRead = Buffer Index |
00 00 |
Int16 |
LengthRead = 0 … Buffer States |
Response
Bytes |
Data Type |
Description |
ii ii |
Int16 |
LengthOfFrame |
00 |
Int8 |
ReturnState |
ss |
Int8 |
Buffer State: 0 - Base Group Begin 1 - Base Not Running 2 - Base Initialized 3 - Base Group End 4 - Standard Group Begin 5 - Standard Erase Before Run 6 - Standard Run 7 - Standard Stop 8 - Standard Group End 9 - Single Shot Group Begin 10 - Single Shot Start 11 - Single Shot Run 12 - Single Shot Stop 13 - Single Shot Group End |
xx xx xx xx |
Int32 |
Header Size |
yy yy yy yy |
Int32 |
Buffer Size (not important because it’s a dynamic value) |
Buffer Header Data:
This subcommand is used to read header data, which is needed for data decoding. The binary header data stream is coded in UDBF format (see Universal Data Bin File format on how to decode the data).
Requests
Bytes |
Data Type |
Description |
ii ii |
Int16 |
LengthOfFrame |
03 |
Int8 |
Command = 3 … CircleBuffer |
00 00 |
Int16 |
OffsetWrite = 0 fixed |
00 00 |
Int16 |
LengthWrite = 0 fixed |
DataWrite = empty |
||
00 00 |
Int16 |
OffsetRead = Buffer Index |
00 01 |
Int16 |
LengthRead = 1 … Buffer Header Data |
Response
Bytes |
Data Type |
Description |
hh hh hh hh |
Binary |
Binary header data. The byte count is given by Header Size. |
Buffer Data Single:
This command is used to read a single CircleBuffer data block. For decoding, the Buffer States and Buffer Header Data must be read first to get information about data types, precisions, and date/time.
Request
Bytes | Data Type | Description |
ii ii | Int16 | LengthOfFrame |
03 | Int8 | Command = 3 … CircleBuffer |
00 00 | Int16 | OffsetWrite = 0 fixed |
00 08 | Int16 | LengthWrite = 8 fixed |
ff ff ff ff ff ff ff ff | double | DataWrite = Backtime The Backtime defines how the CircleBuffer should be prepared by the controller before sending the response. If Backtime is:
|
00 00 | Int16 | OffsetRead = Buffer Index |
00 02 | Int16 | LengthRead = 2 … Buffer data single |
Response
Bytes | Data Type | Description |
bb bb bb bb | Binary | Binary data stream which includes input data frames with the timestamp at the beginning and every input channel. This data has to be decoded by using the buffer header info. There is no information about the number of bytes available. |
Buffer Data Continuous:
This command is used to start a service at the controller, which will periodically send data frames until the connection is terminated. The request is similar to Buffer Data Single, only LengthRead has a value of 3.
Request
Bytes | Data Type |
Description |
00 03 |
Int16 |
LengthRead = 3 … Buffer data continuous |
Response
Bytes |
Data Type |
Description |
bb bb bb bb |
Binary |
Binary data stream which includes input data frames with the timestamp at the beginning and every input channel. This data has to be decoded by using the buffer header info. There is no information about the number of bytes available. |
Buffer Data Single with Preceding State Info:
This subcommand is used to read a single buffer data block with preceding state information and the length of bytes to be transferred. The only difference in the request is the LengthRead to select the subcommand.
Request
Bytes |
Data Type |
Description |
00 04 |
Int16 |
LengthRead = 4 … Buffer data single with preceding state info |
Response
Bytes |
Data Type |
Description |
00 09 |
Int16 |
Length of the frame without buffer data |
00 |
Int8 |
ReturnState |
00 00 |
Int16 |
Structure ID |
00 00 |
Int16 |
LastTransferState Bit0: TransferFailed Bit1: DataLost Ignore at first request!! |
00 00 00 00 |
Int32 |
ToTransferSize delivers the byte count of buffer data to be transferred (= n * length of 1 input data measurement). |
bb bb bb bb |
Binary |
The binary data stream which includes input data frames with the timestamp at the beginning and every input channel. This data has to be decoded by using the buffer header info. |
Buffer Data Single None Erasing With Preceding State Info:
This subcommand is used to read buffer data blocks, but without deleting the read data.
Request
Data |
Data Type | Description |
00 05 |
Int16 |
LengthRead = 5 … Buffer data single none erasing with preceding state info |
Response
It can be difficult to handle data from this subcommand because it is not continuous.
Buffer Data Single Seek Timestamp:
This subcommand is used to read a single buffer data block from a specific time stamp and optionally to a specified end timestamp. It also returns preceding state information and the length of bytes to be transferred.
Request
Bytes | Data Type | Description |
ii ii | Int16 | LengthOfFrame |
03 | Int8 | Command = 3 … CircleBuffer |
00 00 | Int16 | OffsetWrite = 0 fixed |
00 08 | Int16 | LengthWrite = 16 fixed |
ff ff ff ff ff ff ff ff | UInt64 | Start Timestamp = nanoseconds since 01.01.2000, if 0XFFFFFFFFFFFFFFFF data is read from the actual read position and the optional end timestamp is evaluated |
ff ff ff ff ff ff ff ff | UInt64 | Stop Timestamp = nanoseconds since 01.01.2000 Optional: Ignored if 0 or 0XFFFFFFFFFFFFFFFF, otherwise it must be > StartTimestamp. Can also return less data than specified with the timestamp |
00 00 | Int16 | OffsetRead = Buffer Index |
00 04 | Int16 | LengthRead = 6 … Buffer data single with preceding state info |
Response
Bytes | Data Type | Description |
00 09 | Int16 | Length of the frame without buffer data |
00 | Int8 | ReturnState |
00 00 | Int16 | Structure ID |
00 00 | Int16 | LastTransferState Bit0: TransferFailed Bit1: DataLost Ignore at first request!! |
00 00 00 00 | Int32 | ToTransferSize delivers the byte count of buffer data to be transferred. (= n * length of 1 input data measurement) |
bb bb bb bb | Binary |
The binary data stream which includes input data frames with the timestamp at the beginning and every input channel. This data has to be decoded by using the buffer header info. |
Command 0x05: FileTransfer
This command is used to read files and file-related information from the controller. OffsetRead and LengthRead are used to determine between the following subcommands:
OffsetRead |
LengthRead |
Subcommand |
---|---|---|
0 |
0 |
DeleteFile – DataWrite = Filename |
0 |
1 |
ReadDirectory - DataWrite = DriveIndex |
1 |
0 |
ReadFileSize - DataWrite = Filename |
1 |
1 |
ReadFileData - DataWrite = Filename |
For this command, it is very important to implement the decoding of the extended LengthOfFrame (see protocol description for details).
Delete File:
This subcommand is used to delete a specified file on the controller.
Request
Bytes | Data Type | Description |
ii ii | Int16 | LengthOfFrame |
05 | Int8 | Command = 5 … FileTransfer |
00 00 | Int16 | OffsetWrite = 0 fixed |
00 LL | Int16 | LengthWrite (depends on data write length) |
dd …. dd | ASCII | DataWrite = Filename in ASCII format, for example: ”#summary.sta” = 23 73 75 6D 6D 61 72 79 2E 73 74 61 |
00 01 | Int16 | OffsetRead = 0 fixed for this subcommand |
00 00 | Int16 | LengthRead = 0 fixed for this subcommand |
Response
Bytes | Data Type | Description |
00 01 | Int16 | LengthOfFrame |
00 | Int8 | ReturnState |
👉 Handling of application or state files must not be done with this command. Instead, the FTP connection has to be used.
👉 The Delete File command must only be used to delete data files in flash memory.
Read Directory:
This subcommand is used to read file names from the controller. The result can be cut by defining a specified DriveIndex.
Request
Bytes |
Data Type |
Description |
ii ii |
Int16 |
LengthOfFrame |
05 |
Int8 |
Command = 5 … FileTransfer |
00 00 |
Int16 |
OffsetWrite = 0 fixed |
00 LL |
Int16 |
LengthWrite (depends on data write length) |
dd …. dd |
ASCII |
DataWrite = DriveIndex in ASCII format: ”-1” = 2D 31 : all drives ”-2” = 2D 32 : all temporary log files “0” = 30 : [FLASH_APPLICATION]:\ “1” = 31 : [FLASH_DATA]:\ “2” = 32 : [USBSTORAGE_DATA]:\ “1000” = 31 30 30 30 : [VIRTUAL_STATE]:\ “1001” = 31 30 30 31 : [VIRTUAL_CIRCLEBUFFER]:\ “1002” = 31 30 30 32 : [VIRTUAL_ONLINEBUFFER]:\ “1003” = 31 30 30 33 : [VIRTUAL_ARCHIVE]:\ “1004” = 31 30 30 34 : [VIRTUAL_LOGGER]:\ |
00 00 |
Int16 |
OffsetRead = 0 fixed for this subcommand |
00 01 |
Int16 |
LengthRead = 1 fixed for this subcommand |
Response
Bytes |
Data Type |
Description |
ii ii |
Int16 |
LengthOfFrame |
ii ii |
Int16 |
LengthOfFrame: bytes are present, but always 0 (void) |
00 |
Int8 |
ReturnState |
dd … dd |
ASCII |
Drive frame contains (all in ASCII format): DR:\t<DriveName>\t<DriveIndex>\t<TotalSize>\t<FreeSize>\t<UsedSize>\t<BadSize>\n The file frame contains (all in ASCII format): FI:\t<FileName>\t<FileSize>\t<DateTime>\t<AttrStr>\n (AttrStr: B0=READONLY / B1=HIDDEN / B2=SYSTEM / B3=VOLUME / B4=DIR / B5=ARC) The full requested block delimiter is \r\n If an item is ”-1”, this is invalid. Maybe this drive is not installed or the parameter is not available there!!! e.g. ReadDirectory of DriveIndex=0: \x00\x00\x00 DR:\t[FLASH_APPLICATION]:\ \t0\t7077888\t4878336\t2199552\t0\n FI:\tecpu01.bin\t1764336\t2008-03-11\t10:51:40\t0020\n FI:\tecpu01.ini\t495\t1980-01-01\t12:00:00\t0020\n FI:\tconfig.sys\t219\t1980-01-01\t12:00:00\t0020\n FI:\tfpga.bit\t403014\t1980-01-01\t12:00:00\t0020\n FI:\tftp_lic.cnf\t538\t2008-02-26\t15:43:42\t0020\n FI:\tmaster.gcf 10750\t2008-02-26\t15:43:50\t0020\n FI:\tself.ini\t78\t2008-03-11 09:27:36\t0020\n\r\n |
To use the FileName as input for ReadFile, ReadFileSize, or the DeleteFile command, all characters from the file name are required.
ReadFileSize:
This subcommand is used to read the size of a specified file on the controller.
Request
Bytes |
Data Type |
Description |
ii ii |
Int16 |
LengthOfFrame |
05 |
Int8 |
Command = 5 … FileTransfer |
00 00 |
Int16 |
OffsetWrite = 0 fixed |
00 LL |
Int16 |
LengthWrite (depends on data write length) |
dd …. dd |
ASCII |
DataWrite = Filename in ASCII format, for example: |
00 01 |
Int16 |
OffsetRead = 1 fixed for this subcommand |
00 00 |
Int16 |
LengthRead = 0 fixed for this subcommand |
Response
Bytes |
Data Type |
Description |
ii 1+n |
Int16 |
LengthOfFrame |
00 |
Int8 |
ReturnState |
dd … dd |
ASCII |
DataRead = size of the file in ASCII format with length n |
ReadFileData:
This subcommand is used to read a specified file on the controller as a binary stream.
Request
Bytes |
Data Type |
Description |
ii ii |
Int16 |
LengthOfFrame |
05 |
Int8 |
Command = 5 … FileTransfer |
00 00 |
Int16 |
OffsetWrite = 0 fixed |
00 LL |
Int16 |
LengthWrite (depends on data write length) |
dd …. dd |
ASCII |
DataWrite = Filename in ASCII format, for example: |
00 01 |
Int16 |
OffsetRead = 1 fixed for this subcommand |
00 01 |
Int16 |
LengthRead = 1 fixed for this subcommand |
Response
Bytes |
Data Type |
Description |
ii 1+n |
Int16 |
LengthOfFrame (can also be extended!) |
00 |
Int8 |
ReturnState |
dd … dd |
ASCII |
DataRead = Content of file with length n |
If the file is not found on the controller, the state of the response will be 3 (Handling Error)
Diagnostics EX
This command is used to read controller diagnostic information. The command defines if internal, external, or all information should be read. The response is split up into different themes, which give diagnostic information from different points of view:
-
The interface theme contains diagnostic information about the field bus, UART, and internal system.
-
The transport theme contains diagnostic information on the slave modules. The system variable and virtual variable sections are handled as transport entries.
-
The variable theme contains the diagnostic information for every variable.
Command 0x09: DiagnosticsExFull
This command is used to read internal and external diagnostic information from the controller.
Request
Bytes |
Data Type |
Description |
|
00 09 |
Int16 |
LengthOfFrame |
|
09 |
Int8 |
Command = 9 … DiagnosticsExFull |
|
00 00 |
Int16 |
OffsetWrite = 0 fixed |
|
00 00 |
Int16 |
LengthWrite = 0 fixed |
|
00 00 |
Int16 |
OffsetRead = 0 fixed |
|
ff ff |
Int16 |
LengthRead = read all data |
Response
Bytes |
Data Type |
Description |
|
ii ii |
Int16 |
LengthOfFrame |
|
00 |
Int8 |
ReturnState |
|
00 01 |
Int16 |
Structure ID that describes the following structure |
|
00 03 |
Int16 |
InterfaceCount = 3 for fieldBusses + internal + external interfaces |
|
FF FF |
Int16 |
InterfaceKind = FieldBusses if “FF FF” |
FieldBusses |
FF FF |
Int16 |
Interface Index is not used for FieldBusses. |
|
FF FF FF FF |
Int32 |
Cycles count for this Interface. |
|
FF FF FF FF |
Int32 |
Error count for this Interface. |
|
BF F0 00 00 00 00 00 00 |
Double |
Delta Time since the last request in seconds. |
|
00 00 |
Int16 |
InterfaceKind = InternalSystem if “00 00” |
Internal System |
00 00 |
Int16 |
Interface Index |
|
00 00 00 00 |
Int32 |
Cycles count |
|
00 00 00 00 |
Int32 |
Error count |
|
3F BB FD 0D 06 78 C0 05 |
Double |
Delta Time since the last request in seconds. |
|
00 03 |
Int16 |
InterfaceKind = ExternalUart if “00 03” |
External UART |
00 00 |
Int16 |
Interface index |
|
00 00 00 00 |
Int32 |
Cycles count |
|
00 00 00 00 |
Int32 |
Error count |
|
3F BB FD 0D 06 78 C0 05 |
Double |
Delta Time since the last request in seconds. |
|
00 0x |
Int16 |
TransportCount = internal virtual (if available) + internal system (if available) + module count |
|
---|---|---|---|
00 00 |
Int16 |
Global index |
For every Transport entry (Transport count) |
00 00 00 00 |
Int32 |
Error states |
|
00 00 00 0B |
Int32 |
Cycles count |
|
00 00 00 00 |
Int32 |
Error count |
|
BF F0 00 00 00 00 00 00 |
Double |
DeltaTimeS (since last transfer) |
|
00 0y |
Int16 |
Variable count |
|
00 00 |
Int16 |
Global index |
For every variable |
00 00 00 00 |
Int32 |
Error states |
|
00 00 00 0B |
Int32 |
Cycles count – not used but a placeholder |
|
00 00 00 00 |
Int32 |
Error count – not used but a placeholder |
|
BF F0 00 00 00 00 00 00 |
Double |
DeltaTimeS (since last transfer) |
Not included in this example:
00 02 |
Int16 |
InterfaceKind = InternalVirtual |
Command 0x0A: DiagnosticsExInternal
This command is used to receive only diagnostic information from internal interfaces/modules/channels. Request and Response are similar to DiagnosticsExFull, only the command request - command is 10(A) and the response only delivers internal information.
Command 0x0B: DiagnosticsExExternal
This command is used to receive only diagnostic information from external interfaces/modules/channels. Request and Response are similar to DiagnosticsExFull, only the command request - command is 11(B) and the response only delivers external information.
Command 0x0C: Logger
This command is used to read out the test.con data logger. Reading out the data logger has to be done the same way as reading out the circular buffer. The same subcommands are available for Command 3: CircleBuffer. The request command is 12 (hex C) instead of 3 (exception: Buffer Data Continuous for test.con data loggers is not implemented).
Command 0x0D: PostProcessBuffer
Q.station controllers only
This command is used to read the post-process buffer on the Q.station controller. Reading out post-process buffers has to be done the same way as reading out the circular buffer. The same subcommands are available for Command 3: CircleBuffer. The request command is 13 (hex D) instead of 3.
Command 0x10: OutputCircleBuffer
Q.station controllers only (this command is under construction, it will be implemented in Q.station firmware version 1.10 for the first tests)
This command is used to send buffered data synchronously to the output process image. It can be used to send either single variables or multiple variables located next to each other in the output process image. Data can be written time equidistant within the resolution of the SystemCycleFrequency or not time equidistant but based on an absolute timestamp.
Initialize OutputCircleBuffer
This subcommand is used to initialize an output circle buffer. An already existing output circle buffer with the same signature (offset, length, site, timestamp config) will be reused.
Request
Bytes |
Data Type |
Description |
ii ii |
Int16 |
LengthOfFrame |
10 |
Int8 |
Command = 10 … OutputCircleBuffer |
ii ii |
Int16 |
OffsetWrite = 0 fixed |
ii ii |
Int16 |
LengthWrite = 14 fixed |
ii ii ii ii |
UInt32 |
WriteOffset: byte offset in the output process image |
ii ii ii ii |
UInt32 |
WriteLength: byte length in the output process image |
ii ii ii ii |
UInt32 |
BufferFrames: capacity of the output buffer in frames |
BB |
Boolean |
UseAbsoluteTimestamp: if HighSpeedPort data frames need an additional timestamp at the beginning |
BB |
Boolean |
SyncFirstTimestamp: if sending should be started immediately or wait for the absolute timestamp |
00 00 |
Int16 |
OffsetRead = 0 fixed |
00 00 |
Int16 |
LengthRead = 0 … Init OutputCircleBuffer |
Response
Bytes |
Data Type |
Description |
ii ii |
Int16 |
LengthOfFrame |
00 |
Int8 |
ReturnState |
ii ii |
Int16 |
Buffer Handle |
If successful, a Buffer Handle >= 0 will be returned, which is needed to access this buffer. If the initialization was not successful, ReturnState=-3 will be returned.
Free OutputCircleBuffer:
This subcommand is used to free, delete, or destroy an already initialized circle buffer (e.g. to change the geometry of the buffer).
Request
Bytes |
Data Type |
Description |
ii ii |
Int16 |
LengthOfFrame |
10 |
Int8 |
Command = 10 … OutputCircleBuffer |
ii ii |
Int16 |
OffsetWrite = Buffer Handle (as received with “Init OutputCircleBuffer”) |
ii ii |
Int16 |
LengthWrite = 0 fixed |
DataWrite = empty |
||
00 00 |
Int16 |
OffsetRead = 0 fixed |
00 00 |
Int16 |
LengthRead = 1 … Free OutputCircleBuffer |
Response
Bytes |
Data Type |
Description |
ii ii |
Int16 |
LengthOfFrame |
00 |
Int8 |
ReturnState |
If the OutputBuffer does not exist, ReturnState is set accordingly
GetSize OutputCircleBuffer:
This subcommand is used to get the free space of an OutputCircleBuffer.
Request
Bytes |
Data Type |
Description |
ii ii |
Int16 |
LengthOfFrame |
10 |
Int8 |
Command = 10 … OutputCircleBuffer |
ii ii |
Int16 |
OffsetWrite = Buffer Handle (as received with “Init OutputCircleBuffer”) |
ii ii |
Int16 |
LengthWrite = 0 fixed |
DataWrite = empty |
||
00 00 |
Int16 |
OffsetRead = 0 fixed |
00 00 |
Int16 |
LengthRead = 2 … GetSize OutputCircleBuffer |
Response
Bytes |
Data Type |
Description |
ii ii |
Int16 |
LengthOfFrame |
00 |
Int8 |
ReturnState |
ii ii ii ii |
UInt32 |
BufferFrames: number of data frames that are not sent yet |
If the OutputBuffer does not exist, ReturnState is accordingly
AppendData OutputCircleBuffer:
This subcommand is used to append data to an output circle buffer.
Request
Bytes | Data Type | Description |
ii ii | Int16 | LengthOfFrame |
10 | Int8 | Command = 10 … OutputCircleBuffer |
ii ii | Int16 | OffsetWrite = Buffer Handle (as received with “Init OutputCircleBuffer”) |
ii ii | Int16 | LengthWrite = Length of data byte to be written |
bb bb bb | Binary | DataWrite = n * (Timestamp (if used) + Output Data Frame) |
00 00 | Int16 | OffsetRead = 0 fixed |
00 00 | Int16 | LengthRead = 3 … Append Data OutputCircleBuffer |
Response
Bytes | Data Type | Description |
ii ii | Int16 | LengthOfFrame |
00 | Int8 | ReturnState |
ii ii ii ii | UInt32 | BufferFrames: number of data frames that are not sent yet (including this new data block) |
👉 If there was not enough empty space left in the OutputCircleBuffer, this command will return with ReturnState set accordingly. In this case, the whole data block has to be sent again when there is enough empty space available.
👉 It is recommended to use command 2 - Get Size OutputCircleBuffer first, instead of continuously trying to send huge data blocks.
👉 It is not possible to send more than the maximum buffer capacity at once (as set with parameter BufferFrames at Init OutputCircleBuffer).
👉 To get a data stream without interrupts, it is recommended not to send too much data at once otherwise the buffer could run out of data while waiting to have enough space for the next big data block.