i have written code for slave using SOEM library at the output terminal it has shown is it initialized and configured and all those things but it is not able to send command to slave which is blink LED i dont know what wrong im doing can you help with this,is it related to some PDO mapping and all .if yes how to write it in code please explain .i want to record time stamp when command send from master .and when master received that command.
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include <chrono> // For timestamp handling
#include "ethercat.h"
#include "ethercattype.h"
#include "osal.h"
#include "osal_defs.h"
#include "nicdrv.h"
#define SLAVE_ADDRESS 0x1001
#define COMMAND_BLINK_LED 0x01
int main(int argc, char *argv[])
{
char IOmap[4096];
char *ifname = "enp5s0f1"; // Network interface for EtherCAT communication
int slaveCount = 0;
uint16_t slaveState = 0;
printf("Starting EtherCAT mastern");
// Initialize SOEM, bind socket to ifname
if(!ec_init(ifname))
{
printf("Failed to initialize EtherCAT mastern");
return 1;
}
printf("ec_init on %s succeeded.n", ifname);
// Find and auto-config slaves
if (ec_config_init(FALSE) <= 0)
{
printf("No slaves foundn");
ec_close();
return 1;
}
printf("%d slaves found and configured.n", ec_slavecount);
// Map the IOmap
ec_config_map(&IOmap);
// Configure DC
ec_configdc();
printf("Slaves mapped, state to SAFE_OP.n");
// Wait for all slaves to reach SAFE_OP state
ec_statecheck(0, EC_STATE_SAFE_OP, EC_TIMEOUTSTATE * 4);
printf("Request pre-operational state for all slavesn");
// Request pre-operational state for all slaves
ec_slave[0].state = EC_STATE_PRE_OP;
ec_writestate(0);
ec_statecheck(0, EC_STATE_PRE_OP, EC_TIMEOUTSTATE * 4);
// Use PDO mapping from the XML file, typically 0x1600 and 0x1A00 for Rx and Tx respectively
ec_slave[1].SM[2].StartAddr = 0x1700; // Replace with actual RxPDO index from XML if different
ec_slave[1].SM[3].StartAddr = 0x1800; // Replace with actual TxPDO index from XML if different
ec_slave[1].SMtype[2] = 3; // Outputs
ec_slave[1].SMtype[3] = 4; // Inputs
ec_config_map(&IOmap);
printf("Request operational state for all slavesn");
// Request operational state for all slaves
ec_slave[0].state = EC_STATE_OPERATIONAL;
ec_writestate(0);
// Wait for all slaves to reach OP state
int chk = 200;
do
{
ec_send_processdata();
ec_receive_processdata(EC_TIMEOUTRET);
ec_statecheck(0, EC_STATE_OPERATIONAL, 50000);
}
while (chk-- && (ec_slave[0].state != EC_STATE_OPERATIONAL));
if (ec_slave[0].state == EC_STATE_OPERATIONAL)
{
printf("Operational state reached for all slaves.n");
// Record the timestamp before sending the command
auto commandSentTimestamp = std::chrono::steady_clock::now();
// Send the "Blink LED" command
uint8_t *slaveOutput = ec_slave[1].outputs;
slaveOutput[0] = COMMAND_BLINK_LED;
ec_send_processdata();
ec_receive_processdata(EC_TIMEOUTRET);
// Record the timestamp after sending the command
auto commandReceivedTimestamp = std::chrono::steady_clock::now();
// Print the timestamps
std::chrono::duration<double, std::milli> timeDiff = commandReceivedTimestamp - commandSentTimestamp;
printf("Command sent at: %.3f msn", std::chrono::time_point_cast<std::chrono::milliseconds>(commandSentTimestamp).time_since_epoch().count());
printf("Command received at: %.3f msn", std::chrono::time_point_cast<std::chrono::milliseconds>(commandReceivedTimestamp).time_since_epoch().count());
printf("Time difference: %.3f msn", timeDiff.count());
}
else
{
printf("Not all slaves reached operational state.n");
ec_readstate();
for (int i = 1; i <= ec_slavecount; i++)
{
if (ec_slave[i].state != EC_STATE_OPERATIONAL)
{
printf("Slave %d State=0x%2.2x StatusCode=0x%4.4x : %sn", i, ec_slave[i].state, ec_slave[i].ALstatuscode, ec_ALstatuscode2string(ec_slave[i].ALstatuscode));
}
}
}
printf("nRequest init state for all slavesn");
ec_slave[0].state = EC_STATE_INIT;
// Request INIT state for all slaves
ec_writestate(0);
// Clean up
ec_close();
return 0;
}