首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用libmodbus读取modbus/tcp

如何使用libmodbus读取modbus/tcp
EN

Stack Overflow用户
提问于 2019-05-24 16:59:30
回答 2查看 1.9K关注 0票数 1

我有一个moxa ioLogik E1214,我想使用modbus/tcp与它通信。我找到了一个可以做到这一点的库-- libmodbus。首先,我从他们的网站上复制了代码样本,并对其进行了一些修改,使其看起来像这样:

代码语言:javascript
复制
#include <stdio.h>
#ifndef _MSC_VER
#include <unistd.h>
#include <sys/time.h>
#endif
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <errno.h>
#include <modbus.h>
#define G_MSEC_PER_SEC 1000

int main(int argc, char *argv[])
{
    modbus_t *mb;
    uint16_t tab_reg[30];
    int length = 6;

    mb = modbus_new_tcp("192.168.127.254", 502);
    if (modbus_connect(mb) == -1) {
        fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno));
        modbus_free(mb);
        return -1;
    }

    /* Read "length" registers from the address 0 */
    int read_val = modbus_read_registers(mb, 0, length, tab_reg);

    if(read_val==-1)
        printf("ERROR: %s\n", modbus_strerror(errno));
    else
    {
        printf("Read registers: %d\n", read_val);
        for(int i=0; i<length; i++)
        {
            printf("%d ", tab_reg[i]);
        }
        printf("\n");
    }
    modbus_close(mb);
    modbus_free(mb);
    return 0;
}

连接工作正常,但我在读取寄存器时遇到问题。在文档中有一些参数,包括描述、起始地址、长度等,如下所示:

因此,我知道使用int read_val = modbus_read_registers(mb, 0, length, tab_reg);应该从地址0读取一个值并将其存储在tab_reg中。但我得到错误“非法数据地址”。对于我尝试读取的其他地址也是如此。

那么,总而言之--我是否理解正确了?我应该如何使用libmodbus来实际读取寄存器?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-05-24 18:50:44

您的从机似乎在地址0处没有任何保持寄存器,因此它会报错illegal data address错误。

您需要查看您拥有的Modbus寄存器映射,并相应地使用libmodbus中正确的Modbus函数。例如,如果您想要读取变量RLY_pulseOnWidth,则必须使用:

代码语言:javascript
复制
int read_val = modbus_read_input_registers(mb, 52, length, tab_reg);

但要阅读RLY_TotalCount

代码语言:javascript
复制
int read_val = modbus_read_registers(mb, 64, length, tab_reg);

您可以在此处检查与您的"Point Type“列相关的所有Modbus功能代码:

https://github.com/stephane/libmodbus/blob/ddac0cf909d9ab05423df7b9a66e6e60e8bb0fbb/src/modbus.h

票数 1
EN

Stack Overflow用户

发布于 2019-06-13 00:14:42

您正在尝试使用“读取寄存器”(int16值),而您需要的是“读取线圈”(位)。线圈和寄存器存储在不同的表中,因此寻址方式不同。

使用modbus_read_bits读出RLY_status,因为正如您的文档所述,它是一个线圈值。

您将需要读取输入和保持寄存器的方式与线圈不同。您的示例代码应该可以很好地读出保持寄存器。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56289189

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档