udp/udp.packets.json

Exchange data with another computer or PLC over UDP in real time: the packet layout in udp.packets.json and its links in udp.link.json.

The UDP module exchanges one fixed-size datagramA datagram is one UDP message: a block of bytes sent in one go, without a connection. It arrives whole or not at all. in each direction with another computer or a PLC, in real time, next to the regular client connection. udp.packets.json sets the layout of the two datagrams, and udp.link.json connects their fields to the rest of the application.

└── udp
    ├── udp.link.json
    └── udp.packets.json

Turn it on

The module is set up in the UdpComm block of config.json. This is the block of the standard robot configuration, where it is off:

"UdpComm": {
  "Amount": 1,
  "Enable": false,
  "Configurations": [
    {
      "Name": "Device101",
      "Enable": true,
      "ListenOnPort": 16385,
      "ReplyToSource": false,
      "SendCycleTime": 0.1,
      "SendToHost": "192.168.2.101",
      "SendToPort": 16385,
      "Packets": "udp/udp.packets.json",
      "Linking": "udp/udp.link.json"
    }
  ]
}

Each item in Configurations is one connection, with its parameters under root/UdpComm/<Name>/.

Field What it does Default
Enable (block) false turns the whole module off true
Amount How many items of Configurations are used; your license can limit this further 1
Name The connection’s name in the parameter tree Undefined00, Undefined01, …
Enable (item) false skips this connection true
ListenOnPort The UDP port the controller receives on 16385
ReplyToSource true: answer every valid datagram that arrives, to the address it came from. false: send on the controller’s own clock true
SendCycleTime With ReplyToSource false: send a datagram every this many seconds. 0 sends nothing 0
SendToHost With ReplyToSource false: the address to send to 127.0.0.1
SendToPort With ReplyToSource false: the port to send to 16385
Packets The packets file. Required
Linking The link file none

Restart Motorcortex after changing the block.

How the data flows

The packets file creates a parameter for every field, under Outgoing and Incoming. The link file fills the outgoing fields; incoming fields land in the tree by themselves. This example is a shortened version of the one that ships with the UDP module:

Go to The link file Application linked in udp.link.json › On the network one datagram each way root/UdpComm/Device101 Go to The packets file Outgoing sent frameCounteruint32 positionTargetArrayfloat[6] Go to The packets file Incoming received frameCounteruint32 commanduint32 Device101/frameCounter …/axesPositionsActual Incoming needs no link: values land in the tree optional your logic input 28 bytes 4 B 24 B frameCounter positionTargetArray 8 bytes 4 B 4 B frameCounter command any other length is dropped Fields go on the wire in the order of the file, packed without padding. An Outgoing field stays 0 until a link or a client writes it. The Id values are not used.

The packets file

Outgoing is what the controller sends, Incoming what it expects to receive. Each field has a name and a Type:

{
  "Outgoing": {
    "frameCounter":        { "Id": 1, "Type": "uint32" },
    "positionTargetArray": { "Id": 2, "Type": "float[6]" }
  },
  "Incoming": {
    "frameCounter":        { "Id": 1, "Type": "uint32" },
    "command":             { "Id": 2, "Type": "uint32" }
  }
}
  • Type is a data type with an optional length in brackets, as in user parameters: bool, int8 to int64, uint8 to uint64, float or double, and float[6] for six of them.
  • Order decides the layout. The fields go into the datagram in the order of the file, back to back without padding, little-endian. bool, int8 and uint8 take 1 byte, int16 and uint16 2, int32, uint32 and float 4, int64, uint64 and double 8.
  • Id is not read. Keep it as a note for yourself, but the order is what counts.
  • Size must match. A received datagram is only accepted when its length is exactly the size of Incoming; anything else is dropped without a message.

The other side must use the same layout: your Outgoing is its Incoming. Between two Motorcortex applications, copy the Outgoing section of one into the Incoming section of the other. The standard robot configuration sends and expects a single frameCounter:

{
  "Outgoing": {
    "frameCounter": { "Id": 1, "Type": "uint32" }
  },
  "Incoming": {
    "frameCounter": { "Id": 1, "Type": "uint32" }
  }
}

udp.link.json is a link file like the ones in linking/, applied when the module starts. Link into the Outgoing fields to put data on the wire: a field without a link stays 0. Incoming values appear under Incoming without a link; link from them only when the application should act on them.

The module counts every datagram it sends in root/UdpComm/<Name>/frameCounter, but does not put the count on the wire by itself. The standard udp.link.json links it into the outgoing field:

{
  "Version": "1.0.0",
  "Groups": [
    {
      "Name": "frameCounter",
      "SystemMode": "All",
      "Enable": true,
      "Links": [
        {
          "Source": { "Path": "root/UdpComm/Device101/frameCounter" },
          "Destination": { "Path": "root/UdpComm/Device101/Outgoing/frameCounter" }
        }
      ]
    }
  ]
}

The other side can echo the counter back, so the application can compare Incoming/frameCounter with its own count and see that the whole loop is alive.

Connection monitoring

Each connection watches whether valid datagrams keep arriving. These parameters are under root/UdpComm/<Name>/:

Parameter What it shows or sets Default
connected true while valid datagrams arrive
Errors/receiveWarningTimeout Seconds without a valid datagram before Errors/receiveWarning 0.1
Errors/receiveErrorTimeout Seconds without a valid datagram before Errors/receiveError, and connected goes false 0.2
keepIncomingValuesWhenDisconnected true keeps the last incoming values when the connection drops, instead of setting them to 0 false
autoResetErrors true clears the errors as soon as a valid datagram arrives again false
resetErrors Write true to clear the errors
receivePacketDelay The time between the last two valid datagrams, in s
frameCounter The number of datagrams sent

With the defaults, the other side has to send at least every 0.1 s to keep the connection free of warnings.