Modbus 创建客户端

  1. libmodbus 支持 RTU 方式和 TCP/IP 方式;
  2. 传感器使用的是modbus RTU方式
  3. 构造RTU数据帧,并且响应 modbus 请求的一方是 server/slave,而发出请求的一方是 client/master,并且双方通信总是由 client/master 一方发起。所以温湿度传感器是server/slave一方

1. TCP/IP 方式


1.创建一个 modbus_t 类型的 context

     // modbus_t *modbus_new_tcp(const char *ip, int port);

    modbus_t *ctx;
    ctx = modbus_new_tcp("192.168.2.212", 1502);
    modbus_set_debug(ctx, TRUE);  // 是否显示调试信息


2.建立连接

    // int modbus_connect(modbus_t *ctx);
    modbus_connect(ctx);


3.设置超时时间:(这一步不一定需要)

    struct timeval t;
    t.tv_sec = 0;
    t.tv_usec = 1000000;//1000ms
    modbus_set_response_timeout(ctx,&t);


4.读写寄存器的值

    /* SINGLE REGISTER */
    // int modbus_write_register(modbus_t *ctx, int addr, int value);
    // int modbus_read_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest)

    rc = modbus_write_register(ctx, addr, tab_rq_registers[0]);
    if (rc != 1) {
        // error
    } else {
        rc = modbus_read_registers(ctx, addr, 1, tab_rp_registers);
        if (rc != 1) {
            // error
        } else {
            // if error
    }
}


5.释放并关闭modbus

    modbus_close(ctx);
    modbus_free(ctx);


2. RTU


1.创建一个modbus_t类型的context,用来打开串口:

    // modbus_t *modbus_new_rtu(const char *device, int baud, char parity, int data_bit, int stop_bit);
    modbus_t  *ctx;
    ctx = modbus_new_rtu("/dev/ttyUSB0", 19200, 'N', 8, 1);
    modbus_set_slave(ctx, 0x01);  // 设置 slave 地址, 温湿度传感器的modbus站地址为0x01


2.建立连接

    modbus_connect(ctx);//建立和传感器的连接


3.设置超时时间:

    struct timeval t;
    t.tv_sec = 0;
    t.tv_usec = 1000000;//1000ms
    modbus_set_response_timeout(ctx,&t);


5.读写寄存器的值
.同 TCP/IP





示例1. TCP/IP

/*
 * The client of modbus tcp.
 * test 2 register
 *
 * 2017-10-26
 */

#include 
#include 
#include 
#include 
#include 


int main(void)
{
    modbus_t *ctx=NULL;     // context
    int addr=0;             // address
    int rc=0;               // received
    int nb = 3;             // the number of bit

    uint16_t *tab_rq_registers=NULL;
    uint16_t *tab_rp_registers=NULL;

    /* TCP */
    ctx = modbus_new_tcp("192.168.2.29", 1502);
    modbus_set_debug(ctx, TRUE);
    // connect
    if (-1 == modbus_connect(ctx))
    {
        fprintf(stderr, "Conncetion failed: %s\n", modbus_strerror(errno));
        modbus_free(ctx);
        return -1;
    }

    /* Allocate and initialize the memory spaces. */
    tab_rq_registers = (uint16_t *) malloc(nb * sizeof(uint16_t));
    memset(tab_rq_registers, 0, nb * sizeof(uint16_t));
    tab_rp_registers = (uint16_t *) malloc(nb * sizeof(uint16_t));
    memset(tab_rp_registers, 0, nb * sizeof(uint16_t));


    // write
    tab_rq_registers[0] = 25;
    tab_rq_registers[1] = 2;
    tab_rq_registers[2] = 88;


    rc = modbus_write_registers(ctx, addr, nb, tab_rq_registers);
    if (rc != nb)
    {
        printf("ERROR modbus_write_bits single (%d)\n", rc);
        printf("address = %d\n", addr);
    }

    // read
    rc = modbus_read_registers(ctx, addr, nb, tab_rp_registers);
    if (rc != nb)
    {
        printf("ERROR modbus_read_bits single (%d)\n", rc);
        printf("address = %d\n", addr);
    }
    for (int i = 0; i < nb; ++i)
    {
        printf("%d%c", tab_rp_registers[i], (i==nb-1)?'\n':' ');
    }   
        
    free(tab_rq_registers);
    free(tab_rp_registers);
    /* Close the connection */
    modbus_close(ctx);
    modbus_free(ctx);
    
    return 0;
}   


示例2. RTU


#include 
#include 
#include 
#include 
#include 


int main(void)
{
    modbus_t *ctx=NULL;     // context
    int addr=0;             // address
    int rc=0;               // received
    int nb = 3;             // the number of bit

    uint16_t *tab_rq_registers=NULL;
    uint16_t *tab_rp_registers=NULL;

    /* RTU */
    ctx = modbus_new_rtu("/dev/ttySAC3",9600,'N',8,1);
    modbus_set_debug(ctx, TRUE);
    modbus_set_slave(ctx, 0x01);  // 设置从机地址

    // connect
    if (-1 == modbus_connect(ctx))
    {
        fprintf(stderr, "Conncetion failed: %s\n", modbus_strerror(errno));
        modbus_free(ctx);
        return -1;
    }

    // 读取数据
    uint16_t tab_reg[2];  // 存放要读的数据
    int regs=modbus_read_registers(ctx,0,2,tab_reg);

    /* Close the connection */
    modbus_close(ctx);
    modbus_free(ctx);

    return 0;
}





[reference]
[1] stuyou 使用libmodbus读传感器流程
[2] CUC_Tony Modbus RTU程序开发解读

你可能感兴趣的:(Modbus 创建客户端)