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 <modbus.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>


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 <modbus.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>


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程序开发解读

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,172评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,346评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,788评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,299评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,409评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,467评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,476评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,262评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,699评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,994评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,167评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,827评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,499评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,149评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,387评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,028评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,055评论 2 352

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,644评论 18 139
  • ## Generated by install_server.sh ## # Redis configuratio...
    依然饭太稀阅读 2,027评论 0 5
  • 从三月份找实习到现在,面了一些公司,挂了不少,但最终还是拿到小米、百度、阿里、京东、新浪、CVTE、乐视家的研发岗...
    时芥蓝阅读 42,224评论 11 349
  • 第三场跳蚤集市精彩瞬间回顾 这两位小朋友都是第一次做小掌柜,两人互相交易。以后满满的都是回忆。下次妈妈要把孩子的现...
    栋栋妈妈阅读 438评论 0 0
  • 舞 你旋转你拥有的一切 脚趾,臀部,隐秘的秘密 世界是一个椭圆形 斑斓大坑 也是你的蝴蝶翅膀 还在旋转 裙子扭开了...
    我是不是蝎大人阅读 169评论 0 0