ubuntu下libmodbus库的使用

工作项目中,机器人要完成一个电源管理的功能,自带可充电触点接触充电的电池,具体参数不表,代码要完成通过无线网络与西门子的PLC通信,从而控制充电房的开门与关门,以及控制充电处的继电器的开启与关闭,协议是modbus-tcp。因此在网上找来好用的开源库——libmodbus。记录下简单使用过程。
下载地址:
download 选择v3.0.6长期稳定版

本文分为以下部分:

  • 源码安装
  • 测试与使用

源码安装

下载完压缩包放至/home目录下,解压:

tar -zxvf libmodbus-3.0.6.tar.gz

进入libmodbus-3.0.6目录:
cd libmodbus-3.0.6

配置:
./configure

编译与安装:
make && make install

测试与使用

测试

demo:

  modbus_t *mb;
  uint16_t tab_reg[32];

  mb = modbus_new_tcp("127.0.0.1", 1502);
  modbus_connect(mb);

  /* Read 5 registers from the address 0 */
  modbus_read_registers(mb, 0, 5, tab_reg);

  modbus_close(mb);
  modbus_free(mb);

测试modbus-tcp协议通信,代码里使用本地回环地址,端口1502:
进入tests目录打开一个终端,启动server程序:
./unit-test-server tcp
在目录打开另一个终端,启动client程序:
./unit-test-client tcp
启动会打印出很多信息。

使用

而自己使用也需要精简例子代码,并按实际需要更改ip和端口:
libmodbus-3.0.6目录下新建一个mytest目录。
mkdir mytest

将所需头文件拷入,头文件均位于目录src中:
cp modbus.h modbus-rtu.h modbus-tcp.h ../mytest

进入该目录:
cd mytest

创建自己代码main.c如下:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
const uint16_t UT_INPUT_REGISTERS_ADDRESS = 0x1;
const uint16_t UT_BITS_ADDRESS = 0x04;
const uint16_t UT_INPUT_REGISTERS_NB = 0xA;
const uint16_t UT_INPUT_REGISTERS_TAB[] = { 0x000A };
int main(int argc, char const *argv[])
{
    int nb = 0x25;
    int rc = 0;
    modbus_t *ctx;
    uint8_t *tab_rp_bits;
    tab_rp_bits = (uint8_t *) malloc(nb * sizeof(uint8_t));
    memset(tab_rp_bits, 0, nb * sizeof(uint8_t));
    ctx = modbus_new_tcp("192.168.1.120", 502);
    if(ctx == NULL)
    {
        fprintf(stderr, "Unable to allocate libmodbus context\n");
        return -1;
    }

    if(modbus_connect(ctx) == -1)
    {
        fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno));
        modbus_free(ctx);
        return -1;
    }
    while(1)
    {
        rc = modbus_write_bit(ctx, UT_BITS_ADDRESS, 1);
        if (rc != 1) 
        {
            printf("FAILED (nb points %d)\n", rc);
        }
        rc = modbus_read_bits(ctx, UT_BITS_ADDRESS, 1, tab_rp_bits);
        printf("modbus_read_bits 1 \n modbus_read_bits: \n");
        if (rc != 1) 
        {
            printf("FAILED (nb points %d)\n", rc);

        }
        printf("tab_rp_bits [0] is %d\n",tab_rp_bits[0]);
        memset(tab_rp_bits, 0, nb * sizeof(uint8_t));
        sleep(1);
        rc = modbus_write_bit(ctx, UT_BITS_ADDRESS, 0);
        if (rc != 1) 
        {
            printf("FAILED (nb points %d)\n", rc);
        }
        rc = modbus_read_bits(ctx, UT_BITS_ADDRESS, 1, tab_rp_bits);
        printf("modbus_read_bits 0 \n modbus_read_bits: \n");
        if (rc != 1) 
        {
            printf("FAILED (nb points %d)\n", rc);
        }
        printf("tab_rp_bits [0] is %d\n",tab_rp_bits[0]);
        sleep(1);
    }
    modbus_close(ctx);
    modbus_free(ctx);
    return 0;
}

ip 192.168.1.120
端口 502
上述代码功能是:控制读写地址为0x04位的coil status状态,使其不停的反转,在PLC上表现就是指示灯的闪烁。

编译:
cc -o main main.c -lmodbus -I ./
如果链接不过,报错缺so文件,就找到相关的so文件,并复制到/usr/local/lib目录下,并运行ldonfig

运行:
./main

你可能感兴趣的:(通信)