This documentation provides an overview of the SPoE Client, a static C++ library designed for efficient Ethernet communication with SOMANET Integro devices.
Note: This library requires your SOMANET Integro device to have Ethernet firmware installed.
The pre-built static library and examples are available in this public repository.
HTTP Server (ec2h)
An HTTP server application is provided that wraps this library, exposing its functionality via HTTP endpoints. A web-based user interface (UI) is also included. You can access both the server installer and the UI here: http://motion-master-console.synapticon.com/ethernet
Usage
To establish communication, the SOMANET Integro device must have a valid IP address. This can be configured in one of two ways:
- Static Configuration: Assign a fixed IP address using EtherCAT communication.
- Dynamic Configuration: Configuring a DHCP Server on your computer to automatically assign an IP address to the connected device.
Device Class Overview
mm::comm::spoe::Device
Handles TCP communication with SOMANET devices over Ethernet using a custom SPoE protocol.
This class provides methods for connecting to a remote server, sending messages, and receiving responses over a TCP connection using Boost.Asio. It manages the underlying socket, connection, and I/O operations required for client-server communication.
All message exchanges with the device are designed to be thread-safe.
Connection
Create an instance of the SPoE class by specifying the device's IP address and port number:
const std::string
kIp =
"192.168.100.5";
Handles TCP communication with SOMANET devices over SPoE.
Definition spoe.h:302
const uint16_t kPort
Definition spoe_test.cc:17
const std::string kIp
Definition spoe_test.cc:16
Then, connect to the device with:
auto connected = device.connect();
When the device is powered on, it will automatically transition to the OPERATIONAL state, which you can check with:
state = device.getState();
assert(state == 8);
Most request functions support an optional expiryTime parameter of type std::chrono::steady_clock::duration. This specifies the maximum time to wait for a response from the device before a timeout error is triggered. For example:
try {
device.setState(0x02, std::chrono::milliseconds(1000));
} catch (const std::exception& e) {
std::cerr << "Failed to set state: " << e.what() << std::endl;
}
Parameters
To read a device parameter value (e.g., 0x6079: DC link circuit voltage), use:
std::vector<uint8_t>
value = device.readSdo(0x6079, 0x01);
uint8_t * value
Definition co_dictionary.h:9
The returned value is a vector of uint8_t representing a raw data buffer.
To write a device parameter value (e.g., 0x607A: Target position), use:
std::vector<uint8_t>
value{0xe2, 0x04, 0x00, 0x00};
auto success = device.writeSdo(0x607a, 0x00,
value);
There's a better, type-safe way to read and write parameter values. It requires first loading the parameters:
device.loadParameters(false);
This loads parameter metadata from the device into an internal parameter map. Refer to the mm::comm::base::Parameter class for more details. Once the SPoE device has its parameters loaded, you can upload (read) and download (write) parameters using concrete types. These operations will automatically update the stored parameter value.
auto voltage = device.upload<uint32_t>(0x6079, 0x00);
device.download<int32_t>(0x607a, 0x00, 543);
You can also retrieve a parameter and check its value after upload or download:
auto& parameter = device.findParameter(0x607a, 0x00);
assert(parameter.getValue<int32_t>() == 543);
Files
To read a file from the device:
std::vector<uint8_t> data = device.readFile(".hardware_description");
To write a file to the device:
std::vector<uint8_t> fileData(5000, 0xFF);
device.writeFile("ui.config.json", fileData);
If you write app_firmware.bin or com_firmware.bin, you must trigger a firmware update afterward:
device.triggerFirmwareUpdate();
To read the list of available files:
std::vector<std::string> list = device.readFileList(true);
To remove a file from the device:
device.removeFile("ui.config.json");
Process Data
Process data exchange works similarly to SDO communication. You can either use raw data buffers or a simplified, parameter-based interface.
Raw buffer example:
std::vector<uint8_t> outputs(35, 0x00);
std::vector<uint8_t> inputs = device.sendAndReceiveProcessData(outputs);
With the simplified interface, start by loading parameter metadata:
device.loadParameters(false);
Then retrieve and modify a parameter value, for example:
auto& parameter = device.findParameter(0x607a, 0x00);
parameter.setValue<int32_t>(123)
To perform the process data exchange and automatically update parameter values based on the PDO mapping:
device.exchangeProcessDataAndUpdateParameters();
This will send all mapped RxPDO parameter values, receive TxPDO values from the device, and update the corresponding local parameters.
Note: The PDO map is currently static and defined internally by the SpoeDevice. In future versions, it will be dynamically refreshed when loadParameters() is called.
Configuring a DHCP Server
This configuration applies only to firmware that uses the EtherNet/IP protocol.
For devices with PROFINET, use Siemens PRONETA to assign IP addresses.
To assign IP addresses to devices running PROFINET firmware on Linux, you can use pnio_dcp.
PROFINET (PRONETA)
In PRONETA, follow these steps:
- Go to Network Analysis.
- Select Adapter.
- Choose Ethernet.
PRONETA will assign an IP address to the device and display the assigned address.
Windows
Download the DHCP Server
Download the DHCP Server for Windows from https://www.dhcpserver.de/cms/download/.
Extract the Server Files
Extract the contents to C:\dhcpsrv2.5.2.
Add Configuration File
Copy the dhcpsrv.ini file into the extracted folder (C:\dhcpsrv2.5.2).
[SETTINGS]
IPPOOL_1=192.168.100.5-254
IPBIND_1=192.168.100.1
AssociateBindsToPools=1
Trace=1
DeleteOnRelease=0
ExpiredLeaseTimeout=3600
[GENERAL]
LEASETIME=86400
NODETYPE=8
SUBNETMASK=255.255.255.0
NEXTSERVER=192.168.100.1
ROUTER_0=0.0.0.0
[DNS-SETTINGS]
EnableDNS=0
[TFTP-SETTINGS]
EnableTFTP=0
ROOT=C:\dhcpsrv2.5.2\wwwroot
WritePermission=0
[HTTP-SETTINGS]
EnableHTTP=1
ROOT=C:\dhcpsrv2.5.2\wwwroot
[40-49-8A-01-21-04]
IPADDR=192.168.100.5
AutoConfig=04/08/2025 13:03:01
LeaseEnd=1744196934
- Configure Ethernet Adapter
- Open Network Connections.
- For your Ethernet adapter, open the properties for Internet Protocol Version 4 (TCP/IPv4).
- Set the following static IP configuration:
- IP Address: 192.168.100.1
- Subnet Mask: 255.255.255.0
- Start the DHCP Server
- Run C:\dhcpsrv2.5.2\dhcpsrv.exe.
- Click Admin, then Service START, and finally Continue as tray app.
- Verify DHCP Assignment
- Right-click the tray icon labeled DHCP Server v2.5.2.3 and select Open Status.
- Under SERVER_0 > DHCP Clients, you should see the assigned IP 192.168.100.5, indicating the device successfully received its address from the DHCP server.
Linux
Install ISC DHCP Server
sudo apt update
sudo apt install isc-dhcp-server
Edit DHCP configurations
sudo vim /etc/default/isc-dhcp-server
INTERFACESv4="eth0"
sudo vim /etc/dhcp/dhcpd.conf
subnet 192.168.100.0 netmask 255.255.255.0 {
range 192.168.100.10 192.168.100.20;
option routers 192.168.100.1;
option subnet-mask 255.255.255.0;
option domain-name-servers 8.8.8.8, 8.8.4.4;
}
host special-client {
hardware ethernet cc:96:e5:b5:43:52;
fixed-address 192.168.100.10;
}
Assign Static IP address
sudo nmcli connection modify eth0 ipv4.addresses 192.168.100.1/24
sudo nmcli connection modify eth0 ipv4.gateway 192.168.100.1
sudo nmcli connection modify eth0 ipv4.dns "8.8.8.8 8.8.4.4"
sudo nmcli connection modify eth0 ipv4.method manual
sudo nmcli connection up eth0
Alternatively, configure it via Settings > Network > Wired.
Verify the configuration:
ip addr show eth0
3: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether cc:96:e5:b5:43:52 brd ff:ff:ff:ff:ff:ff
inet 192.168.100.1/24 brd 192.168.100.255 scope global noprefixroute eth0
valid_lft forever preferred_lft forever
inet6 fe80::613d:20c3:e823:bdfd/64 scope link noprefixroute
valid_lft forever preferred_lft forever
Restart the DHCP server
sudo systemctl restart isc-dhcp-server
sudo systemctl status isc-dhcp-server
If you encounter problems starting the DHCP server, try changing the permissions of the leases file:
sudo chmod 777 /var/lib/dhcp/dhcpd.leases
Next, verify that the device received the assigned IP address:
Notes
- The default socket port is 8080.
- Firmware versions can be read using the read file command:
- Use cversion to retrieve the firmware version.
- Use bversion to retrieve the bootloader version.