Skip to main content

Communication Module

Plugins can act as master/slave stations, supporting protocol types such as modbus, and can be used to control laser devices, end-effector grippers, welding machines, etc. Communication Module

Ethercat Communication

Read and control slave stations through interfaces. Users can inherit the EcatBaseAPI base class and initialize it in launch. Configure the corresponding hardware connections and data addresses Call SetPdoValue and other corresponding API interfaces to implement.

Usage Example:

#include "ehtercat/ecat_base_api.hpp"

class WeldingMachine:public xcore_api::ecat::EcatBaseAPI{
public:
WeldingMachine(int slave_id):xcore_api::ecat::EcatBaseAPI(slave_id){
RegisterVolPdo();
}
virtual ~WeldingMachine(){}
bool Init(){
return InitEcat();
}
int RegisterVolPdo(){
uint16_t index = 0;
uint16_t byteoffs = 4;
uint16_t bytelen = 4;
// Assign data to m_pdo_vol
return RegisterPdo(m_pdo_vol,index,byteoffs,bytelen);
}
int SetVol(const int vol){
int value = vol;
return SetPdoValue(m_pdo_vol,&value);
}
private:
xecat::PdoAPI m_pdo_vol;
}
// Use interface to set voltage
int slave_id = 10;
WeldingMachine obj(slave_id);
if(obj->Init()){
obj->SetVol(10);
};

Analog Communication

Read and set IO signals, register values, etc. through interfaces.

#include "io/analog_api.hpp"
auto ptr = xcore_api::io::Analog::getInstance();
ptr->SetDOValue("DO0_1",false);
ptr->WriteBoolRegister("regname",true,0);

Register Function Codes

Custom function codes can be implemented: Use the function code API in the Plugin to declare function codes and register them to display in the HMI function code list. Register Function Code

  1. Bind read-only register When the register value changes, the function code will be called to execute the corresponding logic
  2. Bind write-only register Execute the function code function and write to the register. Custom register communication functions can be implemented.

Usage Example:

//1 Declare function code class
DECLARE_FUNCTION_CODE_API(PluginReadReg);

/**
* @brief Implement function code class
*/
FUNCTION_CODE_EXECUTE_API(PluginReadReg){
std::vector<int> v;
ReadIntRegValue(v);
std::string str;
for(auto &item:v){
str += std::to_string(item) + ",";
}
LOG_INFO<<"PluginReadReg:"<<str;
return true;
}

/**
* @brief Create function code instance
*/
std::shared_ptr<xreg::FuncCodeAPI> makeReadRegCmd(){
xreg::FuncCodeCfgAPI cfg;
cfg.SetName("plugin_read_reg_cmd");
cfg.SetSupportType({xreg::RegTypeAPI::BIT,xreg::RegTypeAPI::BOOL,xreg::RegTypeAPI::BYTE,xre g::RegTypeAPI::INT16,xreg::RegTypeAPI::INT32});
cfg.SetLen(1);
cfg.SetWriteable(false);
return std::make_shared<PluginReadReg>(cfg);
}

//4 Register the function code class to the control system during the initialization stage
xreg::RegFuncCodeAPI(makeReadRegCmd());

Example: Function Code
Write Function Code
Function Code Read Write Register

modbus Communication

Taking modbus tcp master as an example:

void ModbusExample() {
std::thread t([](){
using namespace xcore_api::fieldbus;
ModbusCfgAPI cfg(DeviceTypeAPI::MODBUS_TCP_MASTER);
cfg.SetName("plugin_master");
// Set to own slave station's ip
cfg.SetIp("192.168.2.213");
// If slave station does not support reading coils and other operations, set to 0, otherwise it may affect function
cfg.SetCoilsNum(0);
cfg.SetDiscInputNum(0);
FieldbusAPI api(cfg);
int i = 0;
uint16_t src[10] = {0};
uint16_t dest[10] = {0};
api.Open();
while(1){
++i;
int rc = api.ReadRegisters(40000, dest) ;
LOG_DEBUG<<"read registers:"<<rc<< " read value:"<<dest[0];
++src[0];
rc = api.WriteRegisters(40005, src);
LOG_DEBUG<<"write registers:"<<rc<<" write value: "<<src[0];
std::this_thread::sleep_for(std::chrono::seconds(10));
}
api.Close();
});
t.detach();
}

Use modbus slave to set up the slave station, and you can see the data at the corresponding data bits of the slave station. Slave Data 1
Slave Data 2