Как читать из modbus / tcp, используя libmodbus - PullRequest
0 голосов
/ 24 мая 2019

У меня есть moxa ioLogik E1214, и я хочу общаться с ним, используя modbus / tcp. Я нашел библиотеку, которая должна это делать - libmodbus . Сначала я скопировал пример кода с их веб-сайта и изменил его так, чтобы он выглядел так:

#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;
}

Соединение работает, но у меня проблемы с чтением регистров. В документации есть некоторые параметры с описанием, начальным адресом, длиной и т. Д., Это выглядит так: moxa documentation

Итак, я понимаю, что использование int read_val = modbus_read_registers(mb, 0, length, tab_reg); должно прочитать значение с адреса 0 и сохранить его в tab_reg. Но я получаю ошибку «Неверный адрес данных». То же самое относится и к другим адресам, которые я пытался прочитать.

Итак, подведем итог - я все правильно понимаю? Как мне использовать libmodbus для фактического чтения регистров?

Ответы [ 2 ]

1 голос
/ 12 июня 2019

Вы пытаетесь использовать «регистры чтения» (значения int16), когда вы хотите «прочитать катушку» (биты). Катушки и регистры хранятся в отдельных таблицах и поэтому адресуются по-разному.

Используйте modbus_read_bits для считывания RLY_status, поскольку, как указано в вашей документации, это значение катушки.

Вам нужно будет читать входные и удерживающие регистры не так, как катушки. Ваш пример кода должен быть удобен для чтения регистров хранения.

1 голос
/ 24 мая 2019

Похоже, у вашего ведомого нет никаких регистров хранения по адресу 0, и поэтому он жалуется на ошибку illegal data address.

Вам нужно взглянуть на имеющуюся у вас карту регистров Modbus и соответственно использовать правильную функцию Modbus из libmodbus. Например, если вы хотите прочитать вашу переменную RLY_pulseOnWidth, вы должны использовать:

int read_val = modbus_read_input_registers(mb, 52, length, tab_reg);

Но читать RLY_TotalCount:

int read_val = modbus_read_registers(mb, 64, length, tab_reg);

Здесь вы можете проверить все коды функций Modbus, относящиеся к вашему столбцу «Тип точки»:

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

...