一、modbus协议
MODBUS协议支持传统的RS-232、RS-422、RS-485和以太网设备。许多工业设备,包括PLC,DCS,智能仪表等都在使用Modbus协议作为他们之间的通讯标准。
modbus的功能代码:
0x01: 读线圈寄存器
0x02: 读离散输入寄存器
0x03: 读保持寄存器
0x04: 读输入寄存器
0x05: 写单个线圈寄存器
0x06: 写单个保持寄存器
0x0f: 写多个线圈寄存器
0x10: 写多个保持寄存器
详见:https://blog.csdn.net/lingshi75/article/details/105991450/
二、libmodbus
使用教程地址:https://libmodbus.org/docs/v3.1.6/
目前有两种通信形式,串口通信和tcp/ip通信
二(1)、以Z-ERG机械夹爪为例,演示如何使用libmodbus进行串口通信
通过串口连接对应设备
modbus_t* Hand::rtuConnect(modbus_t* ctx,const char *device, int baud, char parity, int data_bit, int stop_bit,int mode)
{
ctx = modbus_new_rtu (device,baud,parity,data_bit,stop_bit);
if ( ctx == nullptr) {
fprintf(stderr,"Unable to create the libmodbus context\n");
return nullptr;
}
modbus_set_slave ( ctx , 1);
modbus_rtu_set_serial_mode(ctx,mode);
modbus_rtu_set_rts(ctx, MODBUS_RTU_RTS_UP);
if( modbus_connect(ctx) == - 1 ){
fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno));
modbus_free (ctx);
return nullptr;
}
return ctx;
}
/**
* @brief loosen hand
* @param ctx a printer of context of modbus
* @param address register address
* @return success:0 failed:-1
*/
int32_t Hand::initialization(modbus_t* ctx, int address){
int rc = modbus_write_register( ctx ,address,1);
//对应modbus功能0x06;
if( rc == - 1 ){
fprintf(stderr, "%s\n ", modbus_strerror (errno));
return -1 ;
}
return 0;
}
/**
* @brief modbus_write_register
* @param ctx a printer of context of modbus
* @param address register address
* @param value float value written to register
* @return success:0 failed:-1
*/
int32_t Hand::write(modbus_t* ctx, int address, float value){
uint16_t dest[2];
modbus_set_float_cdab(value,dest); //注释1
int rc = modbus_write_registers( ctx ,address, 2, dest);
//对应modbus功能0x10;
if( rc == - 1 ){
fprintf(stderr, "%s\n ", modbus_strerror (errno));
return -1 ;
}
return 0;
}
上图注释1部分要留意,如何设置多位寄存器值的字节序
二(2)、以某转台为例,演示如何使用libmodbus进行tcp/ip通信
modbus_t* RotaryTable::tcpConnect(modbus_t* ctx,const char *ip, int port)
{
ctx = modbus_new_tcp(ip, port);
if (ctx == nullptr) {
fprintf(stderr, "Unable to allocate libmodbus context\n");
return nullptr;
}
if (modbus_connect(ctx) == -1) {
fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno));
modbus_free(ctx);
return nullptr;
}
return ctx;
}
其余命令均和夹爪控制类似,模仿构造即可。