modbus协议的认识和libmodbus库使用

一、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;
}

其余命令均和夹爪控制类似,模仿构造即可。

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值